def get_screen(device_id, file_path): """ Save screen of mobile device. :param device_id: Device identifier (example: `emulator-5554`). :param file_path: Path to image that will be saved. """ File.remove(file_path) base_path, file_name = os.path.split(file_path) Folder.create(base_path) device_type = Device.__get_device_type(device_id) if (device_type == DeviceType.EMULATOR) or (device_type == DeviceType.ANDROID): Adb.get_screen(device_id=device_id, file_path=file_path) if device_type == DeviceType.SIMULATOR: Simulator.get_screen(device_id=device_id, file_path=file_path) if device_type == DeviceType.IOS: IDevice.get_screen(device_id=device_id, file_path=file_path) image_saved = False if File.exists(file_path): size = os.path.getsize(file_path) if size > 10: image_saved = True return image_saved
def test_301_prepare_android_platform_specific_files(self): Tns.prepare_android(attributes={"--path": self.app_name}) # Add set of platform specific files File.copy(self.app_name + "/app/app.js", self.app_name + "/app/app.ios.js") File.copy(self.app_name + "/app/app.js", self.app_name + "/app/app.android.js") File.copy(self.app_name + "/app/app.js", self.app_name + "/app/appios.js") File.copy(self.app_name + "/app/app.js", self.app_name + "/app/appandroid.js") File.copy(self.app_name + "/app/app.js", self.app_name + "/app/ios.js") File.copy(self.app_name + "/app/app.js", self.app_name + "/app/android.js") File.copy(self.app_name + "/app/app.css", self.app_name + "/app/app.ios.css") File.copy(self.app_name + "/app/app.css", self.app_name + "/app/app.android.css") File.copy(self.app_name + "/app/app.js", self.app_name + "/app/appNew.js") File.copy(self.app_name + "/app/app.css", self.app_name + "/app/appNew.css") File.remove(self.app_name + "/app/app.js") File.remove(self.app_name + "/app/app.css") Tns.prepare_android(attributes={"--path": self.app_name}) # Verify new files are in available in platforms folder app_path = os.path.join(self.app_name, TnsAsserts.PLATFORM_ANDROID_APP_PATH) assert File.exists(os.path.join(app_path, 'app.css')) assert File.exists(os.path.join(app_path, 'app.js')) assert File.exists(os.path.join(app_path, 'appandroid.js')) assert File.exists(os.path.join(app_path, 'appios.js')) assert File.exists(os.path.join(app_path, 'android.js')) assert File.exists(os.path.join(app_path, 'ios.js')) assert not File.exists(os.path.join(app_path, 'app.ios.css')) assert not File.exists(os.path.join(app_path, 'app.android.css'))
def setUpClass(cls, class_name): print "" print "_________________________________CLASS START_______________________________________" print "Class Name: {0}".format(class_name) print "Start Time: {0}".format(time.strftime("%X")) print "" Tns.kill() Gradle.kill() Process.kill('node') Process.kill('adb') if CURRENT_OS == OSType.OSX: Process.kill('NativeScript Inspector') Process.kill('Safari') Process.kill('Xcode') if class_name is not None: logfile = os.path.join('out', class_name + '.txt') else: logfile = os.path.join(OUTPUT_FOLDER, cls.__name__ + ".txt") File.remove(logfile) sys.stdout = sys.stderr = Logger.Logger(logfile) Folder.cleanup(cls.app_name)
def setUpClass(cls, class_name): print "" print "_________________________________CLASS START_______________________________________" print "Class Name: {0}".format(class_name) print "Start Time: {0}".format(time.strftime("%X")) print "" Tns.kill() Gradle.kill() Process.kill('node') Process.kill('adb') if CURRENT_OS == OSType.OSX: Process.kill('NativeScript Inspector') Process.kill('Safari') Process.kill('Xcode') if class_name is not None: logfile = os.path.join('out', class_name + '.txt') else: logfile = os.path.join(OUTPUT_FOLDER, cls.__name__ + ".txt") File.remove(logfile) sys.stdout = sys.stderr = Logger.Logger(logfile) Folder.cleanup(cls.app_name)
def get_screen(device_id, file_path): """ Save screen of mobile device. :param device_id: Device identifier (example: `emulator-5554`). :param file_path: Path to image that will be saved. """ File.remove(file_path) base_path, file_name = os.path.split(file_path) Folder.create(base_path) device_type = Device.__get_device_type(device_id) if (device_type == DeviceType.EMULATOR) or (device_type == DeviceType.ANDROID): Adb.get_screen(device_id=device_id, file_path=file_path) if device_type == DeviceType.SIMULATOR: Simulator.get_screen(device_id=device_id, file_path=file_path) if device_type == DeviceType.IOS: IDevice.get_screen(device_id=device_id, file_path=file_path) image_saved = False if File.exists(file_path): size = os.path.getsize(file_path) if size > 10: image_saved = True return image_saved
def tearDownClass(cls): Folder.cleanup("TestApp.app") File.remove("TestApp.ipa") Folder.cleanup(cls.app_name) Folder.cleanup(cls.app_name_no_platform) Folder.cleanup(cls.app_name_dash) Folder.cleanup(cls.app_name_space)
def test_210_tns_run_android_add_remove_files_and_folders(self): """ New files and folders should be synced properly. """ log = Tns.run_android(attributes={'--path': self.app_name, '--device': self.DEVICE_ID}, wait=False, assert_success=False) strings = ['Successfully synced application', self.DEVICE_ID] Tns.wait_for_log(log_file=log, string_list=strings, timeout=120, check_interval=10) # Add new files new_file_name = 'main-page2.xml' source_file = os.path.join(self.app_name, 'app', 'main-page.xml') destination_file = os.path.join(self.app_name, 'app', new_file_name) File.copy(source_file, destination_file) strings = ['Successfully transferred main-page2.xml', 'Successfully synced application', self.DEVICE_ID] Tns.wait_for_log(log_file=log, string_list=strings) # Verify new file is synced and available on device. error_message = 'Newly created file {0} not found on {1}'.format(new_file_name, self.DEVICE_ID) app_id = Tns.get_app_id(app_name=self.app_name) path = 'app/{0}'.format(new_file_name) assert Adb.path_exists(device_id=self.DEVICE_ID, package_id=app_id, path=path), error_message # Revert changes(rename file and delete file) File.copy(destination_file, source_file) File.remove(destination_file) strings = ['Successfully transferred main-page.xml', 'Successfully synced application', self.DEVICE_ID] Tns.wait_for_log(log_file=log, string_list=strings) # Verify new file is synced and available on device. error_message = '{0} was deleted, but still available on {1}'.format(new_file_name, self.DEVICE_ID) assert Adb.path_does_not_exist(device_id=self.DEVICE_ID, package_id=app_id, path=path), error_message # Add folder new_folder_name = 'feature2' source_file = os.path.join(self.app_name, 'app', 'feature1') destination_file = os.path.join(self.app_name, 'app', new_folder_name) Folder.copy(source_file, destination_file) strings = ['Successfully transferred', 'Successfully transferred', 'feature1.js', self.DEVICE_ID] Tns.wait_for_log(log_file=log, string_list=strings) # Verify new folder is synced and available on device. error_message = 'Newly created folder {0} not found on {1}'.format(new_folder_name, self.DEVICE_ID) path = 'app/{0}'.format(new_folder_name) assert Adb.path_exists(device_id=self.DEVICE_ID, package_id=app_id, path=path, timeout=20), error_message path = 'app/{0}/{1}'.format(new_folder_name, 'feature1.js') assert Adb.path_exists(device_id=self.DEVICE_ID, package_id=app_id, path=path, timeout=20), error_message # Delete folder Folder.cleanup(destination_file) strings = ['Successfully synced application', self.DEVICE_ID] Tns.wait_for_log(log_file=log, string_list=strings) # Verify new folder is deleted from device. error_message = 'Deleted folder {0} is still available on {1}'.format(new_folder_name, self.DEVICE_ID) assert Adb.path_does_not_exist(device_id=self.DEVICE_ID, package_id=app_id, path=path), error_message
def pack(folder, output_file): try: Folder.navigate_to(folder) run('npm pack', log_level=CommandLogLevel.SILENT) src_file = File.find_by_extension('tgz')[0] File.copy(src=src_file, dest=output_file) File.remove(src_file) except: print 'Failed to pack {0}'.format(folder) Folder.navigate_to(TEST_RUN_HOME, relative_from_current_folder=False)
def pack(folder, output_file): try: Folder.navigate_to(folder) run('npm pack', log_level=CommandLogLevel.SILENT) src_file = File.find_by_extension('tgz')[0] File.copy(src=src_file, dest=output_file) File.remove(src_file) except: print 'Failed to pack {0}'.format(folder) Folder.navigate_to(TEST_RUN_HOME, relative_from_current_folder=False)
def test_321_build_with_copy_to_option(self): # TODO: Remove those lines after https://github.com/NativeScript/nativescript-cli/issues/2547 is fixed. # This is required when build with different SDK Folder.cleanup(self.app_name) Tns.create_app(self.app_name) Tns.platform_add_android(attributes={"--path": self.app_name, "--frameworkPath": ANDROID_PACKAGE}) File.remove(self.debug_apk) Tns.build_android(attributes={"--path": self.app_name, "--copy-to": "./"}) assert File.exists(self.debug_apk) File.remove(self.debug_apk)
def test_004_android_run_hmr_delete_file(self): log = Tns.run_android(attributes={'--path': self.app_name, '--device': EMULATOR_ID, '--hmr': ''}, wait=False, assert_success=False) Tns.wait_for_log(log_file=log, string_list=HelpersHMR.wp_run, not_existing_string_list=HelpersHMR.wp_errors, timeout=240) HelpersHMR.android_screen_match(image=self.image_original, timeout=120) File.remove(self.app_name + 'app', 'main-view-model.js') self.apply_changes(app_name=self.app_name, log=log, platform=Platform.ANDROID) self.revert_changes(app_name=self.app_name, log=log, platform=Platform.ANDROID)
def test_009_android_run_hmr_delete_file(self): log = Tns.run_android(attributes={'--path': self.app_name, '--device': EMULATOR_ID, '--hmr': ''}, wait=False, assert_success=False) Tns.wait_for_log(log_file=log, string_list=HelpersHMR.wp_run, not_existing_string_list=HelpersHMR.wp_errors, timeout=240) HelpersHMR.android_screen_match(image=self.image_original, timeout=120) File.remove(self.app_name + 'app', 'main-view-model.js') self.apply_changes(app_name=self.app_name, log=log, platform=Platform.ANDROID) self.revert_changes(app_name=self.app_name, log=log, platform=Platform.ANDROID)
def setUpClass(cls): BaseClass.setUpClass(cls.__name__) Tns.create_app(cls.app_name) Tns.platform_add_ios(attributes={ "--path": cls.app_name, "--frameworkPath": IOS_PACKAGE }) Folder.cleanup("TestApp.app") File.remove("TestApp.ipa") Xcode.cleanup_cache()
def get_screen_text(device_id): """ Get text of current screen on mobile device. :param device_id: Device identifier (example: `emulator-5554`). :return: All the text visible on screen as string """ img_name = "actual_{0}_{1}.png".format(device_id, time.time()) actual_image_path = os.path.join(OUTPUT_FOLDER, "images", device_id, img_name) if File.exists(actual_image_path): File.remove(actual_image_path) Device.get_screen(device_id=device_id, file_path=actual_image_path) image = Image.open(actual_image_path).convert('LA') text = pytesseract.image_to_string(image) return text
def get_screen(device_id, file_path): """ Save screen of mobile device. :param device_id: Device identifier (example: `emulator-5554`). :param file_path: Name of image that will be saved. """ base_path, file_name = os.path.split(file_path) file_name = file_name.rsplit('.', 1)[0] run(command="idevicescreenshot -u {0} {1}.tiff".format(device_id, file_name), log_level=CommandLogLevel.SILENT) run(command="sips -s format png {0}.tiff --out {1}".format(file_name, file_path), log_level=CommandLogLevel.SILENT) File.remove("{0}.tiff".format(file_name))
def get_screen_text(): """ Get text of current screen of host machine. :return: All the text visible on screen as string """ base_path = os.path.join(OUTPUT_FOLDER, "images", "host") if not File.exists(base_path): Folder.create(base_path) actual_image_path = os.path.join(base_path, "host_{0}.png".format(time.time())) if File.exists(actual_image_path): File.remove(actual_image_path) Screen.save_screen(path=actual_image_path) image = Image.open(actual_image_path) text = pytesseract.image_to_string(image.convert('L')) return text
def get_screen_text(device_id): """ Get text of current screen on mobile device. :param device_id: Device identifier (example: `emulator-5554`). :return: All the text visible on screen as string """ img_name = "actual_{0}_{1}.png".format(device_id, time.time()) actual_image_path = os.path.join(OUTPUT_FOLDER, "images", device_id, img_name) if File.exists(actual_image_path): File.remove(actual_image_path) Device.get_screen(device_id=device_id, file_path=actual_image_path) image = Image.open(actual_image_path).convert('LA') text = pytesseract.image_to_string(image) return text
def get_screen_text(): """ Get text of current screen of host machine. :return: All the text visible on screen as string """ base_path = os.path.join(OUTPUT_FOLDER, "images", "host") if not File.exists(base_path): Folder.create(base_path) actual_image_path = os.path.join(base_path, "host_{0}.png".format(time.time())) if File.exists(actual_image_path): File.remove(actual_image_path) Screen.save_screen(path=actual_image_path) image = Image.open(actual_image_path) text = pytesseract.image_to_string(image.convert('L')) return text
def setUpClass(cls): BaseClass.setUpClass(cls.__name__) Folder.cleanup(cls.app_no_platform) File.remove(cls.debug_apk) File.remove(cls.release_apk) Folder.cleanup('temp') Tns.create_app(cls.app_name) Tns.platform_add_android(attributes={"--path": cls.app_name, "--frameworkPath": ANDROID_PACKAGE}) # Add release and debug configs debug = os.path.join(cls.app_name, 'app', 'config.debug.json') release = os.path.join(cls.app_name, 'app', 'config.release.json') File.write(file_path=debug, text='{"config":"debug"}') File.write(file_path=release, text='{"config":"release"}')
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 test_321_build_with_copy_to_option(self): # TODO: Remove those lines after https://github.com/NativeScript/nativescript-cli/issues/2547 is fixed. # This is required when build with different SDK Folder.cleanup(self.app_name) Tns.create_app(self.app_name) Tns.platform_add_android(attributes={ "--path": self.app_name, "--frameworkPath": ANDROID_PACKAGE }) File.remove(self.debug_apk) Tns.build_android(attributes={ "--path": self.app_name, "--copy-to": "./" }) assert File.exists(self.debug_apk) File.remove(self.debug_apk)
def setUpClass(cls): BaseClass.setUpClass(cls.__name__) Folder.cleanup(cls.app_no_platform) File.remove(cls.debug_apk) File.remove(cls.release_apk) Folder.cleanup('temp') Tns.create_app(cls.app_name) Tns.platform_add_android(attributes={ "--path": cls.app_name, "--frameworkPath": ANDROID_PACKAGE }) # Add release and debug configs debug = os.path.join(cls.app_name, 'app', 'config.debug.json') release = os.path.join(cls.app_name, 'app', 'config.release.json') File.write(file_path=debug, text='{"config":"debug"}') File.write(file_path=release, text='{"config":"release"}')
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 test_310_build_ios_with_copy_to(self): Folder.cleanup("TestApp.app") File.remove("TestApp.ipa") # Tns.platform_add_ios(attributes={"--path": self.app_name, "--frameworkPath": IOS_RUNTIME_PATH}) Tns.build_ios(attributes={ "--path": self.app_name, "--copy-to": "./" }, log_trace=True) assert File.exists("TestApp.app") Tns.build_ios(attributes={ "--path": self.app_name, "--forDevice": "", "--release": "", "--copy-to": "./" }, log_trace=True) assert File.exists("TestApp.ipa")
def test_300_prepare_android_remove_old_files(self): Tns.prepare_android(attributes={"--path": self.app_name}) # Add new files and delete old files time.sleep(1) File.copy(self.app_name + "/app/app.js", self.app_name + "/app/app-new.js") File.copy(self.app_name + "/app/app.css", self.app_name + "/app/app-new.css") File.copy(self.app_name + "/app/main-page.xml", self.app_name + "/app/main-page-new.xml") File.remove(self.app_name + "/app/app.js") File.remove(self.app_name + "/app/app.css") File.remove(self.app_name + "/app/main-page.xml") Tns.prepare_android(attributes={"--path": self.app_name}) # Verify new files are in available in platforms folder app_path = os.path.join(self.app_name, TnsAsserts.PLATFORM_ANDROID_APP_PATH) assert File.exists(os.path.join(app_path, 'app-new.js')) assert File.exists(os.path.join(app_path, 'app-new.css')) assert File.exists(os.path.join(app_path, 'main-page-new.xml')) # Verify old files are removed from folder assert not File.exists(os.path.join(app_path, 'app.js')) assert not File.exists(os.path.join(app_path, 'app.css')) assert not File.exists(os.path.join(app_path, 'main-page.xml'))
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 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 tearDownClass(cls): File.remove(cls.debug_apk) File.remove(cls.release_apk) Folder.cleanup('temp') pass
def test_001_redirect_strerr_output_to_file(self): File.remove('./stderr.txt') output = Tns.run_tns_command("run invalidEntry", attributes={" 2> stderr.txt ": ""}) assert "The input is not valid sub-command for 'run' command" in output
def tearDownClass(cls): File.remove(cls.debug_apk) File.remove(cls.release_apk) Folder.cleanup('temp') pass
def test_001_redirect_strerr_output_to_file(self): File.remove('./stderr.txt') output = Tns.run_tns_command("run invalidEntry", attributes={" 2> stderr.txt ": ""}) assert "The input is not valid sub-command for 'run' command" in output
def test_100_build_xcode10_without_build_xcconfig(self): #https://github.com/NativeScript/nativescript-cli/issues/3912 file = os.path.join(self.app_name, 'app', 'App_Resources', 'iOS', 'build.xcconfig') File.remove(file) Tns.build_ios(attributes={"--path": self.app_name}, log_trace=True)