예제 #1
0
    def test_001_usage_reporting_enable(self):
        output = Tns.run_tns_command("usage-reporting enable")
        assert enabled.format(usage_reporting, "now ") in output
        assert "GA_TRACKING_ID" in File.read(self.config)
        assert "UA-111455-44" in File.read(self.config)

        # Check there is message for tracking in Google Analytics
        output = Tns.run_tns_command("doctor", timeout=180, log_trace=True)
        assert "Will send the following information to Google Analytics" in output

        output = Tns.run_tns_command("usage-reporting status")
        assert enabled.format(usage_reporting, "") in output

        # https://github.com/NativeScript/nativescript-cli/issues/3595
        output = Tns.create_app(self.app_name,
                                attributes={
                                    '--template':
                                    os.path.join('data', 'apps',
                                                 'livesync-hello-world.tgz')
                                },
                                log_trace=True,
                                force_clean=False,
                                update_modules=True)
        assert "label: 'data/apps/livesync-hello-world.tgz'" not in output
        assert "label: 'localTemplate_tns-template-hello-world'" in output
예제 #2
0
    def test_301_build_project_with_space_release(self):
        Tns.create_app(self.app_name_space)
        Tns.platform_add_android(
            attributes={
                "--path": "\"" + self.app_name_space + "\"",
                "--frameworkPath": ANDROID_PACKAGE
            })

        # Ensure ANDROID_KEYSTORE_PATH contain spaces (verification for CLI issue 2650)
        Folder.create("with space")
        base_path, file_name = os.path.split(ANDROID_KEYSTORE_PATH)
        cert_with_space_path = os.path.join("with space", file_name)
        File.copy(src=ANDROID_KEYSTORE_PATH, dest=cert_with_space_path)

        # Verify project builds
        Tns.build_android(
            attributes={
                "--path": "\"" + self.app_name_space + "\"",
                "--keyStorePath": "\"" + cert_with_space_path + "\"",
                "--keyStorePassword": ANDROID_KEYSTORE_PASS,
                "--keyStoreAlias": ANDROID_KEYSTORE_ALIAS,
                "--keyStoreAliasPassword": ANDROID_KEYSTORE_ALIAS_PASS,
                "--release": ""
            })

        output = File.read(self.app_name_space + os.sep + "package.json")
        assert app_identifier in output.lower()

        output = File.read(self.app_name_space + "/" +
                           TnsAsserts.PLATFORM_ANDROID_SRC_MAIN_PATH +
                           "AndroidManifest.xml")
        assert app_identifier in output.lower()
예제 #3
0
    def start(emulator_name=EMULATOR_NAME,
              port=EMULATOR_PORT,
              timeout=300,
              wipe_data=True):
        """
        Start emulator.
        :param wipe_data: If true it will wipe emulator date.
        :param emulator_name: Name of android emulator image (avd).
        :param port: Port for Android emulator.
        :param timeout: Time to wait until emulator boot.
        """
        print 'Starting emulator {0}'.format(emulator_name)

        if CURRENT_OS == OSType.WINDOWS:
            start_command = 'START /B ' + EMULATOR_PATH + ' -avd ' + emulator_name + ' -port ' + port
        else:
            start_command = EMULATOR_PATH + ' -avd ' + emulator_name + ' -port ' + port

        if wipe_data:
            start_command += ' -wipe-data'
        log_file = run(start_command,
                       timeout=timeout,
                       wait=False,
                       log_level=CommandLogLevel.COMMAND_ONLY)

        # Check if emulator is running
        device_name = 'emulator-' + port
        if Emulator.wait(device_name, timeout):
            print 'Emulator started successfully.'
        else:
            print 'Emulator failed to boot!'
            print File.read(log_file)
            raise Exception('Wait for emulator failed!')
    def test_301_build_project_with_space_release(self):
        Tns.create_app(self.app_name_space)
        Tns.platform_add_android(
            attributes={"--path": "\"" + self.app_name_space + "\"", "--frameworkPath": ANDROID_PACKAGE})

        # Ensure ANDROID_KEYSTORE_PATH contain spaces (verification for CLI issue 2650)
        Folder.create("with space")
        base_path, file_name = os.path.split(ANDROID_KEYSTORE_PATH)
        cert_with_space_path = os.path.join("with space", file_name)
        File.copy(src=ANDROID_KEYSTORE_PATH, dest=cert_with_space_path)

        # Verify project builds
        Tns.build_android(attributes={"--path": "\"" + self.app_name_space + "\"",
                                      "--keyStorePath": "\"" + cert_with_space_path + "\"",
                                      "--keyStorePassword": ANDROID_KEYSTORE_PASS,
                                      "--keyStoreAlias": ANDROID_KEYSTORE_ALIAS,
                                      "--keyStoreAliasPassword": ANDROID_KEYSTORE_ALIAS_PASS,
                                      "--release": ""
                                      })

        output = File.read(self.app_name_space + os.sep + "package.json")
        assert app_identifier in output.lower()

        output = File.read(
            self.app_name_space + "/" + TnsAsserts.PLATFORM_ANDROID_SRC_MAIN_PATH + "AndroidManifest.xml")
        assert app_identifier in output.lower()
예제 #5
0
    def test_300_build_project_with_dash_and_ios_inspector_added(self):
        """
        Verify we can build projects with dashes.
        Verify we can build android when inspector is added (test for CLI issue 2467)
        """
        Tns.create_app(self.app_name_dash)
        Tns.platform_add_android(attributes={
            "--path": self.app_name_dash,
            "--frameworkPath": ANDROID_PACKAGE
        })
        if USE_YARN == "True":
            Npm.install(package="tns-ios-inspector",
                        option='--dev',
                        folder=self.app_name_dash)
        else:
            Npm.install(package="tns-ios-inspector",
                        option='--save-dev',
                        folder=self.app_name_dash)
        Tns.build_android(attributes={"--path": self.app_name_dash})

        # Verify project id
        output = File.read(self.app_name_dash + "/package.json")
        assert app_identifier in output.lower()

        # Verify AndroidManifest.xml
        output = File.read(self.app_name_dash + "/" +
                           TnsAsserts.PLATFORM_ANDROID_SRC_MAIN_PATH +
                           "AndroidManifest.xml")
        assert app_identifier in output.lower()
    def start(emulator_name=EMULATOR_NAME, port=EMULATOR_PORT, timeout=300, wipe_data=True):
        """
        Start emulator.
        :param wipe_data: If true it will wipe emulator date.
        :param emulator_name: Name of android emulator image (avd).
        :param port: Port for Android emulator.
        :param timeout: Time to wait until emulator boot.
        """
        print 'Starting emulator {0}'.format(emulator_name)

        if CURRENT_OS == OSType.WINDOWS:
            start_command = 'START /B ' + EMULATOR_PATH + ' -avd ' + emulator_name + ' -port ' + port
        else:
            start_command = EMULATOR_PATH + ' -avd ' + emulator_name + ' -port ' + port

        if wipe_data:
            start_command += ' -wipe-data'
        log_file = run(start_command, timeout=timeout, wait=False, log_level=CommandLogLevel.COMMAND_ONLY)

        # Check if emulator is running
        device_name = 'emulator-' + port
        if Emulator.wait(device_name, timeout):
            print 'Emulator started successfully.'
        else:
            print 'Emulator failed to boot!'
            print File.read(log_file)
            raise Exception('Wait for emulator failed!')
    def test_301_platform_update_ios(self):
        Tns.platform_add_ios(version="2.2.0", attributes={"--path": self.app_name})
        output = File.read(self.app_name + os.sep + "package.json")
        assert "\"version\": \"2.2.0\"" in output

        Tns.platform_update("[email protected]", attributes={"--path": self.app_name, " <  data/keys/enter_key.txt": ""})
        output = File.read(self.app_name + os.sep + "package.json")
        assert "\"version\": \"2.3.0\"" in output

        Tns.build_ios(attributes={"--path": self.app_name})
예제 #8
0
    def test_002_usage_reporting_disable(self):
        output = Tns.run_tns_command("usage-reporting disable")
        assert disabled.format(usage_reporting, "now ") in output
        assert "GA_TRACKING_ID" in File.read(self.config)
        assert "UA-111455-44" in File.read(self.config)

        # Check there is no any message for tracking in Google Analytics
        output = Tns.run_tns_command("doctor", timeout=180, log_trace=True)
        assert "Will send the following information to Google Analytics" not in output

        output = Tns.run_tns_command("usage-reporting status")
        assert disabled.format(usage_reporting, "") in output
    def test_002_usage_reporting_disable(self):
        output = Tns.run_tns_command("usage-reporting disable")
        assert disabled.format(usage_reporting, "now ") in output
        assert "GA_TRACKING_ID" in File.read(self.config)
        assert "UA-111455-44" in File.read(self.config)

        # Check there is no any message for tracking in Google Analytics
        output = Tns.run_tns_command("doctor", timeout=180, log_trace=True)
        assert "Will send the following information to Google Analytics" not in output

        output = Tns.run_tns_command("usage-reporting status")
        assert disabled.format(usage_reporting, "") in output
예제 #10
0
    def test_301_platform_update_ios(self):
        Tns.platform_add_ios(version="2.2.0",
                             attributes={"--path": self.app_name})
        output = File.read(self.app_name + os.sep + "package.json")
        assert "\"version\": \"2.2.0\"" in output

        Tns.platform_update("[email protected]",
                            attributes={
                                "--path": self.app_name,
                                " <  data/keys/enter_key.txt": ""
                            })
        output = File.read(self.app_name + os.sep + "package.json")
        assert "\"version\": \"2.3.0\"" in output

        Tns.build_ios(attributes={"--path": self.app_name})
예제 #11
0
    def test_100_plugin_add_sandbox_pod_can_write_in_app_folder(self):
        Tns.create_app(self.app_name)
        Tns.platform_add_ios(attributes={"--path": self.app_name,
                                         "--frameworkPath": IOS_PACKAGE})

        plugin = os.path.join(TEST_RUN_HOME, "data", "CocoaPods", "nativescript-ios-working-with-sandbox-plugin.tgz")
        output = Tns.plugin_add(plugin, attributes={"--path": self.app_name}, assert_success=False)
        assert "Successfully installed plugin nativescript-ios-working-with-sandbox-plugin." in output
        assert "nativescript-ios-working-with-sandbox-plugin" in File.read(self.app_name + "/package.json")

        output = Tns.prepare_ios(attributes={"--path": self.app_name})
        assert "Successfully prepared plugin " + \
               "nativescript-ios-working-with-sandbox-plugin for ios." in output

        assert "content" in File.read(self.app_name + "/platforms/ios/TestApp/app/I_MADE_THIS_FILE.txt")
예제 #12
0
    def create_app_ng(app_name, attributes={}, log_trace=False, assert_success=True, update_modules=True,
                      template_version=None):
        if template_version is not None:
            template = "tns-template-hello-world-ng@" + template_version
            attr = {"--template": template}
        else:
            if BRANCH is "master":
                attr = {"--template": SUT_FOLDER + os.path.sep + "tns-template-hello-world-ng.tgz"}
            else:
                attr = {"--template": "tns-template-hello-world-ng"}
        attributes.update(attr)
        output = Tns.create_app(app_name=app_name, attributes=attributes, log_trace=log_trace,
                                assert_success=assert_success,
                                update_modules=update_modules)
        if update_modules:
            Tns.update_angular(path=app_name)
            Tns.update_typescript(path=app_name)

        if assert_success:
            if USE_YARN != "True":
                if Npm.version() < 5:
                    assert "nativescript-angular" in output
                assert File.exists(os.path.join(app_name, 'node_modules', 'nativescript-theme-core'))
                package_json = File.read(os.path.join(app_name, 'package.json'))
                assert "tns-core-modules" in package_json
                assert "nativescript-angular" in package_json
                assert "nativescript-dev-typescript" in package_json

        return output
    def test_320_platform_add_ios_custom_bundle_id(self):
        # Create project with different appId
        Folder.cleanup(self.app_name)
        output = Tns.create_app(self.app_name, attributes={"--appid": "org.nativescript.MyApp"}, assert_success=False)
        TnsAsserts.created(self.app_name, output=output, full_check=False)

        output = File.read(self.app_name + os.sep + "package.json")
        assert "\"id\": \"org.nativescript.MyApp\"" in output

        # Add iOS platform
        Tns.platform_add_ios(attributes={"--path": self.app_name, "--frameworkPath": IOS_PACKAGE})

        # Verify plist file in native project (after prepare)
        Tns.prepare_ios(attributes={"--path": self.app_name})
        output = File.read(self.app_name + "/platforms/ios/TestApp/TestApp-Info.plist")
        assert "org.nativescript.MyApp" in output
예제 #14
0
 def test_390_LSApplicationQueriesSchemes_merged(self):
     # https: // github.com / NativeScript / nativescript - cli / issues / 3108
     Folder.cleanup(
         os.path.join(self.app_name, 'app', 'App_Resources', 'iOS',
                      'Info.plist'))
     info_c = os.path.join('data', 'issues', 'info-plist', 'app',
                           'Info.plist')
     info_p = os.path.join(self.app_name, 'app', 'App_Resources', 'iOS')
     Folder.copy(info_c, info_p)
     Tns.plugin_add("nativescript-geolocation",
                    attributes={"--path": self.app_name})
     Folder.cleanup(
         os.path.join(self.app_name, 'node_modules',
                      'nativescript-geolocation', 'platforms', 'ios',
                      'Info.plist'))
     info_plugin_c = os.path.join('data', 'issues', 'info-plist', 'plugin',
                                  'Info.plist')
     info_plugin_p = os.path.join(self.app_name, 'node_modules',
                                  'nativescript-geolocation', 'platforms',
                                  'ios')
     Folder.copy(info_plugin_c, info_plugin_p)
     Tns.build_ios(attributes={"--path": self.app_name})
     output = File.read(
         os.path.join(self.app_name, 'platforms', 'ios', 'TestApp',
                      'TestApp-Info.plist'))
     assert 'itms' in output
     assert "itms-apps" in output
     assert "LSApplicationQueriesSchemes" in output
예제 #15
0
    def wait_for_log(log_file, string_list, not_existing_string_list=None, timeout=45, check_interval=3,
                     clean_log=True):
        """
        Wait until log file contains list of string.
        :param log_file: Path to log file.
        :param string_list: List of strings.
        :param not_existing_string_list: List of string that should not be in logs.
        :param timeout: Timeout.
        :param check_interval: Check interval.
        :param clean_log: Specify if content of log file should be delete after check.
        """
        t_end = time.time() + timeout
        all_items_found = False
        not_found_list = []
        log = ""
        while time.time() < t_end:
            not_found_list = []
            log = File.read(log_file)
            log = str(log.decode('utf8').encode('utf8')).strip()
            for item in string_list:
                if item in log:
                    print "'{0}' found.".format(item)
                else:
                    not_found_list.append(item)
            if not_found_list == []:
                all_items_found = True
                print "Log contains: {0}".format(string_list)
                break
            else:
                print "'{0}' NOT found. Wait...".format(not_found_list)
                time.sleep(check_interval)
            if 'BUILD FAILED' in log:
                print 'BUILD FAILED. No need to wait more time!'
                break
            if 'Unable to sync files' in log:
                print 'Sync process failed. No need to wait more time!'
                break
            if '????????????????????????????' in log:
                print 'Log seems to be corrupted. No need to wait more time!'
                break
            if 'errors were thrown' in log:
                print 'Multiple errors were thrown. No need to wait more time!'
                break

        if clean_log and (CURRENT_OS is not OSType.WINDOWS) and all_items_found:
            File.write(file_path=log_file, text="")

        if all_items_found:
            if not_existing_string_list is None:
                pass
            else:
                for item in not_existing_string_list:
                    assert item not in log, "{0} found! It should not be in logs.\nLog:\n{1}".format(item, log)
        else:
            print "##### OUTPUT BEGIN #####\n"
            print log
            print "##### OUTPUT END #####\n"
            print ""
            assert False, "Output does not contain {0}".format(not_found_list)
    def test_220_build_ios_with_custom_plist(self):
        # Update Info.plist
        src_file = os.path.join(TEST_RUN_HOME, 'data', 'Info.plist')
        target_file = os.path.join(TEST_RUN_HOME, self.app_name, 'app', 'App_Resources', 'iOS', 'Info.plist')
        File.remove(target_file)
        File.copy(src=src_file, dest=target_file)

        # Prepare in debug
        final_plist = os.path.join(TEST_RUN_HOME, self.app_name, 'platforms', 'ios', 'TestApp', 'TestApp-Info.plist')
        Tns.prepare_ios(attributes={"--path": self.app_name})
        assert "<string>fbXXXXXXXXX</string>" in File.read(final_plist)
        assert "<string>orgnativescriptTestApp</string>" in File.read(final_plist)

        # Prepare in release
        Tns.prepare_ios(attributes={"--path": self.app_name, '--release': ''})
        assert "<string>fbXXXXXXXXX</string>" in File.read(final_plist)
        assert "<string>orgnativescriptTestApp</string>" not in File.read(final_plist)
예제 #17
0
 def test_201_platform_remove_ios(self):
     Tns.platform_add_ios(attributes={
         "--path": self.app_name,
         "--frameworkPath": IOS_PACKAGE
     })
     Tns.platform_remove(platform="ios",
                         attributes={"--path": self.app_name})
     assert Folder.is_empty(self.app_name + '/platforms')
     output = File.read(self.app_name + os.sep + "package.json")
     assert "tns-ios" not in output
    def test_300_build_project_with_dash_and_ios_inspector_added(self):
        """
        Verify we can build projects with dashes.
        Verify we can build android when inspector is added (test for CLI issue 2467)
        """
        Tns.create_app(self.app_name_dash)
        Tns.platform_add_android(attributes={"--path": self.app_name_dash, "--frameworkPath": ANDROID_PACKAGE})
        if USE_YARN == "True":
            Npm.install(package="tns-ios-inspector", option='--dev', folder=self.app_name_dash)
        else:
            Npm.install(package="tns-ios-inspector", option='--save-dev', folder=self.app_name_dash)
        Tns.build_android(attributes={"--path": self.app_name_dash})

        # Verify project id
        output = File.read(self.app_name_dash + "/package.json")
        assert app_identifier in output.lower()

        # Verify AndroidManifest.xml
        output = File.read(self.app_name_dash + "/" + TnsAsserts.PLATFORM_ANDROID_SRC_MAIN_PATH + "AndroidManifest.xml")
        assert app_identifier in output.lower()
예제 #19
0
    def test_202_plugin_add_xcconfig_after_platform_add_ios(self):
        Tns.platform_add_ios(attributes={"--path": self.app_name, "--frameworkPath": IOS_PACKAGE})

        plugin_path = TEST_RUN_HOME + "/data/CocoaPods/xcconfig-plugin.tgz"
        output = Tns.plugin_add(plugin_path, attributes={"--path": self.app_name}, assert_success=False)
        assert "Successfully installed plugin xcconfig-plugin." in output
        assert File.exists(self.app_name + "/node_modules/xcconfig-plugin/package.json")
        assert File.exists(self.app_name + "/node_modules/xcconfig-plugin/platforms/ios/build.xcconfig")
        assert File.exists(self.app_name + "/node_modules/xcconfig-plugin/platforms/ios/module.modulemap")
        assert File.exists(self.app_name + "/node_modules/xcconfig-plugin/platforms/ios/XcconfigPlugin.h")
        assert "xcconfig-plugin" in File.read(self.app_name + "/package.json")

        output = Tns.build_ios(attributes={"--path": self.app_name})
        assert "Successfully prepared plugin xcconfig-plugin for ios." in output

        output = File.read(self.app_name + "/platforms/ios/plugins-debug.xcconfig")
        assert "OTHER_LDFLAGS = $(inherited) -l\"sqlite3\"" in output

        output = File.read(self.app_name + "/platforms/ios/TestApp/build-debug.xcconfig")
        assert "#include \"../plugins-debug.xcconfig\"" in output
    def test_001_usage_reporting_enable(self):
        output = Tns.run_tns_command("usage-reporting enable")
        assert enabled.format(usage_reporting, "now ") in output
        assert "GA_TRACKING_ID" in File.read(self.config)
        assert "UA-111455-44" in File.read(self.config)

        # Check there is message for tracking in Google Analytics
        output = Tns.run_tns_command("doctor", timeout=180, log_trace=True)
        assert "Will send the following information to Google Analytics" in output

        output = Tns.run_tns_command("usage-reporting status")
        assert enabled.format(usage_reporting, "") in output

        # https://github.com/NativeScript/nativescript-cli/issues/3595
        output = Tns.create_app(self.app_name,
                                attributes={'--template': os.path.join('data', 'apps', 'livesync-hello-world.tgz')},
                                log_trace=True,
                                force_clean=False, update_modules=True)
        assert "label: 'data/apps/livesync-hello-world.tgz'" not in output
        assert "label: 'localTemplate_tns-template-hello-world'" in output
예제 #21
0
    def test_300_build_ios_with_dash(self):
        Tns.create_app(self.app_name_dash)
        Tns.platform_add_ios(attributes={
            "--path": self.app_name_dash,
            "--frameworkPath": IOS_PACKAGE
        })
        Tns.build_ios(attributes={"--path": self.app_name_dash})

        # Verify project id
        output = File.read(self.app_name_dash + os.sep + "package.json")
        assert app_identifier in output
    def test_002_build_android_release(self):
        Tns.build_android(attributes={"--path": self.app_name,
                                      "--keyStorePath": ANDROID_KEYSTORE_PATH,
                                      "--keyStorePassword": ANDROID_KEYSTORE_PASS,
                                      "--keyStoreAlias": ANDROID_KEYSTORE_ALIAS,
                                      "--keyStoreAliasPassword": ANDROID_KEYSTORE_ALIAS_PASS,
                                      "--release": ""
                                      }, log_trace=True)

        # Configs are respected
        assert 'release' in File.read(os.path.join(self.app_name, TnsAsserts.PLATFORM_ANDROID_APP_PATH, 'config.json'))
        assert File.exists(os.path.join(self.app_name, TnsAsserts.PLATFORM_ANDROID_APK_RELEASE_PATH, self.release_apk))
예제 #23
0
    def test_220_build_ios_with_custom_plist(self):
        # Update Info.plist
        src_file = os.path.join(TEST_RUN_HOME, 'data', 'Info.plist')
        target_file = os.path.join(TEST_RUN_HOME, self.app_name, 'app',
                                   'App_Resources', 'iOS', 'Info.plist')
        File.remove(target_file)
        File.copy(src=src_file, dest=target_file)

        # Prepare in debug
        final_plist = os.path.join(TEST_RUN_HOME, self.app_name, 'platforms',
                                   'ios', 'TestApp', 'TestApp-Info.plist')
        Tns.prepare_ios(attributes={"--path": self.app_name})
        assert "<string>fbXXXXXXXXX</string>" in File.read(final_plist)
        assert "<string>orgnativescriptTestApp</string>" in File.read(
            final_plist)

        # Prepare in release
        Tns.prepare_ios(attributes={"--path": self.app_name, '--release': ''})
        assert "<string>fbXXXXXXXXX</string>" in File.read(final_plist)
        assert "<string>orgnativescriptTestApp</string>" not in File.read(
            final_plist)
 def __verify_debugger_attach(log, app_started=True):
     strings = ["Frontend client connected", "Backend socket created", "NativeScript debugger attached"]
     Tns.wait_for_log(log_file=log, string_list=strings, timeout=90, check_interval=10, clean_log=False)
     time.sleep(10)
     output = File.read(log)
     assert "Frontend socket closed" not in output
     assert "Backend socket closed" not in output
     assert "NativeScript debugger detached" not in output
     assert Process.is_running('NativeScript Inspector')
     if app_started:
         assert "Page loaded 1 time" in output, "Page not reloaded, this is bug!"
     else:
         assert "Page loaded 1 time" not in output, "Page reloaded, this is bug!"
예제 #25
0
    def test_320_build_ios_with_custom_entitlements(self):
        Tns.build_ios(attributes={"--path": self.app_name})

        # Add entitlements in app/App_Resources/iOS/app.entitlements
        source = os.path.join(TEST_RUN_HOME, 'data', 'entitlements',
                              'app.entitlements')
        target = os.path.join(self.app_name, 'app', 'App_Resources', 'iOS',
                              'app.entitlements')
        File.copy(src=source, dest=target)

        # Build again and verify entitlements are merged
        Tns.build_ios(attributes={"--path": self.app_name})
        entitlements_path = self.app_name + '/platforms/ios/' + self.app_name + '/' + self.app_name + '.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, 'data', 'plugins',
                                   'nativescript-test-entitlements-1.0.0.tgz')
        Npm.install(package=plugin_path, option='--save', folder=self.app_name)
        Tns.build_ios(attributes={"--path": 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)
        output = Tns.build_ios(attributes={
            "--path": self.app_name,
            "--forDevice": "",
            "--release": ""
        },
                               assert_success=False)
        assert "Provisioning profile " in output
        assert "doesn't include the aps-environment and inter-app-audio entitlements" in output
예제 #26
0
    def test_320_platform_add_ios_custom_bundle_id(self):
        # Create project with different appId
        Folder.cleanup(self.app_name)
        output = Tns.create_app(
            self.app_name,
            attributes={"--appid": "org.nativescript.MyApp"},
            assert_success=False)
        TnsAsserts.created(self.app_name, output=output, full_check=False)

        output = File.read(self.app_name + os.sep + "package.json")
        assert "\"id\": \"org.nativescript.MyApp\"" in output

        # Add iOS platform
        Tns.platform_add_ios(attributes={
            "--path": self.app_name,
            "--frameworkPath": IOS_PACKAGE
        })

        # Verify plist file in native project (after prepare)
        Tns.prepare_ios(attributes={"--path": self.app_name})
        output = File.read(self.app_name +
                           "/platforms/ios/TestApp/TestApp-Info.plist")
        assert "org.nativescript.MyApp" in output
 def package_json_contains(app_name, string_list=None):
     """
     Assert package.json contains list of strings.
     :param app_name: Application name.
     :param string_list: List of strings.
     """
     package_json_path = os.path.join(app_name, 'package.json')
     output = File.read(package_json_path)
     for item in string_list:
         if item in output:
             print '{0} found in {1}.'.format(item, str(package_json_path))
         else:
             print 'package.json:'
             print output
             assert False, '{0} NOT found in {1}.'.format(item, str(package_json_path))
예제 #28
0
 def package_json_contains(app_name, string_list=None):
     """
     Assert package.json contains list of strings.
     :param app_name: Application name.
     :param string_list: List of strings.
     """
     package_json_path = os.path.join(app_name, 'package.json')
     output = File.read(package_json_path)
     for item in string_list:
         if item in output:
             print '{0} found in {1}.'.format(item, str(package_json_path))
         else:
             print 'package.json:'
             print output
             assert False, '{0} NOT found in {1}.'.format(
                 item, str(package_json_path))
예제 #29
0
    def test_400_plugin_add_sandbox_pod_can_write_outside_app_folder_by_default(self):
        Tns.create_app(self.app_name)
        Tns.platform_add_ios(attributes={"--path": self.app_name,
                                         "--frameworkPath": IOS_PACKAGE})

        plugin = os.path.join(TEST_RUN_HOME, "data", "CocoaPods", "nativescript-ios-fail-with-sandbox-plugin.tgz")
        output = Tns.plugin_add(plugin, attributes={"--path": self.app_name}, assert_success=False)
        assert "Successfully installed plugin nativescript-ios-fail-with-sandbox-plugin." in output
        assert "nativescript-ios-fail-with-sandbox-plugin" in File.read(self.app_name + "/package.json")

        output = Tns.prepare_ios(attributes={"--path": self.app_name}, assert_success=False)
        assert "Successfully prepared " + \
               "plugin nativescript-ios-fail-with-sandbox-plugin for ios." in output

        assert "sh: ../I_MADE_THIS_FILE.txt: Operation not permitted" not in output
        assert File.exists(self.app_name + "/platforms/I_MADE_THIS_FILE.txt")
예제 #30
0
    def test_401_plugin_add_sandbox_pod_can_not_write_outside_app_folder_if_use_pod_sandbox_is_true(self):
        File.replace("node_modules/nativescript/config/config.json", '"USE_POD_SANDBOX": false',
                     '"USE_POD_SANDBOX": true')
        Tns.create_app(self.app_name)
        Tns.platform_add_ios(attributes={"--path": self.app_name, "--frameworkPath": IOS_PACKAGE})

        plugin = os.path.join(TEST_RUN_HOME, "data", "CocoaPods", "nativescript-ios-fail-with-sandbox-plugin.tgz")
        output = Tns.plugin_add(plugin, attributes={"--path": self.app_name}, assert_success=False)
        assert "Successfully installed plugin nativescript-ios-fail-with-sandbox-plugin." in output
        assert "nativescript-ios-fail-with-sandbox-plugin" in File.read(self.app_name + "/package.json")

        output = Tns.prepare_ios(attributes={"--path": self.app_name}, assert_success=False)
        assert "Successfully prepared " + \
               "plugin nativescript-ios-fail-with-sandbox-plugin for ios." in output

        assert "sh: ../I_MADE_THIS_FILE.txt: Operation not permitted" in output
        assert not File.exists(self.app_name + "/platforms/I_MADE_THIS_FILE.txt")
 def test_390_LSApplicationQueriesSchemes_merged(self):
     # https: // github.com / NativeScript / nativescript - cli / issues / 3108
     Folder.cleanup(os.path.join(self.app_name, 'app', 'App_Resources', 'iOS', 'Info.plist'))
     info_c = os.path.join('data', 'issues', 'info-plist', 'app', 'Info.plist')
     info_p = os.path.join(self.app_name, 'app', 'App_Resources', 'iOS')
     Folder.copy(info_c, info_p)
     Tns.plugin_add("nativescript-geolocation", attributes={"--path": self.app_name})
     Folder.cleanup(
         os.path.join(self.app_name, 'node_modules', 'nativescript-geolocation', 'platforms', 'ios', 'Info.plist'))
     info_plugin_c = os.path.join('data', 'issues', 'info-plist', 'plugin', 'Info.plist')
     info_plugin_p = os.path.join(self.app_name, 'node_modules', 'nativescript-geolocation', 'platforms', 'ios')
     Folder.copy(info_plugin_c, info_plugin_p)
     Tns.build_ios(attributes={"--path": self.app_name})
     output = File.read(os.path.join(self.app_name, 'platforms', 'ios', 'TestApp', 'TestApp-Info.plist'))
     assert 'itms' in output
     assert "itms-apps" in output
     assert "LSApplicationQueriesSchemes" in output
예제 #32
0
    def test_002_build_android_release(self):
        Tns.build_android(attributes={
            "--path": self.app_name,
            "--keyStorePath": ANDROID_KEYSTORE_PATH,
            "--keyStorePassword": ANDROID_KEYSTORE_PASS,
            "--keyStoreAlias": ANDROID_KEYSTORE_ALIAS,
            "--keyStoreAliasPassword": ANDROID_KEYSTORE_ALIAS_PASS,
            "--release": ""
        },
                          log_trace=True)

        # Configs are respected
        assert 'release' in File.read(
            os.path.join(self.app_name, TnsAsserts.PLATFORM_ANDROID_APP_PATH,
                         'config.json'))
        assert File.exists(
            os.path.join(self.app_name,
                         TnsAsserts.PLATFORM_ANDROID_APK_RELEASE_PATH,
                         self.release_apk))
예제 #33
0
    def create_app_ng(app_name,
                      attributes={},
                      log_trace=False,
                      assert_success=True,
                      update_modules=True,
                      template_version=None):
        if template_version is not None:
            template = "tns-template-hello-world-ng@" + template_version
            attr = {"--template": template}
        else:
            if BRANCH is "master":
                attr = {
                    "--template":
                    SUT_FOLDER + os.path.sep +
                    "tns-template-hello-world-ng.tgz"
                }
            else:
                attr = {"--template": "tns-template-hello-world-ng"}
        attributes.update(attr)
        output = Tns.create_app(app_name=app_name,
                                attributes=attributes,
                                log_trace=log_trace,
                                assert_success=assert_success,
                                update_modules=update_modules)
        if update_modules:
            Tns.update_angular(path=app_name)
            Tns.update_typescript(path=app_name)

        if assert_success:
            if USE_YARN != "True":
                if Npm.version() < 5:
                    assert "nativescript-angular" in output
                assert File.exists(
                    os.path.join(app_name, 'node_modules',
                                 'nativescript-theme-core'))
                package_json = File.read(os.path.join(app_name,
                                                      'package.json'))
                assert "tns-core-modules" in package_json
                assert "nativescript-angular" in package_json
                assert "nativescript-dev-typescript" in package_json

        return output
예제 #34
0
 def __verify_debugger_attach(log, app_started=True):
     strings = [
         "Frontend client connected", "Backend socket created",
         "NativeScript debugger attached"
     ]
     Tns.wait_for_log(log_file=log,
                      string_list=strings,
                      timeout=90,
                      check_interval=10,
                      clean_log=False)
     time.sleep(10)
     output = File.read(log)
     assert "Frontend socket closed" not in output
     assert "Backend socket closed" not in output
     assert "NativeScript debugger detached" not in output
     assert Process.is_running('NativeScript Inspector')
     if app_started:
         assert "Page loaded 1 time" in output, "Page not reloaded, this is bug!"
     else:
         assert "Page loaded 1 time" not in output, "Page reloaded, this is bug!"
예제 #35
0
def run(command,
        timeout=COMMAND_TIMEOUT,
        output=True,
        wait=True,
        log_level=CommandLogLevel.FULL):
    """
    Execute command in shell.
    :param command: Command to be executed.
    :param timeout: Timeout for command execution.
    :param output:
    :param wait: Specify if method should wait until command execution complete.
    :param log_level: CommandLogLevel value (SILENT, COMMAND_ONLY, FULL).
    :return: If wait=True return output of the command, else return path to file where command writes log.
    """
    def fork_it():
        """
        This function will be emulate in a parallel thread.

        You can redirect the output to one place and the errors to another:
        # dir file.xxx > output.msg 2> output.err

        You can print the errors and standard output to a single file
        by using the "&1" command to redirect the output for STDERR to STDOUT
        and then sending the output from STDOUT to a file:
        # dir file.xxx 1> output.msg 2>&1
        """

        # execute command
        # print "Thread started"
        if output:
            os.system(command + ' 1> ' + out_file + ' 2>&1')
        else:
            os.system(command)

    # If wait=False log should be writen
    out_file = OUTPUT_FILE
    if not wait:
        time_string = "_" + datetime.now().strftime('%Y_%m_%d_%H_%M_%S')
        out_file = OUTPUT_FILE_ASYNC.replace('.', time_string + '.')
        if CURRENT_OS is OSType.WINDOWS:
            command = command + " 1> " + out_file + " 2>&1"
        elif CURRENT_OS is OSType.LINUX:
            command = command + " 1> " + out_file + " 2>&1 &"
        else:
            command = command + " &> " + out_file + " 2>&1 &"

    # remove output.txt
    try:
        File.remove(out_file)
    except OSError:
        print "Failed to delete " + out_file
        time.sleep(1)
        File.remove(out_file)

    # log command that is executed (and append to TEST_LOG file)
    if log_level is not CommandLogLevel.SILENT:
        File.append(TEST_LOG, command)
        print "##### {0} Executing command : {1}\n".format(
            time.strftime("%X"), command)

    # Hack for async commands on Windows
    if CURRENT_OS is OSType.WINDOWS:
        if not wait:
            timeout = 10

    # prepare command line
    thread = threading.Thread(target=fork_it)
    thread.start()

    # wait for thread to finish or timeout
    thread.join(timeout)

    # kill thread if it exceed the timeout
    if thread.is_alive():
        if wait:
            Process.kill_by_commandline(
                command.partition(' ')[0].rpartition(os.sep)[-1])
            thread.join()
            raise NameError('Process has timed out at ' + time.strftime("%X"))

    # get whenever exist in the pipe ?
    pipe_output = 'NOT_COLLECTED'
    if output:
        pipe_output = File.read(out_file)

    if (log_level is CommandLogLevel.FULL) and wait:
        print "##### OUTPUT BEGIN #####\n"
        print pipe_output
        print "##### OUTPUT END #####\n"

    if wait:
        return pipe_output.strip('\r\n')
    else:
        return out_file
예제 #36
0
 def test_300_platform_add_ios_custom_version(self):
     Tns.platform_add_ios(version="2.1.0",
                          attributes={"--path": self.app_name})
     output = File.read(self.app_name + os.sep + "package.json")
     assert "\"version\": \"2.1.0\"" in output
예제 #37
0
 def __get_xcode_project_file(app_name):
     app_id = Tns.__get_final_package_name(app_name, platform=Platform.IOS)
     return File.read(app_name + '/platforms/ios/' + app_id + '.xcodeproj/project.pbxproj')
예제 #38
0
    def test_001_build_android(self):
        Tns.build_android(attributes={"--path": self.app_name})
        assert File.pattern_exists(self.platforms_android, "*.aar")
        assert not File.pattern_exists(self.platforms_android, "*.plist")
        assert not File.pattern_exists(self.platforms_android, "*.android.js")
        assert not File.pattern_exists(self.platforms_android, "*.ios.js")

        # Configs are respected
        assert 'debug' in File.read(
            os.path.join(self.app_name, TnsAsserts.PLATFORM_ANDROID_APP_PATH,
                         'config.json'))

        # And new platform specific file and verify next build is ok (test for issue #2697)
        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=src, dest=dest_1)
        File.copy(src=src, dest=dest_2)

        # Verify incremental native build
        before_build = datetime.datetime.now()
        output = Tns.build_android(attributes={"--path": self.app_name})
        after_build = datetime.datetime.now()
        assert "Gradle build..." in output, "Gradle build not called."
        assert output.count(
            "Gradle build...") is 1, "Only one gradle build is triggered."
        assert (after_build - before_build).total_seconds(
        ) < 20, "Incremental build takes more then 20 sec."

        # Verify platform specific files
        assert File.pattern_exists(self.platforms_android, "*.aar")
        assert not File.pattern_exists(self.platforms_android, "*.plist")
        assert not File.pattern_exists(self.platforms_android, "*.android.js")
        assert not File.pattern_exists(self.platforms_android, "*.ios.js")

        # Verify apk does not contain aar files
        archive = ZipFile(
            os.path.join(self.app_name,
                         TnsAsserts.PLATFORM_ANDROID_APK_DEBUG_PATH,
                         self.debug_apk))
        archive.extractall(self.app_name + "/temp")
        archive.close()
        # Ceanup 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.cleanup(os.path.join(self.app_name, "temp", "META-INF"))
        assert not File.pattern_exists(self.app_name + "/temp", "*.aar")
        assert not File.pattern_exists(self.app_name + "/temp", "*.plist")
        assert not File.pattern_exists(self.app_name + "/temp", "*.android.*")
        assert not File.pattern_exists(self.app_name + "/temp", "*.ios.*")
        Folder.cleanup(self.app_name + "/temp")

        # Verify incremental native build
        before_build = datetime.datetime.now()
        output = Tns.build_android(attributes={"--path": self.app_name})
        after_build = datetime.datetime.now()
        assert "Gradle build..." in output, "Gradle build not called."
        assert output.count(
            "Gradle build...") is 1, "Only one gradle build is triggered."
        assert (after_build - before_build).total_seconds(
        ) < 20, "Incremental build takes more then 20 sec."

        # Verify clean build force native project rebuild
        before_build = datetime.datetime.now()
        output = Tns.build_android(attributes={
            "--path": self.app_name,
            "--clean": ""
        })
        after_build = datetime.datetime.now()
        build_time = (after_build - before_build).total_seconds()
        assert "Gradle clean..." in output, "Gradle clean is not called."
        assert "Gradle build..." in output, "Gradle build is not called."
        assert output.count(
            "Gradle build...") is 1, "More than 1 gradle build is triggered."
        assert build_time > 10, "Clean build takes less then 15 sec."
        assert build_time < 90, "Clean build takes more than 90 sec."
예제 #39
0
 def __get_xcode_project_file(app_name):
     app_id = Tns.__get_final_package_name(app_name, platform=Platform.IOS)
     return File.read(app_name + '/platforms/ios/' + app_id +
                      '.xcodeproj/project.pbxproj')
예제 #40
0
 def test_310_platform_add_ios_custom_experimental_version(self):
     Tns.platform_add_ios(version="0.9.2-exp-ios-8.2",
                          attributes={"--path": self.app_name})
     output = File.read(self.app_name + os.sep + "package.json")
     assert "\"version\": \"0.9.2-exp-ios-8.2\"" in output
예제 #41
0
    def wait_for_log(log_file,
                     string_list,
                     not_existing_string_list=None,
                     timeout=45,
                     check_interval=3,
                     clean_log=True):
        """
        Wait until log file contains list of string.
        :param log_file: Path to log file.
        :param string_list: List of strings.
        :param not_existing_string_list: List of string that should not be in logs.
        :param timeout: Timeout.
        :param check_interval: Check interval.
        :param clean_log: Specify if content of log file should be delete after check.
        """
        t_end = time.time() + timeout
        all_items_found = False
        not_found_list = []
        log = ""
        while time.time() < t_end:
            not_found_list = []
            log = File.read(log_file)
            log = str(log.decode('utf8').encode('utf8')).strip()
            for item in string_list:
                if item in log:
                    print "'{0}' found.".format(item)
                else:
                    not_found_list.append(item)
            if not_found_list == []:
                all_items_found = True
                print "Log contains: {0}".format(string_list)
                break
            else:
                print "'{0}' NOT found. Wait...".format(not_found_list)
                time.sleep(check_interval)
            if 'BUILD FAILED' in log:
                print 'BUILD FAILED. No need to wait more time!'
                break
            if 'Unable to sync files' in log:
                print 'Sync process failed. No need to wait more time!'
                break
            if '????????????????????????????' in log:
                print 'Log seems to be corrupted. No need to wait more time!'
                break
            if 'errors were thrown' in log:
                print 'Multiple errors were thrown. No need to wait more time!'
                break

        if clean_log and (CURRENT_OS
                          is not OSType.WINDOWS) and all_items_found:
            File.write(file_path=log_file, text="")

        if all_items_found:
            if not_existing_string_list is None:
                pass
            else:
                for item in not_existing_string_list:
                    assert item not in log, "{0} found! It should not be in logs.\nLog:\n{1}".format(
                        item, log)
        else:
            print "##### OUTPUT BEGIN #####\n"
            print log
            print "##### OUTPUT END #####\n"
            print ""
            assert False, "Output does not contain {0}".format(not_found_list)
예제 #42
0
def run(command, timeout=COMMAND_TIMEOUT, output=True, wait=True, log_level=CommandLogLevel.FULL):
    """
    Execute command in shell.
    :param command: Command to be executed.
    :param timeout: Timeout for command execution.
    :param output:
    :param wait: Specify if method should wait until command execution complete.
    :param log_level: CommandLogLevel value (SILENT, COMMAND_ONLY, FULL).
    :return: If wait=True return output of the command, else return path to file where command writes log.
    """

    def fork_it():
        """
        This function will be emulate in a parallel thread.

        You can redirect the output to one place and the errors to another:
        # dir file.xxx > output.msg 2> output.err

        You can print the errors and standard output to a single file
        by using the "&1" command to redirect the output for STDERR to STDOUT
        and then sending the output from STDOUT to a file:
        # dir file.xxx 1> output.msg 2>&1
        """

        # execute command
        # print "Thread started"
        if output:
            os.system(command + ' 1> ' + out_file + ' 2>&1')
        else:
            os.system(command)

    # If wait=False log should be writen
    out_file = OUTPUT_FILE
    if not wait:
        time_string = "_" + datetime.now().strftime('%Y_%m_%d_%H_%M_%S')
        out_file = OUTPUT_FILE_ASYNC.replace('.', time_string + '.')
        if CURRENT_OS is OSType.WINDOWS:
            command = command + " 1> " + out_file + " 2>&1"
        elif CURRENT_OS is OSType.LINUX:
            command = command + " 1> " + out_file + " 2>&1 &"
        else:
            command = command + " &> " + out_file + " 2>&1 &"

    # remove output.txt
    try:
        File.remove(out_file)
    except OSError:
        print "Failed to delete " + out_file
        time.sleep(1)
        File.remove(out_file)

    # log command that is executed (and append to TEST_LOG file)
    if log_level is not CommandLogLevel.SILENT:
        File.append(TEST_LOG, command)
        print "##### {0} Executing command : {1}\n".format(time.strftime("%X"), command)

    # Hack for async commands on Windows
    if CURRENT_OS is OSType.WINDOWS:
        if not wait:
            timeout = 10

    # prepare command line
    thread = threading.Thread(target=fork_it)
    thread.start()

    # wait for thread to finish or timeout
    thread.join(timeout)

    # kill thread if it exceed the timeout
    if thread.is_alive():
        if wait:
            Process.kill_by_commandline(command.partition(' ')[0].rpartition(os.sep)[-1])
            thread.join()
            raise NameError('Process has timed out at ' + time.strftime("%X"))

    # get whenever exist in the pipe ?
    pipe_output = 'NOT_COLLECTED'
    if output:
        pipe_output = File.read(out_file)

    if (log_level is CommandLogLevel.FULL) and wait:
        print "##### OUTPUT BEGIN #####\n"
        print pipe_output
        print "##### OUTPUT END #####\n"

    if wait:
        return pipe_output.strip('\r\n')
    else:
        return out_file
 def test_201_platform_remove_ios(self):
     Tns.platform_add_ios(attributes={"--path": self.app_name, "--frameworkPath": IOS_PACKAGE})
     Tns.platform_remove(platform="ios", attributes={"--path": self.app_name})
     assert Folder.is_empty(self.app_name + '/platforms')
     output = File.read(self.app_name + os.sep + "package.json")
     assert "tns-ios" not in output
    def test_001_build_android(self):
        Tns.build_android(attributes={"--path": self.app_name})
        assert File.pattern_exists(self.platforms_android, "*.aar")
        assert not File.pattern_exists(self.platforms_android, "*.plist")
        assert not File.pattern_exists(self.platforms_android, "*.android.js")
        assert not File.pattern_exists(self.platforms_android, "*.ios.js")

        # Configs are respected
        assert 'debug' in File.read(os.path.join(self.app_name, TnsAsserts.PLATFORM_ANDROID_APP_PATH, 'config.json'))

        # And new platform specific file and verify next build is ok (test for issue #2697)
        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=src, dest=dest_1)
        File.copy(src=src, dest=dest_2)

        # Verify incremental native build
        before_build = datetime.datetime.now()
        output = Tns.build_android(attributes={"--path": self.app_name})
        after_build = datetime.datetime.now()
        assert "Gradle build..." in output, "Gradle build not called."
        assert output.count("Gradle build...") is 1, "Only one gradle build is triggered."
        assert (after_build - before_build).total_seconds() < 20, "Incremental build takes more then 20 sec."

        # Verify platform specific files
        assert File.pattern_exists(self.platforms_android, "*.aar")
        assert not File.pattern_exists(self.platforms_android, "*.plist")
        assert not File.pattern_exists(self.platforms_android, "*.android.js")
        assert not File.pattern_exists(self.platforms_android, "*.ios.js")

        # Verify apk does not contain aar files
        archive = ZipFile(os.path.join(self.app_name, TnsAsserts.PLATFORM_ANDROID_APK_DEBUG_PATH, self.debug_apk))
        archive.extractall(self.app_name + "/temp")
        archive.close()
        # Ceanup 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.cleanup(os.path.join(self.app_name, "temp", "META-INF"))
        assert not File.pattern_exists(self.app_name + "/temp", "*.aar")
        assert not File.pattern_exists(self.app_name + "/temp", "*.plist")
        assert not File.pattern_exists(self.app_name + "/temp", "*.android.*")
        assert not File.pattern_exists(self.app_name + "/temp", "*.ios.*")
        Folder.cleanup(self.app_name + "/temp")

        # Verify incremental native build
        before_build = datetime.datetime.now()
        output = Tns.build_android(attributes={"--path": self.app_name})
        after_build = datetime.datetime.now()
        assert "Gradle build..." in output, "Gradle build not called."
        assert output.count("Gradle build...") is 1, "Only one gradle build is triggered."
        assert (after_build - before_build).total_seconds() < 20, "Incremental build takes more then 20 sec."

        # Verify clean build force native project rebuild
        before_build = datetime.datetime.now()
        output = Tns.build_android(attributes={"--path": self.app_name, "--clean": ""})
        after_build = datetime.datetime.now()
        build_time = (after_build - before_build).total_seconds()
        assert "Gradle clean..." in output, "Gradle clean is not called."
        assert "Gradle build..." in output, "Gradle build is not called."
        assert output.count("Gradle build...") is 1, "More than 1 gradle build is triggered."
        assert build_time > 10, "Clean build takes less then 15 sec."
        assert build_time < 90, "Clean build takes more than 90 sec."
 def test_310_platform_add_ios_custom_experimental_version(self):
     Tns.platform_add_ios(version="0.9.2-exp-ios-8.2", attributes={"--path": self.app_name})
     output = File.read(self.app_name + os.sep + "package.json")
     assert "\"version\": \"0.9.2-exp-ios-8.2\"" in output
 def test_300_platform_add_ios_custom_version(self):
     Tns.platform_add_ios(version="2.1.0", attributes={"--path": self.app_name})
     output = File.read(self.app_name + os.sep + "package.json")
     assert "\"version\": \"2.1.0\"" in output