Exemple #1
0
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
Exemple #2
0
    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'))
Exemple #3
0
 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)
Exemple #6
0
    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."
Exemple #7
0
 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)
Exemple #8
0
 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
Exemple #12
0
 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
Exemple #13
0
    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
Exemple #15
0
    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)
Exemple #16
0
    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!')
Exemple #18
0
    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
Exemple #20
0
    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
Exemple #22
0
    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
Exemple #24
0
    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