def run_hello_world_js_ts(app_name, platform, device, bundle=True, hmr=True, uglify=False, release=False, aot=False, snapshot=False, instrumented=False, sync_all_files=False, just_launch=False, default_andr_sdk='29', timeout=240): # Execute `tns run` and wait until logs are OK result = Tns.run(app_name=app_name, platform=platform, emulator=True, wait=False, bundle=bundle, hmr=hmr, release=release, uglify=uglify, aot=aot, snapshot=snapshot, sync_all_files=sync_all_files, just_launch=just_launch) strings = TnsLogs.run_messages(app_name=app_name, platform=platform, run_type=RunType.UNKNOWN, bundle=bundle, hmr=hmr, instrumented=instrumented, device=device, release=release, snapshot=snapshot) TnsLogs.wait_for_log(log_file=result.log_file, string_list=strings, timeout=timeout) # Verify it looks properly device.wait_for_text(text=Changes.JSHelloWord.JS.old_text) device.wait_for_text(text=Changes.JSHelloWord.XML.old_text) blue_count = device.get_pixels_by_color(color=Colors.LIGHT_BLUE) assert blue_count > 100, 'Failed to find blue color on {0}'.format(device.name) initial_state = os.path.join(Settings.TEST_OUT_IMAGES, device.name, 'initial_state.png') device.get_screen(path=initial_state) if platform == Platform.ANDROID: # Verify android sdk the app is built with if release: apk_path = TnsPaths.get_apk_path(app_name=app_name, release=True) else: apk_path = TnsPaths.get_apk_path(app_name=app_name, release=False) TnsAssert.string_in_android_manifest(apk_path, 'compileSdkVersion="{0}"'.format(default_andr_sdk)) if snapshot and Settings.HOST_OS != OSType.WINDOWS: TnsAssert.snapshot_build(TnsPaths.get_apk_path(app_name=app_name, release=True), Settings.TEST_OUT_TEMP) return result
def test_002_build_android_release_uglify_snapshot_sourcemap(self): # https://github.com/NativeScript/nativescript-dev-webpack/issues/920 result = Tns.build_android(self.app_name, release=True, uglify=True, snapshot=True, source_map=True) assert "ERROR in NativeScriptSnapshot. Snapshot generation failed!" not in result.output assert "Target architecture: arm64-v8a" not in result.output # Verify snapshot files in the built .apk apk_path = TnsPaths.get_apk_path(app_name=self.app_name, release=True) if Settings.HOST_OS != OSType.WINDOWS: TnsAssert.snapshot_build(apk_path, self.temp_folder) # Verify app is built with android sdk 29 by default TnsAssert.string_in_android_manifest(apk_path, 'compileSdkVersion="29"') # Configs are respected assert File.exists(TnsPaths.get_apk_path(self.app_name, release=True)) # Create zip command = "tar -czf " + self.app_name + "/app/app.tar.gz " + self.app_name + "/app/app.js" run(cmd=command, cwd=Settings.TEST_RUN_HOME, wait=True) assert File.exists(os.path.join(self.app_path, 'app', 'app.tar.gz'))
def test_120_platform_add_android_inside_project(self): """ Add platform inside project folder (not using --path)""" project_path = os.path.join(Settings.TEST_RUN_HOME, self.app_name) command = 'platform add android' result = Tns.exec_command(command=command, cwd=project_path) TnsAssert.platform_added(app_name=self.app_name, platform=Platform.ANDROID, output=result.output)
def setUpClass(cls): TnsTest.setUpClass() NG.kill() Folder.clean(cls.app_path) # Create app NG.new(collection=NS_SCHEMATICS, project=cls.app_name, shared=False) TnsAssert.created(app_name=cls.app_name, app_data=None)
def setUpClass(cls): TnsTest.setUpClass() NG.kill() Folder.clean(cls.app_path) # Create app NG.new(collection=NS_SCHEMATICS, project=cls.app_name, shared=False) # TODO: Rollback theme=False when schematics use @nativescript/theme TnsAssert.created(app_name=cls.app_name, app_data=None, theme=False)
def test_001_build_android(self): Tns.build_android(self.app_name) assert not File.exists( os.path.join(TnsPaths.get_platforms_android_folder(self.app_name), '*.plist')) assert not File.exists( os.path.join(TnsPaths.get_platforms_android_folder(self.app_name), '*.android.js')) assert not File.exists( os.path.join(TnsPaths.get_platforms_android_folder(self.app_name), '*.ios.js')) src = os.path.join(self.app_name, 'app', 'app.js') dest_1 = os.path.join(self.app_name, 'app', 'new.android.js') dest_2 = os.path.join(self.app_name, 'app', 'new.ios.js') File.copy(src, dest_1) File.copy(src, dest_2) result = Tns.build_android(self.app_name) assert "Gradle build..." in result.output, "Gradle build not called." assert result.output.count( "Gradle build...") == 1, "Only one gradle build is triggered." assert not File.exists( os.path.join(TnsPaths.get_platforms_android_folder(self.app_name), '*.plist')) assert not File.exists( os.path.join(TnsPaths.get_platforms_android_folder(self.app_name), '*.android.js')) assert not File.exists( os.path.join(TnsPaths.get_platforms_android_folder(self.app_name), '*.ios.js')) # Verify apk does not contain aar files apk_path = TnsPaths.get_apk_path(app_name=self.app_name, release=False) File.unzip(apk_path, self.temp_folder) # Clean META-INF folder. It contains com.android.support.... files which are expected to be there due to # https://github.com/NativeScript/nativescript-cli/pull/3923 Folder.clean(os.path.join(self.temp_folder, 'META-INF')) assert not File.pattern_exists(self.temp_folder, '*.aar') assert not File.pattern_exists(self.temp_folder, '*.plist') assert not File.pattern_exists(self.temp_folder, '*.android.*') assert not File.pattern_exists(self.temp_folder, '*.ios.*') # Verify app is built with android sdk 29 by default TnsAssert.string_in_android_manifest(apk_path, 'compileSdkVersion="29"') Folder.clean(self.temp_folder) # Verify incremental native build result = Tns.exec_command(command='build --clean', path=self.app_name, platform=Platform.ANDROID) assert "Gradle clean..." in result.output, "Gradle clean is not called." assert "Gradle build..." in result.output, "Gradle build is not called." assert result.output.count( "Gradle build...") == 1, "More than 1 gradle build is triggered."
def test_150_platform_update_ios_when_platform_not_added(self): """`platform update` should work even if platform is not added""" runtime_version = '5.3.1' command = 'platform update ios@{0}'.format(runtime_version) result = Tns.exec_command(command=command, path=self.app_name) TnsAssert.platform_added(app_name=self.app_name, platform=Platform.IOS, version=runtime_version, output=result.output)
def test_200_create_project_with_template(self, template_source): """Create app should be possible with --template and npm packages, git repos and aliases""" result = Tns.create(app_name=Settings.AppName.DEFAULT, template=template_source, update=False, verify=False) TnsAssert.created(app_name=Settings.AppName.DEFAULT, output=result.output, theme=False)
def test_301_tns_resources_generate_icons_old_template_structure(self): # Create nativescript@4 app result = Tns.create(app_name=APP_NAME, template='[email protected]', verify=False) TnsAssert.created(app_name=APP_NAME, output=result.output, webpack=False) # Generate icons with nativescript self.test_001_tns_resources_generate_icons()
def test_301_tns_resources_update_on_updated_project(self): result = Tns.create(app_name=APP_NAME, template=Template.HELLO_WORLD_JS.local_package, verify=False, update=False) TnsAssert.created(app_name=APP_NAME, output=result.output, webpack=False, theme=False) result = Tns.exec_command(command='resources update', path=APP_NAME) assert 'The App_Resources have already been updated for the Android platform.' in result.output
def platform_remove(app_name=Settings.AppName.DEFAULT, platform=Platform.NONE, verify=True, log_trace=False): command = 'platform remove ' + str(platform) + ' --path ' + app_name result = Tns.exec_command(command=command, log_trace=log_trace) if verify: TnsAssert.platform_removed(app_name=app_name, platform=platform, output=result.output) return result
def test_400_invalid_framework_name(self): result = Tns.create(app_name=APP_NAME, template=Template.HELLO_WORLD_JS.local_package, update=False, verify=False) TnsAssert.created(app_name=APP_NAME, output=result.output, theme=False, webpack=False) result = Tns.test_init(app_name=APP_NAME, framework='jasmin', verify=False) assert 'Unknown or unsupported unit testing framework: jasmin' in result.output
def create_app(app_data, shared, sample, theme, style, prefix, source_dir, webpack): # Create shared project with sample data result = NG.new(collection=NS_SCHEMATICS, project=NGNewTests.app_name, theme=theme, shared=shared, sample=sample, style=style, prefix=prefix, source_dir=source_dir, webpack=webpack) # Verify valid {N} app is created # Temporary do not assert theme is created because in schematics we still use nativescript-theme-core@1 # TODO: Replace with theme=theme when schematics use @nativescript/theme TnsAssert.created(app_name=NGNewTests.app_name, app_data=app_data, theme=False, webpack=webpack) assert 'Directory is already under version control. Skipping initialization of git.' in result.output, \ 'Git init should be skipped because app is created already existing repo (the one with tests).' # Check sample if sample: # TODO: Implement it pass # Check theme if theme: assert App.is_dependency(app_name=NGNewTests.app_name, dependency='@nativescript/theme') else: assert not App.is_dependency(app_name=NGNewTests.app_name, dependency='@nativescript/theme') # Check styling if style is None or style is StylingType.CSS: assert 'app.css' in result.output else: assert 'app.android.scss' in result.output assert 'app.ios.scss' in result.output assert '_app-common.scss' in result.output # Check webpack if webpack: assert App.is_dev_dependency(app_name=NGNewTests.app_name, dependency='nativescript-dev-webpack') else: assert not App.is_dev_dependency(app_name=NGNewTests.app_name, dependency='nativescript-dev-webpack') # Check prefix if prefix is None: prefix = 'app' path = os.path.join(Settings.TEST_RUN_HOME, NGNewTests.app_name, 'angular.json') actual_prefix = JsonUtils.read(file_path=path)['projects'][NGNewTests.app_name]['prefix'] assert str(actual_prefix) == prefix, 'Prefix not set in angular.json' # Check source dir exists (applicable only for shared projects). if shared: if source_dir is None: source_dir = 'src' assert Folder.exists(os.path.join(Settings.TEST_RUN_HOME, NGNewTests.app_name, source_dir))
def test_300_tns_resources_update(self): # Create nativescript@3 app result = Tns.create(app_name=APP_NAME, template='[email protected]', verify=False, update=False) TnsAssert.created(app_name=APP_NAME, output=result.output, webpack=False) # Update resources out = Tns.exec_command(command='resources update', path=APP_NAME).output assert "Successfully updated your project's application resources '/Android' directory structure." in out assert "The previous version of your Android application resources has been renamed to '/Android-Pre-v4'" in out
def setUpClass(cls): TnsRunAndroidTest.setUpClass() Docker.start() # Create app result = Tns.create(app_name=cls.app_name, template='[email protected]', verify=False) TnsAssert.created(app_name=cls.app_name, output=result.output, path=Settings.TEST_RUN_HOME, theme=False) # Copy TestApp to data folder. Folder.copy(source=cls.source_project_dir, target=cls.target_project_dir)
def test_200_doctor_show_warning_when_new_components_are_available(self): result = Tns.create(app_name=self.APP_NAME, template=Template.HELLO_WORLD_JS.local_package, update=False, verify=False) TnsAssert.created(app_name=self.APP_NAME, output=result.output, theme=False, webpack=False) Tns.platform_add_android(app_name=self.APP_NAME, version='4') App.install_dependency(app_name=self.APP_NAME, dependency='tns-core-modules', version='4') doctor_result = Tns.doctor(app_name=self.APP_NAME) doctor_output = doctor_result.output info_result = Tns.info(app_name=self.APP_NAME) info_output = info_result.output for output in (doctor_output, info_output): assert 'Update available for component tns-core-modules' in output assert 'Update available for component tns-android' in output
def workflow(app_name, device, platform, shared): # Create an app app_path = TnsPaths.get_app_path(app_name=app_name) Folder.clean(app_path) NG.new(collection=NS_SCHEMATICS, project=app_name, shared=shared) TnsAssert.created(app_name=app_name, app_data=None) # Run app initially text = 'TAP' if shared: text = 'Welcome to' result = Tns.run(app_name=app_name, platform=platform, emulator=True, hmr=True) strings = TnsLogs.run_messages(app_name=app_name, platform=platform, bundle=True, hmr=True, app_type=AppType.NG) TnsLogs.wait_for_log(log_file=result.log_file, string_list=strings, timeout=300) device.wait_for_text(text=text) # Generate module and component NG.exec_command(command='g m module-test', cwd=app_path) NG.exec_command(command='g c module-test/component-test', cwd=app_path) # Update app.modules.ts app_module_name = 'app.module.ts' app_module_path = os.path.join(app_path, 'app', app_module_name) if shared: app_module_name = 'app.module.tns.ts' app_module_path = os.path.join(app_path, 'src', 'app', app_module_name) old_string = "import { HomeComponent } from './home/home.component';" new_string = "import { ComponentTestComponent } from './module-test/component-test/component-test.component';" File.replace(path=app_module_path, old_string=old_string, new_string=new_string) File.replace(path=app_module_path, old_string='HomeComponent,', new_string='ComponentTestComponent,') # Update app-routing.module.ts app_routing_module_name = 'app-routing.module.ts' app_routing_module_path = os.path.join(app_path, 'app', app_routing_module_name) if shared: app_routing_module_name = 'app.routes.ts' app_routing_module_path = os.path.join(app_path, 'src', 'app', app_routing_module_name) old_string = "import { HomeComponent } from './home/home.component';" new_string = "import { ComponentTestComponent } from './module-test/component-test/component-test.component';" File.replace(path=app_routing_module_path, old_string=old_string, new_string=new_string) File.replace(path=app_routing_module_path, old_string='HomeComponent', new_string='ComponentTestComponent') # Verify app is updated logs = [app_module_name.replace('.tns', ''), app_routing_module_name.replace('.tns', ''), 'Successfully synced application'] TnsLogs.wait_for_log(log_file=result.log_file, string_list=logs, timeout=120) device.wait_for_text(text='component-test works!')
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 platform_update(app_name=Settings.AppName.DEFAULT, platform=Platform.NONE, version=None): platform_add_string = str(platform) if version is not None: platform_add_string = platform_add_string + '@' + version command = 'platform update ' + platform_add_string result = Tns.exec_command(command=command, path=app_name) TnsAssert.platform_added(app_name=app_name, platform=platform, version=version, output=result.output) if version is not None: assert 'Successfully updated to version {0}'.format( version) in result.output else: assert 'Successfully updated to version' in result.output
def test_101(self, title, framework, template, platform): # Create app Tns.create(app_name=APP_NAME, template=template.local_package) # Add platforms if platform == Platform.ANDROID: Tns.platform_add_android( app_name=APP_NAME, framework_path=Settings.Android.FRAMEWORK_PATH) elif platform == Platform.IOS: Tns.platform_add_ios(app_name=APP_NAME, framework_path=Settings.IOS.FRAMEWORK_PATH) else: raise Exception('Unknown platform: ' + str(platform)) # Init tests and run tests if Settings.HOST_OS == OSType.WINDOWS and framework == FrameworkType.QUNIT: # Hack for qunit on windows (see https://github.com/NativeScript/nativescript-cli/issues/4333) Npm.install(package='qunit@2', option='--save-dev', folder=os.path.join(Settings.TEST_RUN_HOME, APP_NAME)) # Tns test init will still fail with exit code 1, so we use `verify=False` and then assert logs. result = Tns.test_init(app_name=APP_NAME, framework=framework, verify=False) TnsAssert.test_initialized(app_name=APP_NAME, framework=framework, output=result.output) else: Tns.test_init(app_name=APP_NAME, framework=framework) # Run Tests result = Tns.test(app_name=APP_NAME, platform=platform, emulator=True, just_launch=False, wait=False) test_change = None if framework == FrameworkType.JASMINE: test_change = Changes.JSHelloWord.TEST if framework == FrameworkType.MOCHA: test_change = Changes.NGHelloWorld.TEST Sync.replace(app_name=APP_NAME, change_set=test_change) strings = ["log for test"] TnsLogs.wait_for_log(log_file=result.log_file, string_list=strings)
def platform_add(app_name=Settings.AppName.DEFAULT, platform=Platform.NONE, framework_path=None, version=None, verify=True, log_trace=False): platform_add_string = str(platform) if version is not None: platform_add_string = platform_add_string + '@' + version command = 'platform add ' + platform_add_string + ' --path ' + app_name if framework_path is not None: command = command + ' --frameworkPath ' + framework_path result = Tns.exec_command(command=command, log_trace=log_trace) if verify: TnsAssert.platform_added(app_name=app_name, platform=platform, output=result.output, version=version) return result
def test_180_platform_list(self): """Platform list command should list installed platforms and if app is prepared for those platforms""" # `tns platform list` on brand new project result = Tns.platform_list(self.app_name) TnsAssert.platform_list_status(output=result.output, prepared=Platform.NONE, added=Platform.NONE) # `tns platform list` when android is added Tns.platform_add_android( self.app_name, framework_path=Settings.Android.FRAMEWORK_PATH) result = Tns.platform_list(self.app_name) TnsAssert.platform_list_status(output=result.output, prepared=Platform.NONE, added=Platform.ANDROID) # `tns platform list` when android is prepared Tns.prepare_android(self.app_name) result = Tns.platform_list(self.app_name) TnsAssert.platform_list_status(output=result.output, prepared=Platform.ANDROID, added=Platform.ANDROID) if Settings.HOST_OS == OSType.OSX: # `tns platform list` when ios is added Tns.platform_add_ios(self.app_name, framework_path=Settings.IOS.FRAMEWORK_PATH) result = Tns.platform_list(self.app_name) TnsAssert.platform_list_status(output=result.output, prepared=Platform.ANDROID, added=Platform.BOTH) # `tns platform list` when ios prepared android is already prepared Tns.prepare_ios(self.app_name) result = Tns.platform_list(self.app_name) TnsAssert.platform_list_status(output=result.output, prepared=Platform.BOTH, added=Platform.BOTH)
def test_init(app_name, framework, update=True, verify=True): """ Execute `tns test init` command. :param app_name: App name (passed as --path <App name>) :param framework: Unit testing framework as string (jasmin, mocha, quinit). :param update: Update nativescript-unit-test-runner if True. :param verify: Verify command was executed successfully. :return: Result of `tns test init` command. """ app_path = TnsPaths.get_app_path(app_name=app_name) command = 'test init --framework {0}'.format(str(framework)) result = Tns.exec_command(command=command, path=app_name, timeout=300) if verify: TnsAssert.test_initialized(app_name=app_name, framework=framework, output=result.output) if update: Npm.uninstall(package='nativescript-unit-test-runner', option='--save', folder=app_path) Npm.install(package='nativescript-unit-test-runner@next', option='--save --save-exact', folder=app_path) return result
def test_100(self, title, framework, template, platform): # Create app Tns.create(app_name=APP_NAME, template=template.local_package) # Add platforms if platform == Platform.ANDROID: Tns.platform_add_android( app_name=APP_NAME, framework_path=Settings.Android.FRAMEWORK_PATH) elif platform == Platform.IOS: Tns.platform_add_ios(app_name=APP_NAME, framework_path=Settings.IOS.FRAMEWORK_PATH) else: raise Exception('Unknown platform: ' + str(platform)) # Init tests and run tests if Settings.HOST_OS == OSType.WINDOWS and framework == FrameworkType.QUNIT: # Hack for qunit on windows (see https://github.com/NativeScript/nativescript-cli/issues/4333) Npm.install(package='qunit@2', option='--save-dev', folder=os.path.join(Settings.TEST_RUN_HOME, APP_NAME)) # Tns test init will still fail with exit code 1, so we use `verify=False` and then assert logs. result = Tns.test_init(app_name=APP_NAME, framework=framework, verify=False) TnsAssert.test_initialized(app_name=APP_NAME, framework=framework, output=result.output) else: Tns.test_init(app_name=APP_NAME, framework=framework) # Run Tests Tns.test(app_name=APP_NAME, platform=platform, emulator=True, just_launch=True)
def create(app_name=Settings.AppName.DEFAULT, template=None, path=None, app_id=None, force=False, default=False, update=True, force_clean=True, log_trace=False, verify=True, app_data=None): """ Create {N} application. :param app_name: Application name (TestApp by default). :param template: Template string (it can be everything that can be npm installed - npm package, git url ...) :param path: Path where app to be created (Passes `--path <value>` to tns command. None by default). :param app_id: Application identifier. :param force: If true passes '--force' to tns command. :param default: If true passes '--default' to tns command. :param update: If True update the app (modules and plugins). :param force_clean: If True clean app folder before creating a project. :param log_trace: If True runs tns command with '--log trace'. :param verify: If True assert app is created properly. :param app_data: AppInfo object with expected data (used to verify app is created properly). """ # Cleanup app folder if force_clean: Folder.clean(TnsPaths.get_app_path(app_name=app_name)) # Create app normalized_app_name = app_name if ' ' in app_name: normalized_app_name = '"' + app_name + '"' command = 'create ' + normalized_app_name if template is not None: command = command + ' --template ' + template if path is not None: command = command + ' --path ' + path if app_id is not None: # noinspection SpellCheckingInspection command = command + ' --appid ' + app_id if force: command += ' --force' if default: command += ' --default' result = Tns.exec_command(command, log_trace=log_trace) # Update the app (if specified) if update: App.update(app_name=app_name) # Let TestContext know app is created TestContext.TEST_APP_NAME = app_name # Verify app is created properly if verify is not False: # Usually we do not pass path on tns create, which actually equals to cwd. # In such cases pass correct path to TnsAssert.created() if path is None: path = Settings.TEST_RUN_HOME TnsAssert.created(app_name=app_name, output=result.output, app_data=app_data, path=path) return result