diff --git a/Dockerfile b/Dockerfile index 30a8a5b..51e56e2 100644 --- a/Dockerfile +++ b/Dockerfile @@ -99,11 +99,16 @@ EXPOSE 6080 #================== # Add Browser APKs #================== -COPY example/browser_apk /root/browser_apk +COPY browser_apk /root/browser_apk + +#==================== +# Add Emulator Skins +#==================== +COPY skins /root/skins #=================== # Run docker-appium #=================== COPY supervisord.conf /root/ -COPY service /root/service +COPY src /root/src CMD /usr/bin/supervisord --configuration supervisord.conf diff --git a/service/start.py b/service/start.py deleted file mode 100644 index 431670f..0000000 --- a/service/start.py +++ /dev/null @@ -1,161 +0,0 @@ -import logging -import os -import re -import subprocess - -import appium - -from service import CONFIG_FILE - -logging.basicConfig() -logger = logging.getLogger('main') - -# not using enum because need to install pip that will make docker image size bigger -TYPE_ARMEABI = 'armeabi' -TYPE_X86 = 'x86' - - -def run(): - """ - Start noVNC, installation of needed android SDK packages and Appium server. - - """ - # Get android version package - android_version = os.getenv('ANDROID_VERSION', '4.2.2') - emulator_name = 'emulator_{version}'.format(version=android_version) - os.environ['EMULATOR_NAME'] = emulator_name - - # Get emulator type - types = [TYPE_ARMEABI, TYPE_X86] - emulator_type = os.getenv('EMULATOR_TYPE', TYPE_ARMEABI).lower() - emulator_type = TYPE_ARMEABI if emulator_type not in types else emulator_type - - # Link emulator shortcut - subprocess.check_call('ln -s $ANDROID_HOME/tools/{shortcut_file} $ANDROID_HOME/tools/emulator'.format( - shortcut_file='emulator64-x86' if emulator_type == TYPE_X86 else 'emulator64-arm'), shell=True) - - # Option to connect with selenium server - connect_to_grid = str_to_bool(str(os.getenv('CONNECT_TO_GRID', False))) - logger.info('Connect with selenium grid? {input}'.format(input=connect_to_grid)) - appium_cmd = 'appium' - if connect_to_grid: - try: - appium_host = os.getenv('APPIUM_HOST', '127.0.0.1') - 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)) - appium.create_node_config(CONFIG_FILE, emulator_name, android_version, - appium_host, appium_port, selenium_host, selenium_port) - appium_cmd += ' --nodeconfig {file}'.format(file=CONFIG_FILE) - except ValueError as v_err: - logger.error(v_err) - - # Start installation of android packages, emulator creation and appium in a terminal - android_cmd = get_android_bash_commands(android_version, emulator_type) - if android_cmd: - cmd = 'xterm -T "Android-Appium" -n "Android-Appium" -e \"{android} && ' \ - '/bin/echo $EMULATOR_NAME && {appium}\"'.format(android=android_cmd, appium=appium_cmd) - else: - logger.warning('There is no android packages installed!') - cmd = 'xterm -e \"{appium}\"'.format(appium=appium_cmd) - subprocess.check_call(cmd, shell=True) - - -def get_available_sdk_packages(): - """ - Get list of available sdk packages. - - :return: List of available packages. - :rtype: bytearray - """ - cmd = ['android', 'list', 'sdk'] - output_str = subprocess.check_output(cmd) - logger.info('List of Android SDK: ') - logger.info(output_str) - return [output.strip() for output in output_str.split('\n')] if output_str else None - - -def get_item_position(keyword, items): - """ - Get position of item in array by given keyword. - - :return: item position - :rtype: int - """ - pos = 0 - for p, v in enumerate(items): - if keyword in v: - pos = p - break # Get the first item that match with keyword - return pos - - -def get_android_bash_commands(android_version, emulator_type): - """ - Get bash commands to install given android version and to create android emulator based on given type. - - To see list of available targets: android list targets - To see list to avd: android list avd - - :param android_version: android version - :type android_version: str - :param emulator_type: emulator type - :type emulator_type: str - :return: bash commands - :rtype: bytearray - """ - bash_command = None - - try: - packages = get_available_sdk_packages() - - if packages: - item_pos = get_item_position(android_version, packages) - logger.info('item position: {pos}'.format(pos=item_pos)) - item = packages[item_pos] - - item_info = item.split('-') - package_number = item_info[0] - api_version = re.search('%s(.*)%s' % ('API', ','), item_info[1]).group(1).strip() - logger.info( - 'Package number: {number}, API version: {version}'.format(number=package_number, version=api_version)) - - commands = [] - - # Command to install SDK package - commands.append('echo y | android update sdk --no-ui --filter {number}'.format(number=package_number)) - - # Command to install system image and create android emulator - sys_img = 'x86' if emulator_type == TYPE_X86 else 'armeabi-v7a' - commands.append('echo y | android update sdk --no-ui -a --filter sys-img-{sys_img}-android-{api}'.format( - sys_img=sys_img, api=api_version)) - commands.append( - 'echo no | android create avd -f -n emulator_{version} -t android-{api} --abi {sys_img}'.format( - version=android_version, api=api_version, sys_img=sys_img)) - - # Join all commands in one str for xterm - bash_command = ' && '.join(commands) - else: - raise RuntimeError('Packages is empty!') - - except IndexError as i_err: - logger.error(i_err) - - return bash_command - - -def str_to_bool(str): - """ - Convert string to boolean. - - :param str: given string - :type str: str - :return: converted string - :rtype: bool - """ - return str.lower() in ('yes', 'true', 't', '1') - - -if __name__ == '__main__': - logger.setLevel(logging.INFO) - run() diff --git a/service/tests/__init__.py b/service/tests/__init__.py deleted file mode 100644 index 9bfca02..0000000 --- a/service/tests/__init__.py +++ /dev/null @@ -1,73 +0,0 @@ -"""Unit test for start.py.""" -import os - -from unittest import TestCase - -import mock - -from service import start - - -class TestService(TestCase): - """Unit test class to test method run.""" - - def setUp(self): - os.environ['ANDROID_VERSION'] = '4.2.2' - os.environ['EMULATOR_TYPE'] = start.TYPE_X86 - os.environ['CONNECT_TO_GRID'] = str(False) - - @mock.patch('subprocess.check_call') - @mock.patch('service.start.get_android_bash_commands') - def test_without_selenium_server(self, mocked_subprocess, mocked_bash_cmd): - self.assertFalse(mocked_subprocess.called) - self.assertFalse(mocked_bash_cmd.called) - start.run() - self.assertTrue(mocked_subprocess.called) - self.assertTrue(mocked_bash_cmd.called) - - @mock.patch('subprocess.check_call') - @mock.patch('service.appium.create_node_config') - @mock.patch('service.start.get_android_bash_commands') - def test_with_selenium_server(self, mocked_subprocess, mocked_config, mocked_bash_cmd): - os.environ['CONNECT_TO_GRID'] = str(True) - self.assertFalse(mocked_subprocess.called) - self.assertFalse(mocked_config.called) - self.assertFalse(mocked_bash_cmd.called) - start.run() - self.assertTrue(mocked_subprocess.called) - self.assertTrue(mocked_config.called) - self.assertTrue(mocked_bash_cmd.called) - - @mock.patch('subprocess.check_call') - @mock.patch('service.appium.create_node_config') - @mock.patch('service.start.get_android_bash_commands') - def test_invalid_integer(self, mocked_subprocess, mocked_config, mocked_bash_cmd): - os.environ['CONNECT_TO_GRID'] = str(True) - os.environ['APPIUM_PORT'] = 'test' - self.assertFalse(mocked_subprocess.called) - self.assertFalse(mocked_config.called) - self.assertFalse(mocked_bash_cmd.called) - start.run() - self.assertTrue(mocked_subprocess.called) - self.assertFalse(mocked_config.called) - self.assertTrue(mocked_bash_cmd.called) - self.assertRaises(ValueError) - - @mock.patch('service.start.get_android_bash_commands') - @mock.patch('subprocess.check_call') - @mock.patch('service.start.logger.warning') - def test_empty_android_cmd(self, mocked_bash_cmd, mocked_subprocess, mocked_logger_warning): - mocked_bash_cmd.return_value = None - self.assertFalse(mocked_subprocess.called) - self.assertFalse(mocked_logger_warning.called) - start.run() - self.assertTrue(mocked_subprocess.called) - self.assertTrue(mocked_logger_warning.called) - - def tearDown(self): - del os.environ['ANDROID_VERSION'] - del os.environ['EMULATOR_TYPE'] - if os.getenv('CONNECT_TO_GRID') == str(True): - del os.environ['CONNECT_TO_GRID'] - if os.getenv('APPIUM_PORT'): - del os.environ['APPIUM_PORT'] diff --git a/setup.cfg b/setup.cfg index 7d693e5..07a9aba 100644 --- a/setup.cfg +++ b/setup.cfg @@ -2,7 +2,7 @@ cover-xml=true cover-xml-file=coverage.xml with-coverage=true -cover-package=service +cover-package=src cover-erase=true with-xunit=true xunit-file=xunit.xml diff --git a/skins/galaxy_nexus/land_back.png b/skins/galaxy_nexus/land_back.png new file mode 100644 index 0000000..4563224 Binary files /dev/null and b/skins/galaxy_nexus/land_back.png differ diff --git a/skins/galaxy_nexus/land_fore.png b/skins/galaxy_nexus/land_fore.png new file mode 100644 index 0000000..01f0d25 Binary files /dev/null and b/skins/galaxy_nexus/land_fore.png differ diff --git a/skins/galaxy_nexus/land_shadow.png b/skins/galaxy_nexus/land_shadow.png new file mode 100644 index 0000000..ab607e1 Binary files /dev/null and b/skins/galaxy_nexus/land_shadow.png differ diff --git a/skins/galaxy_nexus/layout b/skins/galaxy_nexus/layout new file mode 100644 index 0000000..fcbe482 --- /dev/null +++ b/skins/galaxy_nexus/layout @@ -0,0 +1,59 @@ +parts { + device { + display { + width 720 + height 1280 + x 0 + y 0 + } + } + portrait { + background { + image port_back.png + } + onion { + image port_fore.png + } + } + landscape { + background { + image land_back.png + } + onion { + image land_fore.png + } + } +} +layouts { + portrait { + width 1101 + height 1709 + event EV_SW:0:1 + part1 { + name portrait + x 0 + y 0 + } + part2 { + name device + x 192 + y 213 + } + } + landscape { + width 1847 + height 886 + event EV_SW:0:0 + part1 { + name landscape + x 0 + y 0 + } + part2 { + name device + x 304 + y 788 + rotation 3 + } + } +} diff --git a/skins/galaxy_nexus/port_back.png b/skins/galaxy_nexus/port_back.png new file mode 100644 index 0000000..e43fb2b Binary files /dev/null and b/skins/galaxy_nexus/port_back.png differ diff --git a/skins/galaxy_nexus/port_fore.png b/skins/galaxy_nexus/port_fore.png new file mode 100644 index 0000000..afe6429 Binary files /dev/null and b/skins/galaxy_nexus/port_fore.png differ diff --git a/skins/galaxy_nexus/port_shadow.png b/skins/galaxy_nexus/port_shadow.png new file mode 100644 index 0000000..7cea0a1 Binary files /dev/null and b/skins/galaxy_nexus/port_shadow.png differ diff --git a/skins/galaxy_nexus/thumb.png b/skins/galaxy_nexus/thumb.png new file mode 100644 index 0000000..e21a421 Binary files /dev/null and b/skins/galaxy_nexus/thumb.png differ diff --git a/skins/nexus_10/land_back.png b/skins/nexus_10/land_back.png new file mode 100644 index 0000000..4fbe3f0 Binary files /dev/null and b/skins/nexus_10/land_back.png differ diff --git a/skins/nexus_10/land_fore.png b/skins/nexus_10/land_fore.png new file mode 100644 index 0000000..dc69b5b Binary files /dev/null and b/skins/nexus_10/land_fore.png differ diff --git a/skins/nexus_10/land_shadow.png b/skins/nexus_10/land_shadow.png new file mode 100644 index 0000000..77116ea Binary files /dev/null and b/skins/nexus_10/land_shadow.png differ diff --git a/skins/nexus_10/layout b/skins/nexus_10/layout new file mode 100644 index 0000000..be3a0b6 --- /dev/null +++ b/skins/nexus_10/layout @@ -0,0 +1,59 @@ +parts { + device { + display { + width 1600 + height 2560 + x 0 + y 0 + } + } + portrait { + background { + image port_back.png + } + onion { + image port_fore.png + } + } + landscape { + background { + image land_back.png + } + onion { + image land_fore.png + } + } +} +layouts { + portrait { + width 2330 + height 3136 + event EV_SW:0:1 + part1 { + name portrait + x 0 + y 0 + } + part2 { + name device + x 366 + y 266 + } + } + landscape { + width 3340 + height 2176 + event EV_SW:0:0 + part1 { + name landscape + x 0 + y 0 + } + part2 { + name device + x 388 + y 1866 + rotation 3 + } + } +} diff --git a/skins/nexus_10/port_back.png b/skins/nexus_10/port_back.png new file mode 100644 index 0000000..07e60ff Binary files /dev/null and b/skins/nexus_10/port_back.png differ diff --git a/skins/nexus_10/port_fore.png b/skins/nexus_10/port_fore.png new file mode 100644 index 0000000..cf4f664 Binary files /dev/null and b/skins/nexus_10/port_fore.png differ diff --git a/skins/nexus_10/port_shadow.png b/skins/nexus_10/port_shadow.png new file mode 100644 index 0000000..555f1e8 Binary files /dev/null and b/skins/nexus_10/port_shadow.png differ diff --git a/skins/nexus_10/thumb.png b/skins/nexus_10/thumb.png new file mode 100644 index 0000000..ec12a01 Binary files /dev/null and b/skins/nexus_10/thumb.png differ diff --git a/skins/nexus_4/land_back.png b/skins/nexus_4/land_back.png new file mode 100644 index 0000000..087ff6c Binary files /dev/null and b/skins/nexus_4/land_back.png differ diff --git a/skins/nexus_4/land_fore.png b/skins/nexus_4/land_fore.png new file mode 100644 index 0000000..21e2c53 Binary files /dev/null and b/skins/nexus_4/land_fore.png differ diff --git a/skins/nexus_4/land_shadow.png b/skins/nexus_4/land_shadow.png new file mode 100644 index 0000000..0c72ea8 Binary files /dev/null and b/skins/nexus_4/land_shadow.png differ diff --git a/skins/nexus_4/layout b/skins/nexus_4/layout new file mode 100644 index 0000000..aa4f9fa --- /dev/null +++ b/skins/nexus_4/layout @@ -0,0 +1,59 @@ +parts { + device { + display { + width 768 + height 1280 + x 0 + y 0 + } + } + portrait { + background { + image port_back.png + } + onion { + image port_fore.png + } + } + landscape { + background { + image land_back.png + } + onion { + image land_fore.png + } + } +} +layouts { + portrait { + width 958 + height 1678 + event EV_SW:0:1 + part1 { + name portrait + x 0 + y 0 + } + part2 { + name device + x 94 + y 187 + } + } + landscape { + width 1799 + height 885 + event EV_SW:0:0 + part1 { + name landscape + x 0 + y 0 + } + part2 { + name device + x 257 + y 813 + rotation 3 + } + } +} diff --git a/skins/nexus_4/port_back.png b/skins/nexus_4/port_back.png new file mode 100644 index 0000000..ef4e252 Binary files /dev/null and b/skins/nexus_4/port_back.png differ diff --git a/skins/nexus_4/port_fore.png b/skins/nexus_4/port_fore.png new file mode 100644 index 0000000..5327462 Binary files /dev/null and b/skins/nexus_4/port_fore.png differ diff --git a/skins/nexus_4/port_shadow.png b/skins/nexus_4/port_shadow.png new file mode 100644 index 0000000..0557553 Binary files /dev/null and b/skins/nexus_4/port_shadow.png differ diff --git a/skins/nexus_4/thumb.png b/skins/nexus_4/thumb.png new file mode 100644 index 0000000..2988dc9 Binary files /dev/null and b/skins/nexus_4/thumb.png differ diff --git a/skins/nexus_5/land_back.png b/skins/nexus_5/land_back.png new file mode 100644 index 0000000..74f6313 Binary files /dev/null and b/skins/nexus_5/land_back.png differ diff --git a/skins/nexus_5/land_fore.png b/skins/nexus_5/land_fore.png new file mode 100644 index 0000000..d3a5f03 Binary files /dev/null and b/skins/nexus_5/land_fore.png differ diff --git a/skins/nexus_5/land_shadow.png b/skins/nexus_5/land_shadow.png new file mode 100644 index 0000000..edd6026 Binary files /dev/null and b/skins/nexus_5/land_shadow.png differ diff --git a/skins/nexus_5/layout b/skins/nexus_5/layout new file mode 100644 index 0000000..81965d8 --- /dev/null +++ b/skins/nexus_5/layout @@ -0,0 +1,59 @@ +parts { + device { + display { + width 1080 + height 1920 + x 0 + y 0 + } + } + portrait { + background { + image port_back.png + } + onion { + image port_fore.png + } + } + landscape { + background { + image land_back.png + } + onion { + image land_fore.png + } + } +} +layouts { + portrait { + width 1370 + height 2405 + event EV_SW:0:1 + part1 { + name portrait + x 0 + y 0 + } + part2 { + name device + x 144 + y 195 + } + } + landscape { + width 2497 + height 1235 + event EV_SW:0:0 + part1 { + name landscape + x 0 + y 0 + } + part2 { + name device + x 261 + y 1145 + rotation 3 + } + } +} diff --git a/skins/nexus_5/port_back.png b/skins/nexus_5/port_back.png new file mode 100644 index 0000000..e42c6a9 Binary files /dev/null and b/skins/nexus_5/port_back.png differ diff --git a/skins/nexus_5/port_fore.png b/skins/nexus_5/port_fore.png new file mode 100644 index 0000000..708ba50 Binary files /dev/null and b/skins/nexus_5/port_fore.png differ diff --git a/skins/nexus_5/port_shadow.png b/skins/nexus_5/port_shadow.png new file mode 100644 index 0000000..97b74b5 Binary files /dev/null and b/skins/nexus_5/port_shadow.png differ diff --git a/skins/nexus_5x/land_back.png b/skins/nexus_5x/land_back.png new file mode 100644 index 0000000..a1dbf0b Binary files /dev/null and b/skins/nexus_5x/land_back.png differ diff --git a/skins/nexus_5x/land_fore.png b/skins/nexus_5x/land_fore.png new file mode 100644 index 0000000..d09c434 Binary files /dev/null and b/skins/nexus_5x/land_fore.png differ diff --git a/skins/nexus_5x/land_shadow.png b/skins/nexus_5x/land_shadow.png new file mode 100644 index 0000000..f3385ee Binary files /dev/null and b/skins/nexus_5x/land_shadow.png differ diff --git a/skins/nexus_5x/layout b/skins/nexus_5x/layout new file mode 100644 index 0000000..937743b --- /dev/null +++ b/skins/nexus_5x/layout @@ -0,0 +1,59 @@ +parts { + device { + display { + width 1080 + height 1920 + x 0 + y 0 + } + } + portrait { + background { + image port_back.png + } + onion { + image port_fore.png + } + } + landscape { + background { + image land_back.png + } + onion { + image land_fore.png + } + } +} +layouts { + portrait { + width 1370 + height 2446 + event EV_SW:0:1 + part1 { + name portrait + x 0 + y 0 + } + part2 { + name device + x 147 + y 233 + } + } + landscape { + width 2497 + height 1234 + event EV_SW:0:0 + part1 { + name landscape + x 0 + y 0 + } + part2 { + name device + x 278 + y 1143 + rotation 3 + } + } +} diff --git a/skins/nexus_5x/port_back.png b/skins/nexus_5x/port_back.png new file mode 100644 index 0000000..01933a5 Binary files /dev/null and b/skins/nexus_5x/port_back.png differ diff --git a/skins/nexus_5x/port_fore.png b/skins/nexus_5x/port_fore.png new file mode 100644 index 0000000..b19b106 Binary files /dev/null and b/skins/nexus_5x/port_fore.png differ diff --git a/skins/nexus_5x/port_shadow.png b/skins/nexus_5x/port_shadow.png new file mode 100644 index 0000000..851db21 Binary files /dev/null and b/skins/nexus_5x/port_shadow.png differ diff --git a/skins/nexus_6/land_back.png b/skins/nexus_6/land_back.png new file mode 100644 index 0000000..bc6bd5b Binary files /dev/null and b/skins/nexus_6/land_back.png differ diff --git a/skins/nexus_6/land_fore.png b/skins/nexus_6/land_fore.png new file mode 100644 index 0000000..38cefcc Binary files /dev/null and b/skins/nexus_6/land_fore.png differ diff --git a/skins/nexus_6/land_shadow.png b/skins/nexus_6/land_shadow.png new file mode 100644 index 0000000..2fcc542 Binary files /dev/null and b/skins/nexus_6/land_shadow.png differ diff --git a/skins/nexus_6/layout b/skins/nexus_6/layout new file mode 100644 index 0000000..fe01c10 --- /dev/null +++ b/skins/nexus_6/layout @@ -0,0 +1,59 @@ +parts { + device { + display { + width 1440 + height 2560 + x 0 + y 0 + } + } + portrait { + background { + image port_back.png + } + onion { + image port_fore.png + } + } + landscape { + background { + image land_back.png + } + onion { + image land_fore.png + } + } +} +layouts { + portrait { + width 1896 + height 3054 + event EV_SW:0:1 + part1 { + name portrait + x 0 + y 0 + } + part2 { + name device + x 229 + y 239 + } + } + landscape { + width 3142 + height 1639 + event EV_SW:0:0 + part1 { + name landscape + x 0 + y 0 + } + part2 { + name device + x 318 + y 1516 + rotation 3 + } + } +} diff --git a/skins/nexus_6/port_back.png b/skins/nexus_6/port_back.png new file mode 100644 index 0000000..0535439 Binary files /dev/null and b/skins/nexus_6/port_back.png differ diff --git a/skins/nexus_6/port_fore.png b/skins/nexus_6/port_fore.png new file mode 100644 index 0000000..f8821ba Binary files /dev/null and b/skins/nexus_6/port_fore.png differ diff --git a/skins/nexus_6/port_shadow.png b/skins/nexus_6/port_shadow.png new file mode 100644 index 0000000..57e1800 Binary files /dev/null and b/skins/nexus_6/port_shadow.png differ diff --git a/skins/nexus_6p/land_back.png b/skins/nexus_6p/land_back.png new file mode 100644 index 0000000..f1790cd Binary files /dev/null and b/skins/nexus_6p/land_back.png differ diff --git a/skins/nexus_6p/land_fore.png b/skins/nexus_6p/land_fore.png new file mode 100644 index 0000000..566df98 Binary files /dev/null and b/skins/nexus_6p/land_fore.png differ diff --git a/skins/nexus_6p/land_shadow.png b/skins/nexus_6p/land_shadow.png new file mode 100644 index 0000000..036a295 Binary files /dev/null and b/skins/nexus_6p/land_shadow.png differ diff --git a/skins/nexus_6p/layout b/skins/nexus_6p/layout new file mode 100644 index 0000000..fff8a05 --- /dev/null +++ b/skins/nexus_6p/layout @@ -0,0 +1,59 @@ +parts { + device { + display { + width 1440 + height 2560 + x 0 + y 0 + } + } + portrait { + background { + image port_back.png + } + onion { + image port_fore.png + } + } + landscape { + background { + image land_back.png + } + onion { + image land_fore.png + } + } +} +layouts { + portrait { + width 1840 + height 3251 + event EV_SW:0:1 + part1 { + name portrait + x 0 + y 0 + } + part2 { + name device + x 195 + y 329 + } + } + landscape { + width 3427 + height 1620 + event EV_SW:0:0 + part1 { + name landscape + x 0 + y 0 + } + part2 { + name device + x 442 + y 1511 + rotation 3 + } + } +} diff --git a/skins/nexus_6p/port_back.png b/skins/nexus_6p/port_back.png new file mode 100644 index 0000000..710ad89 Binary files /dev/null and b/skins/nexus_6p/port_back.png differ diff --git a/skins/nexus_6p/port_fore.png b/skins/nexus_6p/port_fore.png new file mode 100644 index 0000000..40044e5 Binary files /dev/null and b/skins/nexus_6p/port_fore.png differ diff --git a/skins/nexus_6p/port_shadow.png b/skins/nexus_6p/port_shadow.png new file mode 100644 index 0000000..b19fc4f Binary files /dev/null and b/skins/nexus_6p/port_shadow.png differ diff --git a/skins/nexus_7/land_back.png b/skins/nexus_7/land_back.png new file mode 100644 index 0000000..878fdd8 Binary files /dev/null and b/skins/nexus_7/land_back.png differ diff --git a/skins/nexus_7/land_fore.png b/skins/nexus_7/land_fore.png new file mode 100644 index 0000000..c01fdf5 Binary files /dev/null and b/skins/nexus_7/land_fore.png differ diff --git a/skins/nexus_7/land_shadow.png b/skins/nexus_7/land_shadow.png new file mode 100644 index 0000000..5082811 Binary files /dev/null and b/skins/nexus_7/land_shadow.png differ diff --git a/skins/nexus_7/layout b/skins/nexus_7/layout new file mode 100644 index 0000000..7290fcb --- /dev/null +++ b/skins/nexus_7/layout @@ -0,0 +1,59 @@ +parts { + device { + display { + width 800 + height 1280 + x 0 + y 0 + } + } + portrait { + background { + image port_back.png + } + onion { + image port_fore.png + } + } + landscape { + background { + image land_back.png + } + onion { + image land_fore.png + } + } +} +layouts { + portrait { + width 1094 + height 1689 + event EV_SW:0:1 + part1 { + name portrait + x 0 + y 0 + } + part2 { + name device + x 142 + y 190 + } + } + landscape { + width 1803 + height 1045 + event EV_SW:0:0 + part1 { + name landscape + x 0 + y 0 + } + part2 { + name device + x 260 + y 905 + rotation 3 + } + } +} diff --git a/skins/nexus_7/port_back.png b/skins/nexus_7/port_back.png new file mode 100644 index 0000000..5f7db41 Binary files /dev/null and b/skins/nexus_7/port_back.png differ diff --git a/skins/nexus_7/port_fore.png b/skins/nexus_7/port_fore.png new file mode 100644 index 0000000..1299515 Binary files /dev/null and b/skins/nexus_7/port_fore.png differ diff --git a/skins/nexus_7/port_shadow.png b/skins/nexus_7/port_shadow.png new file mode 100644 index 0000000..693fc5d Binary files /dev/null and b/skins/nexus_7/port_shadow.png differ diff --git a/skins/nexus_7/thumb.png b/skins/nexus_7/thumb.png new file mode 100644 index 0000000..b5db82e Binary files /dev/null and b/skins/nexus_7/thumb.png differ diff --git a/skins/nexus_7_2013/land_back.png b/skins/nexus_7_2013/land_back.png new file mode 100644 index 0000000..c88c18f Binary files /dev/null and b/skins/nexus_7_2013/land_back.png differ diff --git a/skins/nexus_7_2013/land_fore.png b/skins/nexus_7_2013/land_fore.png new file mode 100644 index 0000000..e49b1cd Binary files /dev/null and b/skins/nexus_7_2013/land_fore.png differ diff --git a/skins/nexus_7_2013/land_shadow.png b/skins/nexus_7_2013/land_shadow.png new file mode 100644 index 0000000..aaf1058 Binary files /dev/null and b/skins/nexus_7_2013/land_shadow.png differ diff --git a/skins/nexus_7_2013/layout b/skins/nexus_7_2013/layout new file mode 100644 index 0000000..fb8983b --- /dev/null +++ b/skins/nexus_7_2013/layout @@ -0,0 +1,59 @@ +parts { + device { + display { + width 1200 + height 1920 + x 0 + y 0 + } + } + portrait { + background { + image port_back.png + } + onion { + image port_fore.png + } + } + landscape { + background { + image land_back.png + } + onion { + image land_fore.png + } + } +} +layouts { + portrait { + width 1596 + height 2571 + event EV_SW:0:1 + part1 { + name portrait + x 0 + y 0 + } + part2 { + name device + x 195 + y 301 + } + } + landscape { + width 2772 + height 1479 + event EV_SW:0:0 + part1 { + name landscape + x 0 + y 0 + } + part2 { + name device + x 423 + y 1320 + rotation 3 + } + } +} diff --git a/skins/nexus_7_2013/port_back.png b/skins/nexus_7_2013/port_back.png new file mode 100644 index 0000000..e7f9e98 Binary files /dev/null and b/skins/nexus_7_2013/port_back.png differ diff --git a/skins/nexus_7_2013/port_fore.png b/skins/nexus_7_2013/port_fore.png new file mode 100644 index 0000000..d348dde Binary files /dev/null and b/skins/nexus_7_2013/port_fore.png differ diff --git a/skins/nexus_7_2013/port_shadow.png b/skins/nexus_7_2013/port_shadow.png new file mode 100644 index 0000000..bea7a24 Binary files /dev/null and b/skins/nexus_7_2013/port_shadow.png differ diff --git a/skins/nexus_9/land_back.png b/skins/nexus_9/land_back.png new file mode 100644 index 0000000..909d728 Binary files /dev/null and b/skins/nexus_9/land_back.png differ diff --git a/skins/nexus_9/land_fore.png b/skins/nexus_9/land_fore.png new file mode 100644 index 0000000..c79ab88 Binary files /dev/null and b/skins/nexus_9/land_fore.png differ diff --git a/skins/nexus_9/land_shadow.png b/skins/nexus_9/land_shadow.png new file mode 100644 index 0000000..fdc09ed Binary files /dev/null and b/skins/nexus_9/land_shadow.png differ diff --git a/skins/nexus_9/layout b/skins/nexus_9/layout new file mode 100644 index 0000000..5743f19 --- /dev/null +++ b/skins/nexus_9/layout @@ -0,0 +1,59 @@ +parts { + device { + display { + width 1536 + height 2048 + x 0 + y 0 + } + } + portrait { + background { + image port_back.png + } + onion { + image port_fore.png + } + } + landscape { + background { + image land_back.png + } + onion { + image land_fore.png + } + } +} +layouts { + portrait { + width 1978 + height 2631 + event EV_SW:0:1 + part1 { + name portrait + x 0 + y 0 + } + part2 { + name device + x 219 + y 264 + } + } + landscape { + width 2854 + height 1785 + event EV_SW:0:0 + part1 { + name landscape + x 0 + y 0 + } + part2 { + name device + x 401 + y 1635 + rotation 3 + } + } +} diff --git a/skins/nexus_9/port_back.png b/skins/nexus_9/port_back.png new file mode 100644 index 0000000..561370e Binary files /dev/null and b/skins/nexus_9/port_back.png differ diff --git a/skins/nexus_9/port_fore.png b/skins/nexus_9/port_fore.png new file mode 100644 index 0000000..b17f30f Binary files /dev/null and b/skins/nexus_9/port_fore.png differ diff --git a/skins/nexus_9/port_shadow.png b/skins/nexus_9/port_shadow.png new file mode 100644 index 0000000..2298e56 Binary files /dev/null and b/skins/nexus_9/port_shadow.png differ diff --git a/skins/nexus_one/button.png b/skins/nexus_one/button.png new file mode 100644 index 0000000..7d02136 Binary files /dev/null and b/skins/nexus_one/button.png differ diff --git a/skins/nexus_one/land_back.png b/skins/nexus_one/land_back.png new file mode 100644 index 0000000..e2727be Binary files /dev/null and b/skins/nexus_one/land_back.png differ diff --git a/skins/nexus_one/land_shadow.png b/skins/nexus_one/land_shadow.png new file mode 100644 index 0000000..12565b8 Binary files /dev/null and b/skins/nexus_one/land_shadow.png differ diff --git a/skins/nexus_one/layout b/skins/nexus_one/layout new file mode 100644 index 0000000..e776ad1 --- /dev/null +++ b/skins/nexus_one/layout @@ -0,0 +1,134 @@ +parts { + device { + display { + width 480 + height 800 + x 0 + y 0 + } + } + portrait { + background { + image port_back.png + } + onion { + image port_fore.png + } + buttons { + back { + image button.png + x 161 + y 945 + } + soft-left { + image button.png + x 282 + y 945 + } + home { + image button.png + x 402 + y 945 + } + search { + image button.png + x 524 + y 945 + } + volume-up { + image volume_up.png + x 23 + y 196 + } + volume-down { + image volume_down.png + x 23 + y 258 + } + power { + image power.png + x 147 + y 0 + } + } + + } + landscape { + background { + image land_back.png + } + onion { + image land_fore.png + } + buttons { + back { + image button.png + x 1015 + y 449 + } + soft-left { + image button.png + x 1015 + y 327 + } + home { + image button.png + x 1015 + y 207 + } + search { + image button.png + x 1014 + y 86 + } + volume-up { + image volume_up_land.png + x 262 + y 534 + } + volume-down { + image volume_down_land.png + x 323 + y 534 + } + power { + image power_land.png + x 38 + y 422 + } + } + } +} +layouts { + portrait { + width 732 + height 1178 + event EV_SW:0:1 + part1 { + name portrait + x 0 + y 0 + } + part2 { + name device + x 125 + y 131 + } + } + landscape { + width 1300 + height 612 + event EV_SW:0:0 + part1 { + name landscape + x 0 + y 0 + } + part2 { + name device + x 200 + y 532 + rotation 3 + } + } +} diff --git a/skins/nexus_one/port_back.png b/skins/nexus_one/port_back.png new file mode 100644 index 0000000..76caa31 Binary files /dev/null and b/skins/nexus_one/port_back.png differ diff --git a/skins/nexus_one/port_shadow.png b/skins/nexus_one/port_shadow.png new file mode 100644 index 0000000..5f70396 Binary files /dev/null and b/skins/nexus_one/port_shadow.png differ diff --git a/skins/nexus_one/power.png b/skins/nexus_one/power.png new file mode 100644 index 0000000..2f968a7 Binary files /dev/null and b/skins/nexus_one/power.png differ diff --git a/skins/nexus_one/power_land.png b/skins/nexus_one/power_land.png new file mode 100644 index 0000000..7e16a3c Binary files /dev/null and b/skins/nexus_one/power_land.png differ diff --git a/skins/nexus_one/thumb.png b/skins/nexus_one/thumb.png new file mode 100644 index 0000000..8b9a3d9 Binary files /dev/null and b/skins/nexus_one/thumb.png differ diff --git a/skins/nexus_one/volume_down.png b/skins/nexus_one/volume_down.png new file mode 100644 index 0000000..e0da10b Binary files /dev/null and b/skins/nexus_one/volume_down.png differ diff --git a/skins/nexus_one/volume_down_land.png b/skins/nexus_one/volume_down_land.png new file mode 100644 index 0000000..d7909bb Binary files /dev/null and b/skins/nexus_one/volume_down_land.png differ diff --git a/skins/nexus_one/volume_up.png b/skins/nexus_one/volume_up.png new file mode 100644 index 0000000..77193ff Binary files /dev/null and b/skins/nexus_one/volume_up.png differ diff --git a/skins/nexus_one/volume_up_land.png b/skins/nexus_one/volume_up_land.png new file mode 100644 index 0000000..ffd85c3 Binary files /dev/null and b/skins/nexus_one/volume_up_land.png differ diff --git a/skins/nexus_s/button.png b/skins/nexus_s/button.png new file mode 100644 index 0000000..7d02136 Binary files /dev/null and b/skins/nexus_s/button.png differ diff --git a/skins/nexus_s/land_back.png b/skins/nexus_s/land_back.png new file mode 100644 index 0000000..84cc995 Binary files /dev/null and b/skins/nexus_s/land_back.png differ diff --git a/skins/nexus_s/land_fore.png b/skins/nexus_s/land_fore.png new file mode 100644 index 0000000..5fbae36 Binary files /dev/null and b/skins/nexus_s/land_fore.png differ diff --git a/skins/nexus_s/land_shadow.png b/skins/nexus_s/land_shadow.png new file mode 100644 index 0000000..40d501c Binary files /dev/null and b/skins/nexus_s/land_shadow.png differ diff --git a/skins/nexus_s/layout b/skins/nexus_s/layout new file mode 100644 index 0000000..3a7135f --- /dev/null +++ b/skins/nexus_s/layout @@ -0,0 +1,133 @@ +parts { + device { + display { + width 480 + height 800 + x 0 + y 0 + } + } + portrait { + background { + image port_back.png + } + onion { + image port_fore.png + } + buttons { + back { + image button.png + x 165 + y 991 + } + soft-left { + image button.png + x 279 + y 991 + } + search { + image button.png + x 390 + y 991 + } + home { + image button.png + x 502 + y 993 + } + volume-up { + image volume_up.png + x 23 + y 305 + } + volume-down { + image volume_down.png + x 23 + y 412 + } + power { + image power.png + x 627 + y 215 + } + } + } + landscape { + background { + image land_back.png + } + onion { + image land_fore.png + } + buttons { + back { + image button.png + x 1039 + y 430 + } + soft-left { + image button.png + x 1039 + y 318 + } + search { + image button.png + x 1039 + y 206 + } + home { + image button.png + x 1039 + y 94 + } + volume-up { + image volume_up_land.png + x 361 + y 519 + } + volume-down { + image volume_down_land.png + x 459 + y 519 + } + power { + image power_land.png + x 266 + y -11 + } + } + } +} +layouts { + portrait { + width 719 + height 1139 + event EV_SW:0:1 + part1 { + name portrait + x 0 + y 0 + } + part2 { + name device + x 119 + y 160 + } + } + landscape { + width 1210 + height 586 + event EV_SW:0:0 + part1 { + name landscape + x 0 + y 0 + } + part2 { + name device + x 208 + y 524 + rotation 3 + } + } +} diff --git a/skins/nexus_s/port_back.png b/skins/nexus_s/port_back.png new file mode 100644 index 0000000..c6fff0d Binary files /dev/null and b/skins/nexus_s/port_back.png differ diff --git a/skins/nexus_s/port_fore.png b/skins/nexus_s/port_fore.png new file mode 100644 index 0000000..29760b7 Binary files /dev/null and b/skins/nexus_s/port_fore.png differ diff --git a/skins/nexus_s/port_shadow.png b/skins/nexus_s/port_shadow.png new file mode 100644 index 0000000..88bd96d Binary files /dev/null and b/skins/nexus_s/port_shadow.png differ diff --git a/skins/nexus_s/power.png b/skins/nexus_s/power.png new file mode 100644 index 0000000..fb17043 Binary files /dev/null and b/skins/nexus_s/power.png differ diff --git a/skins/nexus_s/power_land.png b/skins/nexus_s/power_land.png new file mode 100644 index 0000000..2f968a7 Binary files /dev/null and b/skins/nexus_s/power_land.png differ diff --git a/skins/nexus_s/thumb.png b/skins/nexus_s/thumb.png new file mode 100644 index 0000000..8b9a3d9 Binary files /dev/null and b/skins/nexus_s/thumb.png differ diff --git a/skins/nexus_s/volume_down.png b/skins/nexus_s/volume_down.png new file mode 100644 index 0000000..e0da10b Binary files /dev/null and b/skins/nexus_s/volume_down.png differ diff --git a/skins/nexus_s/volume_down_land.png b/skins/nexus_s/volume_down_land.png new file mode 100644 index 0000000..d7909bb Binary files /dev/null and b/skins/nexus_s/volume_down_land.png differ diff --git a/skins/nexus_s/volume_up.png b/skins/nexus_s/volume_up.png new file mode 100644 index 0000000..77193ff Binary files /dev/null and b/skins/nexus_s/volume_up.png differ diff --git a/skins/nexus_s/volume_up_land.png b/skins/nexus_s/volume_up_land.png new file mode 100644 index 0000000..ffd85c3 Binary files /dev/null and b/skins/nexus_s/volume_up_land.png differ diff --git a/skins/pixel_c/land_back.png b/skins/pixel_c/land_back.png new file mode 100644 index 0000000..06b6dd1 Binary files /dev/null and b/skins/pixel_c/land_back.png differ diff --git a/skins/pixel_c/land_fore.png b/skins/pixel_c/land_fore.png new file mode 100644 index 0000000..58976fe Binary files /dev/null and b/skins/pixel_c/land_fore.png differ diff --git a/skins/pixel_c/land_shadow.png b/skins/pixel_c/land_shadow.png new file mode 100644 index 0000000..09cc981 Binary files /dev/null and b/skins/pixel_c/land_shadow.png differ diff --git a/skins/pixel_c/layout b/skins/pixel_c/layout new file mode 100644 index 0000000..a6e65da --- /dev/null +++ b/skins/pixel_c/layout @@ -0,0 +1,59 @@ +parts { + device { + display { + width 1800 + height 2560 + x 0 + y 0 + } + } + portrait { + background { + image port_back.png + } + onion { + image port_fore.png + } + } + landscape { + background { + image land_back.png + } + onion { + image land_fore.png + } + } +} +layouts { + portrait { + width 2307 + height 2971 + event EV_SW:0:1 + part1 { + name portrait + x 0 + y 0 + } + part2 { + name device + x 259 + y 181 + } + } + landscape { + width 3096 + height 2215 + event EV_SW:0:0 + part1 { + name landscape + x 0 + y 0 + } + part2 { + name device + x 269 + y 1988 + rotation 3 + } + } +} diff --git a/skins/pixel_c/port_back.png b/skins/pixel_c/port_back.png new file mode 100644 index 0000000..52d2eda Binary files /dev/null and b/skins/pixel_c/port_back.png differ diff --git a/skins/pixel_c/port_fore.png b/skins/pixel_c/port_fore.png new file mode 100644 index 0000000..8be9d34 Binary files /dev/null and b/skins/pixel_c/port_fore.png differ diff --git a/skins/pixel_c/port_shadow.png b/skins/pixel_c/port_shadow.png new file mode 100644 index 0000000..2ac3296 Binary files /dev/null and b/skins/pixel_c/port_shadow.png differ diff --git a/service/__init__.py b/src/__init__.py similarity index 65% rename from service/__init__.py rename to src/__init__.py index 767cb01..511707c 100644 --- a/service/__init__.py +++ b/src/__init__.py @@ -2,3 +2,4 @@ import os WORKDIR = os.path.dirname(__file__) CONFIG_FILE = os.path.join(WORKDIR, 'nodeconfig.json') +LOGGING_FILE = os.path.join(WORKDIR, 'logging.conf') diff --git a/src/android.py b/src/android.py new file mode 100644 index 0000000..be84ca8 --- /dev/null +++ b/src/android.py @@ -0,0 +1,116 @@ +import logging +import os +import re +import subprocess + +logging.basicConfig() +logger = logging.getLogger('android') + + +def get_api_level(android_version): + """ + Get api level of android version. + + :param android_version: android version + :type android_version: str + :return: api version + :rtype: str + """ + api_version = None + + try: + packages = get_available_sdk_packages() + + if packages: + item_pos = get_item_position(android_version, packages) + logger.info('package in position: {pos}'.format(pos=item_pos)) + item = packages[item_pos] + + item_info = item.split('-') + api_version = re.search('%s(.*)%s' % ('API', ','), item_info[1]).group(1).strip() + logger.info( + 'API level: {api}'.format(api=api_version)) + else: + raise RuntimeError('List of packages is empty!') + + except IndexError as i_err: + logger.error(i_err) + + return api_version + + +def install_package(android_path, emulator_file, api_level, sys_img): + """ + Install sdk package. + + :param android_path: location where android SDK is installed + :type android_path: str + :param emulator_file: emulator file that need to be link + :type emulator_file: str + :param api_level: api level + :type api_level: str + :param sys_img: system image of emulator + :type sys_img: str + """ + # Link emulator shortcut + emu_file = os.path.join(android_path, 'tools', emulator_file) + emu_target = os.path.join(android_path, 'tools', 'emulator') + os.symlink(emu_file, emu_target) + + # Install package based on given android version + cmd = 'echo y | android update sdk --no-ui -a -t android-{api},sys-img-{sys_img}-android-{api}'.format( + api=api_level, sys_img=sys_img) + logger.info('Android installation command : {install}'.format(install=cmd)) + subprocess.check_call('xterm -e \"{cmd}\"'.format(cmd=cmd), shell=True) + + +def create_avd(android_path, avd_name, api_level): + """ + Create android virtual device. + + :param android_path: location where android SDK is installed + :type android_path: str + :param avd_name: desire name + :type avd_name: str + :param api_level: api level + :type api_level: str + """ + # Link emulator skins + skins_rsc = os.path.join(android_path, 'skins') + skins_dst = os.path.join(android_path, 'platforms', 'android-{api}'.format(api=api_level), 'skins') + for skin_file in os.listdir(skins_rsc): + os.symlink(os.path.join(skins_rsc, skin_file), os.path.join(skins_dst, skin_file)) + + # Create android emulator + cmd = 'echo no | android create avd -f -n {name} -t android-{api}'.format(name=avd_name, api=api_level) + logger.info('Emulator creation command : {cmd}'.format(cmd=cmd)) + subprocess.check_call('xterm -e \"{cmd}\"'.format(cmd=cmd), shell=True) + + +def get_available_sdk_packages(): + """ + Get list of available sdk packages. + + :return: List of available packages. + :rtype: bytearray + """ + cmd = ['android', 'list', 'sdk'] + output_str = subprocess.check_output(cmd) + logger.info('List of Android SDK: ') + logger.info(output_str) + return [output.strip() for output in output_str.split('\n')] if output_str else None + + +def get_item_position(keyword, items): + """ + Get position of item in array by given keyword. + + :return: item position + :rtype: int + """ + pos = 0 + for p, v in enumerate(items): + if keyword in v: + pos = p + break # Get the first item that match with keyword + return pos diff --git a/service/appium.py b/src/appium.py similarity index 57% rename from service/appium.py rename to src/appium.py index f1369f9..98b6b00 100644 --- a/service/appium.py +++ b/src/appium.py @@ -1,4 +1,37 @@ import json +import logging +import os +import subprocess + +logger = logging.getLogger('appium') + + +def run(connect_to_grid, emulator_name, android_version): + """ + Run appium server. + + :param connect_to_grid: option to connect with selenium grid + :type connect_to_grid: bool + :param emulator_name: name of emulator + :type emulator_name: str + :param android_version: android version + :type android_version: str + """ + cmd = 'appium' + if connect_to_grid: + from src import CONFIG_FILE + try: + appium_host = os.getenv('APPIUM_HOST', '127.0.0.1') + 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(CONFIG_FILE, emulator_name, android_version, + appium_host, appium_port, selenium_host, selenium_port) + cmd += ' --nodeconfig {file}'.format(file=CONFIG_FILE) + except ValueError as v_err: + logger.error(v_err) + subprocess.check_call('xterm -T "{name}" -n "{name}" -e \"{cmd}\"'.format( + name=emulator_name, cmd=cmd), shell=True) def create_node_config(config_file, emulator_name, android_version, appium_host, appium_port, @@ -46,5 +79,6 @@ def create_node_config(config_file, emulator_name, android_version, appium_host, 'hubPort': selenium_port } } + logger.info('appium node config: {config}'.format(config=config)) with open(config_file, 'w') as cf: cf.write(json.dumps(config)) diff --git a/src/log.py b/src/log.py new file mode 100644 index 0000000..ac9b1da --- /dev/null +++ b/src/log.py @@ -0,0 +1,8 @@ +import logging +import logging.config + +from src import LOGGING_FILE + + +def init(): + logging.config.fileConfig(LOGGING_FILE) diff --git a/src/logging.conf b/src/logging.conf new file mode 100644 index 0000000..f779ca1 --- /dev/null +++ b/src/logging.conf @@ -0,0 +1,38 @@ +[loggers] +keys=root, android, appium, service + +[handlers] +keys=console + +[formatters] +keys=formatter + +[logger_root] +level=INFO +handlers=console + +[logger_android] +level=INFO +handlers=console +propagate=0 +qualname=android + +[logger_appium] +level=INFO +handlers=console +propagate=0 +qualname=appium + +[logger_service] +level=INFO +handlers=console +propagate=0 +qualname=service + +[handler_console] +class=StreamHandler +formatter=formatter +args=(sys.stdout,) + +[formatter_formatter] +format=[%(process)2d] [%(levelname)5s] %(name)s - %(message)s diff --git a/src/service.py b/src/service.py new file mode 100644 index 0000000..c3aba6d --- /dev/null +++ b/src/service.py @@ -0,0 +1,59 @@ +import logging +import os + +from src import android, appium, log + +logger = logging.getLogger('service') + +# not using enum because need to install pip that will make docker image size bigger +TYPE_ARMEABI = 'armeabi' +TYPE_X86 = 'x86' + + +def start(): + """ + Installation of needed sdk package, creation of android emulator and execution of appium server. + + """ + # Get all needed environment variables + android_path = os.getenv('ANDROID_HOME', '/root') + logger.info('Android path: {path}'.format(path=android_path)) + emulator_type = os.getenv('EMULATOR_TYPE', TYPE_ARMEABI).lower() + logger.info('Emulator type: {type}'.format(type=emulator_type)) + android_version = os.getenv('ANDROID_VERSION', '4.2.2') + logger.info('Android version: {version}'.format(version=android_version)) + connect_to_grid = str_to_bool(str(os.getenv('CONNECT_TO_GRID', False))) + logger.info('Connect to selenium grid? {input}'.format(input=connect_to_grid)) + + # Install needed sdk packages + emulator_type = TYPE_ARMEABI if emulator_type not in [TYPE_ARMEABI, TYPE_X86] else emulator_type + emulator_file = 'emulator64-x86' if emulator_type == TYPE_X86 else 'emulator64-arm' + logger.info('Emulator file: {file}'.format(file=emulator_file)) + api_level = android.get_api_level(android_version) + sys_img = 'x86' if emulator_type == TYPE_X86 else 'armeabi-v7a' + logger.info('System image: {sys_img}'.format(sys_img=sys_img)) + android.install_package(android_path, emulator_file, api_level, sys_img) + + # Create android virtual device + avd_name = 'emulator_{version}'.format(version=android_version) + logger.info('AVD name: {avd}'.format(avd=avd_name)) + android.create_avd(android_path, avd_name, api_level) + + # Run appium server + appium.run(connect_to_grid, avd_name, android_version) + + +def str_to_bool(str): + """ + Convert string to boolean. + + :param str: given string + :type str: str + :return: converted string + :rtype: bool + """ + return str.lower() in ('yes', 'true', 't', '1') + +if __name__ == '__main__': + log.init() + start() diff --git a/src/tests/__init__.py b/src/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/tests/android/__init__.py b/src/tests/android/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/service/tests/test_get_command.py b/src/tests/android/test_api_level.py similarity index 55% rename from service/tests/test_get_command.py rename to src/tests/android/test_api_level.py index 8e48957..568f306 100644 --- a/service/tests/test_get_command.py +++ b/src/tests/android/test_api_level.py @@ -1,36 +1,33 @@ -"""Unit test for start.py.""" +"""Unit test for android.py.""" from unittest import TestCase import mock -from service import start +from src import android -@mock.patch('service.start.get_available_sdk_packages') -class TestRunService(TestCase): - """Unit test class to test method get_android_bash_commands.""" +@mock.patch('src.android.get_available_sdk_packages') +class TestApiLevel(TestCase): + """Unit test class to test method get_api_level.""" def setUp(self): self.android_version = '4.2.2' - self.emulator_type = start.TYPE_ARMEABI - def test_create_emulator(self, mocked_packages): + def test_get_api_level(self, mocked_packages): mocked_packages.return_value = ['9- SDK Platform Android 4.4.2, API 19, revision 4', '10- SDK Platform Android 4.3.1, API 18, revision 3', '11- SDK Platform Android 4.2.2, API 17, revision 3'] - cmd = start.get_android_bash_commands(self.android_version, self.emulator_type) - self.assertIsNotNone(cmd) - self.assertTrue('android update sdk' in cmd) - self.assertTrue('android create avd' in cmd) + api_level = android.get_api_level(self.android_version) + self.assertEqual(api_level, '17') def test_empty_packages(self, mocked_packages): mocked_packages.return_value = None with self.assertRaises(RuntimeError): - start.get_android_bash_commands(self.android_version, self.emulator_type) + android.get_api_level(self.android_version) def test_index_error(self, mocked_packages): mocked_packages.return_value = ['9 SDK Platform Android 4.4.2, API 19, revision 4', '10 SDK Platform Android 4.3.1, API 18, revision 3', '11 SDK Platform Android 4.2.2, API 17, revision 3'] - start.get_android_bash_commands(self.android_version, self.emulator_type) + android.get_api_level(self.android_version) self.assertRaises(IndexError) diff --git a/service/tests/test_available_packages.py b/src/tests/android/test_available_packages.py similarity index 77% rename from service/tests/test_available_packages.py rename to src/tests/android/test_available_packages.py index 19f13e4..704ef8c 100644 --- a/service/tests/test_available_packages.py +++ b/src/tests/android/test_available_packages.py @@ -1,9 +1,9 @@ -"""Unit test for start.py.""" +"""Unit test for android.py.""" from unittest import TestCase import mock -from service import start +from src import android class TestAvailablePackages(TestCase): @@ -12,17 +12,17 @@ class TestAvailablePackages(TestCase): @mock.patch('subprocess.check_output') def test_valid_output(self, mocked_output): mocked_output.return_value = 'package 1 \n package 2' - output = start.get_available_sdk_packages() + output = android.get_available_sdk_packages() self.assertEqual(['package 1', 'package 2'], output) @mock.patch('subprocess.check_output') def test_without_line_break(self, mocked_output): mocked_output.return_value = 'package 1, package 2' - output = start.get_available_sdk_packages() + output = android.get_available_sdk_packages() self.assertEqual(['package 1, package 2'], output) @mock.patch('subprocess.check_output') def test_empty_string(self, mocked_output): mocked_output.return_value = None - output = start.get_available_sdk_packages() + output = android.get_available_sdk_packages() self.assertEqual(None, output) diff --git a/src/tests/android/test_create_avd.py b/src/tests/android/test_create_avd.py new file mode 100644 index 0000000..b975ccc --- /dev/null +++ b/src/tests/android/test_create_avd.py @@ -0,0 +1,28 @@ +"""Unit test for android.py.""" +from unittest import TestCase + +import mock + +from src import android + + +class TestAvd(TestCase): + """Unit test class to test method create_avd.""" + + def setUp(self): + self.android_path = '/root' + self.avd_name = 'test' + self.api_level = 21 + + @mock.patch('os.symlink') + @mock.patch('subprocess.check_call') + def test_avd_creation(self, mocked_sys_link, mocked_suprocess): + 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) + android.create_avd(self.android_path, self.avd_name, self.api_level) + self.assertTrue(mocked_list_dir.called) + self.assertTrue(mocked_sys_link.called) + self.assertTrue(mocked_suprocess.called) diff --git a/src/tests/android/test_install_package.py b/src/tests/android/test_install_package.py new file mode 100644 index 0000000..9ded4cb --- /dev/null +++ b/src/tests/android/test_install_package.py @@ -0,0 +1,25 @@ +"""Unit test for android.py.""" +from unittest import TestCase + +import mock + +from src import android + + +class TestInstallPackage(TestCase): + """Unit test class to test method install_package.""" + + def setUp(self): + self.android_path = '/root' + self.emulator_file = 'emulator64-arm' + self.api_level = 21 + self.sys_img = 'armeabi-v7a' + + @mock.patch('os.symlink') + @mock.patch('subprocess.check_call') + def test_package_installation(self, mocked_sys_link, mocked_suprocess): + self.assertFalse(mocked_sys_link.called) + self.assertFalse(mocked_suprocess.called) + android.install_package(self.android_path, self.emulator_file, self.api_level, self.sys_img) + self.assertTrue(mocked_sys_link.called) + self.assertTrue(mocked_suprocess.called) diff --git a/service/tests/test_item_position.py b/src/tests/android/test_item_position.py similarity index 69% rename from service/tests/test_item_position.py rename to src/tests/android/test_item_position.py index e894a42..0a1585e 100644 --- a/service/tests/test_item_position.py +++ b/src/tests/android/test_item_position.py @@ -1,7 +1,7 @@ -"""Unit test for start.py.""" +"""Unit test for android.py.""" from unittest import TestCase -from service import start +from src import android class TestItemPosition(TestCase): @@ -12,16 +12,16 @@ class TestItemPosition(TestCase): def test_valid_params(self): keyword = '4.2' - output = start.get_item_position(keyword, self.items) + output = android.get_item_position(keyword, self.items) self.assertEqual(1, output) def test_invalid_keyword(self): keyword = 'fake' - output = start.get_item_position(keyword, self.items) + output = android.get_item_position(keyword, self.items) self.assertEqual(0, output) def test_empty_array(self): items = [] keyword = '4.2' - output = start.get_item_position(keyword, items) + output = android.get_item_position(keyword, items) self.assertEqual(0, output) diff --git a/src/tests/appium/__init__.py b/src/tests/appium/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/service/tests/test_appium_config.py b/src/tests/appium/test_node_config.py similarity index 81% rename from service/tests/test_appium_config.py rename to src/tests/appium/test_node_config.py index ed37e96..aa3a591 100644 --- a/service/tests/test_appium_config.py +++ b/src/tests/appium/test_node_config.py @@ -3,14 +3,13 @@ import os from unittest import TestCase -from service import CONFIG_FILE -from service import appium +from src import CONFIG_FILE, appium class TestAppiumConfig(TestCase): """Unit test class to test method create_node_config.""" - def test_create_node_config(self): + def test_config_creation(self): self.assertFalse(os.path.exists(CONFIG_FILE)) appium.create_node_config(CONFIG_FILE, 'emulator_name', '4.2.2', '127.0.0.1', 4723, '127.0.0.1', 4444) self.assertTrue(os.path.exists(CONFIG_FILE)) diff --git a/src/tests/appium/test_run.py b/src/tests/appium/test_run.py new file mode 100644 index 0000000..77c7ac3 --- /dev/null +++ b/src/tests/appium/test_run.py @@ -0,0 +1,47 @@ +"""Unit test for appium.py.""" +from unittest import TestCase + +import os + +import mock + +from src import appium + + +@mock.patch('subprocess.check_call') +class TestAppiumConfig(TestCase): + """Unit test class to test method run.""" + + def setUp(self): + self.emulator_name = 'test' + self.android_version = '4.2.2' + + def test_without_selenium_grid(self, mocked_subprocess): + with mock.patch('src.appium.create_node_config') as mocked_config: + self.assertFalse(mocked_config.called) + self.assertFalse(mocked_subprocess.called) + appium.run(False, self.emulator_name, self.android_version) + self.assertFalse(mocked_config.called) + self.assertTrue(mocked_subprocess.called) + + def test_with_selenium_grid(self, mocked_subprocess): + with mock.patch('src.appium.create_node_config') as mocked_config: + self.assertFalse(mocked_config.called) + self.assertFalse(mocked_subprocess.called) + appium.run(True, self.emulator_name, self.android_version) + self.assertTrue(mocked_config.called) + self.assertTrue(mocked_subprocess.called) + + def test_invalid_integer(self, mocked_subprocess): + os.environ['APPIUM_PORT'] = 'test' + with mock.patch('src.appium.create_node_config') as mocked_config: + self.assertFalse(mocked_config.called) + self.assertFalse(mocked_subprocess.called) + appium.run(True, self.emulator_name, self.android_version) + self.assertFalse(mocked_config.called) + self.assertTrue(mocked_subprocess.called) + self.assertRaises(ValueError) + + def tearDown(self): + if os.getenv('APPIUM_PORT'): + del os.environ['APPIUM_PORT'] diff --git a/supervisord.conf b/supervisord.conf index 7730597..d183a7d 100644 --- a/supervisord.conf +++ b/supervisord.conf @@ -24,6 +24,6 @@ stdout_logfile=%(ENV_LOG_PATH)s/novnc.stdout.log stderr_logfile=%(ENV_LOG_PATH)s/novnc.stderr.log [program:docker-appium] -command=python -m service.start +command=python -m src.service stdout_logfile=%(ENV_LOG_PATH)s/docker-appium.stdout.log stderr_logfile=%(ENV_LOG_PATH)s/docker-appium.stderr.log