Exemplo n.º 1
0
class TnsRunJSTestsApi28(TnsRunAndroidTest):
    app_name = Settings.AppName.DEFAULT
    source_project_dir = TnsPaths.get_app_path(app_name)
    target_project_dir = os.path.join(Settings.TEST_RUN_HOME, 'data', 'temp',
                                      app_name)

    @classmethod
    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 setUp(self):
        TnsRunAndroidTest.setUp(self)

        # "src" folder of TestApp will be restored before each test.
        # This will ensure failures in one test do not cause common failures.
        source_src = os.path.join(self.target_project_dir, 'app')
        target_src = os.path.join(self.source_project_dir, 'app')
        Folder.clean(target_src)
        Folder.copy(source=source_src, target=target_src)

    @classmethod
    def tearDownClass(cls):
        TnsRunAndroidTest.tearDownClass()
        Docker.stop()

    def test_100_run_android(self):
        """
            Run android, verify app is built with api28 and verify livesync
        """
        # Run app and verify on emulator
        sync_hello_world_js(self.app_name,
                            Platform.ANDROID,
                            self.emu,
                            default_andr_sdk='28')

    def test_200_run_android_release_snapshot(self):
        """
            Run android, verify app is built with api28
        """
        # Run app and verify on emulator
        run_hello_world_js_ts(self.app_name,
                              Platform.ANDROID,
                              self.emu,
                              default_andr_sdk='28',
                              release=True,
                              snapshot=True)
 def test_302_build_project_with_space_debug_with_plugin(self):
     # skip remove platform because androidx is not released official
     app_space_path = TnsPaths.get_app_path(app_name=self.app_name_with_space)
     # Tns.platform_remove(app_name='"' + self.app_name_with_space + '"', platform=Platform.ANDROID)
     Npm.install(package='nativescript-mapbox', option='--save', folder=app_space_path)
     result = Tns.build_android(app_name='"' + self.app_name_with_space + '"')
     assert "Project successfully built" in result.output
Exemplo n.º 3
0
    def test_100_run_android_app_bundle_compile_snapshot(self):
        """Run app on android with --aab option with optimisations for snapshot.
           Verify the output(app.aab)."""

        path_to_aab = os.path.join(TnsPaths.get_app_path(self.app_name),
                                   "platforms", "android", "app", "build",
                                   "outputs", "bundle", "release",
                                   "app-release.aab")
        path_to_apks = os.path.join(TnsPaths.get_app_path(self.app_name),
                                    "platforms", "android", "app", "build",
                                    "outputs", "bundle", "release",
                                    "app-release.apks")

        # env.snapshot is applicable only in release build
        result = Tns.run_android(self.app_path,
                                 aab=True,
                                 release=True,
                                 snapshot=True,
                                 uglify=True,
                                 verify=False,
                                 compile_snapshot=True)
        strings = [
            'Successfully generated snapshots',
            'The build result is located at: {0}'.format(path_to_aab)
        ]
        TnsLogs.wait_for_log(log_file=result.log_file,
                             string_list=strings,
                             timeout=300)

        # Verify app can be deployed on emulator via nativescript
        # Verify app looks correct inside emulator
        self.emu.wait_for_text(text='TAP', timeout=60)

        # Verify that the correct .so file is included in the package
        File.unzip(path_to_apks, os.path.join(self.app_name, 'apks'))
        File.unzip(
            os.path.join(self.app_name, 'apks', 'standalones',
                         'standalone-arm64_v8a_hdpi.apk'),
            os.path.join(self.app_name, 'standalone-arm64'))
        assert File.exists(
            os.path.join(self.app_name, 'standalone-arm64', 'lib', 'arm64-v8a',
                         'libNativeScript.so'))
        assert not File.exists(
            os.path.join(self.app_name, 'standalone-arm64', 'assets',
                         'snapshots', 'x86_64', 'snapshot.blob'))
class NGGenerateNGTests(TnsTest):
    app_name = Settings.AppName.DEFAULT
    app_path = TnsPaths.get_app_path(app_name=app_name)

    @classmethod
    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 setUp(self):
        TnsTest.setUpClass()
        NG.kill()

    def tearDown(self):
        NG.kill()
        TnsTest.tearDown(self)

    def test_001_generate_component(self):
        result = NG.exec_command(command='g c component-test', cwd=self.app_path)
        assert 'CREATE app/component-test/component-test.component.html' in result.output
        assert 'CREATE app/component-test/component-test.component.ts' in result.output
        assert 'CREATE app/component-test/component-test.component.css' in result.output
        assert 'UPDATE app/app.module.ts' in result.output

    def test_002_generate_module(self):
        result = NG.exec_command(command='g m module-test', cwd=self.app_path)
        assert 'CREATE app/module-test/module-test.module.ts' in result.output

    def test_003_generate_component_in_existing_modules(self):
        result = NG.exec_command(command='g m module-test2', cwd=self.app_path)
        assert 'CREATE app/module-test2/module-test2.module.ts' in result.output

        result = NG.exec_command(command='g c module-test2/component-name', cwd=self.app_path)
        assert 'CREATE app/module-test2/component-name/component-name.component.html' in result.output
        assert 'CREATE app/module-test2/component-name/component-name.component.ts' in result.output
        assert 'CREATE app/module-test2/component-name/component-name.component.css' in result.output
        assert 'UPDATE app/module-test2/module-test2.module.ts' in result.output

    @unittest.skip('Skip because of https://github.com/NativeScript/nativescript-schematics/issues/194')
    def test_004_generate_master_detail(self):
        result = NG.exec_command(command='g master-detail --master=dogs --detail=dog', cwd=self.app_path)
        assert 'CREATE app/dogs/dog-detail/dog-detail.component.html' in result.output
        assert 'CREATE app/dogs/dogs/dogs.component.html' in result.output
        assert 'data.service.ts' in result.output
        assert 'dogs.module.ts' in result.output
Exemplo n.º 5
0
 def platform_removed(app_name, platform, output):
     platform_string = str(platform)
     # Verify output
     assert 'Platform {0} successfully removed'.format(
         platform_string) in output
     # Verify package.json
     app_path = TnsPaths.get_app_path(app_name)
     package_json = os.path.join(app_path, 'package.json')
     json = JsonUtils.read(package_json)
     assert not 'tns-' + platform_string in json
     if platform == Platform.ANDROID:
         assert not Folder.exists(
             TnsPaths.get_platforms_android_folder(app_name))
     else:
         assert not Folder.exists(
             TnsPaths.get_platforms_ios_folder(app_name))
    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!')
Exemplo n.º 7
0
 def platform_clean(app_name, platform=Platform.NONE, verify=True):
     platform_string = str(platform)
     command = 'platform clean ' + platform_string
     result = Tns.exec_command(command=command, path=app_name)
     if verify:
         assert "Platform {0} successfully removed".format(
             platform_string) in result.output
         assert "error" not in result.output
         if platform is Platform.ANDROID:
             assert Folder.exists(
                 TnsPaths.get_platforms_android_folder(app_name))
         if platform is Platform.IOS:
             assert Folder.exists(
                 TnsPaths.get_platforms_ios_folder(app_name))
         assert "Platform {0} successfully added".format(
             platform_string) in result.output
         package_json = os.path.join(TnsPaths.get_app_path(app_name),
                                     'package.json')
         json = JsonUtils.read(package_json)
         assert json['nativescript']['tns-' +
                                     platform_string]['version'] is not None
Exemplo n.º 8
0
 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
class PrepareTests(TnsTest):
    app_name = Settings.AppName.DEFAULT
    app_path = TnsPaths.get_app_path(app_name=app_name)
    app_temp_path = os.path.join(Settings.TEST_RUN_HOME, 'data', 'temp', 'TestApp')

    @classmethod
    def setUpClass(cls):
        TnsTest.setUpClass()
        Tns.create(app_name=cls.app_name, template=Template.HELLO_WORLD_JS.local_package, update=True)
        if Settings.HOST_OS is OSType.OSX:
            Tns.platform_add_ios(cls.app_name, framework_path=Settings.IOS.FRAMEWORK_PATH)
        Tns.platform_add_android(cls.app_name, framework_path=Settings.Android.FRAMEWORK_PATH)
        Folder.copy(cls.app_path, cls.app_temp_path)

    def setUp(self):
        TnsTest.setUp(self)
        Folder.clean(self.app_path)
        Folder.copy(self.app_temp_path, self.app_path)

    def tearDown(self):
        TnsTest.tearDown(self)

    @classmethod
    def tearDownClass(cls):
        TnsTest.tearDownClass()
        Folder.clean(cls.app_temp_path)

    def test_100_prepare_android(self):
        Tns.prepare_android(self.app_name)
        result = Tns.prepare_android(self.app_name)
        # assert "Skipping prepare" in result.output
        Sync.replace(app_name=self.app_name, change_set=Changes.JSHelloWord.JS)
        result = Tns.prepare_android(self.app_name)
        assert "Preparing project..." in result.output

    @unittest.skip("https://github.com/NativeScript/nativescript-dev-webpack/issues/892")
    def test_200_prepare_xml_error(self):
        Tns.platform_remove(self.app_name, platform=Platform.ANDROID)
        Sync.replace(app_name=self.app_name, change_set=Changes.AppFileChanges.CHANGE_XML_INVALID_SYNTAX)
        result = Tns.prepare_android(self.app_name)
        assert "main-page.xml has syntax errors." in result.output
        assert "unclosed xml attribute" in result.output

    @unittest.skipIf(Settings.HOST_OS == OSType.WINDOWS, "Skip on Windows")
    def test_210_platform_not_need_remove_after_bitcode_error(self):
        # https://github.com/NativeScript/nativescript-cli/issues/3741
        Tns.platform_remove(self.app_name, platform=Platform.ANDROID)
        run("touch a", cwd=os.path.join(self.app_name, 'app'))
        run("ln -s a b", cwd=os.path.join(self.app_name, 'app'))
        run("rm a", cwd=os.path.join(self.app_name, 'app'))
        result = Tns.prepare_android(self.app_name)
        assert "Project successfully prepared" in result.output

    @unittest.skipIf(Settings.HOST_OS != OSType.OSX, 'iOS tests can be executed only on macOS.')
    def test_100_prepare_ios(self):
        Tns.prepare_ios(self.app_name)
        result = Tns.prepare_ios(self.app_name)
        # assert "Skipping prepare" in result.output
        Sync.replace(app_name=self.app_name, change_set=Changes.JSHelloWord.JS)
        result = Tns.prepare_ios(self.app_name)
        assert "Preparing project..." in result.output

        # Verify Xcode Schemes
        result = run("xcodebuild -project " + os.path.join(TnsPaths.get_platforms_ios_folder(self.app_name),
                                                           'TestApp.xcodeproj', ' -list'))
        assert "This project contains no schemes." not in result.output
        result1 = re.search(r"Targets:\n\s*TestApp", result.output)
        assert result1 is not None
        result1 = re.search(r"Schemes:\n\s*TestApp", result.output)
        assert result1 is not None

        Tns.prepare_android(self.app_name)
        Tns.prepare_ios(self.app_name)
        result = Tns.prepare_ios(self.app_name)
        # assert "Skipping prepare" in result.output

    @unittest.skipIf(Settings.HOST_OS != OSType.OSX, 'iOS tests can be executed only on macOS.')
    def test_200_prepare_additional_appresources(self):
        Tns.prepare_ios(self.app_name)

        # Create new files in AppResources
        File.copy(os.path.join(TnsPaths.get_path_app_resources(self.app_name), 'iOS', 'Assets.xcassets',
                               'AppIcon.appiconset', 'icon-76.png'),
                  os.path.join(TnsPaths.get_path_app_resources(self.app_name), 'iOS', 'newDefault.png'))

        Tns.prepare_ios(self.app_name)

        # Verify XCode Project include files from App Resources folder
        result = run("cat " + os.path.join(TnsPaths.get_platforms_ios_folder(self.app_name), 'TestApp.xcodeproj',
                                           'project.pbxproj | grep newDefault.png'))
        assert "newDefault.png" in result.output

    @unittest.skip("This test doesn't pass now. Remove skip after webpack only")
    @unittest.skipIf(Settings.HOST_OS != OSType.OSX, 'iOS tests can be executed only on macOS.')
    def test_210_prepare_android_does_not_prepare_ios(self):
        Tns.plugin_add(plugin_name='nativescript-social-share', path=self.app_name)
        Tns.plugin_add(plugin_name='[email protected]', path=self.app_name)

        result = Tns.prepare_android(self.app_name)
        assert "Successfully prepared plugin nativescript-social-share for android" in result.output
        assert "nativescript-iqkeyboardmanager is not supported for android" in result.output

    @unittest.skipIf(Settings.HOST_OS != OSType.OSX, 'iOS tests can be executed only on macOS.')
    def test_220_prepare_ios_with_provisioning(self):
        # Prepare with --provision (debug, emulator)
        Tns.prepare_ios(self.app_name, provision=Settings.IOS.PROVISIONING)

        # Prepare with --provision (release, emulator)
        Tns.prepare_ios(self.app_name, provision=Settings.IOS.PROVISIONING, release=True)

        # Prepare with --provision (debug, device)
        Tns.prepare_ios(self.app_name, for_device=True, provision=Settings.IOS.PROVISIONING)

        # Prepare with --provision (release, device)
        Tns.prepare_ios(self.app_name, release=True, for_device=True, provision=Settings.IOS.PROVISIONING)
 def test_002_js_app_node_modules(self):
     folder = os.path.join(TnsPaths.get_app_path(app_name=self.js_app),
                           'node_modules')
     assert PerfUtils.is_value_in_range(actual=Folder.get_size(folder),
                                        expected=51791943,
                                        tolerance=0.2)
 def test_001_js_app_app_resources(self):
     folder = os.path.join(TnsPaths.get_app_path(app_name=self.js_app),
                           'app')
     assert PerfUtils.is_value_in_range(actual=Folder.get_size(folder),
                                        expected=2991548,
                                        tolerance=0.1)
 def test_101_ng_app_node_modules(self):
     app_folder = os.path.join(TnsPaths.get_app_path(app_name=self.ng_app),
                               'node_modules')
     assert PerfUtils.is_value_in_range(actual=Folder.get_size(app_folder),
                                        expected=200248003,
                                        tolerance=0.2)
 def test_100_ng_app_app_resources(self):
     app_folder = os.path.join(TnsPaths.get_app_path(app_name=self.ng_app),
                               'App_Resources')
     assert PerfUtils.is_value_in_range(actual=Folder.get_size(app_folder),
                                        expected=2986244,
                                        tolerance=0.1)
Exemplo n.º 14
0
class TnsRunJSTests(TnsRunTest):
    app_name = Settings.AppName.DEFAULT
    app_name_space = Settings.AppName.WITH_SPACE
    app_path = TnsPaths.get_app_path(app_name)
    app_resources_path = TnsPaths.get_path_app_resources(app_name)
    source_project_dir = TnsPaths.get_app_path(app_name)
    target_project_dir = os.path.join(Settings.TEST_RUN_HOME, 'data', 'temp', app_name)
    app_resources_android = os.path.join(app_resources_path, 'Android')
    app_resources_ios = os.path.join(app_resources_path, 'iOS')

    @classmethod
    def setUpClass(cls):
        TnsRunTest.setUpClass()

        # Create app
        Tns.create(app_name=cls.app_name, template=Template.HELLO_WORLD_JS.local_package, update=True)
        src = os.path.join(Settings.TEST_RUN_HOME, 'assets', 'logs', 'hello-world-js', 'app.js')
        target = os.path.join(cls.app_path, 'app')
        File.copy(source=src, target=target)
        Tns.platform_add_android(app_name=cls.app_name, framework_path=Settings.Android.FRAMEWORK_PATH)
        if Settings.HOST_OS is OSType.OSX:
            Tns.platform_add_ios(app_name=cls.app_name, framework_path=Settings.IOS.FRAMEWORK_PATH)

        # Copy TestApp to data folder.
        Folder.copy(source=cls.source_project_dir, target=cls.target_project_dir)

    def setUp(self):
        TnsRunTest.setUp(self)

        # "src" folder of TestApp will be restored before each test.
        # This will ensure failures in one test do not cause common failures.
        source_src = os.path.join(self.target_project_dir, 'app')
        target_src = os.path.join(self.source_project_dir, 'app')
        Folder.clean(target_src)
        Folder.copy(source=source_src, target=target_src)

    def test_100_run_android_break_and_fix_app(self):
        """
            Make changes in xml that break the app and then changes thet fix the app.
            Add/remove js files thst break the app and then fix it. Verify recovery.
        """
        # Run app and verify on device
        result = run_hello_world_js_ts(self.app_name, Platform.ANDROID, self.emu)

        # Make changes in xml that will break the app
        Sync.replace(self.app_name, Changes.JSHelloWord.XML_INVALID)
        strings = ['main-page.xml', 'Error: Building UI from XML']
        TnsLogs.wait_for_log(log_file=result.log_file, string_list=strings)
        self.emu.wait_for_text(text='Exception')

        # Revert changes
        Sync.revert(self.app_name, Changes.JSHelloWord.XML_INVALID)

        # Verify app is synced and recovered
        strings = ['Successfully synced application']
        TnsLogs.wait_for_log(log_file=result.log_file, string_list=strings)
        self.emu.wait_for_text(text=Changes.JSHelloWord.JS.old_text)
        assert not self.emu.is_text_visible(text='Exception')

        # Delete app.js and verify app crash with error activity dialog
        app_js_origin_path = os.path.join(self.source_project_dir, 'app', 'app.js')
        app_js_backup_path = os.path.join(self.target_project_dir, 'app', 'app.js')
        File.delete(app_js_origin_path)

        # Verify app is synced
        strings = TnsLogs.run_messages(app_name=self.app_name, platform=Platform.ANDROID,
                                       device=self.emu, run_type=RunType.UNKNOWN)
        TnsLogs.wait_for_log(log_file=result.log_file, string_list=strings)
        self.emu.wait_for_text(text='Exception')

        # Restore app.js and verify app is synced and recovered
        File.copy(app_js_backup_path, app_js_origin_path)
        strings = TnsLogs.run_messages(app_name=self.app_name, platform=Platform.ANDROID,
                                       run_type=RunType.UNKNOWN, 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)
        assert not self.emu.is_text_visible(text='Exception')

    @unittest.skipIf(Settings.HOST_OS != OSType.OSX, 'iOS tests can be executed only on macOS.')
    def test_100_run_ios_break_and_fix_app(self):
        """
            Make changes in xml that break the app and then changes thet fix the app.
            Add/remove js files thst break the app and then fix it. Verify recovery.
        """
        # Run app and verify on device
        result = run_hello_world_js_ts(self.app_name, Platform.IOS, self.sim)

        # Make changes in xml that will break the app
        Sync.replace(self.app_name, Changes.JSHelloWord.XML_INVALID)
        strings = ['main-page.xml', 'Error: Building UI from XML']
        TnsLogs.wait_for_log(log_file=result.log_file, string_list=strings)

        # Revert changes
        Sync.revert(self.app_name, Changes.JSHelloWord.XML_INVALID)

        # Verify app is synced and recovered
        strings = ['Successfully synced application']
        TnsLogs.wait_for_log(log_file=result.log_file, string_list=strings)
        self.sim.wait_for_text(text=Changes.JSHelloWord.XML.old_text)

    @unittest.skipIf(Settings.HOST_OS == OSType.WINDOWS, 'skip on windows untill we fix wait_rof_log method')
    def test_105_tns_run_android_changes_in_app_resounces(self):
        """
            Make changes in AndroidManifest.xml in App_Resources and verify this triggers rebuild of the app.
            Verify that when run on android changes in AppResources/iOS do not trigger rebuild
        """
        # Run app and verify on device
        result = run_hello_world_js_ts(self.app_name, Platform.ANDROID, self.emu)

        # Make changes in AndroidManifest.xml
        manifest_path = os.path.join(self.app_resources_android, 'src', 'main', 'AndroidManifest.xml')
        File.replace(manifest_path, 'largeScreens="true"', 'largeScreens="false"')

        # Verify rebuild is triggered and app is synced
        strings = TnsLogs.run_messages(app_name=self.app_name, platform=Platform.ANDROID,
                                       run_type=RunType.UNKNOWN, device=self.emu)
        TnsLogs.wait_for_log(log_file=result.log_file, string_list=strings, timeout=120)

        self.emu.wait_for_text(text=Changes.JSHelloWord.JS.old_text)
        self.emu.wait_for_text(text=Changes.JSHelloWord.XML.old_text)

        # Make changes in AppResources/Android
        File.copy(os.path.join(Settings.TEST_RUN_HOME, 'assets', 'resources', 'android', 'drawable-hdpi', 'icon.png'),
                  os.path.join(self.app_resources_android, 'src', 'main', 'res', 'drawable-hdpi', 'icon.png'))
        # Verify only build for android is triggered
        strings = TnsLogs.run_messages(app_name=self.app_name, platform=Platform.ANDROID,
                                       run_type=RunType.UNKNOWN, device=self.emu)
        not_existing_strings = ['Xcode build']
        TnsLogs.wait_for_log(log_file=result.log_file, string_list=strings,
                             not_existing_string_list=not_existing_strings, timeout=120)

        # https://github.com/NativeScript/nativescript-cli/issues/3658
        Tns.kill()
        # Make changes in AppResources/iOS
        File.copy(os.path.join('assets', 'resources', 'ios', 'Default.png'),
                  os.path.join(self.app_resources_ios, 'Assets.xcassets', 'LaunchImage.launchimage', 'Default.png'))
        result = Tns.run_android(app_name=self.app_name, device=self.emu.id)
        strings = TnsLogs.run_messages(app_name=self.app_name, platform=Platform.ANDROID,
                                       run_type=RunType.UNKNOWN, device=self.emu)
        # Verify no build is triggered
        not_existing_strings = ['Xcode build', 'Gradle build']
        TnsLogs.wait_for_log(log_file=result.log_file, string_list=strings,
                             not_existing_string_list=not_existing_strings)

    @unittest.skipIf(Settings.HOST_OS != OSType.OSX, 'iOS tests can be executed only on macOS.')
    def test_105_tns_run_ios_changes_in_app_resounces(self):
        """
            Make changes in AndroidManifest.xml in App_Resources and verify this triggers rebuild of the app.
            Verify that when run on android changes in AppResources/iOS do not trigger rebuild
        """
        # Run app and verify on device
        result = run_hello_world_js_ts(self.app_name, Platform.IOS, self.sim)

        # Make changes in app resources, add aditional icon
        File.copy(os.path.join(Settings.TEST_RUN_HOME, 'assets', 'resources', 'ios', 'Default.png'),
                  os.path.join(self.app_resources_ios, 'Assets.xcassets', 'icon.png'))

        # Verify rebuild is triggered and app is synced
        strings = TnsLogs.run_messages(app_name=self.app_name, platform=Platform.IOS,
                                       run_type=RunType.UNKNOWN, device=self.sim)
        TnsLogs.wait_for_log(log_file=result.log_file, string_list=strings)
        self.sim.wait_for_text(text=Changes.JSHelloWord.JS.old_text)
        self.sim.wait_for_text(text=Changes.JSHelloWord.XML.old_text)

        # Make changes in AppResources/IOS
        File.copy(os.path.join(os.path.join(Settings.TEST_RUN_HOME, 'assets', 'resources', 'ios', 'Default.png')),
                  os.path.join(self.app_resources_ios, 'Assets.xcassets', 'AppIcon.appiconset', 'icon-20.png'))
        # Verify only build for ios is triggered
        strings = TnsLogs.run_messages(app_name=self.app_name, platform=Platform.IOS,
                                       run_type=RunType.UNKNOWN, device=self.sim)
        not_existing_strings = ['Gradle build']
        TnsLogs.wait_for_log(log_file=result.log_file, string_list=strings,
                             not_existing_string_list=not_existing_strings)

        # https://github.com/NativeScript/nativescript-cli/issues/3658
        Tns.kill()
        # Make changes in AppResources/Android
        File.copy(os.path.join(Settings.TEST_RUN_HOME, 'assets', 'resources', 'android', 'drawable-hdpi', 'icon.png'),
                  os.path.join(self.app_resources_android, 'src', 'main', 'res', 'drawable-hdpi', 'icon.png'))
        result = Tns.run_ios(app_name=self.app_name, emulator=True, provision=False)
        strings = TnsLogs.run_messages(app_name=self.app_name, platform=Platform.IOS,
                                       run_type=RunType.UNKNOWN, device=self.sim)
        # Verify no build is triggered
        not_existing_strings = ['Xcode build', 'Gradle build']
        TnsLogs.wait_for_log(log_file=result.log_file, string_list=strings,
                             not_existing_string_list=not_existing_strings)

    def test_110_tns_run_android_release(self):
        # Run app and verify on device
        result = Tns.run_android(app_name=self.app_name, release=True, verify=True, emulator=True)
        strings = TnsLogs.run_messages(app_name=self.app_name, platform=Platform.ANDROID,
                                       run_type=RunType.FIRST_TIME, device=self.emu)
        strings.remove('Restarting application on device')
        strings.remove('Successfully synced application org.nativescript.TestApp on device')
        # Verify https://github.com/NativeScript/android-runtime/issues/1024
        not_existing_strings = ['JS:']
        TnsLogs.wait_for_log(log_file=result.log_file, string_list=strings,
                             not_existing_string_list=not_existing_strings, timeout=120)
        self.emu.wait_for_text(text=Changes.JSHelloWord.JS.old_text)
        self.emu.wait_for_text(text=Changes.JSHelloWord.XML.old_text)
        blue_count = self.emu.get_pixels_by_color(color=Colors.LIGHT_BLUE)
        assert blue_count > 100, 'Failed to find blue color on {0}'.format(self.emu.name)

        Tns.kill()
        # Make changes in js, css and xml files
        Sync.replace(app_name=self.app_name, change_set=Changes.JSHelloWord.JS)
        Sync.replace(app_name=self.app_name, change_set=Changes.JSHelloWord.XML)
        Sync.replace(app_name=self.app_name, change_set=Changes.JSHelloWord.CSS)

        # Run with --release again and verify changes are deployed on device
        result = Tns.run_android(app_name=self.app_name, release=True, verify=True, emulator=True)
        self.emu.wait_for_text(text=Changes.JSHelloWord.JS.new_text)
        self.emu.wait_for_text(text=Changes.JSHelloWord.XML.new_text)
        self.emu.wait_for_color(color=Colors.LIGHT_BLUE, pixel_count=blue_count * 2, delta=25)

    @unittest.skipIf(Settings.HOST_OS != OSType.OSX, 'iOS tests can be executed only on macOS.')
    def test_110_tns_run_ios_release(self):
        # Run app and verify on device
        result = Tns.run_ios(app_name=self.app_name, release=True, verify=True, emulator=True)
        strings = ['Webpack compilation complete', 'Project successfully built', 'Successfully installed on device']
        # Verify console logs are not displayed in release builds
        not_existing_strings = ['JS:']
        TnsLogs.wait_for_log(log_file=result.log_file, string_list=strings,
                             not_existing_string_list=not_existing_strings)
        self.sim.wait_for_text(text=Changes.JSHelloWord.JS.old_text)
        self.sim.wait_for_text(text=Changes.JSHelloWord.XML.old_text)
        blue_count = self.sim.get_pixels_by_color(color=Colors.LIGHT_BLUE)
        assert blue_count > 100, 'Failed to find blue color on {0}'.format(self.sim.name)

        Tns.kill()
        # Make changes in js, css and xml files
        Sync.replace(app_name=self.app_name, change_set=Changes.JSHelloWord.JS)
        Sync.replace(app_name=self.app_name, change_set=Changes.JSHelloWord.XML)
        Sync.replace(app_name=self.app_name, change_set=Changes.JSHelloWord.CSS)

        # Run with --release again and verify changes are deployed on device
        result = Tns.run_ios(app_name=self.app_name, release=True, verify=True, emulator=True)
        self.sim.wait_for_text(text=Changes.JSHelloWord.JS.new_text)
        self.sim.wait_for_text(text=Changes.JSHelloWord.XML.new_text)
        self.sim.wait_for_color(color=Colors.LIGHT_BLUE, pixel_count=blue_count * 2, delta=25)

    @unittest.skipIf(Settings.HOST_OS == OSType.WINDOWS, 'skip on windows untill we fix wait_rof_log method')
    def test_115_tns_run_android_add_remove_files_and_folders(self):
        """
        Add/delete files and folders should be synced properly
        """
        # Run app and verify on device
        result = run_hello_world_js_ts(self.app_name, Platform.ANDROID, self.emu)

        # Add new file
        # To verify that file is synced on device we have to refer some function
        # from it and verify it is executed. We will use console.log
        app_folder = os.path.join(self.source_project_dir, 'app')
        new_file = os.path.join(app_folder, 'test.js')
        renamed_file = os.path.join(app_folder, 'test_2.js')
        app_js_file = os.path.join(app_folder, 'app.js')
        File.write(new_file, "console.log('test.js synced!!!');")
        File.append(app_js_file, "require('./test.js');")
        strings = ["JS: test.js synced!!!"]
        TnsLogs.wait_for_log(log_file=result.log_file, string_list=strings)

        # Rename file

        os.rename(new_file, renamed_file)
        File.replace(renamed_file, 'test.js', 'renamed file')
        time.sleep(1)
        File.replace(app_js_file, 'test.js', 'test_2.js')
        strings = ["JS: renamed file synced!!!"]
        TnsLogs.wait_for_log(log_file=result.log_file, string_list=strings)

        # Delete file
        File.delete(renamed_file)
        strings = ["Module build failed: Error: ENOENT", 'Successfully synced application']
        TnsLogs.wait_for_log(log_file=result.log_file, string_list=strings)
        self.emu.wait_for_text(text='Exception')

        File.replace(app_js_file, "require('./test_2.js');", ' ')
        strings = TnsLogs.run_messages(app_name=self.app_name, platform=Platform.ANDROID,
                                       device=self.emu, run_type=RunType.UNKNOWN)
        not_existing_strings = ['12345']
        TnsLogs.wait_for_log(log_file=result.log_file, string_list=strings,
                             not_existing_string_list=not_existing_strings)
        self.emu.wait_for_text(text=Changes.JSHelloWord.JS.old_text)

        # Add folder
        folder_name = os.path.join(app_folder, 'test_folder')
        new_file = os.path.join(folder_name, 'test_in_folder.js')
        Folder.create(folder_name)
        File.write(new_file, "console.log('test_in_folder.js synced!!!');")
        File.append(app_js_file, "require('./test_folder/test_in_folder.js');")
        strings = ["JS: test_in_folder.js synced!!!"]
        TnsLogs.wait_for_log(log_file=result.log_file, string_list=strings)

        # Delete folder
        Folder.clean(folder_name)
        strings = ["Module build failed: Error: ENOENT"]
        TnsLogs.wait_for_log(log_file=result.log_file, string_list=strings)
        self.emu.wait_for_text(text='Exception')

    @unittest.skipIf(Settings.HOST_OS != OSType.OSX, 'iOS tests can be executed only on macOS.')
    def test_115_tns_run_ios_add_remove_files_and_folders(self):
        """
        Add/delete files and folders should be synced properly
        """
        # Run app and verify on device
        result = run_hello_world_js_ts(self.app_name, Platform.IOS, self.sim)

        # Add new file
        # To verify that file is synced on device we have to refer some function
        # from it and verify it is executed. We will use console.log
        app_folder = os.path.join(self.source_project_dir, 'app')
        new_file = os.path.join(app_folder, 'test.js')
        renamed_file = os.path.join(app_folder, 'test_2.js')
        app_js_file = os.path.join(app_folder, 'main-view-model.js')
        File.write(new_file, "console.log('test.js synced!!!');")
        File.append(app_js_file, "require('./test.js');")
        strings = ["test.js synced!!!"]
        TnsLogs.wait_for_log(log_file=result.log_file, string_list=strings)

        # Rename file
        os.rename(new_file, renamed_file)
        File.replace(renamed_file, 'test.js', 'renamed file')
        time.sleep(1)
        File.replace(app_js_file, 'test.js', 'test_2.js')
        strings = ["renamed file synced!!!"]
        TnsLogs.wait_for_log(log_file=result.log_file, string_list=strings)

        # Delete file
        File.delete(renamed_file)
        strings = ["Module build failed: Error: ENOENT", "NativeScript debugger detached"]
        TnsLogs.wait_for_log(log_file=result.log_file, string_list=strings)

        File.replace(app_js_file, "require('./test_2.js');", ' ')
        strings = TnsLogs.run_messages(app_name=self.app_name, platform=Platform.IOS,
                                       device=self.sim, run_type=RunType.UNKNOWN)
        not_existing_strings = ['123']
        TnsLogs.wait_for_log(log_file=result.log_file, string_list=strings,
                             not_existing_string_list=not_existing_strings)
        self.sim.wait_for_text(text=Changes.JSHelloWord.JS.old_text)

        # Add folder
        folder_name = os.path.join(app_folder, 'test_folder')
        new_file = os.path.join(folder_name, 'test_in_folder.js')
        Folder.create(folder_name)
        File.write(new_file, "console.log('test_in_folder.js synced!!!');")
        File.append(app_js_file, "require('./test_folder/test_in_folder.js');")
        strings = ["test_in_folder.js synced!!!"]
        TnsLogs.wait_for_log(log_file=result.log_file, string_list=strings)
        self.sim.wait_for_text(text=Changes.JSHelloWord.JS.old_text)

        # Delete folder
        Folder.clean(folder_name)
        strings = ["Module build failed: Error: ENOENT"]
        TnsLogs.wait_for_log(log_file=result.log_file, string_list=strings)

    def test_120_tns_run_android_just_launch(self):
        """
        This test verify following things:
        1. `--justlaunch` option release the console.
        2. Full rebuild and prepare are not trigerred if no changes are done.
        3. Incremental prepare is triggered if js, xml and css files are changed.
        """
        # Run app with --justlaunch and verify on device
        run_hello_world_js_ts(self.app_name, Platform.ANDROID, self.emu, just_launch=True)
        # On some machines it takes time for thr process to die
        time.sleep(5)
        assert not Process.is_running_by_commandline(Settings.Executables.TNS)

        # Execute run with --justlaunch again and verify no rebuild is triggered
        result = Tns.run_android(app_name=self.app_name, emulator=True, just_launch=True)
        strings = TnsLogs.run_messages(app_name=self.app_name, platform=Platform.ANDROID,
                                       run_type=RunType.JUST_LAUNCH, device=self.emu, just_launch=True)
        TnsLogs.wait_for_log(log_file=result.log_file, string_list=strings)

        # Make changes in js, css and xml files
        Sync.replace(app_name=self.app_name, change_set=Changes.JSHelloWord.JS)
        Sync.replace(app_name=self.app_name, change_set=Changes.JSHelloWord.XML)
        Sync.replace(app_name=self.app_name, change_set=Changes.JSHelloWord.CSS)

        # Execute run with --justlaunch again and verify prepare is triggered
        result = Tns.run_android(app_name=self.app_name, emulator=True, just_launch=True)
        strings = ['Project successfully prepared', 'Webpack compilation complete']
        TnsLogs.wait_for_log(log_file=result.log_file, string_list=strings)
        self.emu.wait_for_text(text=Changes.JSHelloWord.XML.new_text)

    @unittest.skipIf(Settings.HOST_OS != OSType.OSX, 'iOS tests can be executed only on macOS.')
    def test_120_tns_run_ios_just_launch(self):
        """
        This test verify following things:
        1. `--justlaunch` option release the console.
        2. Full rebuild and prepare are not trigerred if no changes are done.
        3. Incremental prepare is triggered if js, xml and css files are changed.
        """
        # Run app with --justlaunch and verify on device
        result = run_hello_world_js_ts(self.app_name, Platform.IOS, self.sim, just_launch=True)
        # On some machines it takes time for thr process to die
        time.sleep(5)
        assert not Process.is_running_by_commandline(Settings.Executables.TNS)

        # Execute run with --justlaunch again and verify no rebuild is triggered
        result = Tns.run_ios(app_name=self.app_name, emulator=True, just_launch=True)
        strings = TnsLogs.run_messages(app_name=self.app_name, platform=Platform.IOS,
                                       run_type=RunType.JUST_LAUNCH, device=self.sim, just_launch=True)
        TnsLogs.wait_for_log(log_file=result.log_file, string_list=strings)

        # Make changes in js, css and xml files
        Sync.replace(app_name=self.app_name, change_set=Changes.JSHelloWord.JS)
        Sync.replace(app_name=self.app_name, change_set=Changes.JSHelloWord.XML)
        Sync.replace(app_name=self.app_name, change_set=Changes.JSHelloWord.CSS)

        # Execute run with --justlaunch again and verify prepare is triggered
        result = Tns.run_ios(app_name=self.app_name, emulator=True, just_launch=True)
        strings = ['Project successfully prepared', 'Webpack compilation complete']
        TnsLogs.wait_for_log(log_file=result.log_file, string_list=strings)
        self.sim.wait_for_text(text=Changes.JSHelloWord.XML.new_text)

    @unittest.skip("Skip because of https://github.com/NativeScript/nativescript-cli/issues/4607")
    def test_290_tns_run_android_should_refresh_images(self):
        """
        Test for https://github.com/NativeScript/nativescript-cli/issues/2981
        """
        # Update app to reference picture from app folder
        source_file = os.path.join(Settings.TEST_RUN_HOME, 'assets', 'issues', 'nativescript-cli-2981', 'main-page.xml')
        dest_file = os.path.join(self.app_path, 'app', 'main-page.xml')
        File.copy(source_file, dest_file)

        # Copy image file to app folder
        source_file = os.path.join(Settings.TEST_RUN_HOME, 'assets', 'resources', 'star.png')
        dest_file = os.path.join(self.app_path, 'app', 'test.png')
        File.copy(source_file, dest_file)
        result = Tns.run_android(app_name=self.app_name, verify=True, device=self.emu.id)
        strings = TnsLogs.run_messages(app_name=self.app_name, platform=Platform.ANDROID,
                                       run_type=RunType.FIRST_TIME, device=self.emu)
        TnsLogs.wait_for_log(log_file=result.log_file, string_list=strings)
        yellow_count = self.emu.get_pixels_by_color(color=Colors.YELLOW_ICON)
        green_count = self.emu.get_pixels_by_color(color=Colors.GREEN_ICON)

        # Verify the referenced image file is displayed on device screen
        assert yellow_count > 0, 'Failed to find yellow color on {0}'.format(self.emu.name)
        assert green_count == 0, 'Found green color on {0}'.format(self.emu.name)

        # Change the image file
        source_file = os.path.join(Settings.TEST_RUN_HOME, 'assets', 'resources', 'android',
                                   'drawable-hdpi', 'background.png')
        dest_file = os.path.join(self.app_path, 'app', 'test.png')
        File.copy(source_file, dest_file)
        strings = TnsLogs.run_messages(app_name=self.app_name, platform=Platform.ANDROID,
                                       run_type=RunType.UNKNOWN, device=self.emu)
        TnsLogs.wait_for_log(log_file=result.log_file, string_list=strings)

        # Verify the new image is synced and displayed on device screen
        yellow_count = self.emu.get_pixels_by_color(color=Colors.YELLOW_ICON)
        green_count = self.emu.get_pixels_by_color(color=Colors.GREEN_ICON)
        assert green_count > 0, 'Failed to find green color on {0}'.format(self.emu.name)
        assert yellow_count == 0, 'Found yellow color on {0}'.format(self.emu.name)

    @unittest.skipIf(Settings.HOST_OS == OSType.WINDOWS, 'skip on windows untill we fix wait_rof_log method')
    def test_300_tns_run_android_clean(self):
        """
        If  set --clean rebuilds the native project
        """
        # Run the project once so it is build for the first time
        run_hello_world_js_ts(self.app_name, Platform.ANDROID, self.emu)

        # Verify run --clean without changes skip prepare and rebuild of native project

        result = Tns.run_android(app_name=self.app_name, verify=True, device=self.emu.id, clean=True, just_launch=True)
        strings = ['Preparing project', 'Building project', 'Gradle clean', 'Successfully synced application']
        TnsLogs.wait_for_log(log_file=result.log_file, string_list=strings, timeout=120)

        self.emu.wait_for_text(text=Changes.JSHelloWord.XML.old_text)

        # Verify if changes are applied and then run with clean it will apply changes on device
        # Verify https://github.com/NativeScript/nativescript-cli/issues/2670 run --clean does
        # clean build only the first time
        Sync.replace(self.app_name, Changes.JSHelloWord.XML)
        result = Tns.run_android(app_name=self.app_name, verify=True, device=self.emu.id, clean=True)
        strings = TnsLogs.run_messages(app_name=self.app_name, platform=Platform.ANDROID,
                                       run_type=RunType.FULL, device=self.emu)
        strings.append('Gradle clean')
        TnsLogs.wait_for_log(log_file=result.log_file, string_list=strings, timeout=120)
        self.emu.wait_for_text(text=Changes.JSHelloWord.XML.new_text)

        # Make changes again and verify changes are synced and clean build is not triggered again
        Sync.revert(self.app_name, Changes.JSHelloWord.XML)
        strings = TnsLogs.run_messages(app_name=self.app_name, platform=Platform.ANDROID,
                                       run_type=RunType.INCREMENTAL, device=self.emu, file_name='main-page.xml')
        not_existing_strings = ['Gradle clean']
        TnsLogs.wait_for_log(log_file=result.log_file, string_list=strings,
                             not_existing_string_list=not_existing_strings)

    @unittest.skipIf(Settings.HOST_OS != OSType.OSX, 'iOS tests can be executed only on macOS.')
    def test_300_tns_run_ios_clean(self):
        """
        If  set --clean rebuilds the native project
        """
        # Run the project once so it is build for the first time
        result = run_hello_world_js_ts(self.app_name, Platform.IOS, self.sim, just_launch=True)

        # Verify run --clean without changes rebuilds native project
        result = Tns.run_ios(app_name=self.app_name, verify=True, device=self.sim.id, clean=True, just_launch=True)
        strings = ['Building project', 'Xcode build...', 'Successfully synced application']
        TnsLogs.wait_for_log(log_file=result.log_file, string_list=strings, timeout=120)
        self.sim.wait_for_text(text=Changes.JSHelloWord.XML.old_text)

        # Verify if changes are applied and then run with clean it will apply changes on device
        # Verify https://github.com/NativeScript/nativescript-cli/issues/2670 run --clean does
        # clean build only the first time
        Sync.replace(self.app_name, Changes.JSHelloWord.XML)
        result = Tns.run_ios(app_name=self.app_name, verify=True, device=self.sim.id, clean=True)
        strings = TnsLogs.run_messages(app_name=self.app_name, platform=Platform.IOS,
                                       run_type=RunType.FULL, device=self.sim)
        strings.append('Xcode build...')
        TnsLogs.wait_for_log(log_file=result.log_file, string_list=strings)
        self.sim.wait_for_text(text=Changes.JSHelloWord.XML.new_text)

        # Make changes again and verify changes are synced and clean build is not triggered again
        Sync.revert(self.app_name, Changes.JSHelloWord.XML)
        strings = TnsLogs.run_messages(app_name=self.app_name, platform=Platform.IOS,
                                       run_type=RunType.INCREMENTAL, device=self.sim, file_name='main-page.xml')
        not_existing_strings = ['Xcode build...']
        TnsLogs.wait_for_log(log_file=result.log_file, string_list=strings,
                             not_existing_string_list=not_existing_strings)

    @unittest.skip("Skip because of https://github.com/NativeScript/nativescript-dev-webpack/issues/899")
    def test_310_tns_run_android_sync_changes_in_node_modules(self):
        """
        Verify changes in node_modules are synced during run command
        """
        # Run the project
        result = run_hello_world_js_ts(self.app_name, Platform.ANDROID, self.emu, sync_all_files=True)

        # Make code changes in tns-core-modules verify livesync is triggered
        Sync.replace(self.app_name, Changes.NodeModules.TNS_MODULES)
        strings = TnsLogs.run_messages(app_name=self.app_name, platform=Platform.ANDROID,
                                       run_type=RunType.INCREMENTAL, device=self.emu, file_name='application-common.js')
        TnsLogs.wait_for_log(log_file=result.log_file, string_list=strings)
        self.emu.wait_for_text(text=Changes.JSHelloWord.JS.old_text)

    @unittest.skip("Skip because of https://github.com/NativeScript/nativescript-dev-webpack/issues/899")
    @unittest.skipIf(Settings.HOST_OS != OSType.OSX, 'iOS tests can be executed only on macOS.')
    def test_310_tns_run_ios_sync_changes_in_node_modules(self):
        """
        Verify changes in node_modules are synced during run command
        """
        # Run the project
        result = run_hello_world_js_ts(self.app_name, Platform.IOS, self.sim, sync_all_files=True)

        # Make code changes in tns-core-modules verify livesync is triggered
        Sync.replace(self.app_name, Changes.NodeModules.TNS_MODULES)
        strings = TnsLogs.run_messages(app_name=self.app_name, platform=Platform.ANDROID,
                                       run_type=RunType.INCREMENTAL, device=self.emu, file_name='application-common.js')
        TnsLogs.wait_for_log(log_file=result.log_file, string_list=strings)
        self.emu.wait_for_text(text=Changes.JSHelloWord.JS.old_text)

    def test_315_tns_run_android_sync_changes_in_aar_files(self):
        """
        Livesync should sync aar file changes inside a plugin
        https://github.com/NativeScript/nativescript-cli/issues/3610
        """
        # Add plugin and run the project
        Tns.plugin_add('nativescript-camera', self.app_name)
        result = run_hello_world_js_ts(self.app_name, Platform.ANDROID, self.emu)

        # Make  changes in nativescript-camera .aar file and  verify livesync is triggered
        new_aar = os.path.join(Settings.TEST_RUN_HOME, 'assets', 'issues', 'nativescript-cli-3932',
                               'nativescript-ui-listview', 'platforms', 'android', 'TNSListView-release.aar')
        target_aar = os.path.join(self.app_name, 'node_modules', 'nativescript-camera', 'platforms', 'android')
        File.copy(new_aar, target_aar)
        strings = TnsLogs.run_messages(app_name=self.app_name, platform=Platform.ANDROID,
                                       run_type=RunType.UNKNOWN, device=self.emu)
        TnsLogs.wait_for_log(log_file=result.log_file, string_list=strings, timeout=120)
        self.emu.wait_for_text(text=Changes.JSHelloWord.JS.old_text)

    def test_320_tns_run_android_should_warn_if_package_ids_dont_match(self):
        """
        If bundle identifiers in package.json and app.gradle do not match CLI should warn the user.
        """

        # Change app id in app.gradle file
        app_gradle = os.path.join(Settings.TEST_RUN_HOME, self.app_name, 'app', 'App_Resources',
                                  'Android', 'app.gradle')
        File.replace(app_gradle, old_string='generatedDensities = []',
                     new_string='applicationId = "org.nativescript.MyApp"')

        # Run the app on device and verify the warnings
        result = Tns.run_android(app_name=self.app_name, just_launch=False)
        strings = ["WARNING: The Application identifier is different from the one inside \"package.json\" file.",
                   "NativeScript CLI might not work properly.",
                   "Project successfully built"]
        TnsLogs.wait_for_log(log_file=result.log_file, string_list=strings)

    @unittest.skipIf(Settings.HOST_OS != OSType.OSX, 'iOS tests can be executed only on macOS.')
    def test_320_tns_run_ios_should_warn_if_package_ids_dont_match(self):
        """
        If bundle identifiers in package.json and Info.plist do not match CLI should warn the user.
        """

        # Change app id in app.gradle file
        old_string = "<string>${EXECUTABLE_NAME}</string>"
        new_string = "<string>${EXECUTABLE_NAME}</string>" \
                     "<key>CFBundleIdentifier</key>" \
                     "<string>org.nativescript.myapp</string>"
        info_plist = os.path.join(Settings.TEST_RUN_HOME, self.app_resources_ios, 'Info.plist')

        File.replace(info_plist, old_string, new_string)

        # Run the app on device and verify the warnings
        result = Tns.run_ios(app_name=self.app_name, just_launch=False)
        strings = ["[WARNING]: The CFBundleIdentifier key inside the 'Info.plist' will be overriden",
                   "Project successfully built"]
        TnsLogs.wait_for_log(log_file=result.log_file, string_list=strings)

    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.')

    @unittest.skipIf(Settings.HOST_OS != OSType.OSX, 'iOS tests can be executed only on macOS.')
    def test_325_tns_run_ios_should_start_simulator(self):
        """
        `tns run android` should start emulator if device is not connected.
        """
        # Run the test only if there are no connected devices
        conected_devices = DeviceManager.get_devices(device_type=DeviceType.IOS)
        if conected_devices.__len__() == 0:
            DeviceManager.Simulator.stop()
            result = Tns.run_ios(self.app_name)
            strings = TnsLogs.run_messages(app_name=self.app_name, platform=Platform.IOS,
                                           run_type=RunType.FULL, device=self.sim)
            TnsLogs.wait_for_log(log_file=result.log_file, string_list=strings, timeout=120)
            DeviceManager.Simulator.stop()
            DeviceManager.Simulator.ensure_available(Settings.Simulators.DEFAULT)
        else:
            raise nose.SkipTest('This test is not valid when devices are connected.')

    @unittest.skipIf(Settings.HOST_OS != OSType.OSX, 'iOS tests can be executed only on macOS.')
    def test_345_tns_run_ios_source_code_in_ios_part_plugin(self):
        """
        https://github.com/NativeScript/nativescript-cli/issues/3650
        """
        # Add plugin with source code in iOS part of the plugin
        plugin_path = os.path.join(Settings.TEST_RUN_HOME, 'assets', 'plugins', 'sample-plugin', 'src')
        Tns.plugin_add(plugin_path, path=self.app_name, verify=True)

        # Call method from the source code of the plugin in main-view-model.js
        old_value = 'viewModel.counter = 42;'
        new_value = 'viewModel.counter = 42;\n var objTC = new TestClass();\n console.log(objTC.sayHey());'
        target_js = os.path.join(Settings.TEST_RUN_HOME, self.app_name, 'app', 'main-view-model.js')
        File.replace(target_js, old_value, new_value)
        result = Tns.run_ios(self.app_name, emulator=True)
        strings = TnsLogs.run_messages(app_name=self.app_name, platform=Platform.IOS,
                                       run_type=RunType.FIRST_TIME, device=self.sim)
        strings.append('Hey!')
        TnsLogs.wait_for_log(log_file=result.log_file, string_list=strings)

        # Verify app looks correct inside simulator
        self.sim.wait_for_text(text=Changes.JSHelloWord.JS.old_text)

    @unittest.skipIf(Settings.HOST_OS != OSType.OSX, 'iOS tests can be executed only on macOS.')
    def test_350_tns_run_ios_source_code_in_app_resources(self):
        """
        https://github.com/NativeScript/nativescript-cli/issues/4343
        """
        # Add plugin with source code in iOS part of the plugin
        source_path = os.path.join(Settings.TEST_RUN_HOME, 'assets', 'issues', 'nativescript-cli-4343', 'src')
        dest_path = os.path.join(self.app_resources_ios, 'src')
        Folder.copy(source_path, dest_path, clean_target=False)

        # Call method from the source code of the plugin in main-view-model.js
        old_value = 'viewModel.counter = 42;'
        new_value = 'viewModel.counter = 42;\n var objTC = new TestClass2();\n console.log(objTC.sayHey());'
        target_js = os.path.join(Settings.TEST_RUN_HOME, self.app_name, 'app', 'main-view-model.js')
        File.replace(target_js, old_value, new_value)

        result = Tns.run_ios(self.app_name, emulator=True)
        strings = TnsLogs.run_messages(app_name=self.app_name, platform=Platform.IOS,
                                       run_type=RunType.FIRST_TIME, device=self.sim)
        strings.append('Hey Native!')
        TnsLogs.wait_for_log(log_file=result.log_file, string_list=strings)

        # Verify app looks correct inside simulator
        self.sim.wait_for_text(text=Changes.JSHelloWord.JS.old_text)

    # @unittest.skip("Webpack only")
    def test_355_tns_run_android_delete_node_modules(self):
        """
        Run should not fail if node_modules folder is deleted
        https://github.com/NativeScript/nativescript-cli/issues/3944
        """
        # Run the project with --justLaunch
        run_hello_world_js_ts(self.app_name, Platform.ANDROID, self.emu, just_launch=True)

        # Delete node_modules
        node_modules = os.path.join(Settings.TEST_RUN_HOME, self.app_name, 'node_modules')
        Folder.clean(node_modules)

        # Run the project again, verify it is build and node_modules folder exists
        run_hello_world_js_ts(self.app_name, Platform.ANDROID, self.emu, just_launch=True)
        assert Folder.exists(node_modules)

    # @unittest.skip("Webpack only")
    @unittest.skipIf(Settings.HOST_OS != OSType.OSX, 'iOS tests can be executed only on macOS.')
    def test_360_tns_run_ios_on_folder_with_spaces(self):
        """
        `tns run ios` for apps with spaces
        """
        Tns.create(app_name=self.app_name_space, template=Template.HELLO_WORLD_JS.local_package, update=True)
        app_name = '"' + self.app_name_space + '"'
        run_hello_world_js_ts(app_name, Platform.ANDROID, self.emu, just_launch=True)

    @unittest.skip("Skip this test due to emulator api28 ui crashing when no space left on device")
    @unittest.skipIf(Settings.HOST_OS != OSType.OSX, '`shell cp -r` fails on emulators on Linux and Win.')
    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)
class BuildTests(TnsTest):
    app_name = Settings.AppName.DEFAULT
    app_name_with_space = Settings.AppName.WITH_SPACE
    app_path = TnsPaths.get_app_path(app_name=app_name)
    app_temp_path = os.path.join(Settings.TEST_RUN_HOME, 'data', 'temp', 'TestApp')
    debug_apk = "app-debug.apk"
    app_identifier = "org.nativescript.testapp"
    temp_folder = os.path.join(app_path, 'temp')

    @classmethod
    def setUpClass(cls):
        TnsTest.setUpClass()
        Docker.start()
        Tns.create(app_name=cls.app_name, template=Template.HELLO_WORLD_JS.local_package, update=True)
        Tns.create(cls.app_name_with_space, template=Template.HELLO_WORLD_JS.local_package, update=True)
        Tns.platform_add_android(cls.app_name, framework_path=Settings.Android.FRAMEWORK_PATH)
        Tns.platform_add_android(app_name='"' + cls.app_name_with_space + '"',
                                 framework_path=Settings.Android.FRAMEWORK_PATH, verify=False)
        if Settings.HOST_OS is OSType.OSX:
            Tns.platform_add_ios(cls.app_name, framework_path=Settings.IOS.FRAMEWORK_PATH)
        Folder.copy(cls.app_path, cls.app_temp_path)

    def setUp(self):
        TnsTest.setUp(self)
        Folder.clean(self.app_path)
        Folder.copy(self.app_temp_path, self.app_path)

    def tearDown(self):
        TnsTest.tearDown(self)

    @classmethod
    def tearDownClass(cls):
        TnsTest.tearDownClass()
        Docker.stop()

        Folder.clean(TnsPaths.get_app_path(app_name=cls.app_temp_path))
        Folder.clean(TnsPaths.get_app_path(cls.app_name_with_space))

    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_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_301_build_project_with_space_release(self):

        # Ensure ANDROID_KEYSTORE_PATH contain spaces (verification for CLI issue 2650)
        Folder.create("with space")
        file_name = os.path.basename(Settings.Android.ANDROID_KEYSTORE_PATH)
        cert_with_space_path = os.path.join("with space", file_name)
        File.copy(Settings.Android.ANDROID_KEYSTORE_PATH, cert_with_space_path)

        Tns.build_android(app_name='"' + self.app_name_with_space + '"', release=True)
        output = File.read(os.path.join(self.app_name_with_space, "package.json"))
        assert self.app_identifier in output.lower()

        output = File.read(os.path.join(TnsPaths.get_platforms_android_src_main_path(self.app_name_with_space),
                                        'AndroidManifest.xml'))
        assert self.app_identifier in output.lower()

    def test_302_build_project_with_space_debug_with_plugin(self):
        # skip remove platform because androidx is not released official
        app_space_path = TnsPaths.get_app_path(app_name=self.app_name_with_space)
        # Tns.platform_remove(app_name='"' + self.app_name_with_space + '"', platform=Platform.ANDROID)
        Npm.install(package='nativescript-mapbox', option='--save', folder=app_space_path)
        result = Tns.build_android(app_name='"' + self.app_name_with_space + '"')
        assert "Project successfully built" in result.output

    def test_310_build_android_with_custom_compile_sdk_new(self):
        Tns.platform_remove(self.app_name, platform=Platform.ANDROID)
        Tns.platform_add_android(self.app_name, framework_path=Settings.Android.FRAMEWORK_PATH)
        Tns.exec_command(command='build --compileSdk 28', path=self.app_name,
                         platform=Platform.ANDROID, bundle=True)

        File.delete(self.debug_apk)
        Tns.exec_command(command='build --copy-to ./', path=self.app_name,
                         platform=Platform.ANDROID, bundle=True)
        assert File.exists(self.debug_apk)
        File.delete(self.debug_apk)

    def test_441_android_typings(self):
        Tns.exec_command(command='build --androidTypings', path=self.app_name,
                         platform=Platform.ANDROID, bundle=True)
        assert File.exists(os.path.join(self.app_name, 'android.d.ts'))
        assert File.exists(os.path.join(self.app_name, 'android-declarations.d.ts'))

    def test_450_resources_update_android(self):
        target_app = os.path.join(self.app_name, 'app', 'App_Resources')
        source_app = os.path.join(TEST_RUN_HOME, 'assets', 'apps', 'test-app-js-41', 'app', 'App_Resources')
        Folder.clean(target_app)
        Folder.copy(source_app, target_app)

        result = Tns.exec_command(command='resources update android', path=self.app_name)

        assert "Successfully updated your project's application resources '/Android' directory structure" in \
               result.output
        assert "The previous version of your Android application resources has been renamed to '/Android-Pre-v4'" in \
               result.output
        assert File.exists(os.path.join(TnsPaths.get_path_app_resources(self.app_name), 'Android-Pre-v4', 'app.gradle'))
        assert File.exists(os.path.join(TnsPaths.get_path_app_resources(self.app_name), 'Android', 'app.gradle'))
        assert File.exists(os.path.join(TnsPaths.get_path_app_resources_main_android(self.app_name),
                                        'AndroidManifest.xml'))
        assert Folder.exists(os.path.join(TnsPaths.get_path_app_resources_main_android(self.app_name), 'assets'))
        assert Folder.exists(os.path.join(TnsPaths.get_path_app_resources_main_android(self.app_name), 'java'))
        assert Folder.exists(os.path.join(TnsPaths.get_path_app_resources_main_android(self.app_name), 'res', 'values'))

        Tns.prepare_android(self.app_name)
        assert File.exists(
            os.path.join(TnsPaths.get_platforms_android_src_main_path(self.app_name), 'AndroidManifest.xml'))

    def test_451_resources_update(self):
        target_app = os.path.join(self.app_name, 'app', 'App_Resources')
        source_app = os.path.join(TEST_RUN_HOME, 'assets', 'apps', 'test-app-js-41', 'app', 'App_Resources')
        Folder.clean(target_app)
        Folder.copy(source_app, target_app)

        result = Tns.exec_command(command='resources update', path=self.app_name)

        assert "Successfully updated your project's application resources '/Android' directory structure" in \
               result.output
        assert "The previous version of your Android application resources has been renamed to '/Android-Pre-v4'" in \
               result.output
        assert File.exists(os.path.join(TnsPaths.get_path_app_resources(self.app_name), 'Android-Pre-v4', 'app.gradle'))
        assert File.exists(os.path.join(TnsPaths.get_path_app_resources(self.app_name), 'Android', 'app.gradle'))
        assert File.exists(os.path.join(TnsPaths.get_path_app_resources_main_android(self.app_name),
                                        'AndroidManifest.xml'))
        assert Folder.exists(os.path.join(TnsPaths.get_path_app_resources_main_android(self.app_name), 'assets'))
        assert Folder.exists(os.path.join(TnsPaths.get_path_app_resources_main_android(self.app_name), 'java'))
        assert Folder.exists(os.path.join(TnsPaths.get_path_app_resources_main_android(self.app_name), 'res', 'values'))
        Tns.prepare_android(self.app_name)
        assert File.exists(
            os.path.join(TnsPaths.get_platforms_android_src_main_path(self.app_name), 'AndroidManifest.xml'))

    @unittest.skipIf(Settings.HOST_OS != OSType.OSX, 'iOS tests can be executed only on macOS.')
    def test_001_build_ios(self):
        Tns.platform_remove(self.app_name, platform=Platform.ANDROID)
        Tns.build_ios(self.app_name)
        Tns.build_ios(self.app_name, release=True)
        Tns.build_ios(self.app_name, for_device=True)
        Tns.build_ios(self.app_name, for_device=True, release=True)
        assert not File.exists(os.path.join(TnsPaths.get_platforms_ios_folder(self.app_name), '*.aar'))
        assert not File.exists(os.path.join(TnsPaths.get_platforms_ios_npm_modules(self.app_name), '*.framework'))

        # Verify ipa has both armv7 and arm64 archs
        ipa_path = TnsPaths.get_ipa_path(app_name=self.app_name, release=True, for_device=True)
        run("mv " + ipa_path + " TestApp-ipa.tgz")
        run("unzip -o TestApp-ipa.tgz")
        result = run("lipo -info Payload/TestApp.app/TestApp")
        Folder.clean("Payload")
        assert "Architectures in the fat file: Payload/TestApp.app/TestApp are: armv7 arm64" in result.output

    @unittest.skipIf(Settings.HOST_OS != OSType.OSX, 'iOS tests can be executed only on macOS.')
    def test_190_build_ios_distribution_provisions(self):
        Tns.platform_remove(self.app_name, platform=Platform.ANDROID)
        result = Tns.exec_command(command='build ios --provision', path=self.app_name)
        assert "Provision Name" in result.output
        assert "Provision UUID" in result.output
        assert "App Id" in result.output
        assert "Team" in result.output
        assert "Type" in result.output
        assert "Due" in result.output
        assert "Devices" in result.output
        assert Settings.IOS.PROVISIONING in result.output
        assert Settings.IOS.DISTRIBUTION_PROVISIONING in result.output
        assert Settings.IOS.DEVELOPMENT_TEAM in result.output

        # Build with correct distribution provision
        Tns.build_ios(self.app_name, provision=Settings.IOS.DISTRIBUTION_PROVISIONING, for_device=True, release=True)

        # Verify that passing wrong provision shows user friendly error
        result = Tns.build_ios(self.app_name, provision="fake", verify=False)
        assert "Failed to find mobile provision with UUID or Name: fake" in result.output

    @unittest.skipIf(Settings.HOST_OS != OSType.OSX, 'iOS tests can be executed only on macOS.')
    def test_310_build_ios_with_copy_to(self):
        Tns.platform_remove(self.app_name, platform=Platform.IOS)
        Tns.exec_command(command='build --copy-to ' + TEST_RUN_HOME, path=self.app_name,
                         platform=Platform.IOS, bundle=True)
        assert Folder.exists(os.path.join(TEST_RUN_HOME, 'TestApp.app'))
        Tns.exec_command(command='build --copy-to ' + TEST_RUN_HOME, path=self.app_name, platform=Platform.IOS,
                         bundle=True, for_device=True, release=True, provision=Settings.IOS.PROVISIONING)
        assert File.exists(os.path.join(TEST_RUN_HOME, 'TestApp.ipa'))

    @unittest.skipIf(Settings.HOST_OS != OSType.OSX, 'iOS tests can be executed only on macOS.')
    def test_320_build_ios_with_custom_entitlements(self):
        # Add entitlements in app/App_Resources/iOS/app.entitlements
        source = os.path.join(TEST_RUN_HOME, 'assets', 'entitlements', 'app.entitlements')
        target = os.path.join(self.app_name, 'app', 'App_Resources', 'iOS', 'app.entitlements')
        File.copy(source, target)

        # Build again and verify entitlements are merged
        Tns.build_ios(self.app_name)
        entitlements_path = os.path.join(TnsPaths.get_platforms_ios_folder(self.app_name), self.app_name,
                                         'TestApp.entitlements')
        assert File.exists(entitlements_path), "Entitlements file is missing!"
        entitlements_content = File.read(entitlements_path)
        assert '<key>aps-environment</key>' in entitlements_content, "Entitlements file content is wrong!"
        assert '<string>development</string>' in entitlements_content, "Entitlements file content is wrong!"

        # Install plugin with entitlements, build again and verify entitlements are merged
        plugin_path = os.path.join(TEST_RUN_HOME, 'assets', 'plugins', 'nativescript-test-entitlements-1.0.0.tgz')
        Npm.install(package=plugin_path, option='--save', folder=self.app_name)

        Tns.build_ios(self.app_name)
        entitlements_content = File.read(entitlements_path)
        assert '<key>aps-environment</key>' in entitlements_content, "Entitlements file content is wrong!"
        assert '<string>development</string>' in entitlements_content, "Entitlements file content is wrong!"
        assert '<key>inter-app-audio</key>' in entitlements_content, "Entitlements file content is wrong!"
        assert '<true/>' in entitlements_content, "Entitlements file content is wrong!"

        # Build in release, for device (provision without entitlements)
        result = Tns.build_ios(self.app_name, for_device=True, release=True, verify=False)
        assert "Provisioning profile" in result.output
        assert "doesn't include the aps-environment and inter-app-audio entitlements" in result.output
Exemplo n.º 16
0
class TemplateTests(TnsRunTest):
    app_name = Settings.AppName.DEFAULT
    app_folder = TnsPaths.get_app_path(app_name=app_name)

    test_data = [
        [Template.BLANK_JS.name, Template.BLANK_JS],
        [Template.BLANK_TS.name, Template.BLANK_TS],
        [Template.BLANK_NG.name, Template.BLANK_NG],
        [Template.VUE_BLANK.name, Template.VUE_BLANK],
        [Template.DRAWER_NAVIGATION_JS.name, Template.DRAWER_NAVIGATION_JS],
        [Template.DRAWER_NAVIGATION_TS.name, Template.DRAWER_NAVIGATION_TS],
        [Template.DRAWER_NAVIGATION_NG.name, Template.DRAWER_NAVIGATION_NG],
        [Template.DRAWER_NAVIGATION_VUE.name, Template.DRAWER_NAVIGATION_VUE],
        [Template.HELLO_WORLD_JS.name, Template.HELLO_WORLD_JS],
        [Template.HELLO_WORLD_TS.name, Template.HELLO_WORLD_TS],
        [Template.HELLO_WORLD_NG.name, Template.HELLO_WORLD_NG],
        [
            Template.MASTER_DETAIL_KINVEY_JS.name,
            Template.MASTER_DETAIL_KINVEY_JS
        ],
        [
            Template.MASTER_DETAIL_KINVEY_TS.name,
            Template.MASTER_DETAIL_KINVEY_TS
        ],
        [
            Template.MASTER_DETAIL_KINVEY_NG.name,
            Template.MASTER_DETAIL_KINVEY_NG
        ], [Template.MASTER_DETAIL_JS.name, Template.MASTER_DETAIL_JS],
        [Template.MASTER_DETAIL_TS.name, Template.MASTER_DETAIL_TS],
        [Template.MASTER_DETAIL_NG.name, Template.MASTER_DETAIL_NG],
        [Template.MASTER_DETAIL_VUE.name, Template.MASTER_DETAIL_VUE],
        [Template.TAB_NAVIGATION_JS.name, Template.TAB_NAVIGATION_JS],
        [Template.TAB_NAVIGATION_TS.name, Template.TAB_NAVIGATION_TS],
        [Template.TAB_NAVIGATION_NG.name, Template.TAB_NAVIGATION_NG],
        [Template.TAB_NAVIGATION_VUE.name, Template.TAB_NAVIGATION_VUE]
    ]

    @parameterized.expand(test_data)
    def test(self, template_name, template_info):
        TnsRunTest.setUp(self)

        # Create app
        app_name = template_info.name.replace('template-', '')
        Tns.create(app_name=app_name,
                   template='tns-' + template_name,
                   update=False)
        if Settings.ENV != EnvironmentType.LIVE and Settings.ENV != EnvironmentType.PR:
            App.update(app_name=app_name)

        # Run Android
        result = Tns.run_android(app_name=app_name, device=self.emu.id)
        strings = TnsLogs.run_messages(app_name=app_name,
                                       run_type=RunType.UNKNOWN,
                                       platform=Platform.ANDROID)
        TnsLogs.wait_for_log(log_file=result.log_file,
                             string_list=strings,
                             timeout=300)
        if template_info.texts is not None:
            for text in template_info.texts:
                self.emu.wait_for_text(text=text, timeout=60)
        else:
            self.emu.wait_for_main_color(color=Colors.WHITE, timeout=60)

        # Run iOS
        if Settings.HOST_OS is OSType.OSX:
            Simctl.uninstall_all(simulator_info=self.sim)
            result = Tns.run_ios(app_name=app_name, device=self.sim.id)
            strings = TnsLogs.run_messages(app_name=app_name,
                                           run_type=RunType.UNKNOWN,
                                           platform=Platform.IOS)
            TnsLogs.wait_for_log(log_file=result.log_file,
                                 string_list=strings,
                                 timeout=300)
            if template_info.texts is not None:
                for text in template_info.texts:
                    self.sim.wait_for_text(text=text, timeout=60)
            else:
                self.sim.wait_for_main_color(color=Colors.WHITE, timeout=60)

        # Cleanup
        Folder.clean(os.path.join(Settings.TEST_RUN_HOME, app_name))
        TnsRunTest.tearDown(self)
Exemplo n.º 17
0
class PluginTests(TnsTest):
    app_name = Settings.AppName.DEFAULT
    app_path = TnsPaths.get_app_path(app_name=app_name)
    app_temp_path = os.path.join(Settings.TEST_RUN_HOME, 'data', 'temp',
                                 'TestApp')

    @classmethod
    def setUpClass(cls):
        TnsTest.setUpClass()
        Tns.create(app_name=cls.app_name,
                   template=Template.HELLO_WORLD_JS.local_package,
                   update=True)
        Tns.platform_add_android(
            cls.app_name, framework_path=Settings.Android.FRAMEWORK_PATH)
        if Settings.HOST_OS is OSType.OSX:
            Tns.platform_add_ios(cls.app_name,
                                 framework_path=Settings.IOS.FRAMEWORK_PATH)
        Folder.copy(cls.app_path, cls.app_temp_path)

    def setUp(self):
        TnsTest.setUp(self)
        Folder.clean(self.app_path)
        Folder.copy(self.app_temp_path, self.app_path)

    def tearDown(self):
        TnsTest.tearDown(self)

    @classmethod
    def tearDownClass(cls):
        TnsTest.tearDownClass()
        Folder.clean(cls.app_temp_path)

    def test_100_plugin_add_after_platform_add_android(self):
        result = Tns.plugin_add(plugin_name='tns-plugin', path=self.app_name)
        assert 'Successfully installed plugin tns-plugin' in result.output
        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'))

        output = File.read(os.path.join(self.app_path, 'package.json'))
        assert 'org.nativescript.TestApp' in output
        assert 'dependencies' in output
        assert 'tns-plugin' in output

    def test_101_plugin_add_prepare_verify_apk_android(self):
        Tns.plugin_add(plugin_name='tns-plugin', path=self.app_name)
        Tns.build_android(app_name=self.app_name)
        assert File.exists(os.path.join(TnsPaths.get_apk_path(self.app_name)))
        # assert File.exists(os.path.join(TnsPaths.get_platforms_android_npm_modules(self.app_name), 'tns-plugin',
        #                                 'index.js'))

    def test_102_plugin_add_verify_command_list_used_plugins_android(self):
        Tns.plugin_add(plugin_name='tns-plugin', path=self.app_name)
        Tns.prepare_android(app_name=self.app_name)
        result = Tns.exec_command(command='plugin', path=self.app_name)
        assert 'tns-plugin' in result.output

    @unittest.skip("Webpack only")
    def test_200_plugin_platforms_should_not_exist_in_tns_modules_android(
            self):
        """
        Test for issue https://github.com/NativeScript/nativescript-cli/issues/3932
        """
        issue_path = os.path.join(Settings.TEST_RUN_HOME, 'assets', 'issues',
                                  'nativescript-cli-3932')
        Tns.platform_remove(app_name=self.app_name, platform=Platform.ANDROID)
        Tns.plugin_add(plugin_name='nativescript-ui-listview',
                       path=self.app_name)
        Folder.clean(os.path.join(self.app_name, 'node_modules'))
        File.delete(os.path.join(self.app_name, 'package.json'))
        copy = os.path.join(issue_path, 'nativescript-ui-listview')
        paste = os.path.join(self.app_path, 'nativescript-ui-listview')
        Folder.copy(copy, paste)
        copy = os.path.join(issue_path, 'package.json')
        paste = os.path.join(self.app_name)
        File.copy(copy, paste)
        Tns.platform_add_android(
            app_name=self.app_name,
            framework_path=Settings.Android.FRAMEWORK_PATH)
        folder_path = os.path.join(self.app_path, 'nativescript-ui-listview')
        Npm.install(option='--ignore-scripts', folder=folder_path)
        Tns.build_android(app_name=self.app_name, bundle=False)
        app_path = os.path.join(
            TnsPaths.get_platforms_android_npm_modules(self.app_name))
        assert not File.exists(
            os.path.join(app_path, 'nativescript-ui-listview', 'node_modules',
                         'nativescript-ui-core', 'platforms'))

    @unittest.skip("Webpack only")
    def test_210_plugin_with_promise_in_hooks_android(self):
        Tns.plugin_add(plugin_name='[email protected]',
                       path=self.app_name)
        result = Tns.prepare_android(app_name=self.app_name, verify=False)
        assert 'Failed to execute hook' in result.output
        assert 'nativescript-fabric.js' in result.output
        assert 'TypeError' not in result.output
        assert 'Cannot read property' not in result.output

    def test_302_plugin_and_npm_modules_in_same_project_android(self):
        Tns.plugin_add(plugin_name='nativescript-social-share',
                       path=self.app_name)
        output = Npm.install(package='nativescript-appversion',
                             option='--save',
                             folder=self.app_path)
        assert 'ERR!' not in output
        assert 'nativescript-appversion@' in output

        Tns.build_android(app_name=self.app_name, verify=False)

    def test_410_plugin_remove_should_not_fail_if_plugin_name_has_dot_android(
            self):
        """
        Test for issue https://github.com/NativeScript/nativescript-cli/issues/3451
        """
        Tns.platform_remove(app_name=self.app_name, platform=Platform.ANDROID)
        Tns.plugin_add(plugin_name='[email protected]',
                       path=self.app_name)
        assert Folder.exists(
            os.path.join(self.app_path, 'node_modules',
                         'nativescript-socket.io'))
        result = Tns.plugin_remove(plugin_name='nativescript-socket.io',
                                   path=self.app_name,
                                   log_trace=True)
        assert 'Successfully removed plugin nativescript-socket.io' in result.output
        assert 'stdout: removed 1 package' in result.output
        assert 'Exec npm uninstall nativescript-socket.io --save' in result.output
        output = File.read(os.path.join(self.app_path, 'package.json'))
        assert 'nativescript-socket.io' not in output

    @unittest.skipIf(Settings.HOST_OS != OSType.OSX,
                     'iOS tests can be executed only on macOS.')
    def test_101_plugin_add_prepare_verify_app_ios(self):
        Tns.plugin_add(plugin_name='tns-plugin', path=self.app_name)
        Tns.build_ios(app_name=self.app_name)
        path_app = os.path.join(TnsPaths.get_ipa_path(self.app_name))
        assert Folder.exists(path_app)

    @unittest.skipIf(Settings.HOST_OS != OSType.OSX,
                     'iOS tests can be executed only on macOS.')
    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

    @unittest.skip("Webpack only")
    @unittest.skipIf(Settings.HOST_OS != OSType.OSX,
                     'iOS tests can be executed only on macOS.')
    def test_311_plugin_platforms_should_not_exist_in_tnsmodules_ios(self):
        """
        Test for issue https://github.com/NativeScript/nativescript-cli/issues/3932
        """
        Tns.platform_remove(app_name=self.app_name, platform=Platform.IOS)
        Tns.plugin_add(plugin_name='nativescript-ui-listview',
                       path=self.app_name)
        Folder.clean(os.path.join(self.app_name, 'node_modules'))
        File.delete(os.path.join(self.app_name, 'package.json'))
        copy = os.path.join('assets', 'issues', 'nativescript-cli-3932',
                            'nativescript-ui-listview')
        paste = os.path.join(self.app_name, 'nativescript-ui-listview')
        Folder.copy(copy, paste)
        copy = os.path.join('assets', 'issues', 'nativescript-cli-3932',
                            'package.json')
        paste = os.path.join(self.app_name)
        File.copy(copy, paste)
        Tns.platform_add_ios(app_name=self.app_name,
                             framework_path=Settings.IOS.FRAMEWORK_PATH)
        folder_path = os.path.join(self.app_name, 'nativescript-ui-listview')
        Npm.install(option='--ignore-scripts', folder=folder_path)
        Tns.build_ios(app_name=self.app_name, bundle=False)
        app_path = os.path.join(
            TnsPaths.get_platforms_ios_folder(self.app_name))
        assert not File.exists(
            os.path.join(app_path, 'nativescript-ui-listview', 'node_modules',
                         'nativescript-ui-core', 'platforms'))

    @unittest.skipIf(Settings.HOST_OS != OSType.OSX,
                     'iOS tests can be executed only on macOS.')
    def test_320_cfbundleurltypes_overridden_from_plugin_ios(self):
        """
        Test for issue https://github.com/NativeScript/nativescript-cli/issues/2936
        """
        Tns.platform_remove(app_name=self.app_name, platform=Platform.IOS)
        plugin_path = os.path.join(Settings.TEST_RUN_HOME, 'assets', 'plugins',
                                   'CFBundleURLName-Plugin.tgz')
        Tns.plugin_add(plugin_path, path=self.app_name)
        Tns.prepare_ios(app_name=self.app_name)
        plist = File.read(
            os.path.join(TnsPaths.get_platforms_ios_folder(self.app_name),
                         self.app_name, self.app_name + '-Info.plist'))
        assert '<key>NSAllowsArbitraryLoads</key>' in plist, \
            'NSAppTransportSecurity from plugin is not found in final Info.plist'
        assert '<string>bar</string>' in plist, 'CFBundleURLTypes from plugin is not found in final Info.plist'

    @unittest.skipIf(Settings.HOST_OS != OSType.OSX,
                     'iOS tests can be executed only on macOS.')
    def test_401_plugin_add_invalid_plugin(self):
        Tns.platform_remove(app_name=self.app_name, platform=Platform.IOS)
        Tns.platform_remove(app_name=self.app_name, platform=Platform.ANDROID)
        result = Tns.plugin_add(plugin_name='wd',
                                path=self.app_name,
                                verify=False)
        assert 'wd is not a valid NativeScript plugin' in result.output
        assert 'Verify that the plugin package.json file ' + \
               'contains a nativescript key and try again' in result.output
        Tns.platform_add_android(
            self.app_name, framework_path=Settings.Android.FRAMEWORK_PATH)
        Tns.platform_add_ios(self.app_name,
                             framework_path=Settings.IOS.FRAMEWORK_PATH)

        # Verify iOS only plugin
        result = Tns.plugin_add(plugin_name='[email protected]',
                                path=self.app_name)
        assert 'tns-plugin is not supported for android' in result.output
        assert 'Successfully installed plugin tns-plugin' in result.output

        # Verify Android only plugin
        result = Tns.plugin_add(plugin_name='acra-telerik-analytics',
                                path=self.app_name)
        assert 'acra-telerik-analytics is not supported for ios' in result.output
        assert 'Successfully installed plugin acra-telerik-analytics' in result.output

        Tns.build_ios(app_name=self.app_name, bundle=False)
        ios_path = os.path.join(
            TnsPaths.get_platforms_ios_folder(self.app_name))
        assert not File.pattern_exists(ios_path, pattern='*.aar')
        assert not File.pattern_exists(ios_path, pattern='*acra*')

        Tns.build_android(app_name=self.app_name, bundle=False)
        android_path = os.path.join(
            TnsPaths.get_platforms_android_folder(self.app_name))
        assert File.pattern_exists(android_path, pattern='*.aar')
        assert File.pattern_exists(android_path, pattern='*acra*')
Exemplo n.º 18
0
class NGNewTests(TnsRunTest):
    app_name = Settings.AppName.DEFAULT
    app_path = TnsPaths.get_app_path(app_name=app_name)

    def setUp(self):
        TnsRunTest.setUp(self)
        NG.kill()
        Folder.clean(self.app_path)

    def tearDown(self):
        NG.kill()
        TnsRunTest.tearDown(self)

    def test_001_simple(self):
        NGNewTests.create_and_run(shared=False)
        NGNewTests.build_release()

    def test_010_shared(self):
        NGNewTests.create_and_run(shared=True)
        NG.serve(project=self.app_name)
        NG.kill()
        NGNewTests.build_release()
        NG.serve(project=self.app_name, prod=True)

    def test_100_shared_with_sample(self):
        NGNewTests.create_and_run(shared=True, sample=True)

    def test_200_simple_no_theme(self):
        NGNewTests.create_and_run(shared=False, theme=False)

    def test_201_shared_with_sass(self):
        NGNewTests.create_and_run(shared=False, style=StylingType.SCSS)

    def test_202_shared_with_custom_source_dir_and_prefix(self):
        NGNewTests.create_and_run(shared=True,
                                  prefix='myapp',
                                  source_dir='mysrc',
                                  style=StylingType.CSS)

    @unittest.skip(
        'Ignore because of https://github.com/NativeScript/nativescript-schematics/issues/157'
    )
    def test_300_help_ng_new(self):
        output = NG.exec_command(
            'new --collection={0} --help'.format(NS_SCHEMATICS)).output
        assert '--sample' in output
        assert 'Specifies whether a sample master detail should be generated' in output
        assert '--shared' in output
        assert 'Specifies whether to generate a shared project or a {N} only' in output
        assert '--source-dir (-sd)' in output
        assert 'The path of the source directory' in output
        assert '--style' in output
        assert 'The file extension to be used for style files. Supported are css and scss' in output
        assert '--theme' in output
        assert 'Specifies whether the {N} theme for styling should be included' in output
        assert '--webpack' in output
        assert 'Specifies whether the new application has webpack set up' in output

    @staticmethod
    def create_and_run(shared=True,
                       sample=False,
                       theme=True,
                       style=None,
                       prefix=None,
                       source_dir=None,
                       webpack=True):
        # Get test data based on app type
        app_data = Apps.SCHEMATICS_NS
        if shared:
            if sample:
                app_data = Apps.SCHEMATICS_SHARED_SAMPLE
            else:
                app_data = Apps.SCHEMATICS_SHARED

        # Create app
        NGNewTests.create_app(app_data=app_data,
                              shared=shared,
                              sample=sample,
                              theme=theme,
                              style=style,
                              prefix=prefix,
                              source_dir=source_dir,
                              webpack=webpack)

        # Update the app
        if Settings.ENV != EnvironmentType.LIVE:
            App.update(app_name=NGNewTests.app_name,
                       modules=True,
                       angular=True,
                       typescript=True,
                       web_pack=True)

        # Run the app
        NGNewTests.run_bundle(app_data=app_data,
                              webpack=webpack,
                              shared=shared,
                              theme=theme,
                              emu=NGNewTests.emu,
                              sim=NGNewTests.sim)

    @staticmethod
    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
        TnsAssert.created(app_name=NGNewTests.app_name,
                          app_data=app_data,
                          theme=theme,
                          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-core')
        else:
            assert not App.is_dependency(app_name=NGNewTests.app_name,
                                         dependency='nativescript-theme-core')

        # 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
            assert '_app-variables.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))

    @staticmethod
    def run_bundle(app_data, webpack, shared, theme, emu, sim):
        # Run android (if webpack is available -> use --bundle)
        Tns.run(app_name=NGNewTests.app_name,
                platform=Platform.ANDROID,
                emulator=True,
                bundle=webpack)
        for text in app_data.texts:
            emu.wait_for_text(text=text, timeout=300)
            # Check if theme is really applied (only for non shared projects, shared is not good example to check)
            if not shared:
                blue_pixels = emu.get_pixels_by_color(color=Colors.LIGHT_BLUE)
                if theme:
                    assert blue_pixels > 1000, 'Default {N} theme is NOT applied on Android.'
                else:
                    assert blue_pixels == 0, 'Default {N} theme is applied, but it should not.'

        # Run ios (if webpack is available -> use --bundle)
        if Settings.HOST_OS is OSType.OSX:
            Tns.run(app_name=NGNewTests.app_name,
                    platform=Platform.IOS,
                    emulator=True,
                    bundle=webpack)
            for text in app_data.texts:
                sim.wait_for_text(text=text, timeout=300)
                # Check if theme is really applied (only for non shared projects, shared is not good example to check)
                if not shared:
                    blue_pixels = emu.get_pixels_by_color(
                        color=Colors.LIGHT_BLUE)
                    if theme:
                        assert blue_pixels > 1000, 'Default {N} theme is NOT applied on iOS.'
                    else:
                        assert blue_pixels == 0, 'Default {N} theme is applied, but it should not.'

    @staticmethod
    def build_release():
        Tns.build(app_name=NGNewTests.app_name,
                  platform=Platform.ANDROID,
                  release=True,
                  bundle=True,
                  aot=True,
                  uglify=True,
                  snapshot=True)
        if Settings.HOST_OS is OSType.OSX:
            Tns.build(app_name=NGNewTests.app_name,
                      platform=Platform.IOS,
                      release=True,
                      for_device=True,
                      bundle=True,
                      aot=True,
                      uglify=True)
class NGGenE2ETestsNS(TnsRunTest):
    app_name = Settings.AppName.DEFAULT
    app_path = TnsPaths.get_app_path(app_name=app_name)

    @classmethod
    def setUpClass(cls):
        TnsRunTest.setUpClass()
        NG.kill()

    def setUp(self):
        TnsRunTest.setUp(self)
        NG.kill()

    def tearDown(self):
        NG.kill()
        TnsRunTest.tearDown(self)

    def test_100_ns_generate_during_run_android(self):
        NGGenE2ETestsNS.workflow(app_name=self.app_name,
                                 device=self.emu,
                                 platform=Platform.ANDROID,
                                 shared=False)

    @unittest.skipIf(Settings.HOST_OS != OSType.OSX,
                     'Skip iOS tests on non macOS machines.')
    def test_100_ns_generate_during_run_ios(self):
        NGGenE2ETestsNS.workflow(app_name=self.app_name,
                                 device=self.sim,
                                 platform=Platform.IOS,
                                 shared=False)

    def test_200_shared_generate_during_run_android(self):
        NGGenE2ETestsNS.workflow(app_name=self.app_name,
                                 device=self.emu,
                                 platform=Platform.ANDROID,
                                 shared=True)

    @unittest.skipIf(Settings.HOST_OS != OSType.OSX,
                     'Skip iOS tests on non macOS machines.')
    def test_200_shared_generate_during_run_ios(self):
        NGGenE2ETestsNS.workflow(app_name=self.app_name,
                                 device=self.sim,
                                 platform=Platform.IOS,
                                 shared=True)

    @staticmethod
    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,
                                       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)
        sleep(3)
        NG.exec_command(command='g c module-test/component-test', cwd=app_path)
        sleep(3)

        # Update app.modules.ts
        app_module_name = 'app.module.ts'
        app_module_path = os.path.join(app_path, 'app', app_module_name)
        old_string = "import { HomeComponent } from './home/home.component';"
        new_string = "import { ComponentTestComponent } from './module-test/component-test/component-test.component';"
        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 '@src/app/home/home.component';"
            new_string = \
                "import { ComponentTestComponent } from '@src/app/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,')
        sleep(3)

        # 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)
        old_string = "import { HomeComponent } from './home/home.component';"
        new_string = "import { ComponentTestComponent } from './module-test/component-test/component-test.component';"
        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 '@src/app/home/home.component';"
            new_string = \
                "import { ComponentTestComponent } from '@src/app/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')
        sleep(3)

        # Verify app is updated
        logs = [
            app_module_name, app_routing_module_name,
            '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 tearDownClass(cls):
        TnsTest.tearDownClass()
        Docker.stop()

        Folder.clean(TnsPaths.get_app_path(app_name=cls.app_temp_path))
        Folder.clean(TnsPaths.get_app_path(cls.app_name_with_space))
Exemplo n.º 21
0
    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