Compare commits

...
199 Commits
Author SHA1 Message Date
Budi UtomoandGitHub 9a714e5fb3 Merge pull request #111 from devilankur18/custom_args
Able to pass custom arguments to Emulator
2018-08-21 16:23:22 +02:00
Ankur Agarwal a6394bcf74 added support for custom arguments while running/creating emulator 2018-08-21 17:50:50 +05:30
Budi UtomoandGitHub f3abb0a828 Merge pull request #110 from devilankur18/emulator_backup_restore
AVD initialisation based on devices xml file
2018-08-16 18:04:20 +02:00
Ankur Agarwal c653efc7b1 fixes related to initialization 2018-08-16 12:36:51 +00:00
butomo1989 d7c9730712 Fixed issue #90 2018-08-03 15:58:07 +02:00
butomo1989 735bc64a2d Cleaned up 2018-08-03 15:56:36 +02:00
butomo1989 307d6502af Fixed string 2018-08-02 12:52:31 +02:00
butomo1989 91a4e270c6 Refactored code 2018-08-02 11:42:19 +02:00
Budi UtomoandGitHub d13e60a122 Merge pull request #104 from devilankur18/master
Added device_id support via ENV variable or auto uuid values
2018-07-31 09:04:58 +02:00
Ankur AgarwalandGitHub c4be3a1ac0 Merge branch 'master' into master 2018-07-31 01:24:15 +05:30
Ankur AgarwalandGitHub 7c7eed4a3d Fixing trailing whitespaces 2018-07-31 01:17:01 +05:30
Budi UtomoandGitHub d0271e0be0 Merge pull request #103 from mehrdad-abdoli/master
Update Google Play Store app
2018-07-30 17:00:42 +02:00
App-Test 9d71ecded7 Update Google Play Services and some other useful stuff by adb 2018-07-30 16:30:19 +04:30
App-Test 81af88e7a4 Update Google Play Services and some other useful stuff by adb 2018-07-30 16:28:41 +04:30
App-Test a8f7fd2d02 Update Google Play Services and some other useful stuff by adb 2018-07-30 16:26:57 +04:30
App-Test de71e5156c Update Google Play Services and some other useful stuff by adb 2018-07-30 16:19:05 +04:30
Ankur AgarwalandGitHub bcf27f0489 Added logging 2018-07-28 23:20:06 +05:30
Ankur AgarwalandGitHub 972445a8bc Assign device_id via environment variable 2018-07-28 23:07:03 +05:30
App-Test 460e0b8daf Update Google Play Services and some other useful stuff by adb 2018-07-28 16:53:26 +04:30
Budi UtomoandGitHub 3673d195ea Updated Readme 2018-07-25 12:27:09 +02:00
Budi UtomoandGitHub 77c6ac8507 Updated Readme 2018-07-25 12:24:34 +02:00
Budi UtomoandGitHub cd35f4a3ab Merge pull request #100 from bonigarcia/master
Download proper version of chromedriver for each Android version
2018-07-25 12:20:11 +02:00
Boni Garcia 217df7cd65 Include browser name, browser version, and chromedriver version in Docker images table 2018-07-25 11:44:21 +02:00
Boni Garcia ccfdef4fe8 Set default chromedriver version 2018-07-24 17:18:41 +02:00
Boni Garcia b40ec48136 Download proper version of chromedriver 2018-07-24 15:59:11 +02:00
Budi UtomoandGitHub 064331de0e Merge pull request #97 from shadow1163/issue87
Once container start, add flag -wipe-data to command.
2018-07-20 08:01:40 +02:00
Budi UtomoandGitHub 5ef52ca622 Merge branch 'master' into issue87 2018-07-20 07:57:23 +02:00
junbo 15c51a4ab1 roll back is_initialized 2018-07-20 09:53:46 +08:00
Budi UtomoandGitHub 7e2b364c08 Merge pull request #96 from JoeSSS/patch-2
Add information about connecting to adb from outside the container in README
2018-07-19 13:02:04 +02:00
Serghei MoretandGitHub 0b18e4995c Update README.md 2018-07-19 12:41:04 +02:00
Serghei MoretandGitHub f0fb5ef009 Update README.md 2018-07-19 12:39:16 +02:00
Serghei MoretandGitHub ec0c381fb6 Update README.md 2018-07-19 12:38:24 +02:00
Serghei MoretandGitHub 58f7693024 Add adbkey part to README 2018-07-19 12:35:28 +02:00
junbo 40f6e67d83 fix issue 87 2018-07-19 18:11:59 +08:00
Budi UtomoandGitHub 852daa4e32 Merge pull request #92 from red-avtovo/mymaster
Initialise emulator just once
2018-07-10 19:10:49 +02:00
Aleksandr Bochev bf65a73eb1 removed time dependency 2018-07-10 18:45:29 +02:00
Aleksandr Bochev 3577d7e0a1 fixed emulator is unauthorized
performed avd creation just once
2018-07-10 18:34:53 +02:00
Budi UtomoandGitHub 1371744b36 Merge pull request #89 from JoeSSS/patch-1
Fix issue #86
2018-07-09 21:20:51 +02:00
Serghei MoretandGitHub cf3b1cf683 Fix adb getting into the loop 2018-07-09 18:06:58 +02:00
Budi UtomoandGitHub 416a88143f Updated README.md 2018-07-06 10:33:17 +02:00
butomo1989 55719bb638 Use Chrome driver version for Chrome that is inside Emulator 2018-07-05 22:40:41 +02:00
butomo1989 c22fe34e7c Updated README.md 2018-07-05 21:21:24 +02:00
butomo1989 69154410f2 Updated 2018-07-05 21:11:21 +02:00
butomo1989 4975ebcc47 Cleaned up 2018-07-05 21:06:00 +02:00
butomo1989 e4180a6e65 Passed chrome driver version through environment variable 2018-07-05 20:10:47 +02:00
butomo1989 e22b8f141e Removed arm image 2018-07-05 20:04:25 +02:00
butomo1989 7d29525b48 Build version 8.0 and 8.1 2018-07-05 19:56:14 +02:00
butomo1989 f47cc495b0 Merge branch 'release-1.1' of github.com:butomo1989/docker-android into release-1.1 2018-07-05 19:51:46 +02:00
butomo1989 bc516d5a8e Updated permission 2018-07-05 19:11:14 +02:00
Budi UtomoandGitHub b54fcd2087 Merge pull request #72 from greenerchen/patch-2
Build docker images with play store
2018-07-05 17:50:00 +02:00
Greener ChenandGitHub 7e7d12e4e8 Merge branch 'release-1.1' into patch-2 2018-07-05 23:34:22 +08:00
Budi UtomoandGitHub 8d9fc61158 Merge pull request #83 from bonigarcia/master
Use latest version of chromedriver
2018-07-05 17:01:19 +02:00
Budi UtomoandGitHub bc5635ed0a Merge pull request #81 from JoeSSS/JoeSSS-patch-1
Support for Android 8.0 and 8.1
2018-07-05 15:32:59 +02:00
Serghei MoretandGitHub 0b7ca97939 Merge branch 'release-1.1' into JoeSSS-patch-1 2018-07-05 15:28:54 +02:00
Budi UtomoandGitHub 7e0a2e4770 Merge pull request #85 from red-avtovo/sdk_installation_cleanup
cleaned sdk installation
2018-07-05 15:25:35 +02:00
Serghei Moret c82443e221 Update release.sh 2018-07-05 14:29:54 +02:00
Boni Garcia 1d7b7c2ac7 Improve script to download latest version of chromedriver automatically 2018-07-05 12:56:10 +02:00
Aleksandr Bochev 59f792f7c0 cleaned sdk installation 2018-07-05 12:23:13 +02:00
Boni Garcia 84ac59f66a Update chromedriver version to 2.40 2018-07-05 11:41:09 +02:00
Serghei MoretandGitHub d176e69cc1 Let default emulator pick the right kernel 2018-07-03 20:46:23 +02:00
Serghei MoretandGitHub 59f61e057e Update Emulator_x86 2018-07-03 20:44:13 +02:00
butomo1989 601d58c51f Changed apk path 2018-06-28 01:03:27 +02:00
butomo1989 ac33a1f687 Changed apk path 2018-06-28 00:47:49 +02:00
butomo1989 91ebdbf5ab Edited permission 2018-06-28 00:43:26 +02:00
butomo1989 c8fb92e400 Using adb version inside container 2018-06-26 22:53:34 +02:00
butomo1989 80a64e82dd Added demo how to use Genymotion cloud 2018-06-25 23:53:06 +02:00
butomo1989 780278b519 Edited README.md 2018-06-25 22:56:05 +02:00
butomo1989 b4544ae90f Cleaned up Dockerfile 2018-06-25 22:54:01 +02:00
butomo1989 0af1143e72 Deleted genymotion manual installation 2018-06-25 22:48:30 +02:00
butomo1989 48eb6bf9ae Edited README.md 2018-06-22 02:34:29 +02:00
butomo1989 f8940c79f5 Cleaned up 2018-06-22 02:32:01 +02:00
butomo1989 4b7d2aa125 Deleted unused parameter 2018-06-22 02:23:21 +02:00
butomo1989 d4832ad2b8 Fixed unit test 2018-06-22 01:37:54 +02:00
butomo1989 54d5365907 Cleaned up 2018-06-22 01:16:40 +02:00
butomo1989 2922e3ba92 Cleaned up 2018-06-22 00:34:43 +02:00
butomo1989 820b6e0e0e Enable debug modus for emulator 2018-06-21 21:16:54 +02:00
butomo1989 75514ef1f0 Updated README.md 2018-06-20 23:32:34 +02:00
butomo1989 ab34ca36d9 Enabled relaxed security 2018-06-20 23:30:54 +02:00
butomo1989 15f6541621 Fixed if-else logic 2018-06-20 23:28:41 +02:00
butomo1989 99c1b1f6b6 Using the latest base image 2018-06-20 21:10:59 +02:00
butomo1989 32258461be Enable to specify port 2018-06-19 01:20:15 +02:00
butomo1989 b7f332fd3b Added genymotion logo 2018-06-19 00:07:32 +02:00
butomo1989 09068f20c5 Formatted 2018-06-19 00:01:33 +02:00
butomo1989 59bf049159 Updated supported OS 2018-06-18 23:45:59 +02:00
butomo1989 d6b69863ca Cleaned up 2018-06-12 01:05:35 +02:00
butomo1989 68d0c2fc81 Cleaned up 2018-06-06 23:35:59 +02:00
butomo1989 5b89a28198 Renamed docker-image 2018-05-30 00:57:21 +02:00
butomo1989 705be0e3c9 Added auto-stop feature 2018-05-30 00:54:06 +02:00
butomo1989 b5f8c28fc1 Edited path 2018-05-30 00:51:16 +02:00
butomo1989 79f797213c Added integreation with geny cloud 2018-05-29 02:04:30 +02:00
butomo1989 424b6bb2ec Added script to revert a release 2018-05-29 00:09:28 +02:00
butomo1989 efccb144a4 Updated selenium hub 2018-05-29 00:08:14 +02:00
butomo1989 a960f34381 Updated base image 2018-05-28 21:02:26 +02:00
butomo1989 11e3428145 Added how to enable proxy inside container 2018-05-26 16:07:12 +02:00
butomo1989 cde35287c7 Using the latest base image 2018-05-12 13:13:21 +02:00
butomo1989 29898ba91e Fixed issue #52 2018-05-11 00:43:16 +02:00
butomo1989 2d25517bfa Using the latest version of docker-appium 2018-04-29 20:06:17 +02:00
Budi UtomoandGitHub e3219ac24b Changed order 2018-04-23 19:25:24 +02:00
Budi UtomoandGitHub c4fb6243c5 Fixed tag 2018-04-23 19:23:54 +02:00
Budi UtomoandGitHub d021fd69e6 Added video conference 2018-04-23 19:22:10 +02:00
butomo1989 cacfe568a2 Added video image 2018-04-23 21:17:41 +02:00
Diego MolinaandGitHub 9d0c66fb2b Merge branch 'master' into patch-2 2018-04-09 11:38:33 +02:00
butomo1989 cb100330ad Using appium-docker-android docker image for executing Appium UI-Test 2018-03-21 19:08:48 +01:00
butomo1989 bc0972318f Using the latest version of docker-selenium 2018-03-21 12:29:54 +01:00
Greener Chen 2b02843cfd Build docker images with play store for emulators with x86 processor and API 24 or later version 2018-03-12 01:41:16 +08:00
Budi UtomoandGitHub 3a88fa4ae4 Merge pull request #71 from greenerchen/patch-1
Add instructions for VMWare or Parallels Desktop
2018-03-05 13:44:18 +01:00
Greener Chen 398a694ccd Add supplementary images 2018-03-05 18:37:19 +08:00
Greener ChenandGitHub 14a29344b8 Add instructions for VMWare or Parallels Desktop 2018-03-05 18:28:07 +08:00
butomo1989 47621a7ccb Added sample how to build Android project 2018-02-17 10:00:03 +01:00
butomo1989 c1d66496fb Added GitHub templates 2018-02-17 09:59:09 +01:00
Budi UtomoandGitHub 1365ec736b Replaced code line 2018-02-13 11:18:50 +01:00
butomo1989 4aee17de2d Deleted unused image 2018-02-12 18:47:02 +01:00
butomo1989 5c9ad32522 Automated some steps in screen mirroring for real device 2018-02-12 18:09:14 +01:00
butomo1989 366aa8b3b3 Added real device configuration in docker-compose 2018-02-12 11:07:37 +01:00
butomo1989 905f2c723b Using the latest base image 2018-02-12 10:49:26 +01:00
Budi UtomoandGitHub 0e028d9a4a Updated version of docker-selenium hub 2018-02-06 20:33:24 +01:00
butomo1989 ce61b992f9 Using the newest version of base image 2018-01-29 16:57:46 +01:00
butomo1989 e62573036c Added dockerandroid logo 2017-11-23 21:03:12 +01:00
butomo1989 e27b2e5fdf Edited permission 2017-11-21 15:39:08 +01:00
butomo1989 fdd4a86c40 Merge remote-tracking branch 'origin/master' into release-0.9 2017-11-14 15:40:21 +01:00
Budi UtomoandGitHub 15012fd3b4 Edited README.md 2017-11-14 15:38:46 +01:00
butomo1989 1f440e1a07 Using the latest image 2017-11-09 11:44:35 +01:00
butomo1989 567a494ccb Using new usage process of new SDK 2017-11-09 11:25:21 +01:00
butomo1989 d28c4dc5e0 Fixed docker images 2017-11-07 17:33:22 +01:00
butomo1989 7a052b7e2f Merge remote-tracking branch 'origin' into update-sdk 2017-11-03 12:26:05 +01:00
butomo1989 988397318f Updated README.md 2017-11-03 11:15:38 +01:00
butomo1989 0d6356ba47 Upgraded README.md 2017-11-01 15:53:25 +01:00
butomo1989 0ea71ea6b8 Refactored auto-recording function 2017-10-30 20:42:36 +01:00
butomo1989 08ff64d950 Fixed docker-compose volume 2017-10-30 20:41:27 +01:00
butomo1989 fcffca21ff Fixed error due to file name 2017-10-27 21:02:00 +02:00
butomo1989 95adfd1fbd Installed jq 2017-10-27 21:00:10 +02:00
butomo1989 5029d33528 Fixed error 2017-10-27 20:59:19 +02:00
Budi UtomoandGitHub c9ab42ecfb Merge pull request #28 from thelittlefireman/master
fix file error when start/stop/start container
2017-08-01 16:16:12 +02:00
thelittlefiremanandGitHub 7c48af9b84 fix codacy-bot warrning 2017-08-01 10:30:04 +02:00
thelittlefiremanandGitHub e1d6e3cdbe delete useless code 2017-07-31 15:58:38 +02:00
thelittlefiremanandGitHub 648010d519 delete useless code 2017-07-31 15:56:50 +02:00
thelittlefiremanandGitHub 9d3cb60f41 add unit test last case 2017-07-31 15:28:33 +02:00
thelittlefiremanandGitHub e2ad6b75d2 add unit test to symlink_force 2017-07-31 15:12:46 +02:00
thelittlefiremanandGitHub 486fb5825b fix bad python impl 2017-07-29 22:51:36 +02:00
thelittlefiremanandGitHub e56eb0e3ab fix : file already exist on start and stop container 2017-07-28 22:45:34 +02:00
thelittlefiremanandGitHub 6fe6a80f40 Merge pull request #1 from thelittlefireman/thelittlefireman-fix-files-already-exist
fix python error when files already exist
2017-07-28 15:15:08 +02:00
thelittlefiremanandGitHub f7b30c3129 fix python error when files already exist
related to :
```
  File "/usr/lib/python3.5/runpy.py", line 184, in _run_module_as_main                                                                                                                                 
    "__main__", mod_spec)                                                                                                                                                                              
  File "/usr/lib/python3.5/runpy.py", line 85, in _run_code                                                                                                                                            
    exec(code, run_globals)                                                                                                                                                                            
  File "/root/src/app.py", line 189, in <module>                                                                                                                                                       
    run()                                                                                                                                                                                              
  File "/root/src/app.py", line 178, in run                                                                                                                                                            
    prepare_avd(device, avd_name)                                                                                                                                                                      
  File "/root/src/app.py", line 74, in prepare_avd                                                                                                                                                     
    os.symlink(os.path.join(skin_rsc_path, s), os.path.join(skin_dst_path, s))                                                                                                                         
FileExistsError: [Errno 17] File exists: '/root/devices/skins/galaxy_nexus' -> '/root/platforms/android-25/skins/galaxy_nexus'                                                                         
Traceback (most recent call last):                                                                                                                                                                     
  File "/usr/lib/python3.5/runpy.py", line 184, in _run_module_as_main                                                                                                                                 
    "__main__", mod_spec)                                                                                                                                                                              
  File "/usr/lib/python3.5/runpy.py", line 85, in _run_code                                                                                                                                            
    exec(code, run_globals)                                                                                                                                                                            
  File "/root/src/app.py", line 189, in <module>                                                                                                                                                       
    run()                                                                                                                                                                                              
  File "/root/src/app.py", line 178, in run                                                                                                                                                            
    prepare_avd(device, avd_name)                                                                                                                                                                      
  File "/root/src/app.py", line 74, in prepare_avd                                                                                                                                                     
    os.symlink(os.path.join(skin_rsc_path, s), os.path.join(skin_dst_path, s))                                                                                                                         
FileExistsError: [Errno 17] File exists: '/root/devices/skins/galaxy_nexus' -> '/root/platforms/android-25/skins/galaxy_nexus' 
```
2017-07-28 15:13:45 +02:00
butomo1989 1062da3dcc Fixed installation issue 2017-07-18 17:44:09 +02:00
butomo1989 c431118465 Using the latest image version of appium-docker-android 2017-07-18 12:06:38 +02:00
butomo1989 b6a1a57bed Enable video recording 2017-07-14 20:40:14 +02:00
butomo1989 83baa09384 Fixed not expected error in supervisor 2017-07-13 18:55:32 +02:00
Budi UtomoandGitHub 8a69c64de3 Merge pull request #22 from andrcuns/real_device_mirroring
Real device mirroring
2017-07-08 23:57:52 +02:00
Andrejs Cunskis 488e53149c Release script for image with real device support 2017-07-07 23:46:04 +03:00
Andrejs Cunskis 2bc30edf4c Add support for real device and screen mirroring 2017-07-03 22:50:37 +03:00
butomo1989 8d544448f1 All badges in one line 2017-06-29 09:05:56 +02:00
The Gitter BadgerandBudi Utomo f7b560a28b Add Gitter badge (#19) 2017-06-29 09:04:05 +02:00
butomo1989 0e578710f3 Automated all steps from PR #12 2017-06-14 15:06:01 +02:00
butomo1989 65df456066 Using docker-appium as base image 2017-06-14 15:04:19 +02:00
butomo1989 5b694c2c55 Fixed issue #13 regarding arm image for 6.0 2017-06-09 11:59:07 +02:00
AndrejsandBudi Utomo 6406504f94 Possibility to run appium with custom chromedriver executable (#12)
* Possibility to run appium with custom chromedriver executable
* Unit test added
* README update
2017-06-09 10:44:58 +02:00
butomo1989 b7c4538896 Downgraded selenium to be able to run E2E Tests 2017-06-02 16:55:51 +02:00
butomo1989 c7d988bd61 Refactored 2017-06-02 15:30:51 +02:00
butomo1989 47e968927a Updated Sample and End2End Tests 2017-06-02 14:49:55 +02:00
butomo1989 dcf196ec4a Run E2E Tests only if needed 2017-06-02 13:18:00 +02:00
butomo1989 aff1b062e1 Added End-2-End Test 2017-06-02 12:14:14 +02:00
butomo1989 59f6e4bd33 Mocked os package in unit tests to clear all warning messages 2017-05-30 17:25:07 +02:00
butomo1989 0b9af7e6b2 Using git tag for same docker images 2017-05-30 16:28:28 +02:00
butomo1989 d9b5f8d86c Using latest version of build tool 2017-05-30 16:26:09 +02:00
butomo1989 0360c181c0 Cleaned up 2017-05-29 14:34:35 +02:00
budi utomoandGitHub 47ff7bf223 Merge pull request #10 from ilya-netomedia/patch-1
Increase unregister delay timeout
2017-05-26 10:28:07 +02:00
ilya-netomediaandGitHub bedf77e83d Update app.py
The Problem : Selenium grid 3.0.1 marking the node as down
Solution: Node config should be changed
2017-05-25 17:48:59 +03:00
budi utomoandGitHub 151e3a8d6f Merge pull request #8 from andrcuns/appium_host_for_scale_support
Support docker-compose scale when connecting to selenium hub
2017-05-24 23:36:39 +02:00
Andrejs Cunskis 7170ee20d4 Fix method name and build 6.0 without google_apis 2017-05-24 17:00:29 +03:00
Andrejs Cunskis 768d793ba0 Merge remote-tracking branch 'upstream/master' into appium_host_for_scale_support 2017-05-24 16:51:59 +03:00
Andrejs Cunskis 5501a20426 Set default browser, mobile web test parameter and docker compose example 2017-05-24 15:50:34 +03:00
butomo1989 1a7453d6b6 Added codacy badge 2017-05-24 12:01:10 +02:00
butomo1989 d379133801 Renamed method to fix codacy violation 2017-05-24 11:52:48 +02:00
Andrejs Cunskis 333c2b2a90 Fix unit tests 2017-05-23 16:57:53 +03:00
Andrejs Cunskis ab45f6bb52 Support for docker-compose scale and set default browserName 2017-05-23 16:47:41 +03:00
Andrejs Cunskis a2e59992d9 Set container ip as default APPIUM_HOST address 2017-05-23 10:12:45 +03:00
butomo1989 e9ed10d08c Splitted into different Dockerfiles to optimize size for each docker image 2017-05-22 13:20:30 +02:00
budi utomoandGitHub d1a1bb5fa7 Deleted parentheses in README.md 2017-05-19 13:42:15 +02:00
butomo1989 c3c7f9506f Using UIAutomator2 for UI test example for better performance 2017-05-19 13:37:25 +02:00
butomo1989 8c4d947833 Updated README 2017-05-19 11:17:19 +02:00
butomo1989 80bbf1bd36 Using latest version of build-tool 2017-05-19 11:16:59 +02:00
butomo1989 f05d2564fa Added more timeout in health check to support arm docker image 2017-05-19 11:16:15 +02:00
budi utomoandGitHub 81e63fb88e Merge pull request #5 from andrcuns/container_health_check
Container health check based on Android Emulator boot completion
2017-05-15 16:15:23 +02:00
Andrejs Cunskis a7c9be6fc3 Container health check based on Android Emulator boot completion 2017-05-15 14:31:26 +03:00
budi utomoandGitHub 76393754fb Updated README.md 2017-05-04 16:32:01 +02:00
budi utomoandGitHub 10eb1b0d31 Merge pull request #3 from andrcuns/chrome_driver_fix
Fix chromedriver linux missing shared library libgconf-2.so.4 error
2017-05-04 10:23:41 +02:00
Andrejs Cunskis c3ad9b3d48 Fix chromedriver linux missing shared library libgconf-2.so.4 error 2017-05-04 01:29:41 +03:00
butomo1989 e2a0b7c840 Put only working devices 2017-04-26 16:34:27 +02:00
butomo1989 e325706d17 Fixed android 5.0.1 and 5.1.1 2017-04-26 15:16:26 +02:00
butomo1989 3679a9bd48 Renamed log file 2017-04-26 14:19:46 +02:00
butomo1989 666489987b Use build matrix to speed up build and push processes 2017-04-26 11:42:40 +02:00
butomo1989 b785d70389 Updated README.md 2017-04-26 11:38:20 +02:00
butomo1989 f1663eb05e Renamed avd in sample UI tests 2017-04-24 15:50:18 +02:00
butomo1989 e46800e322 Cleaned up README.md 2017-04-24 14:04:16 +02:00
butomo1989 d2843d7260 Silent mode to reduce logs 2017-04-21 15:50:12 +02:00
butomo1989 67726cf735 Updated unit test 2017-04-21 15:27:54 +02:00
butomo1989 e59c28ebd8 Turn off appium server by default 2017-04-21 15:18:01 +02:00
butomo1989 7ce3cfba96 Using google_apis 2017-04-21 15:06:53 +02:00
butomo1989 63e64d219b Changed path of target apk 2017-04-21 13:46:04 +02:00
butomo1989 2ef82e3894 Added android 7.0 in the list 2017-04-21 11:23:24 +02:00
57 changed files with 1643 additions and 347 deletions
+1
View File
@@ -0,0 +1 @@
*.mp4 filter=lfs diff=lfs merge=lfs -text
+22
View File
@@ -0,0 +1,22 @@
**Please make sure that it is an issue / a feature request. If it is a question / help wanted, please visit [our group chat](https://gitter.im/butomo1989/docker-android). Thank you!**
Operating System:
<!-- OSX Yosemite, Ubuntu 16.04, Windows 10 etc -->
Docker Image:
<!-- butomo1989/docker-android-x86-7.1.1, butomo1989/docker-android-real-device etc -->
Docker Version:
<!-- 17.09.0-ce, 17.06.2-ce etc -->
Docker-compose version (Only if you use it):
<!-- 1.16.1 etc -->
Docker Command to start docker-android:
<!-- docker run ... -->
## Expected Behavior
<!-- Explaination about expected behaviour goes here -->
## Actual Behavior
<!-- Explaination about actual behaviour goes here -->
+12
View File
@@ -0,0 +1,12 @@
### Purpose of changes
<!-- Please describe why this change is required / What problem you want to solve. -->
### Types of changes
_Put an `x` in the boxes that apply_
- [ ] Bug fix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
### How has this been tested?
<!-- Please describe in detail how you tested your changes. -->
+1 -1
View File
@@ -6,4 +6,4 @@
.coverage
coverage.xml
xunit.xml
coverage/*
coverage/*
+10
View File
@@ -10,6 +10,16 @@ services:
install: "pip install -r requirements.txt"
env:
- ANDROID_VERSION=5.0.1
- ANDROID_VERSION=5.1.1
- ANDROID_VERSION=6.0
- ANDROID_VERSION=7.0
- ANDROID_VERSION=7.1.1
- ANDROID_VERSION=8.0
- ANDROID_VERSION=8.1
- REAL_DEVICE=True
script: bash travis.sh
after_success:
+299 -81
View File
@@ -1,65 +1,90 @@
Docker-Android
==============
<p align="center">
<img id="header" src="./images/logo_dockerandroid_small.png" />
</p>
[![Join the chat at https://gitter.im/butomo1989/docker-android](https://badges.gitter.im/butomo1989/docker-android.svg)](https://gitter.im/butomo1989/docker-android?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![Build Status](https://travis-ci.org/butomo1989/docker-android.svg?branch=master)](https://travis-ci.org/butomo1989/docker-android)
[![Docker Pulls](https://img.shields.io/docker/pulls/butomo1989/docker-android-x86-7.1.1.svg?style=flat-square&style=plastic)](https://hub.docker.com/r/butomo1989/docker-android-x86-7.1.1/)
[![codecov](https://codecov.io/gh/butomo1989/docker-android/branch/master/graph/badge.svg)](https://codecov.io/gh/butomo1989/docker-android)
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/3f000ffb97db45a59161814e1434c429)](https://www.codacy.com/app/butomo1989/docker-appium?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=butomo1989/docker-appium&amp;utm_campaign=Badge_Grade)
Android in docker solution with noVNC supported
Docker-Android is a docker image built to be used for everything related to mobile website testing and Android project.
<p align="center">
<a href="https://youtu.be/pQdpjuYwvp8"><img src="./images/appiumconf2018.png" alt="Appium Conference 2018" width="600"></a>
</p>
Emulator - Samsung Device | Emulator - Nexus Device | Real Device
:---------------------------:|:---------------------------:|:---------------------------:
![][emulator samsung] |![][emulator nexus] |![][real device]
Purpose
-------
1. Run UI tests for mobile websites with [appium]
2. Build Android project and run unit tests with the latest build-tools
3. Run UI tests for Android applications with different frameworks ([appium], [espresso], [robotium], etc.)
4. Run monkey / stress tests
5. SMS testing
Advantages compare with other docker-android projects
-----------------------------------------------------
1. noVNC to see what happen inside docker container
2. Emulator for different devices / skins, such as Samsung Galaxy S6, LG Nexus 4, HTC Nexus One and more.
3. Ability to connect to Selenium Grid
4. Ability to control emulator from outside container by using adb connect
5. Support real devices with screen mirroring
6. Ability to record video during test execution for debugging
7. Open source with more features coming
List of Docker images
---------------------
|OS |Android |API |Browser |Browser version |Chromedriver |Image |Size |
|:---|:---|:---|:---|:---|:---|:---|:---|
|Linux|5.0.1|21|browser|37.0|2.12|butomo1989/docker-android-x86-5.0.1|[![](https://images.microbadger.com/badges/image/butomo1989/docker-android-x86-5.0.1.svg)](https://microbadger.com/images/butomo1989/docker-android-x86-5.0.1 "Get your own image badge on microbadger.com")|
|Linux|5.1.1|22|browser|39.0|2.13|butomo1989/docker-android-x86-5.1.1|[![](https://images.microbadger.com/badges/image/butomo1989/docker-android-x86-5.1.1.svg)](https://microbadger.com/images/butomo1989/docker-android-x86-5.1.1 "Get your own image badge on microbadger.com")|
|Linux|6.0|23|browser|44.0|2.18|butomo1989/docker-android-x86-6.0|[![](https://images.microbadger.com/badges/image/butomo1989/docker-android-x86-6.0.svg)](https://microbadger.com/images/butomo1989/docker-android-x86-6.0 "Get your own image badge on microbadger.com")|
|Linux|7.0|24|chrome|51.0|2.23|butomo1989/docker-android-x86-7.0|[![](https://images.microbadger.com/badges/image/butomo1989/docker-android-x86-7.0.svg)](https://microbadger.com/images/butomo1989/docker-android-x86-7.0 "Get your own image badge on microbadger.com")|
|Linux|7.1.1|25|chrome|55.0|2.28|butomo1989/docker-android-x86-7.1.1|[![](https://images.microbadger.com/badges/image/butomo1989/docker-android-x86-7.1.1.svg)](https://microbadger.com/images/butomo1989/docker-android-x86-7.1.1 "Get your own image badge on microbadger.com")|
|Linux|8.0|26|chrome|58.0|2.31|butomo1989/docker-android-x86-8.0|[![](https://images.microbadger.com/badges/image/butomo1989/docker-android-x86-8.0.svg)](https://microbadger.com/images/butomo1989/docker-android-x86-8.0 "Get your own image badge on microbadger.com")|
|Linux|8.1|27|chrome|61.0|2.33|butomo1989/docker-android-x86-8.1|[![](https://images.microbadger.com/badges/image/butomo1989/docker-android-x86-8.1.svg)](https://microbadger.com/images/butomo1989/docker-android-x86-8.1 "Get your own image badge on microbadger.com")|
|All |-|-|-|-|-|butomo1989/docker-android-real-device|[![](https://images.microbadger.com/badges/image/butomo1989/docker-android-real-device.svg)](https://microbadger.com/images/butomo1989/docker-android-real-device "Get your own image badge on microbadger.com")|
|Linux|All|All|All|All|All|butomo1989/docker-android-genymotion|[![](https://images.microbadger.com/badges/image/butomo1989/docker-android-genymotion.svg)](https://microbadger.com/images/butomo1989/docker-android-genymotion "Get your own image badge on microbadger.com")|
List of Devices
---------------
Type | Device Name
----- | -----
Phone | Samsung Galaxy S6
Phone | Nexus 4
Phone | Nexus 5
Phone | Nexus One
Phone | Nexus S
Tablet | Nexus 7
Requirements
------------
Docker is installed in your system.
Purpose
-------
1. Build android project / application and run unit test
2. Run UI Test for mobile website with appium framework
3. Run UI Test for mobile application with different frameworks (appium, espresso, etc.)
4. Simulate Short Message Service (SMS)
Features
--------
1. Android emulator with different devices
2. latest build-tool (version 25.0.2)
3. noVNC to see what happen inside docker container
4. Appium server for automation test framework and it is able to connect with selenium grid
List of Docker images
---------------------
|Supported OS |Android version |API level |Image name |Image status |
|:---|:---|:---|:---|:---:|
|Linux|5.0.1|21|butomo1989/docker-android-x86-5.0.1|[![](https://images.microbadger.com/badges/image/butomo1989/docker-android-x86-5.0.1.svg)](https://microbadger.com/images/butomo1989/docker-android-x86-5.0.1 "Get your own image badge on microbadger.com")|
|Linux|5.1.1|22|butomo1989/docker-android-x86-5.1.1|[![](https://images.microbadger.com/badges/image/butomo1989/docker-android-x86-5.1.1.svg)](https://microbadger.com/images/butomo1989/docker-android-x86-5.1.1 "Get your own image badge on microbadger.com")|
|Linux|6.0|23|butomo1989/docker-android-x86-6.0|[![](https://images.microbadger.com/badges/image/butomo1989/docker-android-x86-6.0.svg)](https://microbadger.com/images/butomo1989/docker-android-x86-6.0 "Get your own image badge on microbadger.com")|
|Linux|7.0|24|*TODO* because still have a Bug||
|Linux|7.1.1|25|*TODO* because still have a Bug||
|OSX / Windows|5.0.1|21|butomo1989/docker-android-arm-5.0.1|[![](https://images.microbadger.com/badges/image/butomo1989/docker-android-arm-5.0.1.svg)](https://microbadger.com/images/butomo1989/docker-android-arm-5.0.1 "Get your own image badge on microbadger.com")|
|OSX / Windows|5.1.1|22|butomo1989/docker-android-arm-5.1.1|[![](https://images.microbadger.com/badges/image/butomo1989/docker-android-arm-5.1.1.svg)](https://microbadger.com/images/butomo1989/docker-android-arm-5.1.1 "Get your own image badge on microbadger.com")|
|OSX / Windows|6.0|23|butomo1989/docker-android-arm-6.0|[![](https://images.microbadger.com/badges/image/butomo1989/docker-android-arm-6.0.svg)](https://microbadger.com/images/butomo1989/docker-android-arm-6.0 "Get your own image badge on microbadger.com")|
|OSX / Windows|7.0|24|*TODO* because still have a Bug||
|OSX / Windows|7.1.1|25|*TODO* because still have a Bug||
Quick Start
-----------
1. Enable **Virtualization** under **System Setup** in **BIOS**. (It is only for Ubuntu OS. If you use different OS, you can skip this step).
1. Run docker-android
2. Run docker-android
- For ***Linux OS***, please use image name that contains "x86"
```bash
docker run --privileged -d -p 6080:6080 -p 4723:4723 -p 5554:5554 -p 5555:5555 -e DEVICE="Samsung Galaxy S6" -e APPIUM=False --name android-container butomo1989/docker-android-x86-5.0.1
```
```bash
docker run --privileged -d -p 6080:6080 -p 5554:5554 -p 5555:5555 -e DEVICE="Samsung Galaxy S6" --name android-container butomo1989/docker-android-x86-8.1
```
**Optional arguments**
- For ***OSX*** and ***Windows OS***, please use Virtual Machine that support Virtualization with Ubuntu OS
-v <android_project_or_apk>:/root : You need to share volume or apk file if for example you want to build the android project inside docker container or you want to run UI test by using appium.
-e APPIUM=True: If you want to use appium as UI test framework to test mobile website or android application
3. Verify the ip address of docker-machine.
2. Verify the ip address of docker host.
- For OSX, you can find out by using following command:
@@ -69,45 +94,144 @@ Quick Start
- For different OS, localhost should work.
4. Open ***http://docker-machine-ip-address:6080*** from web browser.
3. Open ***http://docker-host-ip-address:6080*** from web browser.
![][noVNC]
Run Appium Server
-----------------
Appium is automation test framework to test mobile website and mobile application, including android. To be able to use appium, you need to run appium-server. You run appium server inside docker-android container by ***opening port 4723*** and ***passing an environment variable APPIUM=true***.
```bash
docker run --privileged -d -p 6080:6080 -p 5554:5554 -p 5555:5555 -p 4723:4723 -e DEVICE="Samsung Galaxy S6" -e APPIUM=true --name android-container butomo1989/docker-android-x86-8.1
```
### Connect to Selenium Grid
It is also possible to connect appium server that run inside docker-android with selenium grid by passing following environment variables:
- CONNECT\_TO\_GRID=true
- APPIUM_HOST="\<host\_ip\_address>"
- APPIUM_PORT=\<port\_number>
- SELENIUM_HOST="\<host\_ip\_address>"
- SELENIUM_PORT=\<port\_number>
To run tests for mobile browser, following parameter can be passed:
- MOBILE\_WEB\_TEST=true
```bash
docker run --privileged -d -p 6080:6080 -p 4723:4723 -p 5554:5554 -p 5555:5555 -e DEVICE="Samsung Galaxy S6" -e APPIUM=true -e CONNECT_TO_GRID=true -e APPIUM_HOST="127.0.0.1" -e APPIUM_PORT=4723 -e SELENIUM_HOST="172.17.0.1" -e SELENIUM_PORT=4444 -e MOBILE_WEB_TEST=true --name android-container butomo1989/docker-android-x86-8.1
```
### Custom Emulator Arguments
If you want to add more arguments for running emulator, you can ***pass an evnironemnt variable EMULATOR_ARGS*** while running docker command.
```bash
docker run --privileged -d -p 6080:6080 -p 4723:4723 -p 5554:5554 -p 5555:5555 -e DEVICE="Samsung Galaxy S6" -e EMULATOR_ARGS="-no-snapshot-load -partition-size 512" -e APPIUM=true -e CONNECT_TO_GRID=true -e APPIUM_HOST="127.0.0.1" -e APPIUM_PORT=4723 -e SELENIUM_HOST="172.17.0.1" -e SELENIUM_PORT=4444 -e MOBILE_WEB_TEST=true --name android-container butomo1989/docker-android-x86-8.1
```
### Back & Restore
If you want to backup/reuse the avds created with furture upgrades or for replication, run the container with two extra mounts
- -v local_backup/.android:/root/.android
- -v local_backup/android_emulator:/root/android_emulator
```bash
docker run --privileged -d -p 6080:6080 -p 4723:4723 -p 5554:5554 -p 5555:5555 -v local_backup/.android:/root/.android -v local_backup/android_emulator:local_backup/android_emulator -e DEVICE="Nexus 5" -e APPIUM=true -e CONNECT_TO_GRID=true -e APPIUM_HOST="127.0.0.1" -e APPIUM_PORT=4723 -e SELENIUM_HOST="172.17.0.1" -e SELENIUM_PORT=4444 --name android-container butomo1989/docker-android-x86-8.1
```
For the first run, this will create a new avd and all the changes will be accessible in the `local_backup` directory.
Now for all future runs, it will reuse the avds. Even this should work with new releases of `docker-android`
Connect to Selenium Grid
------------------------
### Share Volume
This feature can be used only if you set **APPIUM=True** in environment variable.
If you want to use appium to test UI of your android application, you need to share volume where the APK is located to folder ***/root/tmp***.
**Arguments**
```bash
docker run --privileged -d -p 6080:6080 -p 4723:4723 -p 5554:5554 -p 5555:5555 -v $PWD/example/sample_apk:/root/tmp -e DEVICE="Nexus 5" -e APPIUM=true -e CONNECT_TO_GRID=true -e APPIUM_HOST="127.0.0.1" -e APPIUM_PORT=4723 -e SELENIUM_HOST="172.17.0.1" -e SELENIUM_PORT=4444 --name android-container butomo1989/docker-android-x86-8.1
```
-e CONNECT_TO_GRID=True : to connect appium server to your selenium grid.
-e APPIUM_HOST="<host_ip_address>": where / on which instance appium server is running. Default value: 127.0.0.1
-e APPIUM_PORT=<port_number>: which port appium server is running. Default port: 4723
-e SELENIUM_HOST="<host_ip_address>": where / on which instance selenium grid is running. Default value: 172.17.0.1
-e SELENIUM_PORT=<port_number>: which port selenium grid is running. default port: 4444
### Video Recording
![][connect to grid 1] ![][connect to grid 2]
You can deactivate auto_record by changing the value to "False" in docker-compose file. e.g. change value to "False" in this [line].
List of Devices
---------------
### Language
Type | Device Name
--- | ---
Phone | Samsung Galaxy S6
Phone | Nexus 4
Phone | Nexus 5
Phone | Nexus 5x
Phone | Nexus 6
Phone | Nexus 6P
Phone | Nexus One
Phone | Nexus S
Tablet | Pixel C
Tablet | Nexus 7
Tablet | Nexus 9
Tablet | Nexus 10
You can change the language setting of Android Emulator on the fly by passing following environment variable:
- LANGUAGE="\<language>"
- COUNTRY="\<country>"
### Docker-Compose
![][compose]
There is [example of compose file] to run complete selenium grid and docker-android container as nodes. [docker-compose] version [1.13.0] or higher is required to be able to execute that compose file.
```bash
docker-compose up -d
```
### Google Play Services and Google Play Store
The Docker "Android Emulator" images contain Google Play Service (v12.8.74) and Google Play Store (v11.0.50). Both applications are downloaded from [apklinker](https://www.apklinker.com/), so please be aware of it in case you use private/company account to that applications.
Build Android project
---------------------
docker-android can be used for building Android project and executing its unit test. This following steps will illustrate how to build Android project:
1. Clone [this sample test project](https://github.com/googlesamples/android-testing).
```bash
git clone git@github.com:googlesamples/android-testing.git
```
2. Build the project
```bash
docker run -it --rm -v $PWD/android-testing/ui/espresso/BasicSample:/root/tmp butomo1989/docker-android-x86-8.1 tmp/gradlew build
```
Proxy
-----
You can enable proxy inside container by passing following environment variables:
- HTTP_PROXY="\<language>docker\_bridge\_ip\_address>"
- HTTPS_PROXY="\<docker\_bridge\_ip\_address>"
- NO_PROXY="localhost"
Relaxed Security
-----
Pass environment variable RELAXED_SECURITY=true to disable additional security check to use some advanced features.
Genymotion
----------
![Genymotion](images/logo_genymotion.png)
Docker-Android supports [Genymotion Cloud].
You can easily scale your Appium tests on Genymotion Android virtual devices in the cloud.
Use [device.json] to define the device to start. You can specify the port on which the device will start so you don't need to change the device name in your tests every time you need to run those tests. Then run following command
```bash
export USER="xxx"
export PASS="xxx"
export LICENSE="xxx"
docker run -it --rm -p 4723:4723 -v $PWD/genymotion/example/sample_devices:/root/tmp -e USER=$USER -e PASS=$PASS -e LICENSE=$LICENSE butomo1989/docker-android-genymotion
```
You can also use [this docker-compose file].
<p align="center">
<a href="https://youtu.be/jXhUEyaVeMY"><img src="./images/Genymotion_cloud.png" alt="Docker-Android supports Genymotion Cloud" width="600"></a>
</p>
![][galaxy s6] ![][nexus 5]
Control android emulator outside container
------------------------------------------
@@ -120,6 +244,15 @@ adb connect <docker-machine-ip-address>:5555
**Note:** You need to have Android Debug Bridge (adb) installed in your host machine.
Get rid of unauthorized device popup while connecting to the emulator outside the container
------------------------------------------
In order to connect to the emulator using already generated adbkey on your machine you will need to mount your `.android` folder to the container (this is needed only when you work with emulator based on playstore image):
```
docker run -v <local Android key directory>:/root/.android/ ...
```
SMS Simulation
--------------
@@ -154,23 +287,108 @@ SMS Simulation
docker exec -it android-container adb emu sms send <phone_number> <message>
```
3. You can also integrate it inside project using [adblib].
3. You can also integrate it inside project using adb library.
![][sms]
How to use docker-android in VMWare or Parallels Desktop
---------------
The following instructions are used for OS X. You'll need [docker-machine-parallels](https://github.com/Parallels/docker-machine-parallels) to create a virtual machine (vm) with tiny core linux for running docker images. After that, you may start the vm you created for VMWare Fusion or Parallels Desktop and run a docker container inside this vm. If you're going to use the android docker of emulator with x86 processor, setup this vm for nested virtualization and kvm support before you run a docker container.
1. Install docker-machine-parallels via Homebrew:
```bash
$ brew install docker-machine-parallels
```
2. Create a virtual machine for running docker images based on the virtual machine tool you use
2.1. Create a virtual machine of VMWare Fusion
```bash
$ docker-machine create --driver=vmwarefusion vmware-dev
```
2.2. Create a virtual machine of Parallels Desktop
```bash
$ docker-machine create --driver=parallels prl-dev
```
This utility `docker-machine-parallels` will fetch boot2docker.iso to create a vm of VMWare fusion or Parallels Desktop. When the vm is created, you'll see it's booted with VMWare fusion or Parallels Desktop where the network of vm is set to NAT and one IP is assigned. You'll be able to connect to vnc service inside the docker image through that IP. Say it's `10.211.55.3` and we'll use it later.
3. Setup the virtual machine for nested virtualization support
3.1. Shutdown the vm by running the command below in the boot2docker vm before you setup it.
```bash
# shutdown -h now
```
If you use VMWare Fusion, go to menu bar > Vitual Machine > Settings > Processors and Memory, expand Advanced options, and select `Enable hypervisor applications in this virtual machine`.
![Enable nested virtualization for VMWare Fusion](images/vmwarefusion_enable_nested_virtualization.png)
If you use Parallels Desktop, open settings screen of that vm and go to `CPU & Memory` under `hardware` tab, expand Advanced settings and select `Enable nested virtualization`.
![Enable nested virtualization for Parallels Desktop](images/parallels_enable_nested_virtualization.png)
4. Enable kvm inside virtual machine
4.1. Run as an account other than root to install kvm packages using tce-load.
```bash
# su docker
$ tce-load -wi kvm
```
4.2. Run as root to load kvm module after kvm packages install.
```bash
$ sudo modprobe kvm_intel
```
4.3. Check if the kvm device is loaded.
```bash
$ ls /dev/kvm
```
4.4. Check if your CPU supports hardware virtualization now
```bash
$ egrep -c '(vmx|svm)' /proc/cpuinfo
```
If **0** it means that your CPU doesn't support hardware virtualization.
If **1** or more it does - but you still need to make sure that virtualization is enabled in the BIOS.
5. You may now run a docker container
5.1. Let's run a docker image for an emulator with x86 processor.
```bash
docker run --privileged -d -p 6080:6080 -p 5554:5554 -p 5555:5555 -e DEVICE="Samsung Galaxy S6" --name android-container butomo1989/docker-android-x86-8.1
```
When the services inside this docker container are running, connect to http://10.211.55.3:6080/vnc.html (the IP we got when the docker machine was created) and login. The emulator with x86 processor should be running on screen.
Troubleshooting
---------------
All logs inside container are stored under folder **/var/log/supervisor**. you can print out log file by using **docker exec**. Example:
```bash
docker exec -it android-container tail -f /var/log/supervisor/docker-appium.stdout.log
docker exec -it android-container tail -f /var/log/supervisor/docker-android.stdout.log
```
[noVNC]: <images/noVNC.png> "login with noVNC to see what happen inside container"
[connect to grid 1]: <images/appium_with_selenium_grid_01.png>
[connect to grid 2]: <images/appium_with_selenium_grid_02.png>
[galaxy s6]: <images/run_under_galaxy_s6.png>
[nexus 5]: <images/run_under_nexus_5.png>
Special Thanks
--------------
- [Gian Christanto] for creating a great logo!
[appium]: <https://appium.io>
[espresso]: <https://google.github.io/android-testing-support-library/docs/espresso/>
[robotium]: <https://github.com/RobotiumTech/robotium>
[emulator samsung]: <images/emulator_samsung_galaxy_s6.png>
[emulator nexus]: <images/emulator_nexus_5.png>
[real device]: <images/real_device.png>
[compose]: <images/compose.png>
[line]: <https://github.com/butomo1989/docker-android/blob/master/docker-compose.yml#L70>
[example of compose file]: <docker-compose.yml>
[utils bash file]: <src/utils.sh>
[docker-compose]: <https://docs.docker.com/compose/install/>
[1.13.0]: <https://github.com/docker/compose/releases/tag/1.13.0>
[Genymotion Cloud]: <https://www.genymotion.com/cloud/>
[device.json]: <genymotion/example/sample_devices/devices.json>
[this docker-compose file]: <genymotion/example/geny.yml>
[adb_connection]: <images/adb_connection.png>
[sms]: <images/SMS.png>
[adblib]: <https://github.com/tananaev/adblib>
[gian christanto]: <https://www.linkedin.com/in/gian-christanto-0b398b131/>
+114
View File
@@ -0,0 +1,114 @@
# Note: It requires docker-compose 1.13.0
#
# Usage: docker-compose up -d
version: "2.2"
services:
# Selenium hub
selenium_hub:
image: selenium/hub:3.12.0-americium
ports:
- 4444:4444
# There is a bug for using appium. Issue: https://github.com/butomo1989/docker-android/issues/73
# Real devices
#real_device:
# image: butomo1989/docker-android-real-device
# privileged: true
# depends_on:
# - selenium_hub
# ports:
# - 6080:6080
# volumes:
# - ./video-real-device:/tmp/video
# - /dev/bus/usb:/dev/bus/usb
# - ~/.android:/root/.android
# environment:
# - CONNECT_TO_GRID=true
# - APPIUM=true
# - SELENIUM_HOST=selenium_hub
# - AUTO_RECORD=true
# - BROWSER_NAME=chrome
# Using Appium Docker Android
real_device:
image: appium/appium
depends_on:
- selenium_hub
network_mode: "service:selenium_hub"
privileged: true
volumes:
- /dev/bus/usb:/dev/bus/usb
- ~/.android:/root/.android
- $PWD/example/sample_apk:/root/tmp
environment:
- CONNECT_TO_GRID=true
- SELENIUM_HOST=selenium_hub
# Enable it for msite testing
#- BROWSER_NAME=chrome
# Docker-Android for Android application testing
nexus_7.1.1:
image: butomo1989/docker-android-x86-7.1.1
privileged: true
# Increase scale number if needed
scale: 1
depends_on:
- selenium_hub
- real_device
ports:
- 6080
# Change path of apk that you want to test. I use sample_apk that I provide in folder "example"
volumes:
- $PWD/example/sample_apk:/root/tmp/sample_apk
- ./video-nexus_7.1.1:/tmp/video
environment:
- DEVICE=Nexus 5
- CONNECT_TO_GRID=true
- APPIUM=true
- SELENIUM_HOST=selenium_hub
- AUTO_RECORD=true
# Docker-Android for mobile website testing with chrome browser
# Chrome browser exists only for version 7.0 and 7.1.1
samsung_galaxy_web_7.1.1:
image: butomo1989/docker-android-x86-8.1
privileged: true
# Increase scale number if needed
scale: 1
depends_on:
- selenium_hub
- real_device
ports:
- 6080
volumes:
- ./video-samsung_7.1.1:/tmp/video
environment:
- DEVICE=Samsung Galaxy S6
- CONNECT_TO_GRID=true
- APPIUM=true
- SELENIUM_HOST=selenium_hub
- MOBILE_WEB_TEST=true
- AUTO_RECORD=true
# Docker-Android for mobile website testing with default browser
# Default browser exists only for version 5.0.1, 5.1.1 and 6.0
samsung_galaxy_web_5.1.1:
image: butomo1989/docker-android-x86-5.1.1
privileged: true
# Increase scale number if needed
scale: 1
depends_on:
- selenium_hub
- real_device
ports:
- 6080
volumes:
- ./video-samsung_5.1.1:/tmp/video
environment:
- DEVICE=Samsung Galaxy S6
- CONNECT_TO_GRID=true
- APPIUM=true
- SELENIUM_HOST=selenium_hub
- MOBILE_WEB_TEST=true
- AUTO_RECORD=true
+47 -53
View File
@@ -1,6 +1,6 @@
FROM ubuntu:16.04
FROM appium/appium:1.8.1-p2
ENV DEBIAN_FRONTEND noninteractive
LABEL maintainer "Budi Utomo <budi.ut.1989@gmail.com>"
#=============
# Set WORKDIR
@@ -10,27 +10,15 @@ WORKDIR /root
#==================
# General Packages
#------------------
# wget
# Network downloader
# unzip
# Unzip zip file
# curl
# Transfer data from or to a server
# xterm
# Terminal emulator
# supervisor
# Process manager
# openjdk-8-jdk
# Java
# libqt5webkit5
# Web content engine (Fix issue in Android)
# socat
# Port forwarder
#------------------
# NoVNC Packages
#------------------
# xvfb
# X virtual framebuffer
# x11vnc
# VNC server for X display
# openbox
@@ -42,6 +30,13 @@ WORKDIR /root
# net-tools
# Netstat
#------------------
# Video Recording
#------------------
# ffmpeg
# Video recorder
# jq
# Sed for JSON data
#------------------
# KVM Package
# for emulator x86
# https://help.ubuntu.com/community/KVM/Installation
@@ -51,21 +46,17 @@ WORKDIR /root
# ubuntu-vm-builder
# bridge-utils
#==================
RUN apt-get update && apt-get install -y --no-install-recommends \
wget \
unzip \
curl \
RUN apt-get -qqy update && apt-get -qqy install --no-install-recommends \
xterm \
supervisor \
openjdk-8-jdk \
libqt5webkit5 \
socat \
xvfb \
x11vnc \
openbox \
menu \
python-numpy \
net-tools \
ffmpeg \
jq \
qemu-kvm \
libvirt-bin \
ubuntu-vm-builder \
@@ -79,57 +70,55 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
#=======
ENV NOVNC_SHA="b403cb92fb8de82d04f305b4f14fa978003890d7" \
WEBSOCKIFY_SHA="558a6439f14b0d85a31145541745e25c255d576b"
RUN wget -O noVNC.zip "https://github.com/kanaka/noVNC/archive/${NOVNC_SHA}.zip" \
RUN wget -nv -O noVNC.zip "https://github.com/kanaka/noVNC/archive/${NOVNC_SHA}.zip" \
&& unzip -x noVNC.zip \
&& rm noVNC.zip \
&& mv noVNC-${NOVNC_SHA} noVNC \
&& wget -O websockify.zip "https://github.com/kanaka/websockify/archive/${WEBSOCKIFY_SHA}.zip" \
&& wget -nv -O websockify.zip "https://github.com/kanaka/websockify/archive/${WEBSOCKIFY_SHA}.zip" \
&& unzip -x websockify.zip \
&& mv websockify-${WEBSOCKIFY_SHA} ./noVNC/utils/websockify \
&& rm websockify.zip \
&& ln noVNC/vnc_auto.html noVNC/index.html
#=====================
# Install Android SDK
#=====================
ENV JAVA_HOME /usr/lib/jvm/java-8-openjdk-amd64/jre
ENV PATH ${PATH}:${JAVA_HOME}/bin
ENV SDK_VERSION=25.2.3 \
ANDROID_HOME=/root
RUN wget -O android.zip https://dl.google.com/android/repository/tools_r${SDK_VERSION}-linux.zip \
&& unzip android.zip && rm android.zip
ENV PATH ${PATH}:${ANDROID_HOME}/tools
RUN echo y | android update sdk --no-ui -a --filter platform-tools
ENV PATH ${PATH}:${ANDROID_HOME}/platform-tools
#====================================
# Install latest nodejs, npm, appium
#====================================
RUN curl -sL https://deb.nodesource.com/setup_7.x | bash - \
&& apt-get update && apt-get install -y nodejs && rm -rf /var/lib/apt/lists/*
ENV APPIUM_VERSION 1.6.3
RUN npm install -g appium@$APPIUM_VERSION && npm cache clean
#======================
# Install SDK packages
#======================
ARG ANDROID_VERSION=5.0.1
ARG BUILD_TOOL=21.1.2
ARG API_LEVEL=21
ARG PROCESSOR=x86
ARG SYS_IMG=x86_64
ARG SYS_IMG=x86
ARG IMG_TYPE=google_apis
ARG BROWSER=android
ARG CHROME_DRIVER=2.40
ARG GOOGLE_PLAY_SERVICE=12.8.74
ARG GOOGLE_PLAY_STORE=11.0.50
ENV ANDROID_VERSION=$ANDROID_VERSION \
BUILD_TOOL=$BUILD_TOOL \
API_LEVEL=$API_LEVEL \
PROCESSOR=$PROCESSOR \
SYS_IMG=$SYS_IMG
RUN echo y | android update sdk --no-ui -a --filter build-tools-${BUILD_TOOL}
SYS_IMG=$SYS_IMG \
IMG_TYPE=$IMG_TYPE \
BROWSER=$BROWSER \
CHROME_DRIVER=$CHROME_DRIVER \
GOOGLE_PLAY_SERVICE=$GOOGLE_PLAY_SERVICE \
GOOGLE_PLAY_STORE=$GOOGLE_PLAY_STORE
ENV PATH ${PATH}:${ANDROID_HOME}/build-tools
RUN rm ${ANDROID_HOME}/tools/emulator \
&& ln -s ${ANDROID_HOME}/tools/emulator64-${PROCESSOR} ${ANDROID_HOME}/tools/emulator
RUN echo y | android update sdk --no-ui -a -t android-${API_LEVEL},sys-img-${SYS_IMG}-android-${API_LEVEL}
RUN yes | sdkmanager --licenses && \
sdkmanager "platforms;android-${API_LEVEL}" "system-images;android-${API_LEVEL};${IMG_TYPE};${SYS_IMG}" "emulator"
#==============================================
# Download proper version of chromedriver
# to be able to use Chrome browser in emulator
#==============================================
RUN wget -nv -O chrome.zip "https://chromedriver.storage.googleapis.com/${CHROME_DRIVER}/chromedriver_linux64.zip" \
&& unzip -x chrome.zip \
&& rm chrome.zip
#================================================================
# Download Google Play Services APK and Play Store from apklinker
#================================================================
Run wget -nv -O google_play_services.apk "https://www.apklinker.com/wp-content/uploads/uploaded_apk/5b5155e5ef4f8/com.google.android.gms_${GOOGLE_PLAY_SERVICE}-020700-204998136_12874013_MinAPI21_(x86)(nodpi)_apklinker.com.apk"
Run wget -nv -O google_play_store.apk "https://www.apklinker.com/wp-content/uploads/uploaded_apk/5b632b1164e31/com.android.vending_${GOOGLE_PLAY_STORE}-all-0-PR-206665793_81105000_MinAPI16_(armeabi,armeabi-v7a,mips,mips64,x86,x86_64)(240,320,480dpi)_apklinker.com.apk"
#================================================
# noVNC Default Configurations
@@ -143,6 +132,7 @@ ENV DISPLAY=:0 \
LOCAL_PORT=5900 \
TARGET_PORT=6080 \
TIMEOUT=1 \
VIDEO_PATH=/tmp/video \
LOG_PATH=/var/log/supervisor
#===============
@@ -170,4 +160,8 @@ COPY devices /root/devices
COPY src /root/src
COPY supervisord.conf /root/
RUN chmod -R +x /root/src && chmod +x /root/supervisord.conf
HEALTHCHECK --interval=2s --timeout=40s --retries=1 \
CMD timeout 40 adb wait-for-device shell 'while [[ -z $(getprop sys.boot_completed) ]]; do sleep 1; done'
CMD /usr/bin/supervisord --configuration supervisord.conf
+125
View File
@@ -0,0 +1,125 @@
FROM appium/appium:1.8.1-p2
LABEL maintainer "Budi Utomo <budi.ut.1989@gmail.com>"
#=============
# Set WORKDIR
#=============
WORKDIR /root
#==================
# General Packages
#------------------
# xterm
# Terminal emulator
# supervisor
# Process manager
# socat
# Port forwarder
#------------------
# Genymotion spec
#------------------
# bzip2
# File compression
#------------------
# NoVNC Packages
#------------------
# x11vnc
# VNC server for X display
# openbox
# Windows manager
# menu
# Debian menu
# python-numpy
# Numpy, For faster performance: https://github.com/novnc/websockify/issues/77
# net-tools
# Netstat
#------------------
# Video Recording
#------------------
# ffmpeg
# Video recorder
# jq
# Sed for JSON data
#==================
RUN apt-get -qqy update && apt-get -qqy install --no-install-recommends \
xterm \
supervisor \
socat \
bzip2 \
x11vnc \
openbox \
menu \
python-numpy \
net-tools \
ffmpeg \
jq \
&& rm -rf /var/lib/apt/lists/*
#=======
# noVNC
# Use same commit id that docker-selenium uses
# https://github.com/elgalu/docker-selenium/blob/236b861177bd2917d864e52291114b1f5e4540d7/Dockerfile#L412-L413
#=======
ENV NOVNC_SHA="b403cb92fb8de82d04f305b4f14fa978003890d7" \
WEBSOCKIFY_SHA="558a6439f14b0d85a31145541745e25c255d576b"
RUN wget -nv -O noVNC.zip "https://github.com/kanaka/noVNC/archive/${NOVNC_SHA}.zip" \
&& unzip -x noVNC.zip \
&& rm noVNC.zip \
&& mv noVNC-${NOVNC_SHA} noVNC \
&& wget -nv -O websockify.zip "https://github.com/kanaka/websockify/archive/${WEBSOCKIFY_SHA}.zip" \
&& unzip -x websockify.zip \
&& mv websockify-${WEBSOCKIFY_SHA} ./noVNC/utils/websockify \
&& rm websockify.zip \
&& ln noVNC/vnc_auto.html noVNC/index.html
#================================================
# noVNC Default Configurations
# These Configurations can be changed through -e
#================================================
ENV DISPLAY=:0 \
SCREEN=0 \
SCREEN_WIDTH=1600 \
SCREEN_HEIGHT=900 \
SCREEN_DEPTH=16 \
LOCAL_PORT=5900 \
TARGET_PORT=6080 \
TIMEOUT=1 \
VIDEO_PATH=/tmp/video \
LOG_PATH=/var/log/supervisor
#====================
# Install genymotion
#====================
ARG GENYMOTION_VERSION=2.12.1
ENV GENYMOTION=true \
GENYMOTION_VERSION=$GENYMOTION_VERSION \
PATH="${PATH}:/opt/genymobile/genymotion/" \
APPIUM_LOG=$LOG_PATH/appium.log
RUN wget -nv -O genymotion.bin "https://dl.genymotion.com/releases/genymotion-${GENYMOTION_VERSION}/genymotion-${GENYMOTION_VERSION}-linux_x64.bin" \
&& chmod +x ./genymotion.bin \
&& yes | ./genymotion.bin \
&& rm genymotion.bin
COPY genymotion/generate_config.sh genymotion/geny_start.sh /root/
#===============
# Expose Ports
#---------------
# 4723
# Appium port
# 6080
# noVNC port
# 5555
# ADB connection port
#===============
EXPOSE 4723 6080 5555
#=======================
# Run docker-genymotion
#=======================
COPY src /root/src
COPY supervisord.conf /root/
RUN chmod -R +x /root/src && chmod +x /root/supervisord.conf /root/geny_start.sh
RUN gmtool --cloud config use_custom_sdk=on sdk_path=/root
CMD ["./geny_start.sh"]
+112
View File
@@ -0,0 +1,112 @@
FROM appium/appium:1.8.1-p2
LABEL maintainer "Budi Utomo <budi.ut.1989@gmail.com>"
#=============
# Set WORKDIR
#=============
WORKDIR /root
#==================
# General Packages
#------------------
# xterm
# Terminal emulator
# supervisor
# Process manager
# socat
# Port forwarder
#------------------
# NoVNC Packages
#------------------
# x11vnc
# VNC server for X display
# openbox
# Windows manager
# menu
# Debian menu
# python-numpy
# Numpy, For faster performance: https://github.com/novnc/websockify/issues/77
# net-tools
# Netstat
#------------------
# Video Recording
#------------------
# ffmpeg
# Video recorder
# jq
# Sed for JSON data
#==================
RUN apt-get -qqy update && apt-get -qqy install --no-install-recommends \
xterm \
supervisor \
socat \
x11vnc \
openbox \
menu \
python-numpy \
net-tools \
ffmpeg \
jq \
&& rm -rf /var/lib/apt/lists/*
#=======
# noVNC
# Use same commit id that docker-selenium uses
# https://github.com/elgalu/docker-selenium/blob/236b861177bd2917d864e52291114b1f5e4540d7/Dockerfile#L412-L413
#=======
ENV NOVNC_SHA="b403cb92fb8de82d04f305b4f14fa978003890d7" \
WEBSOCKIFY_SHA="558a6439f14b0d85a31145541745e25c255d576b"
RUN wget -nv -O noVNC.zip "https://github.com/kanaka/noVNC/archive/${NOVNC_SHA}.zip" \
&& unzip -x noVNC.zip \
&& rm noVNC.zip \
&& mv noVNC-${NOVNC_SHA} noVNC \
&& wget -nv -O websockify.zip "https://github.com/kanaka/websockify/archive/${WEBSOCKIFY_SHA}.zip" \
&& unzip -x websockify.zip \
&& mv websockify-${WEBSOCKIFY_SHA} ./noVNC/utils/websockify \
&& rm websockify.zip \
&& ln noVNC/vnc_auto.html noVNC/index.html
#================================================
# noVNC Default Configurations
# These Configurations can be changed through -e
#================================================
ENV DISPLAY=:0 \
SCREEN=0 \
SCREEN_WIDTH=1600 \
SCREEN_HEIGHT=900 \
SCREEN_DEPTH=16 \
LOCAL_PORT=5900 \
TARGET_PORT=6080 \
TIMEOUT=1 \
VIDEO_PATH=/tmp/video \
LOG_PATH=/var/log/supervisor
#=========================
# Set default variables
#=========================
ENV APPIUM_LOG=$LOG_PATH/appium.log
ENV REAL_DEVICE=true
ENV BROWSER=android
#===============
# Expose Ports
#---------------
# 4723
# Appium port
# 6080
# noVNC port
# 5555
# ADB connection port
#===============
EXPOSE 4723 6080 5555
#===================
# Run docker-appium
#===================
COPY sm/asm.jar /root/
COPY src /root/src
COPY supervisord.conf /root/
RUN chmod -R +x /root/src && chmod +x /root/supervisord.conf
CMD /usr/bin/supervisord --configuration supervisord.conf
+5 -3
View File
@@ -1,7 +1,7 @@
Docker-Android-Appium Sample
----------------------------
Docker-Android Sample UITests with Appium
-----------------------------------------
Example UI test to use docker-appium.
Example UI test with [Appium] to use docker-android.
Requirements
============
@@ -12,3 +12,5 @@ Quick Start
===========
1. pip install -r requirements.txt
2. python app_simple.py
[Appium]: <https://appium.io>
+5 -3
View File
@@ -9,10 +9,12 @@ class SimpleAndroidUITests(unittest.TestCase):
desired_caps = {
'platformName': 'Android',
'deviceName': 'Android Emulator',
'app': '/root/sample_apk_debug.apk',
'avd': 'nexus_5_5.0'
'automationName': 'UIAutomator2',
'app': '/root/tmp/sample_apk_debug.apk',
'browserName': 'android',
'avd': 'nexus_5_7.1.1'
}
self.driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub', desired_caps)
self.driver = webdriver.Remote('http://127.0.0.1:4444/wd/hub', desired_caps)
def tearDown(self):
self.driver.quit()
@@ -0,0 +1,42 @@
import unittest
from time import sleep
from appium import webdriver
class MSiteChromeAndroidUITests(unittest.TestCase):
def setUp(self):
# Default google chrome does not exist for android < 6.0
desired_caps = {
'platformName': 'Android',
'deviceName': 'Android Emulator',
'appPackage': 'com.android.chrome',
'appActivity': 'com.google.android.apps.chrome.Main',
'browserName': 'chrome'
}
self.driver = webdriver.Remote('http://127.0.0.1:4444/wd/hub', desired_caps)
def test_open_url(self):
self.driver.get('http://google.com')
# Handle Welcome Home
self.driver.switch_to.context('NATIVE_APP')
self.driver.find_element_by_id('terms_accept').click()
self.driver.find_element_by_id('negative_button').click()
# Search for Github
self.driver.switch_to.context('CHROMIUM')
search = self.driver.find_element_by_name('q')
search.send_keys('butomo1989 docker-android')
search.submit()
sleep(2)
def tearDown(self):
self.driver.quit()
if __name__ == '__main__':
suite = unittest.TestLoader().loadTestsFromTestCase(MSiteChromeAndroidUITests)
unittest.TextTestRunner(verbosity=2).run(suite)
@@ -1,22 +1,31 @@
import unittest
from time import sleep
from appium import webdriver
class MSiteDefaultBrowserAndroidUITests(unittest.TestCase):
def setUp(self):
# Default browser does not exist for android >= 6.0
desired_caps = {
'platformName': 'Android',
'deviceName': 'Android Emulator',
'appPackage': 'com.android.browser',
'appActivity': 'com.android.browser.BrowserActivity',
'avd': 'nexus_5_5.0'
'browserName': 'browser'
}
self.driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub', desired_caps)
self.driver = webdriver.Remote('http://127.0.0.1:4444/wd/hub', desired_caps)
def test_open_url(self):
self.driver.get('http://targeturl.com')
self.driver.get('http://google.com')
search = self.driver.find_element_by_name('q')
search.send_keys('butomo1989 docker-android')
search.submit()
sleep(2)
def tearDown(self):
self.driver.quit()
+29
View File
@@ -0,0 +1,29 @@
# Note: It requires docker-compose 1.13.0
#
# Usage: docker-compose up -d
version: "2.2"
services:
# Selenium hub
selenium_hub:
image: selenium/hub:3.12.0-americium
ports:
- 4444:4444
# Please stop this container by using docker stop instead of docker-compose stop
genymotion:
image: butomo1989/docker-android-genymotion
depends_on:
- selenium_hub
ports:
- 6080:6080
- 4723:4723
volumes:
- $PWD/sample_apk:/root/tmp/sample_apk
- $PWD/sample_devices:/root/tmp
environment:
- GENY_TEMPLATE=/root/tmp/devices.json
- USER=xxx
- PASS=xxx
- LICENSE=xxx
- CONNECT_TO_GRID=true
Binary file not shown.
+11
View File
@@ -0,0 +1,11 @@
[
{
"template": "Samsung Galaxy S7 - 6.0.0 - API 23 - 1440x2560",
"device": "SamsungS7V6",
"port": 38727
},
{
"template": "Google Nexus 6 - 8.0 - API 26 - 1440x2560",
"device": "Nexus6V8"
}
]
+81
View File
@@ -0,0 +1,81 @@
#!/bin/bash
node_config_json=$1
if [ -z "$PLATFORM_NAME" ]; then
PLATFORM_NAME="Android"
fi
if [ -z "$APPIUM_HOST" ]; then
APPIUM_HOST=$(hostname -i)
fi
if [ -z "$APPIUM_PORT" ]; then
APPIUM_PORT=4723
fi
if [ -z "$SELENIUM_HOST" ]; then
SELENIUM_HOST="172.17.0.1"
fi
if [ -z "$SELENIUM_PORT" ]; then
SELENIUM_PORT=4444
fi
if [ -z "$BROWSER_NAME" ]; then
BROWSER_NAME="android"
fi
if [ -z "$NODE_TIMEOUT" ]; then
NODE_TIMEOUT=300
fi
#Get device names
devices=($(adb devices | grep -oP "\K([^ ]+)(?=\sdevice(\W|$))"))
echo "Devices found: ${#devices[@]}"
#Create capabilities json configs
function create_capabilities() {
capabilities=""
for name in ${devices[@]}; do
os_version="$(adb -s $name shell getprop ro.build.version.release | tr -d '\r')"
capabilities+=$(cat <<_EOF
{
"platform": "$PLATFORM_NAME",
"platformName": "$PLATFORM_NAME",
"version": "$os_version",
"browserName": "$BROWSER_NAME",
"deviceName": "$name",
"maxInstances": 1,
"applicationName": "$name"
}
_EOF
)
if [ ${devices[-1]} != $name ]; then
capabilities+=', '
fi
done
echo "$capabilities"
}
#Final node configuration json string
nodeconfig=$(cat <<_EOF
{
"capabilities": [$(create_capabilities)],
"configuration": {
"cleanUpCycle": 2000,
"timeout": $NODE_TIMEOUT,
"proxy": "org.openqa.grid.selenium.proxy.DefaultRemoteProxy",
"url": "http://$APPIUM_HOST:$APPIUM_PORT/wd/hub",
"host": "$APPIUM_HOST",
"port": $APPIUM_PORT,
"maxSession": 6,
"register": true,
"registerCycle": 5000,
"hubHost": "$SELENIUM_HOST",
"hubPort": $SELENIUM_PORT
}
}
_EOF
)
echo "$nodeconfig" > $node_config_json
+29
View File
@@ -0,0 +1,29 @@
#!/bin/bash
# This script is needed because of https://www.ctl.io/developers/blog/post/gracefully-stopping-docker-containers/
if [ -z "$GENY_TEMPLATE" ]; then
GENY_TEMPLATE="/root/tmp/devices.json"
fi
if [ ! -f "$GENY_TEMPLATE" ]; then
echo "File not found! Nothing to do!"
exit 1
fi
getAbort() {
if [ "$GENYMOTION" = true ]; then
contents=$(cat $GENY_TEMPLATE)
echo "ABORT SIGNAL detected! Stopping all created emulators..."
for row in $(echo "${contents}" | jq -r '.[] | @base64'); do
get_value() {
echo ${row} | base64 --decode | jq -r ${1}
}
gmtool --cloud admin stopdisposable $(get_value '.device')
done
echo "Done"
fi
}
trap 'getAbort; exit' EXIT
/usr/bin/supervisord --configuration supervisord.conf
Binary file not shown.

After

Width:  |  Height:  |  Size: 441 KiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 146 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 146 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 229 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 261 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 183 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 311 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 240 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 341 KiB

+110 -63
View File
@@ -2,7 +2,6 @@
# Bash version should >= 4 to be able to run this script.
IMAGE="butomo1989/docker-android"
LATEST_BUILD_TOOL=25.0.2
if [ -z "$1" ]; then
read -p "Task (test|build|push|all) : " TASK
@@ -11,32 +10,37 @@ else
fi
if [ -z "$2" ]; then
read -p "Android version (5.0.1|5.1.1|6.0|all): " ANDROID_VERSION
read -p "Android version (5.0.1|5.1.1|6.0|7.0|7.1.1|8.0|8.1|all): " ANDROID_VERSION
else
ANDROID_VERSION=$2
fi
if [ -z "$3" ]; then
read -p "Processor type (x86|arm|all): " PROCESSOR
else
PROCESSOR=$3
fi
if [ -z "$4" ]; then
read -p "Release version: " RELEASE
else
RELEASE=$4
RELEASE=$3
fi
declare -A list_of_levels=(
[5.0.1]=21
[5.1.1]=22
[6.0]=23
[7.0]=24
[7.1.1]=25
[8.0]=26
[8.1]=27
)
declare -A list_of_processors=(
[arm]=armeabi-v7a
[x86]=x86_64
# The version of the Chrome browser installed on the Android emulator needs to be known beforehand
# in order to chose the proper version of chromedriver (see http://chromedriver.chromium.org/downloads)
declare -A chromedriver_versions=(
[5.0.1]="2.12"
[5.1.1]="2.13"
[6.0]="2.18"
[7.0]="2.23"
[7.1.1]="2.28"
[8.0]="2.31"
[8.1]="2.33"
)
function get_android_versions() {
@@ -56,77 +60,120 @@ function get_android_versions() {
# If version cannot be found in the list
if [ -z "$versions" ]; then
echo "Android version \"$ANDROID_VERSION\" is not found in the list or not supported! Support only version 5.0.1, 5.1.1, 6.0, 7.0, 7.1.1"
echo "Android version \"$ANDROID_VERSION\" is not found in the list or not supported! Support only version 5.0.1, 5.1.1, 6.0, 7.0, 7.1.1, 8.0, 8.1"
exit 1
fi
echo "Android versions: ${versions[@]}"
}
function get_processors() {
processors=()
if [ "$PROCESSOR" == "all" ]; then
for key in "${!list_of_processors[@]}"; do
processors+=($key)
done
else
for key in "${!list_of_processors[@]}"; do
if [[ $key == *"$PROCESSOR"* ]]; then
processors+=($key)
fi
done
fi
# If version cannot be found in the list
if [ -z "$processors" ]; then
echo "Invalid processor \"$PROCESSOR\"! Valid options: x86, arm"
exit 1
fi
echo "Processors: ${processors[@]}"
}
get_android_versions
get_processors
processor=x86
function test() {
(export ANDROID_HOME=/root && export ANDROID_VERSION=5.0.1 && export API_LEVEL=21 \
&& export PROCESSOR=x86 && export SYS_IMG=x86_64 && nosetests -v)
# Prepare needed parameter to run tests
test_android_version=7.1.1
test_api_level=25
test_processor=x86
test_sys_img=$test_processor
test_img_type=google_apis
test_browser=chrome
test_image=test_img
test_container=test_con
# Run e2e tests
# E2E tests must be run only for linux OS / x86 image to reduce duration of test execution
if [ "$(uname -s)" == 'Linux' ] && [ "$E2E" = true ]; then
echo "----BUILD TEST IMAGE----"
docker build -t $test_image --build-arg ANDROID_VERSION=$test_android_version \
--build-arg API_LEVEL=$test_api_level --build-arg PROCESSOR=$test_processor --build-arg SYS_IMG=$test_sys_img \
--build-arg IMG_TYPE=$test_img_type --build-arg BROWSER=$test_browser -f docker/Emulator_x86 .
echo "----REMOVE OLD TEST CONTAINER----"
docker kill $test_container && docker rm $test_container
echo "----PREPARE CONTAINER----"
docker run --privileged -d -p 4723:4723 -p 6080:6080 -e APPIUM=True -e DEVICE="Samsung Galaxy S6" --name $test_container $test_image
docker cp example/sample_apk $test_container:/root/tmp
attempt=0
while [ ${attempt} -le 10 ]; do
attempt=$(($attempt + 1))
output=$(docker ps | grep healthy | grep test_con | wc -l)
if [[ "$output" == 1 ]]; then
echo "Emulator is ready."
break
else
echo "Waiting 10 seconds for emulator to be ready (attempt: $attempt)"
sleep 10
fi
if [[ $attempt == 10 ]]; then
echo "Failed!"
exit 1
fi
done
echo "----RUN E2E TESTS----"
nosetests src/tests/e2e -v
echo "----REMOVE TEST CONTAINER----"
docker kill $test_container && docker rm $test_container
fi
# Run unit tests (After e2e test to get coverage result)
echo "----UNIT TESTS----"
(export ANDROID_HOME=/root && export ANDROID_VERSION=$test_android_version && export API_LEVEL=$test_api_level \
&& export PROCESSOR=$test_processor && export SYS_IMG=$test_sys_img && export IMG_TYPE=$test_img_type \
&& nosetests src/tests/unit -v)
}
function build() {
# Remove pyc files
find . -name "*.pyc" -exec rm -f {} \;
# Build docker image(s)
for p in "${processors[@]}"; do
for v in "${versions[@]}"; do
level=${list_of_levels[$v]}
echo "[BUILD] API Level: $level"
sys_img=${list_of_processors[$p]}
echo "[BUILD] System Image: $sys_img"
image_version="$IMAGE-$p-$v:$RELEASE"
image_latest="$IMAGE-$p-$v:latest"
echo "[BUILD] Image name: $image_version and $image_latest"
docker build -t $image_version --build-arg ANDROID_VERSION=$v --build-arg BUILD_TOOL=$LATEST_BUILD_TOOL \
--build-arg API_LEVEL=$level --build-arg PROCESSOR=$p --build-arg SYS_IMG=$sys_img .
docker build -t $image_latest --build-arg ANDROID_VERSION=$v --build-arg BUILD_TOOL=$LATEST_BUILD_TOOL \
--build-arg API_LEVEL=$level --build-arg PROCESSOR=$p --build-arg SYS_IMG=$sys_img .
done
# Build docker image
FILE_NAME=docker/Emulator_x86
for v in "${versions[@]}"; do
# Find image type and default web browser
if [ "$v" == "5.0.1" ] || [ "$v" == "5.1.1" ]; then
IMG_TYPE=default
BROWSER=browser
elif [ "$v" == "6.0" ]; then
# It is because there is no ARM EABI v7a System Image for 6.0
IMG_TYPE=google_apis
BROWSER=browser
else
#adb root cannot be run in IMG_TYPE=google_apis_playstore
IMG_TYPE=google_apis
BROWSER=chrome
fi
echo "[BUILD] IMAGE TYPE: $IMG_TYPE"
level=${list_of_levels[$v]}
echo "[BUILD] API Level: $level"
sys_img=$processor
echo "[BUILD] System Image: $sys_img"
chrome_driver="${chromedriver_versions[$v]}"
echo "[BUILD] chromedriver version: $chrome_driver"
image_version="$IMAGE-$processor-$v:$RELEASE"
image_latest="$IMAGE-$processor-$v:latest"
echo "[BUILD] Image name: $image_version and $image_latest"
echo "[BUILD] Dockerfile: $FILE_NAME"
docker build -t $image_version --build-arg ANDROID_VERSION=$v --build-arg API_LEVEL=$level \
--build-arg PROCESSOR=$processor --build-arg SYS_IMG=$sys_img --build-arg IMG_TYPE=$IMG_TYPE \
--build-arg BROWSER=$BROWSER --build-arg CHROME_DRIVER=$chrome_driver -f $FILE_NAME .
docker tag $image_version $image_latest
done
}
function push() {
# Push docker image(s)
for p in "${processors[@]}"; do
for v in "${versions[@]}"; do
image_version="$IMAGE-$p-$v:$RELEASE"
image_latest="$IMAGE-$p-$v:latest"
echo "[PUSH] Image name: $image_version and $image_latest"
docker push $image_version
docker push $image_latest
done
for v in "${versions[@]}"; do
image_version="$IMAGE-$processor-$v:$RELEASE"
image_latest="$IMAGE-$processor-$v:latest"
echo "[PUSH] Image name: $image_version and $image_latest"
docker push $image_version
docker push $image_latest
done
}
+48
View File
@@ -0,0 +1,48 @@
#!/bin/bash
if [ -z "$1" ]; then
read -p "Task (build|push|all) : " TASK
else
TASK=$1
fi
if [ -z "$2" ]; then
read -p "Release version: " RELEASE
else
RELEASE=$2
fi
IMAGE="butomo1989/docker-android"
FILE_NAME=docker/Real_device
image_version="$IMAGE-real-device:$RELEASE"
image_latest="$IMAGE-real-device:latest"
function build() {
echo "[BUILD] Image name: $image_version and $image_latest"
echo "[BUILD] Dockerfile: $FILE_NAME"
docker build -t $image_version -f $FILE_NAME .
docker tag $image_version $image_latest
}
function push() {
echo "[PUSH] Image name: $image_version and $image_latest"
docker push $image_version
docker push $image_latest
}
case $TASK in
build)
build
;;
push)
push
;;
all)
build
push
;;
*)
echo "Invalid environment! Valid options: test, build, push, all"
;;
esac
+2
View File
@@ -1,3 +1,5 @@
selenium==3.3.1
Appium-Python-Client==0.24
coverage==4.2
mock==2.0.0
nose==1.3.7
+29
View File
@@ -0,0 +1,29 @@
#!/bin/bash
IMAGE_NAME="butomo1989/docker-android"
if [ -z "$1" ]; then
read -p "Type : " TYPE
else
TYPE=$1
fi
if [ -z "$2" ]; then
read -p "Version : " VERSION
else
VERSION=$2
fi
declare -a versions=("7.1.1" "7.0" "6.0" "5.1.1" "5.0.1")
## now loop through the above array
for v in "${versions[@]}"
do
IMAGE="$IMAGE_NAME-$TYPE-$v"
IMAGE_OLD="$IMAGE:$VERSION"
IMAGE_LATEST="$IMAGE:latest"
echo "Revert image \"$IMAGE_LATEST\" to version \"$IMAGE_OLD\""
docker pull $IMAGE_OLD
docker tag $IMAGE_OLD $IMAGE_LATEST
docker push $IMAGE_LATEST
done
Executable
BIN
View File
Binary file not shown.
+1
View File
@@ -2,5 +2,6 @@ import os
ROOT = '/root'
WORKDIR = os.path.dirname(__file__)
CHROME_DRIVER = os.path.join(ROOT, 'chromedriver')
CONFIG_FILE = os.path.join(WORKDIR, 'nodeconfig.json')
LOGGING_FILE = os.path.join(WORKDIR, 'logging.conf')
+78 -35
View File
@@ -4,14 +4,25 @@ import json
import logging
import os
import subprocess
import uuid
from src import CONFIG_FILE, ROOT
from src import CHROME_DRIVER, CONFIG_FILE, ROOT
from src import log
log.init()
logger = logging.getLogger('app')
def symlink_force(target, link_name):
try:
os.symlink(target, link_name)
except OSError as e:
import errno
if e.errno == errno.EEXIST:
os.remove(link_name)
os.symlink(target, link_name)
def get_or_raise(env: str) -> str:
"""
Check if needed environment variables are given.
@@ -26,7 +37,7 @@ def get_or_raise(env: str) -> str:
return env_value
def str_to_bool(str: str) -> bool:
def convert_str_to_bool(str: str) -> bool:
"""
Convert string to boolean.
@@ -39,17 +50,22 @@ def str_to_bool(str: str) -> bool:
logger.error(err)
def is_initialized() -> bool:
return os.path.exists(os.path.join(ROOT, '.android', 'devices.xml'))
ANDROID_HOME = get_or_raise('ANDROID_HOME')
ANDROID_VERSION = get_or_raise('ANDROID_VERSION')
API_LEVEL = get_or_raise('API_LEVEL')
PROCESSOR = get_or_raise('PROCESSOR')
SYS_IMG = get_or_raise('SYS_IMG')
IMG_TYPE = get_or_raise('IMG_TYPE')
logger.info('Android version: {version} \n'
'API level: {level} \n'
'Processor: {processor} \n'
'System image: {img}'.format(version=ANDROID_VERSION, level=API_LEVEL, processor=PROCESSOR,
img=SYS_IMG))
'System image: {img} \n'
'Image type: {img_type}'.format(version=ANDROID_VERSION, level=API_LEVEL, processor=PROCESSOR,
img=SYS_IMG, img_type=IMG_TYPE))
def prepare_avd(device: str, avd_name: str):
@@ -59,21 +75,9 @@ def prepare_avd(device: str, avd_name: str):
:param device: Device name
:param avd_name: Name of android virtual device / emulator
"""
cmd = 'echo no | android create avd -f -n {name} -t android-{api} -b {sys_img}'.format(
name=avd_name, api=API_LEVEL, sys_img=SYS_IMG)
# Link emulator skins
skin_rsc_path = os.path.join(ROOT, 'devices', 'skins')
logger.info('Skin ressource path: {rsc}'.format(rsc=skin_rsc_path))
skin_dst_path = os.path.join(ANDROID_HOME, 'platforms', 'android-{api}'.format(api=API_LEVEL), 'skins')
logger.info('Skin destination path: {dst}'.format(dst=skin_dst_path))
for s in os.listdir(skin_rsc_path):
os.symlink(os.path.join(skin_rsc_path, s), os.path.join(skin_dst_path, s))
# Hardware and its skin
device_name_bash = device.replace(' ', '\ ')
skin_name = device.replace(' ', '_').lower()
logger.info('Device name in bash: {db}, Skin name: {skin}'.format(db=device_name_bash, skin=skin_name))
# For custom hardware profile
profile_dst_path = os.path.join(ROOT, '.android', 'devices.xml')
@@ -82,12 +86,22 @@ def prepare_avd(device: str, avd_name: str):
profile_src_path = os.path.join(ROOT, 'devices', 'profiles', '{profile}.xml'.format(profile=skin_name))
logger.info('Hardware profile resource path: {rsc}'.format(rsc=profile_src_path))
logger.info('Hardware profile destination path: {dst}'.format(dst=profile_dst_path))
os.symlink(profile_src_path, profile_dst_path)
symlink_force(profile_src_path, profile_dst_path)
# Append command
cmd += ' -d {device} -s {skin}'.format(device=device_name_bash, skin=skin_name)
logger.info('AVD creation command: {cmd}'.format(cmd=cmd))
subprocess.check_call(cmd, shell=True)
avd_path = '/'.join([ANDROID_HOME, 'android_emulator'])
creation_cmd = 'avdmanager create avd -f -n {name} -b {img_type}/{sys_img} -k "system-images;android-{api_lvl};' \
'{img_type};{sys_img}" -d {device} -p {path}'.format(name=avd_name, img_type=IMG_TYPE,
sys_img=SYS_IMG,
api_lvl=API_LEVEL, device=device_name_bash,
path=avd_path)
logger.info('Command to create avd: {command}'.format(command=creation_cmd))
subprocess.check_call(creation_cmd, shell=True)
skin_path = '/'.join([ANDROID_HOME, 'devices', 'skins', skin_name])
config_path = '/'.join([avd_path, 'config.ini'])
with open(config_path, 'a') as file:
file.write('skin.path={sp}'.format(sp=skin_path))
logger.info('Skin was added in config.ini')
def appium_run(avd_name: str):
@@ -96,25 +110,38 @@ def appium_run(avd_name: str):
:param avd_name: Name of android virtual device / emulator
"""
cmd = 'appium'
DEFAULT_LOG_PATH = '/var/log/supervisor/appium.log'
cmd = 'appium --log {log}'.format(log=os.getenv('APPIUM_LOG', DEFAULT_LOG_PATH))
grid_connect = str_to_bool(str(os.getenv('CONNECT_TO_GRID', False)))
relaxed_security = convert_str_to_bool(str(os.getenv('RELAXED_SECURITY', False)))
logger.info('Relaxed security? {rs}'.format(rs=relaxed_security))
if relaxed_security:
cmd += ' --relaxed-security'
default_web_browser = os.getenv('BROWSER')
cmd += ' --chromedriver-executable {driver}'.format(driver=CHROME_DRIVER)
grid_connect = convert_str_to_bool(str(os.getenv('CONNECT_TO_GRID', False)))
logger.info('Connect to selenium grid? {connect}'.format(connect=grid_connect))
if grid_connect:
local_ip = os.popen('ifconfig eth0 | grep \'inet addr:\' | cut -d: -f2 | awk \'{ print $1}\'').read().strip()
try:
appium_host = os.getenv('APPIUM_HOST', '127.0.0.1')
mobile_web_test = convert_str_to_bool(str(os.getenv('MOBILE_WEB_TEST', False)))
appium_host = os.getenv('APPIUM_HOST', local_ip)
appium_port = int(os.getenv('APPIUM_PORT', 4723))
selenium_host = os.getenv('SELENIUM_HOST', '172.17.0.1')
selenium_port = int(os.getenv('SELENIUM_PORT', 4444))
create_node_config(avd_name, appium_host, appium_port, selenium_host, selenium_port)
browser_name = default_web_browser if mobile_web_test else 'android'
create_node_config(avd_name, browser_name, appium_host, appium_port, selenium_host, selenium_port)
cmd += ' --nodeconfig {file}'.format(file=CONFIG_FILE)
except ValueError as v_err:
logger.error(v_err)
titel = 'Appium Server'
subprocess.check_call('xterm -T "{titel}" -n "{titel}" -e \"{cmd}\"'.format(titel=titel, cmd=cmd), shell=True)
title = 'Appium Server'
subprocess.check_call('xterm -T "{title}" -n "{title}" -e \"{cmd}\"'.format(title=title, cmd=cmd), shell=True)
def create_node_config(avd_name: str, appium_host: str, appium_port: int, selenium_host: str, selenium_port: int):
def create_node_config(avd_name: str, browser_name: str, appium_host: str, appium_port: int, selenium_host: str,
selenium_port: int):
"""
Create custom node config file in json format to be able to connect with selenium server.
@@ -130,7 +157,8 @@ def create_node_config(avd_name: str, appium_host: str, appium_port: int, seleni
'platform': 'Android',
'platformName': 'Android',
'version': ANDROID_VERSION,
'browserName': avd_name,
'browserName': browser_name,
'deviceName': avd_name,
'maxInstances': 1,
}
],
@@ -145,7 +173,8 @@ def create_node_config(avd_name: str, appium_host: str, appium_port: int, seleni
'register': True,
'registerCycle': 5000,
'hubHost': selenium_host,
'hubPort': selenium_port
'hubPort': selenium_port,
'unregisterIfStillDownAfter': 120000
}
}
logger.info('Appium node config: {config}'.format(config=config))
@@ -157,20 +186,34 @@ def run():
"""Run app."""
device = os.getenv('DEVICE', 'Nexus 5')
logger.info('Device: {device}'.format(device=device))
custom_args=os.getenv('EMULATOR_ARGS', '')
logger.info('Custom Args: {custom_args}'.format(custom_args=custom_args))
avd_name = '{device}_{version}'.format(device=device.replace(' ', '_').lower(), version=ANDROID_VERSION)
logger.info('AVD name: {avd}'.format(avd=avd_name))
is_first_run = not is_initialized()
if is_first_run:
logger.info('Preparing emulator...')
prepare_avd(device, avd_name)
logger.info('Preparing emulator...')
prepare_avd(device, avd_name)
logger.info('Run emulator...')
cmd = 'emulator -avd {name}'.format(name=avd_name)
subprocess.Popen(cmd.split())
dp_size = os.getenv('DATAPARTITION', '550m')
with open("/root/android_emulator/config.ini", "a") as cfg:
cfg.write('\ndisk.dataPartition.size={dp}'.format(dp=dp_size))
appium = str_to_bool(str(os.getenv('APPIUM', True)))
if is_first_run:
cmd = 'emulator/emulator @{name} -gpu off -verbose -wipe-data {custom_args}'.format(name=avd_name, custom_args=custom_args)
else:
cmd = 'emulator/emulator @{name} -gpu off -verbose {custom_args}'.format(name=avd_name, custom_args=custom_args)
appium = convert_str_to_bool(str(os.getenv('APPIUM', False)))
if appium:
subprocess.Popen(cmd.split())
logger.info('Run appium server...')
appium_run(avd_name)
else:
result = subprocess.Popen(cmd.split(), stdout=subprocess.PIPE).communicate()
if __name__ == '__main__':
run()
+62
View File
@@ -0,0 +1,62 @@
#!/bin/bash
if [ -z "$GENY_TEMPLATE" ]; then
GENY_TEMPLATE="/root/tmp/devices.json"
fi
function prepare_geny_cloud() {
contents=$(cat $GENY_TEMPLATE)
# Register
gmtool config username="${USER}" password="${PASS}"
gmtool license register "${LICENSE}"
# Start device(s)
echo "Creating device(s) based on given json file..."
for row in $(echo "${contents}" | jq -r '.[] | @base64'); do
get_value() {
echo ${row} | base64 --decode | jq -r ${1}
}
template=$(get_value '.template')
device=$(get_value '.device')
port=$(get_value '.port')
if [[ $port != null ]]; then
echo "Starting \"$device\" with template name \"$template\" on port \"$port\"..."
gmtool --cloud admin startdisposable "${template}" "${device}" --adb-serial-port "${port}"
else
echo "Starting \"$device\" with template name \"$template\"..."
gmtool --cloud admin startdisposable "${template}" "${device}"
fi
done
}
function run_appium() {
echo "Preparing appium-server..."
CMD="appium --log $APPIUM_LOG"
if [ "$CONNECT_TO_GRID" = true ]; then
NODE_CONFIG_JSON="/root/src/nodeconfig.json"
/root/generate_config.sh $NODE_CONFIG_JSON
CMD+=" --nodeconfig $NODE_CONFIG_JSON"
fi
if [ "$RELAXED_SECURITY" = true ]; then
CMD+=" --relaxed-security"
fi
echo "Preparation is done"
$CMD
}
if [ "$REAL_DEVICE" = true ]; then
echo "Using real device"
run_appium
elif [ "$GENYMOTION" = true ]; then
echo "Using Genymotion"
prepare_geny_cloud
run_appium
else
echo "Using Emulator"
python3 -m src.app
fi
+8
View File
@@ -0,0 +1,8 @@
#!/bin/bash
if [ -z "$REAL_DEVICE"]; then
echo "Container is using android emulator"
else
echo "Starting android screen mirro..."
java -jar /root/asm.jar $ANDROID_HOME
fi
+47
View File
@@ -0,0 +1,47 @@
#!/bin/bash
function start() {
mkdir -p $VIDEO_PATH
name="$(date '+%d_%m_%Y_%H_%M_%S').mp4"
echo "Start video recording"
ffmpeg -video_size 1599x899 -framerate 15 -f x11grab -i $DISPLAY $VIDEO_PATH/$name -y
}
function stop() {
echo "Stop video recording"
kill $(ps -ef | grep [f]fmpeg | awk '{print $2}')
}
function auto_record() {
echo "Auto record: $AUTO_RECORD"
sleep 6
while [ "$AUTO_RECORD" = true ]; do
# Check if there is test running
no_test=true
while $no_test; do
task=$(curl -s localhost:4723/wd/hub/sessions | jq -r '.value')
if [ "$task" = "" ] || [ "$task" = "[]" ]; then
sleep .5
else
start &
no_test=false
fi
done
# Check if test is finished
while [ $no_test = false ]; do
task=$(curl -s localhost:4723/wd/hub/sessions | jq -r '.value')
if [ "$task" = "" ] || [ "$task" = "[]" ]; then
stop
no_test=true
else
sleep .5
fi
done
done
echo "Auto recording is disabled!"
}
$@
-53
View File
@@ -1,53 +0,0 @@
"""Unit test to test app."""
import os
from unittest import TestCase
import mock
from src import app
class TestApp(TestCase):
"""Unit test class to test other methods in the app."""
def test_valid_env(self):
key = 'ENV_1'
os.environ[key] = 'test'
app.get_or_raise(key)
del os.environ[key]
def test_invalid_env(self):
with self.assertRaises(RuntimeError):
app.get_or_raise('ENV_2')
def test_valid_bool(self):
self.assertEqual(app.str_to_bool('True'), True)
self.assertEqual(app.str_to_bool('t'), True)
self.assertEqual(app.str_to_bool('1'), True)
self.assertEqual(app.str_to_bool('YES'), True)
def test_invalid_bool(self):
self.assertEqual(app.str_to_bool(''), False)
self.assertEqual(app.str_to_bool('test'), False)
def test_invalid_format(self):
self.assertEqual(app.str_to_bool(True), None)
@mock.patch('src.app.prepare_avd')
@mock.patch('subprocess.Popen')
def test_run_with_appium(self, mocked_avd, mocked_subprocess):
with mock.patch('src.app.appium_run') as mocked_appium:
app.run()
self.assertTrue(mocked_avd.called)
self.assertTrue(mocked_subprocess.called)
self.assertTrue(mocked_appium.called)
@mock.patch('src.app.prepare_avd')
@mock.patch('subprocess.Popen')
def test_run_withhout_appium(self, mocked_avd, mocked_subprocess):
with mock.patch('src.app.appium_run') as mocked_appium:
os.environ['APPIUM'] = str(False)
app.run()
self.assertTrue(mocked_avd.called)
self.assertTrue(mocked_subprocess.called)
self.assertFalse(mocked_appium.called)
View File
+29
View File
@@ -0,0 +1,29 @@
"""e2e test to test sample android application inside docker-android"""
from unittest import TestCase
from appium import webdriver
class TestE2EAndroidApk(TestCase):
def setUp(self):
desired_caps = {
'platformName': 'Android',
'deviceName': 'Android Emulator',
'automationName': 'UIAutomator2',
'app': '/root/tmp/sample_apk_debug.apk'
}
self.driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps)
def test_calculation(self):
text_fields = self.driver.find_elements_by_class_name('android.widget.EditText')
text_fields[0].send_keys(4)
text_fields[1].send_keys(6)
btn_calculate = self.driver.find_element_by_class_name('android.widget.Button')
btn_calculate.click()
self.assertEqual('10', text_fields[2].text)
def tearDown(self):
self.driver.quit()
+34
View File
@@ -0,0 +1,34 @@
"""e2e test to test chrome application inside docker-android"""
from unittest import TestCase
from appium import webdriver
class TestE2EChrome(TestCase):
def setUp(self):
desired_caps = {
'platformName': 'Android',
'deviceName': 'Android Emulator',
'appPackage': 'com.android.chrome',
'appActivity': 'com.google.android.apps.chrome.Main',
'browserName': 'chrome'
}
self.driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps)
def test_open_url(self):
self.driver.get('http://google.com')
# Handle Welcome Home
self.driver.switch_to.context('NATIVE_APP')
self.driver.find_element_by_id('terms_accept').click()
self.driver.find_element_by_id('negative_button').click()
# Search for Github
self.driver.switch_to.context('CHROMIUM')
search = self.driver.find_element_by_name('q')
search.send_keys('butomo1989 docker-android')
search.submit()
def tearDown(self):
self.driver.quit()
-42
View File
@@ -1,42 +0,0 @@
"""Unit test for android virtual device creation.py."""
import os
from unittest import TestCase
import mock
from src import app
@mock.patch('subprocess.check_call')
@mock.patch('os.symlink')
class TestAvd(TestCase):
"""Unit test class to test method create_avd."""
def setUp(self):
self.avd_name = 'test_avd'
def test_nexus_avd_as_default(self, mocked_suprocess, mocked_sys_link):
with mock.patch('os.listdir') as mocked_list_dir:
mocked_list_dir.return_value = ['file1', 'file2']
self.assertFalse(mocked_list_dir.called)
self.assertFalse(mocked_sys_link.called)
self.assertFalse(mocked_suprocess.called)
app.prepare_avd('Nexus 5', self.avd_name)
self.assertTrue(mocked_list_dir.called)
self.assertTrue(mocked_sys_link.called)
self.assertTrue(mocked_suprocess.called)
def test_samsung_avd(self, mocked_suprocess, mocked_sys_link):
with mock.patch('os.listdir') as mocked_list_dir:
mocked_list_dir.return_value = ['file1', 'file2']
self.assertFalse(mocked_list_dir.called)
self.assertFalse(mocked_sys_link.called)
self.assertFalse(mocked_suprocess.called)
app.prepare_avd('Samsung Galaxy S6', self.avd_name)
self.assertTrue(mocked_list_dir.called)
self.assertTrue(mocked_sys_link.called)
self.assertTrue(mocked_suprocess.called)
def tearDown(self):
if os.getenv('DEVICE'):
del os.environ['DEVICE']
View File
+95
View File
@@ -0,0 +1,95 @@
"""Unit test to test app."""
import os
from unittest import TestCase
import mock
from src import app
class TestApp(TestCase):
"""Unit test class to test other methods in the app."""
@classmethod
def test_symlink(self):
res = os.path.join('testFile1.txt')
dest = os.path.join('link_testFile1.txt')
open(res, 'a').close()
app.symlink_force(res, dest)
os.remove(res)
os.remove(dest)
@classmethod
def test_symlink_already_exist(self):
res = os.path.join('testFile1.txt')
dest = os.path.join('link_testFile1.txt')
open(res, 'a').close()
open(dest, 'a').close()
app.symlink_force(res, dest)
os.remove(res)
os.remove(dest)
def test_valid_env(self):
key = 'ENV_1'
os.environ[key] = 'test'
app.get_or_raise(key)
del os.environ[key]
def test_invalid_env(self):
with self.assertRaises(RuntimeError):
app.get_or_raise('ENV_2')
def test_valid_bool(self):
self.assertEqual(app.convert_str_to_bool('True'), True)
self.assertEqual(app.convert_str_to_bool('t'), True)
self.assertEqual(app.convert_str_to_bool('1'), True)
self.assertEqual(app.convert_str_to_bool('YES'), True)
def test_invalid_bool(self):
self.assertEqual(app.convert_str_to_bool(''), False)
self.assertEqual(app.convert_str_to_bool('test'), False)
def test_invalid_format(self):
self.assertEqual(app.convert_str_to_bool(True), None)
@mock.patch('src.app.prepare_avd')
@mock.patch('builtins.open')
@mock.patch('subprocess.Popen')
def test_run_with_appium(self, mocked_avd, mocked_open, mocked_subprocess):
with mock.patch('src.app.appium_run') as mocked_appium:
os.environ['APPIUM'] = str(True)
app.run()
self.assertTrue(mocked_avd.called)
self.assertTrue(mocked_open.called)
self.assertTrue(mocked_subprocess.called)
self.assertTrue(mocked_appium.called)
@mock.patch('src.app.prepare_avd')
@mock.patch('builtins.open')
@mock.patch('subprocess.Popen')
def test_run_without_appium(self, mocked_avd, mocked_open, mocked_subprocess):
with mock.patch('src.app.appium_run') as mocked_appium:
os.environ['APPIUM'] = str(False)
app.run()
self.assertTrue(mocked_avd.called)
self.assertTrue(mocked_open.called)
self.assertTrue(mocked_subprocess.called)
self.assertFalse(mocked_appium.called)
@mock.patch('builtins.open')
@mock.patch('subprocess.Popen')
@mock.patch('os.path.exists', mock.MagicMock(return_value=False))
def test_run_first_run(self, mocked_open, mocked_subprocess):
with mock.patch('src.app.prepare_avd') as mocked_prepare_avd:
app.run()
self.assertFalse(app.is_initialized())
self.assertTrue(mocked_prepare_avd.called)
@mock.patch('builtins.open')
@mock.patch('subprocess.Popen')
@mock.patch('os.path.exists', mock.MagicMock(return_value=True))
def test_run_next_run(self, mocked_open, mocked_subprocess):
with mock.patch('src.app.prepare_avd') as mocked_prepare_avd:
app.run()
self.assertTrue(app.is_initialized())
self.assertFalse(mocked_prepare_avd.called)
@@ -14,6 +14,14 @@ class TestAppium(TestCase):
os.environ['CONNECT_TO_GRID'] = str(True)
self.avd_name = 'test_avd'
@mock.patch('subprocess.check_call')
def test_chrome_driver(self, mocked_subprocess):
os.environ['CONNECT_TO_GRID'] = str(False)
os.environ['BROWSER'] = 'chrome'
self.assertFalse(mocked_subprocess.called)
app.appium_run(self.avd_name)
self.assertTrue(mocked_subprocess.called)
@mock.patch('subprocess.check_call')
def test_without_selenium_grid(self, mocked_subprocess):
os.environ['CONNECT_TO_GRID'] = str(False)
@@ -21,30 +29,36 @@ class TestAppium(TestCase):
app.appium_run(self.avd_name)
self.assertTrue(mocked_subprocess.called)
@mock.patch('os.popen')
@mock.patch('subprocess.check_call')
def test_with_selenium_grid(self, mocked_subprocess):
def test_with_selenium_grid(self, mocked_os, mocked_subprocess):
with mock.patch('src.app.create_node_config') as mocked_config:
self.assertFalse(mocked_config.called)
self.assertFalse(mocked_os.called)
self.assertFalse(mocked_subprocess.called)
app.appium_run(self.avd_name)
self.assertTrue(mocked_config.called)
self.assertTrue(mocked_os.called)
self.assertTrue(mocked_subprocess.called)
@mock.patch('os.popen')
@mock.patch('subprocess.check_call')
def test_invalid_integer(self, mocked_subprocess):
def test_invalid_integer(self, mocked_os, mocked_subprocess):
os.environ['APPIUM_PORT'] = 'test'
with mock.patch('src.app.create_node_config') as mocked_config:
self.assertFalse(mocked_config.called)
self.assertFalse(mocked_os.called)
self.assertFalse(mocked_subprocess.called)
app.appium_run(self.avd_name)
self.assertFalse(mocked_config.called)
self.assertTrue(mocked_os.called)
self.assertTrue(mocked_subprocess.called)
self.assertRaises(ValueError)
def test_config_creation(self):
from src import CONFIG_FILE
self.assertFalse(os.path.exists(CONFIG_FILE))
app.create_node_config('test', '127.0.0.1', 4723, '127.0.0.1', 4444)
app.create_node_config('test', 'android', '127.0.0.1', 4723, '127.0.0.1', 4444)
self.assertTrue(os.path.exists(CONFIG_FILE))
os.remove(CONFIG_FILE)
@@ -52,3 +66,5 @@ class TestAppium(TestCase):
del os.environ['CONNECT_TO_GRID']
if os.getenv('APPIUM_PORT'):
del os.environ['APPIUM_PORT']
if os.getenv('BROWSER'):
del os.environ['BROWSER']
+38
View File
@@ -0,0 +1,38 @@
"""Unit test for android virtual device creation.py."""
import os
from unittest import TestCase
import mock
from src import app
@mock.patch('subprocess.check_call')
class TestAvd(TestCase):
"""Unit test class to test method create_avd."""
def setUp(self):
self.avd_name = 'test_avd'
@mock.patch("builtins.open", create=True)
def test_nexus_avd_as_default(self, mocked_suprocess, mocked_open):
self.assertFalse(mocked_suprocess.called)
self.assertFalse(mocked_open.called)
app.prepare_avd('Nexus 5', self.avd_name)
self.assertTrue(mocked_suprocess.called)
self.assertTrue(mocked_open.called)
@mock.patch('os.symlink')
@mock.patch("builtins.open", create=True)
def test_samsung_avd(self, mocked_suprocess, mocked_sys_link, mocked_open):
self.assertFalse(mocked_sys_link.called)
self.assertFalse(mocked_suprocess.called)
self.assertFalse(mocked_open.called)
app.prepare_avd('Samsung Galaxy S6', self.avd_name)
self.assertTrue(mocked_sys_link.called)
self.assertTrue(mocked_suprocess.called)
self.assertTrue(mocked_open.called)
def tearDown(self):
if os.getenv('DEVICE'):
del os.environ['DEVICE']
Executable
+44
View File
@@ -0,0 +1,44 @@
#!/bin/bash
function wait_emulator_to_be_ready () {
boot_completed=false
while [ "$boot_completed" == false ]; do
status=$(adb wait-for-device shell getprop sys.boot_completed | tr -d '\r')
echo "Boot Status: $status"
if [ "$status" == "1" ]; then
boot_completed=true
else
sleep 1
fi
done
}
function change_language_if_needed() {
if [ ! -z "${LANGUAGE// }" ] && [ ! -z "${COUNTRY// }" ]; then
wait_emulator_to_be_ready
echo "Languge will be changed to ${LANGUAGE}-${COUNTRY}"
adb root && adb shell "setprop persist.sys.language $LANGUAGE; setprop persist.sys.country $COUNTRY; stop; start"
echo "Language is changed!"
fi
}
function install_google_play () {
wait_emulator_to_be_ready
echo "Google Play Service will be installed"
adb install -r "/root/google_play_services.apk"
echo "Google Play Store will be installed"
adb install -r "/root/google_play_store.apk"
}
function disable_animation () {
# To improve performance
adb shell "settings put global window_animation_scale 0.0"
adb shell "settings put global transition_animation_scale 0.0"
adb shell "settings put global animator_duration_scale 0.0"
}
change_language_if_needed
sleep 1
install_google_play
disable_animation
+33 -3
View File
@@ -2,33 +2,63 @@
nodaemon=true
logfile=%(ENV_LOG_PATH)s/supervisord.log
childlogdir=%(ENV_LOG_PATH)s
priority=1
[program:xvfb]
command=/usr/bin/Xvfb %(ENV_DISPLAY)s -screen %(ENV_SCREEN)s %(ENV_SCREEN_WIDTH)sx%(ENV_SCREEN_HEIGHT)sx%(ENV_SCREEN_DEPTH)s
stdout_logfile=%(ENV_LOG_PATH)s/xvfb.stdout.log
stderr_logfile=%(ENV_LOG_PATH)s/xvfb.stderr.log
priority=1
[program:openbox]
command=/usr/bin/openbox-session
stdout_logfile=%(ENV_LOG_PATH)s/openbox.stdout.log
stderr_logfile=%(ENV_LOG_PATH)s/openbox.stderr.log
priority=2
[program:x11vnc]
command=/usr/bin/x11vnc -display %(ENV_DISPLAY)s -nopw -forever -shared
stdout_logfile=%(ENV_LOG_PATH)s/x11vnc.stdout.log
stderr_logfile=%(ENV_LOG_PATH)s/x11vnc.stderr.log
priority=2
[program:novnc]
command=./noVNC/utils/launch.sh --vnc localhost:%(ENV_LOCAL_PORT)s --listen %(ENV_TARGET_PORT)s
stdout_logfile=%(ENV_LOG_PATH)s/novnc.stdout.log
stderr_logfile=%(ENV_LOG_PATH)s/novnc.stderr.log
priority=2
[program:port-forward]
command=./src/port_forward.sh
autorestart=false
priority=1
;startsecs to fix "not expected" error. see: https://github.com/Supervisor/supervisor/issues/212#issuecomment-47933372
[program:android-screen-mirror]
command=./src/asm.sh
autorestart=false
startsecs=0
stdout_logfile=%(ENV_LOG_PATH)s/android-screen-mirror.stdout.log
stderr_logfile=%(ENV_LOG_PATH)s/android-screen-mirror.stderr.log
priority=3
[program:docker-appium]
command=python3 -m src.app
command=./src/appium.sh
autorestart=false
stdout_logfile=%(ENV_LOG_PATH)s/docker-appium.stdout.log
stderr_logfile=%(ENV_LOG_PATH)s/docker-appium.stderr.log
stdout_logfile=%(ENV_LOG_PATH)s/docker-android.stdout.log
stderr_logfile=%(ENV_LOG_PATH)s/docker-android.stderr.log
priority=4
[program:auto-recording]
command=./src/record.sh auto_record
autorestart=false
stdout_logfile=%(ENV_LOG_PATH)s/video-recording.stdout.log
stderr_logfile=%(ENV_LOG_PATH)s/video-recording.stderr.log
priority=4
[program:adb-utils]
command=./src/utils.sh
autorestart=false
stdout_logfile=%(ENV_LOG_PATH)s/adb-utils.stdout.log
stderr_logfile=%(ENV_LOG_PATH)s/adb-utils.stderr.log
priority=5
+9 -4
View File
@@ -5,10 +5,15 @@ if [ -z "$TRAVIS_TAG" ]; then
echo "UNIT TEST ONLY"
bash release.sh test all all 0.1
else
echo "Log in to docker hub"
docker login -u="$DOCKER_USERNAME" -p="$DOCKER_PASSWORD"
echo "RUN UNIT TEST, BUILD DOCKER IMAGES AND PUSH THOSE TO DOCKER HUB"
bash release.sh all all all $TRAVIS_TAG
if [ ! -z "$ANDROID_VERSION" ]; then
echo "Log in to docker hub"
docker login -u="$DOCKER_USERNAME" -p="$DOCKER_PASSWORD"
echo "[Version: $ANDROID_VERSION] RUN UNIT TEST, BUILD DOCKER IMAGES AND PUSH THOSE TO DOCKER HUB"
bash release.sh all $ANDROID_VERSION $TRAVIS_TAG
elif [ ! -z "$REAL_DEVICE" ]; then
echo "[SUPPORT FOR REAL DEVICE: BUILD DOCKER IMAGES AND PUSH THOSE TO DOCKER HUB ]"
bash release_real.sh all $TRAVIS_TAG
fi
echo "Log out of docker hub"
docker logout
fi