def get_screen(self, path, log_level=logging.INFO): """ Save screen of mobile device. :param path: Path to image that will be saved. :param log_level: Log level. """ # Ensure folder to save the screen exists File.delete(path) Folder.create(folder=os.path.dirname(path)) if self.type is DeviceType.EMU or self.type is DeviceType.ANDROID: Adb.get_screen(device_id=self.id, file_path=path) if self.type is DeviceType.SIM: Simctl.get_screen(sim_id=self.id, file_path=path) if self.type is DeviceType.IOS: IDevice.get_screen(device_id=self.id, file_path=path) image_saved = False if File.exists(path): size = os.path.getsize(path) if size > 10: image_saved = True if image_saved: message = "Image of {0} saved at {1}".format(self.id, path) Log.log(level=log_level, msg=message) else: message = "Failed to save image of {0} saved at {1}".format( self.id, path) Log.error(message) raise Exception(message)
def setUpClass(cls): # Get class name and log TestContext.STARTED_PROCESSES = [] TestContext.STARTED_DEVICES = [] TestContext.TEST_APP_NAME = None TestContext.CLASS_NAME = cls.__name__ try: for item in inspect.stack(): TestContext.CLASS_NAME = item[0].f_locals['cls'].__name__ except Exception: pass Log.test_class_start(class_name=TestContext.CLASS_NAME) # Kill processes Adb.restart() Tns.kill() Gradle.kill() TnsTest.kill_emulators() TnsTest.__clean_backup_folder_and_dictionary() # Ensure log folders are create Folder.create(Settings.TEST_OUT_HOME) Folder.create(Settings.TEST_OUT_LOGS) Folder.create(Settings.TEST_OUT_IMAGES) Folder.create(Settings.TEST_OUT_TEMP) # Set default simulator based on Xcode version if Settings.HOST_OS == OSType.OSX: if Xcode.get_version() < 10: Settings.Simulators.DEFAULT = Settings.Simulators.SIM_IOS11 else: if Xcode.get_version() < 11: Settings.Simulators.DEFAULT = Settings.Simulators.SIM_IOS12 else: Settings.Simulators.DEFAULT = Settings.Simulators.SIM_IOS13
def test_200_build_android_app_bundle(self): """Build app with android app bundle option. Verify the output(app.aab) and use bundletool to deploy on device""" path_to_aab = os.path.join(self.app_name, "platforms", "android", "app", "build", "outputs", "bundle", "debug", "app.aab") Tns.build_android(self.app_path, aab=True, verify=False) # There is an issue at the moment that the path is not shown in log. # TODO: uncomment this when the issue is fixed # assert "The build result is located at:" in result.output # assert path_to_aab in result.output assert File.exists(path_to_aab) # Verify app can be deployed on emulator via bundletool # Use bundletool to create the .apks file self.bundletool_build(self.bundletool_path, path_to_aab, self.path_to_apks) assert File.exists(self.path_to_apks) # Deploy on device self.bundletool_deploy(self.bundletool_path, self.path_to_apks, device_id=self.emu.id) # Start the app on device Adb.start_application(self.emu.id, "org.nativescript.TestApp") # Verify app looks correct inside emulator self.emu.wait_for_text(text='TAP')
def get_devices(device_type=any): devices = [] # Get Android devices if device_type is DeviceType.ANDROID or device_type is any: for device_id in Adb.get_ids(include_emulators=False): version = Adb.get_version(device_id=device_id) device = Device(id=device_id, name=device_id, type=DeviceType.ANDROID, version=version, model=None) devices.append(device) # Get iOS devices if device_type is DeviceType.IOS or device_type is any: for device_id in IDevice.get_devices(): device = Device(id=device_id, name=device_id, type=DeviceType.IOS, version=None, model=None) devices.append(device) for device in devices: TestContext.STARTED_DEVICES.append(device) return devices
def test_454_support_Kotlin_with_jar_without_use_kotlin(self): """ Support gradle.properties file for enable Kotlin https://github.com/NativeScript/android-runtime/issues/1459 https://github.com/NativeScript/android-runtime/issues/1463 """ Tns.plugin_remove("sample-plugin-2", verify=False, path=APP_NAME) Adb.clear_logcat(self.emulator.id) source_app_gradle = os.path.join(TEST_RUN_HOME, 'assets', 'runtime', 'android', 'files', 'android-runtime-1463-1459', 'test-jar-1.0-SNAPSHOT.jar') target_app_gradle = os.path.join(TEST_RUN_HOME, APP_NAME, 'app', 'App_Resources', 'Android', 'libs') Folder.create(target_app_gradle) File.copy(source=source_app_gradle, target=target_app_gradle, backup_files=True) source_js = os.path.join(TEST_RUN_HOME, 'assets', 'runtime', 'android', 'files', 'android-runtime-1463-1459', 'main-view-model.js') target_js = os.path.join(TEST_RUN_HOME, APP_NAME, 'app', 'main-view-model.js') File.copy(source=source_js, target=target_js, backup_files=True) log = Tns.run_android(APP_NAME, device=self.emulator.id, wait=False, verify=False) strings = ['Project successfully built', 'Successfully installed on device with identifier', self.emulator.id, 'Successfully synced application'] test_result = Wait.until(lambda: all(string in File.read(log.log_file) for string in strings), timeout=300, period=5) messages = "App with Kotlin enabled and kotlin jar not build correctly! Logs: " assert test_result, messages + File.read(log.log_file) self.assert_kotlin_is_working(self.emulator)
def test_453_support_gradle_properties_for_enable_Kotlin_with_kotlin_file(self): """ Support gradle.properties file for enable Kotlin https://github.com/NativeScript/android-runtime/issues/1459 https://github.com/NativeScript/android-runtime/issues/1463 """ Tns.platform_remove(APP_NAME, platform=Platform.ANDROID) Tns.platform_add_android(APP_NAME, framework_path=Android.FRAMEWORK_PATH) Adb.clear_logcat(self.emulator.id) source_app_gradle = os.path.join(TEST_RUN_HOME, 'assets', 'runtime', 'android', 'files', 'android-runtime-1463-1459', 'gradle.properties') target_app_gradle = os.path.join(TEST_RUN_HOME, APP_NAME, 'app', 'App_Resources', 'Android') File.copy(source=source_app_gradle, target=target_app_gradle, backup_files=True) source_app_gradle = os.path.join(TEST_RUN_HOME, 'assets', 'runtime', 'android', 'files', 'android-runtime-1463-1459', 'Test.kt') target_app_gradle = os.path.join(TEST_RUN_HOME, APP_NAME, 'app', 'App_Resources', 'Android', 'src', 'main', 'java', 'com') Folder.create(target_app_gradle) File.copy(source=source_app_gradle, target=target_app_gradle, backup_files=True) source_js = os.path.join(TEST_RUN_HOME, 'assets', 'runtime', 'android', 'files', 'android-runtime-1463-1459', 'main-view-model.js') target_js = os.path.join(TEST_RUN_HOME, APP_NAME, 'app', 'main-view-model.js') File.copy(source=source_js, target=target_js, backup_files=True) log = Tns.run_android(APP_NAME, device=self.emulator.id, wait=False, verify=False) strings = ['Project successfully built', 'Successfully installed on device with identifier', self.emulator.id, 'Successfully synced application'] test_result = Wait.until(lambda: all(string in File.read(log.log_file) for string in strings), timeout=300, period=5) messages = "App with Kotlin enabled and kotlin jar not build correctly! Logs: " assert test_result, messages + File.read(log.log_file) self.assert_kotlin_is_working(self.emulator)
def test_400_no_error_activity_in_release_builds(self): # Break the app to test error activity # add workaround with for-cycle for https://github.com/NativeScript/nativescript-cli/issues/3812 Adb.clear_logcat(self.emulator.id) wait_code = 'var e = new Date().getTime() + 3000; while (new Date().getTime() <= e) {} ' exception_code = 'throw new Error("Kill the app!");' file_path = os.path.join(Settings.TEST_RUN_HOME, APP_NAME, 'app', 'app.js') old_value = 'application.run({ moduleName: "app-root" });' new_value = wait_code + exception_code File.replace(path=file_path, old_string=old_value, new_string=new_value, backup_files=True) Tns.run_android(app_name=APP_NAME, release=True, emulator=True, wait=False) if self.emulator.version < 10.0: self.emulator.wait_for_text('Unfortunately', timeout=180, retry_delay=10) self.emulator.is_text_visible('Exception') else: regex_to_check = r"""System\.err: Error: Kill the app! .+System\.err: File: \(file:\/\/\/]data\/data\/org\.nativescript\.TestApp\/files\/app\/bundle\.js:\d+:\d+\) .+System\.err:.+ .+System\.err: StackTrace:.+ .+System\.err:.+\(file:\/\/\/data\/data\/org\.nativescript\.TestApp\/files\/app\/bundle\.js:\d+:\d+\) .+System\.err:.+at \.\/app\.js\(file:\/\/\/data\/data\/org\.nativescript\.TestApp\/files\/app\/bundle\.js:\d+:\d+\) .+System\.err:.+at __webpack_require__\(file:\/\/\/data\/data\/org\.nativescript\.TestApp\/files\/app\/runtime\.js:\d+:\d+\) .+System\.err:.+at checkDeferredModules\(file:\/\/\/data\/data\/org\.nativescript\.TestApp\/files\/app\/runtime\.js:\d+:\d+\) .+System\.err:.+at webpackJsonpCallback\(file:\/\/\/data\/data\/org\.nativescript\.TestApp\/files\/app\/runtime\.js:\d+:\d+\) .+System\.err:.+at \(file:\/\/\/data\/data\/org\.nativescript\.TestApp\/files\/app\/bundle\.js:\d+:\d+\) .+System\.err:.+at require\(:\d+:\d+\)""" # noqa: E501, E261, W291 Wait.until(lambda: "Error: Kill the app!" in Adb.get_logcat(self.emulator.id), timeout=240, period=5) Assert.assert_with_regex(Adb.get_logcat(self.emulator.id), regex_to_check)
def click(self, text, case_sensitive=False): self.wait_for_text(text=text, case_sensitive=case_sensitive) if self.type is DeviceType.EMU or self.type is DeviceType.ANDROID: Adb.click_element_by_text(self.id, text, case_sensitive) elif self.type is DeviceType.SIM: SimAuto.click(self, text=text) else: raise NotImplementedError('Click not implemented for iOS devices.') Log.info('Click on "{0}" text.'.format(text))
def test_300_deploy_list_and_run_applications(self): # Deploy test application app_id = TnsPaths.get_bundle_id(app_name=APP_NAME) result = Tns.deploy(app_name=APP_NAME, platform=Platform.ANDROID, just_launch=True, wait=True) for device in self.ANDROID_DEVICES: assert device.id in result.output if Settings.HOST_OS == OSType.OSX: result = Tns.deploy(app_name=APP_NAME, platform=Platform.IOS, just_launch=True, wait=True) for device in self.IOS_DEVICES: assert device.id in result.output # Verify list-applications command list default android apps and the app we've just deployed for device in self.ANDROID_DEVICES: result = Tns.exec_command( 'device list-applications --device {0}'.format(device.id)) assert 'com.android' in result.output assert app_id in result.output # Verify `device run <bundle-id>` will start the app device = self.ANDROID_DEVICES[0] Adb.stop_application(device_id=device.id, app_id=app_id) assert not device.is_text_visible( text=Changes.JSHelloWord.JS.old_value), 'Failed to stop the app.' Tns.exec_command(command='device run {0}'.format(app_id), device=device.id, wait=True, just_launch=True) device.wait_for_text(text=Changes.JSHelloWord.JS.old_value) # Get Android device logs result = Tns.exec_command(command='device log', device=device.id, wait=False) TnsLogs.wait_for_log(log_file=result.log_file, string_list=['beginning of'], timeout=120) assert 'I' or 'D' or 'W' in File.read( result.log_file ), 'Log does not contain INFO, DEBUG or WARN messages.' # Get iOS device logs if Settings.HOST_OS == OSType.OSX: device = self.IOS_DEVICES[0] result = Tns.exec_command(command='device log', device=device.id, wait=False) TnsLogs.wait_for_log(log_file=result.log_file, string_list=['>:'], timeout=120) assert "<Notice>:" or "<Error>:" in File.read( result.log_file), 'tns device log fails to get ios logs.'
def test_210_tns_preview_on_simulator_and_emulator_livesync(self): """ Preview app on simulator and emulator. Verify livesync. """ # Preview on emulator result = Tns.preview(app_name=self.app_name) # Read the log and extract the url to load the app on emulator log = File.read(result.log_file) url = Preview.get_url(log) Preview.run_url(url=url, device=self.emu) strings = TnsLogs.preview_initial_messages(platform=Platform.ANDROID) TnsLogs.wait_for_log(log_file=result.log_file, string_list=strings) self.emu.wait_for_text(text=Changes.JSHelloWord.JS.old_text) # Click on TAP button on emulator Adb.click_element_by_text(self.emu.id, 'TAP', case_sensitive=True) # Preview on simulator Preview.run_url(url=url, device=self.sim) strings = TnsLogs.preview_initial_messages(platform=Platform.IOS) TnsLogs.wait_for_log(log_file=result.log_file, string_list=strings) self.sim.wait_for_text(text=Changes.JSHelloWord.JS.old_text) # Verify emulator is not refreshed, state of app is preserved self.emu.wait_for_text(text='41 taps left', timeout=30) # Edit JS file and verify changes are applied on both emulators Sync.replace(app_name=self.app_name, change_set=Changes.JSHelloWord.JS) self.emu.wait_for_text(text=Changes.JSHelloWord.JS.new_text) self.sim.wait_for_text(text=Changes.JSHelloWord.JS.new_text) # Check changes are not synced more than once per platform # Extract the last part of the log log = File.read(result.log_file) log = File.extract_part_of_text(log, '[VERIFIED]') # Verify files are synced once TnsAssert.file_is_synced_once(log, Platform.ANDROID, 'main-view-model.js') TnsAssert.file_is_synced_once(log, Platform.IOS, 'main-view-model.js') # Mark that part of the log as verified before next sync File.append(result.log_file, '[VERIFIED]') # Edit XML file and verify changes are applied on both emulators Sync.replace(app_name=self.app_name, change_set=Changes.JSHelloWord.XML) self.emu.wait_for_text(text=Changes.JSHelloWord.XML.new_text) self.sim.wait_for_text(text=Changes.JSHelloWord.XML.new_text) # Check changes are not synced more than once per platform # Extract the last part of the log log = File.read(result.log_file) log = File.extract_part_of_text(log, '[VERIFIED]') # Verify files are synced once TnsAssert.file_is_synced_once(log, Platform.ANDROID, 'main-page.xml') TnsAssert.file_is_synced_once(log, Platform.IOS, 'main-page.xml')
def test_205_build_android_app_bundle_env_snapshot(self): """Build app with android app bundle option with --bundle and optimisations for snapshot. Verify the output(app.aab) and use bundletool to deploy on device.""" # This test will not run on windows because env.snapshot option is not available on that OS path_to_aab = os.path.join(self.app_name, "platforms", "android", "app", "build", "outputs", "bundle", "release", "app-release.aab") # Configure app with snapshot optimisations source = os.path.join('assets', 'abdoid-app-bundle', 'app.gradle') target = os.path.join(self.app_name, 'app', 'App_Resources', 'Android', 'app.gradle') File.copy(source, target) webpack_config = os.path.join(self.app_name, 'webpack.config.js') File.replace( webpack_config, 'webpackConfig: config,', """webpackConfig: config, \nuseLibs: true,\nandroidNdkPath: \"$ANDROID_NDK_HOME\",""") # env.snapshot is applicable only in release build result = Tns.build_android(self.app_path, aab=True, release=True, snapshot=True, uglify=True, verify=False) assert "The build result is located at:" in result.output assert path_to_aab in result.output assert File.exists(path_to_aab) # Verify app can be deployed on emulator via bundletool # Use bundletool to create the .apks file self.bundletool_build(self.bundletool_path, path_to_aab, self.path_to_apks) assert File.exists(self.path_to_apks) # Verify that the correct .so file is included in the package File.unzip(self.path_to_apks, os.path.join(self.app_name, 'apks')) File.unzip( os.path.join(self.app_name, 'apks', 'splits', 'base-x86.apk'), os.path.join(self.app_name, 'base_apk')) assert File.exists( os.path.join(self.app_name, 'base_apk', 'lib', 'x86', 'libNativeScript.so')) # Deploy on device self.bundletool_deploy(self.bundletool_path, self.path_to_apks, device_id=self.emu.id) # Start the app on device Adb.start_application(self.emu.id, "org.nativescript.TestApp") # Verify app looks correct inside emulator self.emu.wait_for_text(text='TAP')
def is_running(emulator): """ Check if device is running :param emulator: EmulatorInfo object. :return: True if running, False if not running. """ if Adb.is_running(device_id=emulator.emu_id): if str(emulator.os_version) in Adb.get_device_version(device_id=emulator.emu_id): return True return False
def install_preview_app(device_info, platform, timeout=60): """Installs Preview App on emulator and simulator""" package_android = os.path.join(TEST_SUT_HOME, 'app-universal-release.apk') package_ios = os.path.join(TEST_SUT_HOME, 'nsplaydev.app') if platform is Platform.IOS: # Unpack the .tgz file to get the nsplaydev.app File.unpack_tar(os.path.join(TEST_SUT_HOME, 'nsplaydev.tgz'), TEST_SUT_HOME) Simctl.install(device_info, package_ios) elif platform is Platform.ANDROID: Adb.install(package_android, device_info.id, timeout)
def clear_log(self): """ Clean device log. """ if self.type is DeviceType.EMU or self.type is DeviceType.ANDROID: Adb.clear_logcat(self.id) elif self.type is DeviceType.SIM: self.device_log_file = Simctl.get_log_file(self.id) else: raise NotImplementedError('Click not implemented for iOS devices.')
def install_playground_app(device_info, platform): """Installs Playground App on emulator and simulator""" package_android = os.path.join(TEST_SUT_HOME, "app-release.apk") package_ios = os.path.join(TEST_SUT_HOME, 'nsplay.app') if platform is Platform.IOS: # Unpack the .tgz file to get the nsplay.app File.unpack_tar(os.path.join(TEST_SUT_HOME, 'nsplay.tgz'), TEST_SUT_HOME) Simctl.install(device_info, package_ios) elif platform is Platform.ANDROID: Adb.install(package_android, device_info.id)
def install_preview_app_no_unpack(device_info, platform, uninstall=True): """Installs Preview App on emulator and simulator""" package_android = os.path.join(TEST_SUT_HOME, 'app-universal-release.apk') package_ios = os.path.join(TEST_SUT_HOME, 'nsplaydev.app') if platform is Platform.IOS: if uninstall: Simctl.uninstall(device_info, Settings.Packages.PREVIEW_APP_ID) Simctl.install(device_info, package_ios) elif platform is Platform.ANDROID: if uninstall: Adb.uninstall(Settings.Packages.PREVIEW_APP_ID, device_info.id, False) Adb.install(package_android, device_info.id)
def test_300_tns_run_on_specific_device(self): Adb.open_home(device_id=self.emu.id) Adb.open_home(device_id=self.android_device.id) result = Tns.run(app_name=self.app_name, platform=Platform.ANDROID, device=self.android_device.id) # Wait for logs strings = TnsLogs.run_messages(app_name=self.app_name, platform=Platform.ANDROID, run_type=RunType.UNKNOWN) TnsLogs.wait_for_log(log_file=result.log_file, string_list=strings, timeout=300) # Verify it looks properly on device self.android_device.wait_for_text(text=Changes.JSHelloWord.JS.old_text) # Verify not working on emulator assert Changes.JSHelloWord.JS.old_text not in self.emu.get_text() assert self.emu.id not in File.read(result.log_file)
def test_06_kill_process(self): if not Adb.is_application_installed(self.emu.id, "com.wdiodemoapp"): Adb.install(self.apk_path, self.emu.id) Adb.start_application(self.emu.id, "com.wdiodemoapp") time.sleep(5) Adb.kill_process(self.emu.id, "com.wdiodemoapp") time.sleep(5) service_info = Adb.get_active_services(self.emu.id, "com.wdiodemoapp").replace("\r", "").replace("\n", "") pid = Adb.get_process_pid(self.emu.id, "com.wdiodemoapp") assert pid == "", "Application not killed! PID " + pid error_message = "Service is not killed. Log: " + service_info assert service_info == "ACTIVITY MANAGER SERVICES (dumpsys activity services) (nothing)", error_message
def run_url(url, device): """ Runs project in the Preview App. :param url: Playground url. :param device: DeviceInfo object. """ # Url needs to be escaped before open with adb or simctl url = url.replace(r'?', r'\?') url = url.replace(r'&', r'\&') # Run url Log.info('Open "{0}" on {1}.'.format(url, device.name)) if device.type == DeviceType.EMU or device.type == DeviceType.ANDROID: cmd = 'shell am start -a android.intent.action.VIEW -d "{0}" org.nativescript.preview'.format( url) output = Adb.run_adb_command(command=cmd, device_id=device.id).output assert 'error' not in output, 'Failed to open URL!' + os.linesep + 'Error:' + os.linesep + output elif device.type == DeviceType.SIM: output = Simctl.run_simctl_command( command='openurl {0} {1}.'.format(device.id, url)).output assert 'error' not in output, 'Failed to open URL!' + os.linesep + 'Error:' + os.linesep + output else: raise NotImplementedError( 'Open url not implemented for real iOS devices.')
def test_201_build_app_for_both_platforms(self): Tns.plugin_add(plugin_name='tns-plugin', path=self.app_name) # Verify files of the plugin assert File.exists( os.path.join(TnsPaths.get_app_node_modules_path(self.app_name), 'tns-plugin', 'index.js')) assert File.exists( os.path.join(TnsPaths.get_app_node_modules_path(self.app_name), 'tns-plugin', 'package.json')) assert File.exists( os.path.join(TnsPaths.get_app_node_modules_path(self.app_name), 'tns-plugin', 'test.android.js')) assert File.exists( os.path.join(TnsPaths.get_app_node_modules_path(self.app_name), 'tns-plugin', 'test.ios.js')) assert File.exists( os.path.join(TnsPaths.get_app_node_modules_path(self.app_name), 'tns-plugin', 'test2.android.xml')) assert File.exists( os.path.join(TnsPaths.get_app_node_modules_path(self.app_name), 'tns-plugin', 'test2.ios.xml')) Tns.build_ios(app_name=self.app_name) Tns.build_android(app_name=self.app_name) apk_path = os.path.join(TnsPaths.get_apk_path(self.app_name)) output = Adb.get_package_permission(apk_path) assert 'android.permission.READ_EXTERNAL_STORAGE' in output assert 'android.permission.WRITE_EXTERNAL_STORAGE' in output assert 'android.permission.INTERNET' in output
def __init__(self, id, name, type, model, version): self.id = id self.type = type self.version = version self.model = model self.name = name if type is DeviceType.IOS: type = run(cmd="ideviceinfo | grep ProductType").output type = type.replace(',', '') type = type.replace('ProductType:', '').strip(' ') self.name = type if type is DeviceType.SIM: self.model = name if type is DeviceType.EMU: cmd = 'shell getprop ro.product.model' model = Adb.run_adb_command(command=cmd, wait=True, device_id=self.id).output self.model = model.strip('\n\r') else: self.name = name if type is DeviceType.SIM: self.device_log_file = Simctl.get_log_file(self.id)
def start(emulator): # Define emulator start options and command emulator_path = os.path.join(ANDROID_HOME, 'emulator', 'emulator') options = '-port {0} -wipe-data -no-snapshot-save -no-boot-anim -no-audio -netspeed lte'.format( emulator.port) # Check if clean snapshot is available and use it snapshot_name = 'clean_boot' home = os.path.expanduser("~") snapshot = os.path.join(home, '.android', 'avd', '{0}.avd'.format(emulator.avd), 'snapshots', snapshot_name) if Folder.exists(snapshot): Log.info('{0} has clean boot snapshot! Will user it.'.format(emulator.avd)) options = '-port {0} -no-snapshot-save -no-boot-anim -no-audio -snapshot {1}'.format(emulator.port, snapshot_name) command = '{0} @{1} {2}'.format(emulator_path, emulator.avd, options) Log.info('Booting {0} with cmd:'.format(emulator.avd)) Log.info(command) run(cmd=command, wait=False, register=False) booted = Adb.wait_until_boot(device_id=emulator.emu_id) if booted: Log.info('{0} is up and running!'.format(emulator.avd)) device = Device(id=emulator.emu_id, name=emulator.avd, type=DeviceType.EMU, version=emulator.os_version) TestContext.STARTED_DEVICES.append(device) return device else: raise Exception('Failed to boot {0}!'.format(emulator.avd))
def __cleanup(): """ Wipe TEST_OUT_HOME. """ Folder.clean(os.path.join(Settings.TEST_RUN_HOME, 'node_modules')) Folder.clean(Settings.TEST_OUT_HOME) Folder.create(Settings.TEST_OUT_LOGS) Folder.create(Settings.TEST_OUT_IMAGES) Folder.create(Settings.TEST_OUT_TEMP) DeviceManager.Emulator.stop() if Settings.HOST_OS == OSType.OSX: DeviceManager.Simulator.stop() Adb.restart() Tns.kill() Gradle.kill()
def test_210_tns_preview_android_livesync_on_two_emulators(self): """ Test when preview on second emulator only the current one is refreshed. Test changes are synced on both emulators. """ # Preview on emulator result = Tns.preview(app_name=self.app_name) # Read the log and extract the url to load the app on emulator log = File.read(result.log_file) url = Preview.get_url(log) Preview.run_url(url=url, device=self.emu) strings = TnsLogs.preview_initial_messages(device=self.emu) TnsLogs.wait_for_log(log_file=result.log_file, string_list=strings) self.emu.wait_for_text(text=Changes.JSHelloWord.JS.old_text, timeout=120) # Click on TAP button on emulator Adb.click_element_by_text(self.emu.id, 'TAP', case_sensitive=True) # Preview on second emulator Preview.run_url(url=url, device=self.emu_API24) # Here use bundle=False because on consecutive preview build is not executed again # and no bundle messages are displayed in log strings = TnsLogs.preview_initial_messages(device=self.emu, bundle=False) TnsLogs.wait_for_log(log_file=result.log_file, string_list=strings, timeout=120) self.emu_API24.wait_for_text(text=Changes.JSHelloWord.JS.old_text) # Verify first emulator is not refreshed, state of app is preserved self.emu.wait_for_text(text='41 taps left', timeout=30) # Edit JS file and verify changes are applied on both emulators Sync.replace(app_name=self.app_name, change_set=Changes.JSHelloWord.JS) self.emu.wait_for_text(text=Changes.JSHelloWord.JS.new_text) self.emu_API24.wait_for_text(text=Changes.JSHelloWord.JS.new_text) # Edit XML file and verify changes are applied Sync.replace(app_name=self.app_name, change_set=Changes.JSHelloWord.XML) self.emu.wait_for_text(text=Changes.JSHelloWord.XML.new_text) self.emu_API24.wait_for_text(text=Changes.JSHelloWord.XML.new_text)
def get_log(self): """ Get device log. """ if self.type is DeviceType.EMU or self.type is DeviceType.ANDROID: return Adb.get_logcat(self.id) elif self.type is DeviceType.SIM: Log.debug('Read log file: {0}'.format(self.device_log_file)) return File.read(self.device_log_file) else: raise NotImplementedError('Click not implemented for iOS devices.')
def test_210_tns_preview_on_simulator_and_emulator_livesync(self): """ Preview app on simulator and emulator. Verify livesync. """ # Preview on emulator result = Tns.preview(app_name=self.app_name) # Read the log and extract the url to load the app on emulator log = File.read(result.log_file) url = Preview.get_url(log) Preview.run_url(url=url, device=self.emu) strings = TnsLogs.preview_initial_messages(platform=Platform.ANDROID) TnsLogs.wait_for_log(log_file=result.log_file, string_list=strings) self.emu.wait_for_text(text=Changes.JSHelloWord.JS.old_text) # Click on TAP button on emulator Adb.click_element_by_text(self.emu.id, 'TAP', case_sensitive=True) # Preview on simulator Preview.run_url(url=url, device=self.sim) strings = TnsLogs.preview_initial_messages(platform=Platform.IOS) TnsLogs.wait_for_log(log_file=result.log_file, string_list=strings) self.sim.wait_for_text(text=Changes.JSHelloWord.JS.old_text) # Verify emulator is not refreshed, state of app is preserved self.emu.wait_for_text(text='41 taps left', timeout=30) # Edit JS file and verify changes are applied on both emulators Sync.replace(app_name=self.app_name, change_set=Changes.JSHelloWord.JS) self.emu.wait_for_text(text=Changes.JSHelloWord.JS.new_text) self.sim.wait_for_text(text=Changes.JSHelloWord.JS.new_text) # Edit XML file and verify changes are applied Sync.replace(app_name=self.app_name, change_set=Changes.JSHelloWord.XML) self.emu.wait_for_text(text=Changes.JSHelloWord.XML.new_text) self.sim.wait_for_text(text=Changes.JSHelloWord.XML.new_text)
def test_325_tns_run_android_should_start_emulator(self): """ `tns run android` should start emulator if device is not connected. """ # Run the test only if there are no connected devices conected_devices = Adb.get_ids() if conected_devices.__len__() == 0: DeviceManager.Emulator.stop() result = Tns.run_android(self.app_name) strings = ['Starting Android emulator with image'] TnsLogs.wait_for_log(log_file=result.log_file, string_list=strings, timeout=120) DeviceManager.Emulator.stop() DeviceManager.Emulator.ensure_available(Settings.Emulators.DEFAULT) else: raise nose.SkipTest('This test is not valid when devices are connected.')
def is_text_visible(self, text, case_sensitive=False): is_visible = False if self.type is DeviceType.EMU or self.type is DeviceType.ANDROID: is_visible = Adb.is_text_visible(device_id=self.id, text=text, case_sensitive=case_sensitive) if self.type is DeviceType.SIM: is_visible = SimAuto.is_text_visible(self, text) # Retry find with ORC (only for IOS, for example if macOS automation fails) if not is_visible and (self.type is DeviceType.SIM or self.type is DeviceType.IOS): actual_text = self.get_text() if text in actual_text: is_visible = True else: Log.debug('Current text on {0}: {1}{2}'.format( self.id, os.linesep, actual_text)) return is_visible
def test_365_tns_run_android_should_respect_adb_errors(self): """ If device memory is full and error is thrown during deploy cli should respect it https://github.com/NativeScript/nativescript-cli/issues/2170 """ # Deploy the app to make sure we have something at /data/data/org.nativescript.TestApp result = run_hello_world_js_ts(self.app_name, Platform.ANDROID, self.emu, just_launch=True) # Use all the disk space on emulator dest_file = '/data/data/' + TnsPaths.get_bundle_id(self.app_name) for index in range(1, 3000): command = "shell 'su 0 cp -r {0} {0}{1}'".format(dest_file, str(index)) result = Adb.run_adb_command(device_id=self.emu.id, command=command) Log.info(result.output) if "No space left on device" in result.output: break # Create new app Tns.create(app_name='TestApp2', template=Template.HELLO_WORLD_JS.local_package, update=True) # Run the app and verify there is appropriate error result = Tns.run_android('TestApp2', verify=True, device=self.emu.id, just_launch=True) strings = ['No space left on device'] TnsLogs.wait_for_log(log_file=result.log_file, string_list=strings, timeout=120)
def test_201_error_is_shown_when_metadata_folder_in_apk_is_missing(self): """ https://github.com/NativeScript/android-runtime/issues/1471 https://github.com/NativeScript/android-runtime/issues/1382 """ Adb.uninstall("org.nativescript.TestApp", self.emulator.id, True) Tns.build_android(os.path.join(TEST_RUN_HOME, APP_NAME), verify=True) apk_folder_path = os.path.join(TEST_RUN_HOME, APP_NAME, PLATFORM_ANDROID_APK_DEBUG_PATH) apk_path = os.path.join(apk_folder_path, "app-debug.apk") unzip_folder = os.path.join(apk_folder_path, "app-debug") File.unzip(apk_path, unzip_folder) Folder.clean(os.path.join(unzip_folder, "assets", "metadata")) File.delete(apk_path) File.zip(unzip_folder, apk_path) self.sign_apk(apk_path) Adb.install(apk_path, self.emulator.id, 60) Adb.start_application(self.emulator.id, "org.nativescript.TestApp") text_on_screen = "com.tns.NativescriptException: metadata folder couldn\'t be opened!" self.emulator.wait_for_text(text_on_screen) error_message = "Missing metadata in apk is not causing the correct error! Logs: " assert self.emulator.is_text_visible(text_on_screen), error_message + self.emulator.get_text()