def set_up_device(opt): if not opt.wifi_ssid or not opt.wifi_key or not opt.wifi_pass: raise ValueError('Missing --wifi options') mc = Marionette('localhost', opt.adb_port) for i in range(2): try: mc.start_session() break except socket.error: sh('adb forward tcp:%s tcp:%s' % (opt.adb_port, opt.adb_port)) if opt.shell: from pdb import set_trace set_trace() return # watch out! This is how gaiatest does it. mc.__class__ = type('Marionette', (Marionette, MarionetteTouchMixin), {}) device = GaiaDevice(mc) device.restart_b2g() apps = GaiaApps(mc) data_layer = GaiaData(mc) lockscreen = LockScreen(mc) mc.setup_touch() lockscreen.unlock() apps.kill_all() data_layer.enable_wifi() if opt.wifi_key == 'WPA-PSK': pass_key = 'psk' elif opt.wifi_key == 'WEP': pass_key = 'wep' else: assert 0, 'unknown key management' data = {'ssid': opt.wifi_ssid, 'keyManagement': opt.wifi_key, pass_key: opt.wifi_pass} data_layer.connect_to_wifi(data) mc.switch_to_frame() all_apps = set(a['manifest']['name'] for a in get_installed(apps)) if 'Marketplace Dev' not in all_apps: mc.execute_script( 'navigator.mozApps.install' '("https://marketplace-dev.allizom.org/manifest.webapp");') wait_for_element_displayed(mc, 'id', 'app-install-install-button') yes = mc.find_element('id', 'app-install-install-button') mc.tap(yes) wait_for_element_displayed(mc, 'id', 'system-banner') print 'Pushing payment prefs' sh('adb shell stop b2g') sh('adb push "%s" /data/local/user.js' % ( os.path.join(os.path.dirname(__file__), 'payment-prefs.js'))) sh('adb shell start b2g') print 'When your device reboots, Marketplace Dev will be installed'
def _StartProcess(self): if not self.isEmulatorInitialized: print("Starting Emulator ...") self.emulatorProcess = subprocess.Popen( [self.emulatorStartScript], cwd=os.path.dirname(self.emulatorStartScript), shell=True) # adb shell setprop net.dns1 10.0.2.3 self._isBootFinished() self.monitoringProcessId = self.adb.getPID( self.monitoredProcessName) print("Forwarding TCP port %d ..." % self.forwardedPortADB) self.adb.command([ "forward", "tcp:%d" % self.forwardedPortADB, "tcp:%d" % self.forwardedPortADB ]) self.isEmulatorInitialized = True time.sleep(20) if self.crashSuccess: print("Restarting %s ..." % self.monitoredProcessName) self.adb.killProcess(self.monitoredProcessName, True) time.sleep(40) self.monitoringProcessId = self.adb.getPID( self.monitoredProcessName) self.crashSuccess = False self.debugLogData = str() self.adb.checkCmd(["logcat", "-c"]) print("Starting Marionette session ...") marionette = Marionette('localhost', self.forwardedPortADB) print(marionette.status()) marionette.start_session() marionette.set_script_timeout(self.scriptTimeout) marionette.switch_to_frame() lock = gaia.LockScreen(marionette) lock.unlock() apps = gaia.GaiaApps(marionette) print(apps.runningApps()) print("Launching Browser application") apps.launch(self.appName, switch_to_frame=True) print("Navigating to %s ..." % self.publisherURL) marionette.execute_script( "return window.wrappedJSObject.Browser.navigate('%s')" % self.publisherURL) self.isMonitorInitialized = True
def launch_app(app_name, adb_path="adb", script_timeout=5000, marionette=None, device_serial=None): """ Launches the given app NOTE: if a marionette session is passed, this function switches to the top-most frame. """ dm = mozdevice.DeviceManagerADB(adbPath=adb_path, deviceSerial=device_serial) installed_app_name = app_name.lower() installed_app_name = installed_app_name.replace(" ", "-") dm.forward("tcp:2828", "tcp:2828") if not marionette: m = Marionette() m.start_session() else: m = marionette m.switch_to_frame() launch_app = """ var launchWithName = function(name) { let apps = window.wrappedJSObject.applications || window.wrappedJSObject.Applications; let installedApps = apps.installedApps; for (let manifestURL in installedApps) { let app = installedApps[manifestURL]; let origin = null; let entryPoints = app.manifest.entry_points; if (entryPoints) { for (let ep in entryPoints) { let currentEntryPoint = entryPoints[ep]; let appName = currentEntryPoint.name; if (name == appName.toLowerCase()) { app.launch(); return true; } } } else { let appName = app.manifest.name; if (name == appName.toLowerCase()) { app.launch(); return true; } } } return false; }; return launchWithName("%s"); """ m.set_script_timeout(script_timeout) m.execute_script(launch_app % app_name.lower()) if not marionette: m.delete_session()
def uninstall_app(app_name, adb_path="adb", script_timeout=5000, marionette=None): """ Uninstalls the given app. NOTE: if a marionette session is passed, this function switches to the top-most frame. """ dm = mozdevice.DeviceManagerADB(adbPath=adb_path) installed_app_name = app_name.lower() installed_app_name = installed_app_name.replace(" ", "-") if dm.forward("tcp:2828", "tcp:2828") != 0: raise Exception("Can't use localhost:2828 for port forwarding." \ "Is something else using port 2828?") if not marionette: m = Marionette() m.start_session() else: m = marionette m.switch_to_frame() uninstall_app = """ var uninstallWithName = function(name) { let apps = window.wrappedJSObject.applications || window.wrappedJSObject.Applications; let installedApps = apps.installedApps; for (let manifestURL in installedApps) { let app = installedApps[manifestURL]; let origin = null; let entryPoints = app.manifest.entry_points; if (entryPoints) { for (let ep in entryPoints) { let currentEntryPoint = entryPoints[ep]; let appName = currentEntryPoint.name; if (name == appName.toLowerCase()) { window.wrappedJSObject.navigator.mozApps.mgmt.uninstall(app); return true; } } } else { let appName = app.manifest.name; if (name == appName.toLowerCase()) { window.wrappedJSObject.navigator.mozApps.mgmt.uninstall(app); return true; } } } return false; }; return uninstallWithName("%s"); """ m.set_script_timeout(script_timeout) m.execute_script(uninstall_app % app_name.lower()) if not marionette: m.delete_session()
def launch_app(app_name, adb_path="adb", script_timeout=5000, marionette=None, device_serial=None): """ Launches the given app NOTE: if a marionette session is passed, this function switches to the top-most frame. """ dm = mozdevice.DeviceManagerADB(adbPath=adb_path,deviceSerial=device_serial) installed_app_name = app_name.lower() installed_app_name = installed_app_name.replace(" ", "-") dm.forward("tcp:2828", "tcp:2828") if not marionette: m = Marionette() m.start_session() else: m = marionette m.switch_to_frame() launch_app = """ var launchWithName = function(name) { let apps = window.wrappedJSObject.applications || window.wrappedJSObject.Applications; let installedApps = apps.installedApps; for (let manifestURL in installedApps) { let app = installedApps[manifestURL]; let origin = null; let entryPoints = app.manifest.entry_points; if (entryPoints) { for (let ep in entryPoints) { let currentEntryPoint = entryPoints[ep]; let appName = currentEntryPoint.name; if (name == appName.toLowerCase()) { app.launch(); return true; } } } else { let appName = app.manifest.name; if (name == appName.toLowerCase()) { app.launch(); return true; } } } return false; }; return launchWithName("%s"); """ m.set_script_timeout(script_timeout) m.execute_script(launch_app % app_name.lower()) if not marionette: m.delete_session()
def _StartProcess(self): if not self.isDeviceInitialized: print("Starting ...") self.monitoringProcessId = self.adb.getPID( self.monitoredProcessName) print("Forwarding TCP port %d ..." % self.forwardedPortADB) self.adb.command([ "forward", "tcp:%d" % self.forwardedPortADB, "tcp:%d" % self.forwardedPortADB ]) self.isDeviceInitialized = True print("Sleeping ...") time.sleep(20) if self.crashSuccess: print("Restarting %s" % self.monitoredProcessName) self.adb.killProcess(self.monitoredProcessName, True) time.sleep(40) self.monitoringProcessId = self.adb.getPID( self.monitoredProcessName) self.crashSuccess = False self.debugLogData = str() self.adb.checkCmd(["logcat", "-c"]) print("Starting Marionette session") marionette = Marionette('localhost', self.forwardedPortADB) print(marionette.status()) marionette.start_session() marionette.set_script_timeout(self.scriptTimeout) marionette.switch_to_frame() lock = gaia.LockScreen(marionette) assert (lock.unlock()) apps = gaia.GaiaApps(marionette) print(apps.runningApps()) print("Launching Browser application") apps.launch(self.appName, switch_to_frame=True) print("Navigating to %s ..." % self.publisherURL) marionette.execute_script( "return window.wrappedJSObject.Browser.navigate('%s')" % self.publisherURL) self.isMonitorInitialized = True
def _StartProcess(self): if not self.isEmulatorInitialized: print("Starting Emulator ...") self.emulatorProcess = subprocess.Popen( [self.emulatorStartScript], cwd=os.path.dirname(self.emulatorStartScript), shell=True) # adb shell setprop net.dns1 10.0.2.3 self._isBootFinished() self.monitoringProcessId = self.adb.getPID(self.monitoredProcessName) print("Forwarding TCP port %d ..." % self.forwardedPortADB) self.adb.command(["forward", "tcp:%d" % self.forwardedPortADB, "tcp:%d" % self.forwardedPortADB]) self.isEmulatorInitialized = True time.sleep(20) if self.crashSuccess: print("Restarting %s ..." % self.monitoredProcessName) self.adb.killProcess(self.monitoredProcessName, True) time.sleep(40) self.monitoringProcessId = self.adb.getPID(self.monitoredProcessName) self.crashSuccess = False self.debugLogData = str() self.adb.checkCmd(["logcat", "-c"]) print("Starting Marionette session ...") marionette = Marionette('localhost', self.forwardedPortADB) print(marionette.status()) marionette.start_session() marionette.set_script_timeout(self.scriptTimeout) marionette.switch_to_frame() lock = gaia.LockScreen(marionette) lock.unlock() apps = gaia.GaiaApps(marionette) print(apps.runningApps()) print("Launching Browser application") apps.launch(self.appName, switch_to_frame=True) print("Navigating to %s ..." % self.publisherURL) marionette.execute_script("return window.wrappedJSObject.Browser.navigate('%s')" % self.publisherURL) self.isMonitorInitialized = True
def install_app(app_name, app_path, adb_path="adb", script_timeout=5000, marionette=None, device_serial=None): """ This installs the given application. NOTE: if a marionette session is passed, this function switches to 'content' context and will be at the top-most frame. """ if is_installed(app_name, adb_path=adb_path, device_serial=device_serial): raise Exception("%s is already installed" % app_name) sys.exit(1) app_zip = os.path.basename(app_path) dm = mozdevice.DeviceManagerADB(adbPath=adb_path, deviceSerial=device_serial) dm.pushFile("%s" % app_path, "/data/local/%s" % app_zip) # forward the marionette port dm.forward("tcp:2828", "tcp:2828") # install the app install_js = pkg_resources.resource_filename( __name__, os.path.sep.join(['app_install.js'])) with open(install_js, "r") as f: script = f.read() installed_app_name = app_name.lower().replace(" ", "-") script = script.replace("YOURAPPID", installed_app_name) script = script.replace("YOURAPPZIP", app_zip) if not marionette: m = Marionette() m.start_session() else: m = marionette m.switch_to_frame() m.set_context("chrome") m.set_script_timeout(script_timeout) m.execute_async_script(script) if not marionette: m.delete_session() else: m.set_context("content")
def install_app(app_name, app_path, adb_path="adb", script_timeout=5000, marionette=None): """ This installs the given application. NOTE: if a marionette session is passed, this function switches to 'content' context and will be at the top-most frame. """ if is_installed(app_name, adb_path=adb_path): raise Exception("%s is already installed" % app_name) sys.exit(1) app_zip = os.path.basename(app_path) dm = mozdevice.DeviceManagerADB(adbPath=adb_path) dm.pushFile("%s" % app_path, "/data/local/%s" % app_zip) # forward the marionette port if dm.forward("tcp:2828", "tcp:2828") != 0: raise Exception("Can't use localhost:2828 for port forwarding." \ "Is something else using port 2828?") # install the app install_js = pkg_resources.resource_filename(__name__, os.path.sep.join([ 'app_install.js'])) with open(install_js, "r") as f: script = f.read() installed_app_name = app_name.lower().replace(" ", "-") script = script.replace("YOURAPPID", installed_app_name) script = script.replace("YOURAPPZIP", app_zip) if not marionette: m = Marionette() m.start_session() else: m = marionette m.switch_to_frame() m.set_context("chrome") m.set_script_timeout(script_timeout) m.execute_async_script(script) if not marionette: m.delete_session() else: m.set_context("content")
class current_frame(): def main(self, p_snippet, p_frame_array=False): # # p_el is an array for the element. # p_frame_array is a list of iframes to iterate through (optional). # self.marionette = Marionette(host='localhost', port=2828) self.marionette.start_session() self.marionette.set_search_timeout(1000) self.actions = Actions(self.marionette) # # Switch to the correct iframe (unless it's "()"). # self.marionette.switch_to_frame() first_iframe = True for x in p_frame_array: # (just to make it look nice ;) typ_str = "'" + x[0] + "'" if first_iframe: first_iframe = False print "" print "Switching to iframe with " + typ_str.rjust(10) + " = '" + x[1] + "'" else: print "... then to iframe with " + typ_str.rjust(10) + " = '" + x[1] + "'" my_iframe = self.marionette.find_element("xpath", "//iframe[@" + x[0] + "='" + x[1] + "']") self.marionette.switch_to_frame(my_iframe) if first_iframe: print "" print "Using 'top level' iframe () ..." # Run the code snippet. print "" print "Running code snippet from this location ..." print "" execfile(p_snippet)
def _StartProcess(self): if not self.isDeviceInitialized: print("Starting ...") self.monitoringProcessId = self.adb.getPID(self.monitoredProcessName) print("Forwarding TCP port %d ..." % self.forwardedPortADB) self.adb.command(["forward", "tcp:%d" % self.forwardedPortADB, "tcp:%d" % self.forwardedPortADB]) self.isDeviceInitialized = True print("Sleeping ...") time.sleep(20) if self.crashSuccess: print("Restarting %s" % self.monitoredProcessName) self.adb.killProcess(self.monitoredProcessName, True) time.sleep(40) self.monitoringProcessId = self.adb.getPID(self.monitoredProcessName) self.crashSuccess = False self.debugLogData = str() self.adb.checkCmd(["logcat", "-c"]) print("Starting Marionette session") marionette = Marionette('localhost', self.forwardedPortADB) print(marionette.status()) marionette.start_session() marionette.set_script_timeout(self.scriptTimeout) marionette.switch_to_frame() lock = gaia.LockScreen(marionette) assert(lock.unlock()) apps = gaia.GaiaApps(marionette) print(apps.runningApps()) print("Launching Browser application") apps.launch(self.appName, switch_to_frame=True) print("Navigating to %s ..." % self.publisherURL) marionette.execute_script("return window.wrappedJSObject.Browser.navigate('%s')" % self.publisherURL) self.isMonitorInitialized = True
class B2gExecutor(Executor): def __init__(self, app_name, app_id, device=False): self.device = device if self.device: call(['adb', 'forward', 'tcp:2828', 'tcp:2828']) self._app_name = app_name self._app_id = app_id self._marionette = Marionette() self._marionette.start_session() self._gaia_apps = GaiaApps(self._marionette) self._gaia_data = GaiaData(self._marionette) self._gaia_device = GaiaDevice(self._marionette) ''' Deprecated # https://github.com/mozilla-b2g/gaia/blob/b568b7ae8adb6ee3651bd75acbaaedff86a08912/tests/python/gaia-ui-tests/gaiatest/gaia_test.py js = os.path.abspath(os.path.join(__file__, os.path.pardir, 'atoms', "gaia_apps.js")) self._marionette.import_script(js) js = os.path.abspath(os.path.join(__file__, os.path.pardir, 'atoms', "gaia_data_layer.js")) self._marionette.set_context(self._marionette.CONTEXT_CHROME) self._marionette.import_script(js) self._marionette.set_context(self._marionette.CONTEXT_CONTENT) # C:\Users\Jun-Wei\Desktop\b2g\battery\manifest.webapp #app = GaiaApps(self._marionette).launch(self._app_name) #app = GaiaApps(self._marionette).launch('Battery', manifest_url='C:/Users/Jun-Wei/Desktop/b2g/battery/manifest.webapp', entry_point='/index.html') app = GaiaApps(self._marionette).launch('Battery') print app.frame print app.src print app.origin print app.name #print g_app.manifest_url #self._app_frame = g_app.frame self._app_frame_id = app.frame self._app_src = app.src self._app_origin = app.origin #self.app_manifest_url = g_app.manifest_url #self.gaia_apps = GaiaApps(self.__marionette) #print self.gaia_apps.displayed_app.name #print self.gaia_apps.installed_apps #print self.gaia_apps.running_apps() #js = os.path.abspath(os.path.join(__file__, os.path.pardir, 'atoms', "gaia_apps.js")) #self.__marionette.import_script(js) ''' def fire_event(self, clickable): logger.info('fire_event: id: %s (xpath: %s)', clickable.get_id(), clickable.get_xpath()) try: # id staring with DomAnalyzer.serial_prefix is given by our monkey and should be ignored when locating if clickable.get_id() and not clickable.get_id().startswith(DomAnalyzer.serial_prefix): self._marionette.find_element('id', clickable.get_id()).tap() elif clickable.get_xpath(): self._marionette.find_element('xpath', clickable.get_xpath()).tap() else: logger.error('No id nor xpath for the clickable: id: %s (xpath: %s)', clickable.get_id(), clickable.get_xpath()) sys.exit() except (ElementNotVisibleException, InvalidElementStateException, NoSuchElementException): logger.info('Element is not interactable in fire_event(): id: %s (xpath: %s)', clickable.get_id(), clickable.get_xpath()) except Exception as e: logger.error('Unknown Exception: %s in fire_event(): id: %s (xpath: %s)', str(e), clickable.get_id(), clickable.get_xpath()) sys.exit() def fill_form(self, clickable): for f in clickable.get_forms(): for input_field in f.get_inputs(): try: if input_field.get_id() and not input_field.get_id().startswith(DomAnalyzer.serial_prefix): self._marionette.find_element('id', input_field.get_id()).send_keys(input_field.get_value()) elif input_field.get_xpath(): self._marionette.find_element('xpath', input_field.get_xpath()).send_keys(input_field.get_value()) else: logger.error('No id nor xpath for an input field in the form id: %s (xpath: %s)', f.get_id(), f.get_xpath()) sys.exit() except (ElementNotVisibleException, InvalidElementStateException, NoSuchElementException): logger.info('Element is not interactable in fill_form(): id: %s (xpath: %s)', f.get_id(), f.get_xpath()) except Exception as e: logger.error('Unknown Exception: %s in fill_form(): id: %s (xpath: %s)', str(e), f.get_id(), f.get_xpath()) sys.exit() def empty_form(self, clickable): for f in clickable.get_forms(): for input_field in f.get_inputs(): try: if input_field.get_id() and not input_field.get_id().startswith(DomAnalyzer.serial_prefix): self._marionette.find_element('id', input_field.get_id()).clear() elif input_field.get_xpath(): self._marionette.find_element('xpath', input_field.get_xpath()).clear() else: logger.error('No id nor xpath for an input field in the form %s (%s)', f.get_id(), f.get_xpath()) sys.exit() except (ElementNotVisibleException, InvalidElementStateException, NoSuchElementException): logger.info('Element is not interactable in empty_form(): id: %s (xpath: %s)', f.get_id(), f.get_xpath()) except Exception as e: logger.error('Unknown Exception: %s in empty_form(): id: %s (xpath: %s)', str(e), f.get_id(), f.get_xpath()) sys.exit() def get_source(self): return self._marionette.page_source.encode(sys.stdout.encoding, 'ignore') def get_screenshot(self, clickable=None): element = None if clickable: try: if clickable.get_id() and not clickable.get_id().startswith(DomAnalyzer.serial_prefix): element = self._marionette.find_element('id', clickable.get_id()) elif clickable.get_xpath(): element = self._marionette.find_element('xpath', clickable.get_xpath()) else: logger.error('No id nor xpath for the clickable: id: %s (xpath: %s)', clickable.get_id(), clickable.get_xpath()) sys.exit() except (ElementNotVisibleException, InvalidElementStateException, NoSuchElementException): logger.info('Element is not interactable in get_screenshot(): id: %s (xpath: %s)', clickable.get_id(), clickable.get_xpath()) except Exception as e: logger.error('Unknown Exception: %s in get_screenshot(): id: %s (xpath: %s)', str(e), clickable.get_id(), clickable.get_xpath()) sys.exit() if not element: # set context to CHROME to capture whole screen # system frame e.g. FileNotFound cannot be captured without CONTEXT_CHROME (Don't know why) self._marionette.set_context(self._marionette.CONTEXT_CHROME) screenshot = self._marionette.screenshot(element) self._marionette.set_context(self._marionette.CONTEXT_CONTENT) return screenshot def switch_to_frame(self, by, frame_str): """ :param by: options: "id", "xpath", "link text", "partial link text", "name", "tag name", "class name", "css selector", "anon attribute" """ # self.switch_to_top_frame() frame = self._marionette.find_element(by, frame_str) self._marionette.switch_to_frame(frame) def switch_to_top_frame(self): self._marionette.switch_to_frame() # switch to the top-level frame def restart_app(self): # remember to disable screen timeout and screen lock before testing # todo: open b2g simulator, install app, # unlock_screen # self._marionette.execute_script('window.wrappedJSObject.lockScreen.unlock();') self.kill_all_apps() # kill_all_apps() will also kill the 'homescreen app' on real device # so trigger a home event to restore homescreen if self.device: self._dispatch_home_button_event() self.clear_data() self.touch_home_button() # launch the app self._gaia_apps.launch(self._app_name) ''' Deprecated if self.device: icon = self._marionette.find_element('xpath', "//li[contains(@aria-label, '" + self._app_name + "')]") else: icon = self._marionette.find_element('xpath', "//div[contains(@class, 'icon')]//span[contains(text(),'" + self._app_name + "')]") icon.tap() ''' time.sleep(5) # wait for app screen self._marionette.switch_to_frame() # this wait seems not working, need to find another useful one Wait(self._marionette).until(lambda m: m.find_element('css selector', "iframe[data-url*='" + self._app_id + "']").is_displayed()) app_frame = self._marionette.find_element('css selector', "iframe[data-url*='" + self._app_id + "']") self._marionette.switch_to_frame(app_frame) def touch_home_button(self): # ref: https://github.com/mozilla-b2g/gaia/blob/master/tests/python/gaia-ui-tests/gaiatest/gaia_test.py#L751 apps = self._gaia_apps if apps.displayed_app.name.lower() != 'homescreen': # touching home button will return to homescreen self._dispatch_home_button_event() Wait(self._marionette).until( lambda m: apps.displayed_app.name.lower() == 'homescreen') apps.switch_to_displayed_app() else: apps.switch_to_displayed_app() mode = self._marionette.find_element(By.TAG_NAME, 'body').get_attribute('class') self._dispatch_home_button_event() apps.switch_to_displayed_app() if 'edit-mode' in mode: # touching home button will exit edit mode Wait(self._marionette).until(lambda m: m.find_element( By.TAG_NAME, 'body').get_attribute('class') != mode) else: # touching home button inside homescreen will scroll it to the top Wait(self._marionette).until(lambda m: m.execute_script( "return window.wrappedJSObject.scrollY") == 0) def _dispatch_home_button_event(self): self._gaia_device._dispatch_home_button_event() ''' Deprecated self._marionette.switch_to_frame() self._marionette.execute_script("window.wrappedJSObject.dispatchEvent(new Event('home'));") ''' time.sleep(0.5) def clear_data(self): # for now, clear contact data # https://github.com/mozilla-b2g/gaia/blob/v2.2/tests/python/gaia-ui-tests/gaiatest/gaia_test.py#L208 self._marionette.set_context(self._marionette.CONTEXT_CHROME) result = self._marionette.execute_async_script('return GaiaDataLayer.removeAllContacts();') assert result, 'Unable to remove all contacts' self._marionette.set_context(self._marionette.CONTEXT_CONTENT) time.sleep(0.5) def kill_all_apps(self): self._marionette.switch_to_frame() self._marionette.execute_async_script(""" // Kills all running apps, except the homescreen. function killAll() { let manager = window.wrappedJSObject.appWindowManager; let apps = manager.getApps(); for (let id in apps) { let origin = apps[id].origin; if (origin.indexOf('verticalhome') == -1) { manager.kill(origin); } } }; killAll(); // return true so execute_async_script knows the script is complete marionetteScriptFinished(true); """) time.sleep(0.5)
class Runner(object): _INPUT_NONE = '' _INPUT_EXIT_COMMAND = 'exit' _INPUT_MULTIPLE_LINE = ' \\' _INPUT_COMMAND_PREFIX = ':' _INPUT_SYSTEM_APP_KEYWORD = 'system' _is_async = False _sync_prompt = '>>> ' _async_prompt = 'a>> ' _prompt = _sync_prompt def __init__(self, **kwargs): # Added parser parser = OptionParser() parser.add_option('-a', '--address', action='store', type='string', dest='address', default='localhost', help='The host address of b2g instance. Default=localhost') parser.add_option('-p', '--port', action='store', type='int', dest='port', default=2828, help='The port of b2g instance.') parser.add_option('-l', '--list', action='store_true', dest='enable_list', default='False', help='List all apps of b2g instance. Default=False') parser.add_option('-c', '--connect', action='store', type='string', dest='connect', default=None, help='Connect to the App iframe.' \ 'Use # ID or App URL to connect.') (options, args) = parser.parse_args() self.connect = options.connect # start marionette session self.m = Marionette(options.address, options.port) self.m.start_session() # list all iframes if options.enable_list: self.list_all_iframes() # list active iframes elif self.connect == None: self.list_active_iframes() # connect to App if self.connect == None: exit(0) else: # connect App print 'Start...' if self.open_app(self.connect): self.start_js() else: exit(-1) def switch_sync_async(self): self._is_async = not self._is_async self._prompt = self._async_prompt if self._is_async else self._sync_prompt print 'Swith to', ('Async' if self._is_async else 'Sync'), 'JS execution' def start_js(self): print 'Enter \'%s\' or Crtl+D to exit the shell.' % self._INPUT_EXIT_COMMAND print 'And enter \':h\' for more commands.' try: while True: input = raw_input(self._prompt) # if input is EXIT command, exit this program if input.lower() == self._INPUT_EXIT_COMMAND: self.goodbye() break # if input is NONE, then do nothing and keep going... elif input == self._INPUT_NONE: continue # if input start with ":", it should be the command. elif input.startswith(self._INPUT_COMMAND_PREFIX): CmdDispatcher(self, input) # if the postfix of input is MULTIPLE_LINE, then record this line and wait the next line until no input with MULTIPLE_LINE. elif input.endswith(self._INPUT_MULTIPLE_LINE): input_multiple = input[:len(input) - 1] + '; ' while True: next_input = raw_input('... ') if next_input.endswith(self._INPUT_MULTIPLE_LINE): input_multiple = input_multiple + next_input[:len(next_input) - 1] + '; ' pass else: input_multiple = input_multiple + next_input + '; ' print self.execute_script(input_multiple) break # if input is NOT above inputs, then run marionette.execute_script(INPUT)/marionette.execute_async_script(INPUT) # and print return value. else: print self.execute_script(input) except EOFError: self.goodbye() exit() except Exception as e: print e if self.open_app(-1): self.start_js() exit() def execute_script(self, script): try: if self._is_async: return self.m.execute_async_script(script) else: return self.m.execute_script(script) except Exception as ex: print str(ex.message) def goodbye(self): print 'End. Bye!!' def open_app(self, input): try: # connect App by ID app_id = int(input) if app_id < 0: print 'Connect to', self._get_system_URL() self.set_current_frame(self._get_system_URL()) self.m.switch_to_frame() else: iframes = self.get_all_iframes_id_name_pair() print 'Connect to', iframes[str(app_id)] self.set_current_frame(iframes[str(app_id)]) self.m.switch_to_frame(app_id) return True except(ValueError): # connect to System app if (input.lower() == self._INPUT_SYSTEM_APP_KEYWORD) or (input.lower() in self._get_system_URL()): print 'Connect to', self._get_system_URL() self.set_current_frame(self._get_system_URL()) self.m.switch_to_frame() return True # connect App by substring iframes = self.get_all_iframes_id_name_pair() suitable_iframes = {} for k, v in iframes.items(): if input in v: suitable_iframes[k] = v # connect to App if there is one fit if len(suitable_iframes) == 1: target = suitable_iframes.keys()[0] print 'Connect to', suitable_iframes.values()[0] self.set_current_frame(suitable_iframes.values()[0]) self.m.switch_to_frame(int(target)) return True # exit if there are more than one app fit the query elif len(suitable_iframes) > 1: print 'There are more than one Apps fit the query string [', input, '].' print '{0:2s} {1:s}'.format('#', 'App URL') for k, v in sorted(suitable_iframes.items()): print '{0:2s} {1:s}'.format(k, v) return False # exit if there is no app fit the query else: print 'There is no App fit the query string [', input, '].' return False def set_current_frame(self, frame_name): self._current_frame = frame_name def get_current_frame(self): return self._current_frame def switch_to_system_frame(self): self.m.switch_to_frame() def _get_system_URL(self): self.switch_to_system_frame() system_URL = self.m.execute_script('return document.URL') return system_URL def _get_all_iframes(self): self.switch_to_system_frame() iframes = self.m.execute_script('return document.getElementsByTagName("iframe")') return iframes def get_all_iframes_id_name_pair(self): iframes = self._get_all_iframes() result = {} for idx in range(0, iframes['length']): iframe = iframes[str(idx)] result[str(idx)] = iframe.get_attribute('src') return result def list_all_iframes(self): iframes = self._get_all_iframes() print '{0:2s} {1:7s} {2:s}'.format('#', 'Status', 'App URL') print '{0:2s} {1:7s} {2:s}'.format('-1', '', self._get_system_URL()) for idx in range(0, iframes['length']): iframe = iframes[str(idx)] print '{0:2s} {1:7s} {2:s}'.format(str(idx), ('active' if iframe.is_displayed() else ''), iframe.get_attribute('src')) def list_active_iframes(self): iframes = self._get_all_iframes() print '{0:2s} {1:7s} {2:s}'.format('#', 'Status', 'App URL') result = {} for idx in range(0, iframes['length']): iframe = iframes[str(idx)] if iframe.is_displayed(): result[str(idx)] = iframe for idx, iframe in result.items(): print '{0:2s} {1:7s} {2:s}'.format(idx, ('active' if iframe.is_displayed() else ''), iframe.get_attribute('src')) # TODO: seems like should using Javascript to get the idx of each iframe!? def get_all_iframes_by_marionette(self): iframes = self.m.find_elements('css selector', 'iframe') return iframes def list_all_iframes_by_marionette(self): iframes = self.get_all_iframes_by_marionette() for iframe in iframes: print iframe.get_attribute('src') def list_active_iframes_by_marionette(self): iframes = self.get_all_iframes_by_marionette() result = [] for iframe in iframes: if iframe.is_displayed(): result.append(iframe) for iframe in result: print iframe.get_attribute('src')
def ftu(locale, device_flags, hashes): db = get_db(locale) app = 'ftu' app_categ = 'communications' app_type = 'apps' gaia_hash = hashes[0] hg_hash = hashes[1] screenshot_path = app_type + '/' + app_categ + '/' + app create_screenshot_dir(locale, screenshot_path) client = Marionette('localhost', 2828) client.start_session() change_screen_timeout(client) ftu_iframe = client.find_element( 'css selector', "iframe[src='app://communications.gaiamobile.org/ftu/index.html']") if client.switch_to_frame(ftu_iframe): time.sleep(short_time) # app://communications.gaiamobile.org/ftu/index.html#languages file_name = 'languages' screenshot_entry = { "id": file_name, "script": app, "gaia": gaia_hash, "hg": hg_hash, "changed": False, "path": screenshot_path } test_flags = {} if check_flags(test_flags, device_flags): screenshot_entry.update(test_flags) if take_screenshot(locale, screenshot_path, client, file_name): screenshot_entry['changed'] = True log_displayed_l10n_strings(client, db, app, app_categ, screenshot_entry, '#activation-screen') # switch to app://communications.gaiamobile.org/ftu/index.html#data_3g (unlock-sim-screen screen) next = client.find_element('css selector', '#forward') next.tap() time.sleep(short_time) # app://communications.gaiamobile.org/ftu/index.html#data_3g (sim pin screen - unlock-sim-screen - 1st attempt) file_name = 'data_3g-unlock_sim_screen-pin_screen' screenshot_entry = { "id": file_name, "script": app, "gaia": gaia_hash, "hg": hg_hash, "changed": False, "path": screenshot_path } test_flags = {"sim": True, "no-sim": False} if check_flags(test_flags, device_flags): screenshot_entry.update(test_flags) if take_screenshot(locale, screenshot_path, client, file_name): screenshot_entry['changed'] = True log_displayed_l10n_strings(client, db, app, app_categ, screenshot_entry, '#unlock-sim-screen') # invalid pin -> error about pin characters # stay at app://communications.gaiamobile.org/ftu/index.html#data_3g (unlock-sim-screen screen) next = client.find_element('css selector', '#unlock-sim-button') next.tap() time.sleep(short_time) # app://communications.gaiamobile.org/ftu/index.html#data_3g (sim pin screen - unlock-sim-screen - pin error) file_name = 'data_3g-unlock_sim_screen-pin_screen-invalid_pin' screenshot_entry = { "id": file_name, "script": app, "gaia": gaia_hash, "hg": hg_hash, "changed": False, "path": screenshot_path } test_flags = {"sim": True, "no-sim": False} if check_flags(test_flags, device_flags): screenshot_entry.update(test_flags) if take_screenshot(locale, screenshot_path, client, file_name): screenshot_entry['changed'] = True log_displayed_l10n_strings(client, db, app, app_categ, screenshot_entry, '#unlock-sim-screen') # insert wrong pin (attempt 1 of 3) pin_input = client.find_element('css selector', '#pin-input') pin_input.send_keys(wrong_sim_pin) # stay at app://communications.gaiamobile.org/ftu/index.html#data_3g (unlock-sim-screen screen) next = client.find_element('css selector', '#unlock-sim-button') next.tap() time.sleep(short_time) # app://communications.gaiamobile.org/ftu/index.html#data_3g (sim pin screen - unlock-sim-screen - 2nd attempt) file_name = 'data_3g-unlock_sim_screen-pin_screen-wrong_pin-1st_time' screenshot_entry = { "id": file_name, "script": app, "gaia": gaia_hash, "hg": hg_hash, "changed": False, "path": screenshot_path } test_flags = {"sim": True, "no-sim": False} if check_flags(test_flags, device_flags): screenshot_entry.update(test_flags) if take_screenshot(locale, screenshot_path, client, file_name): screenshot_entry['changed'] = True log_displayed_l10n_strings(client, db, app, app_categ, screenshot_entry, '#unlock-sim-screen') # insert wrong pin (attempt 2 of 3) pin_input = client.find_element('css selector', '#pin-input') pin_input.send_keys(wrong_sim_pin) # stay at app://communications.gaiamobile.org/ftu/index.html#data_3g (unlock-sim-screen screen) next = client.find_element('css selector', '#unlock-sim-button') next.tap() time.sleep(short_time) # app://communications.gaiamobile.org/ftu/index.html#data_3g (sim pin screen - unlock-sim-screen - 3rd attempt) file_name = 'data_3g-unlock_sim_screen-pin_screen-wrong_pin-2nd_time' screenshot_entry = { "id": file_name, "script": app, "gaia": gaia_hash, "hg": hg_hash, "changed": False, "path": screenshot_path } test_flags = {"sim": True, "no-sim": False} if check_flags(test_flags, device_flags): screenshot_entry.update(test_flags) if take_screenshot(locale, screenshot_path, client, file_name): screenshot_entry['changed'] = True log_displayed_l10n_strings(client, db, app, app_categ, screenshot_entry, '#unlock-sim-screen') # insert wrong pin (atempt 3 of 3) - continues to puk screen pin_input = client.find_element('css selector', '#pin-input') pin_input.send_keys(wrong_sim_pin) # switch to app://communications.gaiamobile.org/ftu/index.html#data_3g (sim puk screen - unlock-sim-screen) next = client.find_element('css selector', '#unlock-sim-button') next.tap() time.sleep(short_time) # tap the header in order to hide keyboard and get full screenshot of the puk screen header = client.find_element('css selector', '#unlock-sim-header') header.tap() # app://communications.gaiamobile.org/ftu/index.html#data_3g (sim puk screen - unlock-sim-screen - 1st attempt) file_name = 'data_3g-unlock_sim_screen-puk_screen' screenshot_entry = { "id": file_name, "script": app, "gaia": gaia_hash, "hg": hg_hash, "changed": False, "path": screenshot_path } test_flags = {"sim": True, "no-sim": False} if check_flags(test_flags, device_flags): screenshot_entry.update(test_flags) if take_screenshot(locale, screenshot_path, client, file_name): screenshot_entry['changed'] = True log_displayed_l10n_strings(client, db, app, app_categ, screenshot_entry, '#unlock-sim-screen') # invalid puk -> error about puk characters # stay at app://communications.gaiamobile.org/ftu/index.html#data_3g (sim puk screen - unlock-sim-screen) next = client.find_element('css selector', '#unlock-sim-button') next.tap() time.sleep(short_time) # app://communications.gaiamobile.org/ftu/index.html#data_3g (sim puk screen - unlock-sim-screen - puk error) file_name = 'data_3g-unlock_sim_screen-puk_screen-invalid_puk' screenshot_entry = { "id": file_name, "script": app, "gaia": gaia_hash, "hg": hg_hash, "changed": False, "path": screenshot_path } test_flags = {"sim": True, "no-sim": False} if check_flags(test_flags, device_flags): screenshot_entry.update(test_flags) if take_screenshot(locale, screenshot_path, client, file_name): screenshot_entry['changed'] = True log_displayed_l10n_strings(client, db, app, app_categ, screenshot_entry, '#unlock-sim-screen') # insert wrong puk - invalid new pin -> error about pin characters puk_input = client.find_element('css selector', '#puk-input') puk_input.send_keys(wrong_sim_puk) # stay at app://communications.gaiamobile.org/ftu/index.html#data_3g (sim puk screen - unlock-sim-screen) next = client.find_element('css selector', '#unlock-sim-button') next.tap() time.sleep(short_time) # app://communications.gaiamobile.org/ftu/index.html#data_3g (sim puk screen - unlock-sim-screen - pin error) file_name = 'data_3g-unlock_sim_screen-puk_screen-invalid_new_pin' screenshot_entry = { "id": file_name, "script": app, "gaia": gaia_hash, "hg": hg_hash, "changed": False, "path": screenshot_path } test_flags = {"sim": True, "no-sim": False} if check_flags(test_flags, device_flags): screenshot_entry.update(test_flags) if take_screenshot(locale, screenshot_path, client, file_name): screenshot_entry['changed'] = True log_displayed_l10n_strings(client, db, app, app_categ, screenshot_entry, '#unlock-sim-screen') # insert new pin without confirmed it -> error about pin confirmation (wrong puk is preserved at its input) newpin_input = client.find_element('css selector', '#newpin-input') newpin_input.send_keys(sim_pin) # stay at app://communications.gaiamobile.org/ftu/index.html#data_3g (sim puk screen - unlock-sim-screen) next = client.find_element('css selector', '#unlock-sim-button') next.tap() time.sleep(short_time) # app://communications.gaiamobile.org/ftu/index.html#data_3g (sim puk screen - unlock-sim-screen - pin error) file_name = 'data_3g-unlock_sim_screen-puk_screen-invalid_new_pin_confirmation' screenshot_entry = { "id": file_name, "script": app, "gaia": gaia_hash, "hg": hg_hash, "changed": False, "path": screenshot_path } test_flags = {"sim": True, "no-sim": False} if check_flags(test_flags, device_flags): screenshot_entry.update(test_flags) if take_screenshot(locale, screenshot_path, client, file_name): screenshot_entry['changed'] = True log_displayed_l10n_strings(client, db, app, app_categ, screenshot_entry, '#unlock-sim-screen') # insert confirmation of the new pin (wrong puk and new pin are preserved at their inputs) newpin_input = client.find_element('css selector', '#confirm-newpin-input') newpin_input.send_keys(sim_pin) # wrong puk (attempt 1 of 9) # stay at app://communications.gaiamobile.org/ftu/index.html#data_3g (sim puk screen - unlock-sim-screen) next = client.find_element('css selector', '#unlock-sim-button') next.tap() time.sleep(short_time) # app://communications.gaiamobile.org/ftu/index.html#data_3g (sim puk screen - unlock-sim-screen - puk error) file_name = 'data_3g-unlock_sim_screen-puk_screen-wrong_puk-1st_time' screenshot_entry = { "id": file_name, "script": app, "gaia": gaia_hash, "hg": hg_hash, "changed": False, "path": screenshot_path } test_flags = {"sim": True, "no-sim": False} if check_flags(test_flags, device_flags): screenshot_entry.update(test_flags) if take_screenshot(locale, screenshot_path, client, file_name): screenshot_entry['changed'] = True log_displayed_l10n_strings(client, db, app, app_categ, screenshot_entry, '#unlock-sim-screen') # insert wrong puk (attempt 2 of 9) (new pin and its confirmation are preserved at their inputs) puk_input = client.find_element('css selector', '#puk-input') puk_input.send_keys(wrong_sim_puk) # stay at app://communications.gaiamobile.org/ftu/index.html#data_3g (sim puk screen - unlock-sim-screen) next = client.find_element('css selector', '#unlock-sim-button') next.tap() time.sleep(short_time) # app://communications.gaiamobile.org/ftu/index.html#data_3g (sim puk screen - unlock-sim-screen - 2nd attempt) file_name = 'data_3g-unlock_sim_screen-puk_screen-wrong_puk-2nd_time' screenshot_entry = { "id": file_name, "script": app, "gaia": gaia_hash, "hg": hg_hash, "changed": False, "path": screenshot_path } test_flags = {"sim": True, "no-sim": False} if check_flags(test_flags, device_flags): screenshot_entry.update(test_flags) if take_screenshot(locale, screenshot_path, client, file_name): screenshot_entry['changed'] = True log_displayed_l10n_strings(client, db, app, app_categ, screenshot_entry, '#unlock-sim-screen') # insert right puk (attempt 2 of 9) (new pin and its confirmation are preserved at their inputs) puk_input = client.find_element('css selector', '#puk-input') puk_input.send_keys(sim_puk) # switch to app://communications.gaiamobile.org/ftu/index.html#data_3g next = client.find_element('css selector', '#unlock-sim-button') next.tap() time.sleep(short_time) # app://communications.gaiamobile.org/ftu/index.html#data_3g file_name = 'data_3g' screenshot_entry = { "id": file_name, "script": app, "gaia": gaia_hash, "hg": hg_hash, "changed": False, "path": screenshot_path } test_flags = {"sim": True, "no-sim": False} if check_flags(test_flags, device_flags): screenshot_entry.update(test_flags) if take_screenshot(locale, screenshot_path, client, file_name): screenshot_entry['changed'] = True log_displayed_l10n_strings(client, db, app, app_categ, screenshot_entry, '#activation-screen') # switch to app://communications.gaiamobile.org/ftu/index.html#wifi next = client.find_element('css selector', '#forward') next.tap() time.sleep(long_time) # enable overlay "scanningNetworks" spinner screen (loading-overlay) client.execute_script( "window.wrappedJSObject.utils.overlay.show('scanningNetworks', 'spinner');" ) time.sleep(middle_time) # overlay "scanningNetworks" spinner screen file_name = 'wifi-loading_overlay-scanning_networks' screenshot_entry = { "id": file_name, "script": app, "gaia": gaia_hash, "hg": hg_hash, "changed": False, "path": screenshot_path } test_flags = {} if check_flags(test_flags, device_flags): screenshot_entry.update(test_flags) if take_screenshot(locale, screenshot_path, client, file_name): screenshot_entry['changed'] = True log_displayed_l10n_strings(client, db, app, app_categ, screenshot_entry, '#loading-overlay') # disable overlay "scanningNetworks" spinner screen client.execute_script( "window.wrappedJSObject.utils.overlay.hide('scanningNetworks', 'spinner');" ) time.sleep(middle_time) # app://communications.gaiamobile.org/ftu/index.html#wifi file_name = 'wifi' screenshot_entry = { "id": file_name, "script": app, "gaia": gaia_hash, "hg": hg_hash, "changed": False, "path": screenshot_path } test_flags = {} if check_flags(test_flags, device_flags): screenshot_entry.update(test_flags) if take_screenshot(locale, screenshot_path, client, file_name): screenshot_entry['changed'] = True log_displayed_l10n_strings(client, db, app, app_categ, screenshot_entry, '#wifi') # switch to app://communications.gaiamobile.org/ftu/index.html#date_and_time next = client.find_element('css selector', '#forward') next.tap() time.sleep(short_time) # Set time in order to be the same at every screenshot set_time(client) # app://communications.gaiamobile.org/ftu/index.html#date_and_time file_name = 'date_and_time' screenshot_entry = { "id": file_name, "script": app, "gaia": gaia_hash, "hg": hg_hash, "changed": False, "path": screenshot_path } test_flags = {} if check_flags(test_flags, device_flags): screenshot_entry.update(test_flags) if take_screenshot(locale, screenshot_path, client, file_name): screenshot_entry['changed'] = True log_displayed_l10n_strings(client, db, app, app_categ, screenshot_entry, '#date_and_time') # switch to app://communications.gaiamobile.org/ftu/index.html#geolocation next = client.find_element('css selector', '#forward') next.tap() time.sleep(short_time) # app://communications.gaiamobile.org/ftu/index.html#geolocation file_name = 'geolocation' screenshot_entry = { "id": file_name, "script": app, "gaia": gaia_hash, "hg": hg_hash, "changed": False, "path": screenshot_path } test_flags = {} if check_flags(test_flags, device_flags): screenshot_entry.update(test_flags) if take_screenshot(locale, screenshot_path, client, file_name): screenshot_entry['changed'] = True log_displayed_l10n_strings(client, db, app, app_categ, screenshot_entry, '#geolocation') # switch to app://communications.gaiamobile.org/ftu/index.html#import_contacts next = client.find_element('css selector', '#forward') next.tap() time.sleep(middle_time) # app://communications.gaiamobile.org/ftu/index.html#import_contacts file_name = 'import_contacts' screenshot_entry = { "id": file_name, "script": app, "gaia": gaia_hash, "hg": hg_hash, "changed": False, "path": screenshot_path } test_flags = {} if check_flags(test_flags, device_flags): screenshot_entry.update(test_flags) if take_screenshot(locale, screenshot_path, client, file_name): screenshot_entry['changed'] = True log_displayed_l10n_strings(client, db, app, app_categ, screenshot_entry, '#import_contacts') # switch to app://communications.gaiamobile.org/ftu/index.html#welcome_browser next = client.find_element('css selector', '#forward') next.tap() time.sleep(short_time) # app://communications.gaiamobile.org/ftu/index.html#welcome_browser file_name = 'welcome_browser' screenshot_entry = { "id": file_name, "script": app, "gaia": gaia_hash, "hg": hg_hash, "changed": False, "path": screenshot_path } test_flags = {} if check_flags(test_flags, device_flags): screenshot_entry.update(test_flags) if take_screenshot(locale, screenshot_path, client, file_name): screenshot_entry['changed'] = True log_displayed_l10n_strings(client, db, app, app_categ, screenshot_entry) # switch to app://communications.gaiamobile.org/ftu/index.html#browser_privacy next = client.find_element('css selector', '#forward') next.tap() time.sleep(short_time) # app://communications.gaiamobile.org/ftu/index.html#browser_privacy file_name = 'browser_privacy' screenshot_entry = { "id": file_name, "script": app, "gaia": gaia_hash, "hg": hg_hash, "changed": False, "path": screenshot_path } test_flags = {} if check_flags(test_flags, device_flags): screenshot_entry.update(test_flags) if take_screenshot(locale, screenshot_path, client, file_name): screenshot_entry['changed'] = True log_displayed_l10n_strings(client, db, app, app_categ, screenshot_entry) # switch to app://communications.gaiamobile.org/ftu/index.html#step1 (first tutorial screen) next = client.find_element('css selector', '#forward') next.tap() time.sleep(long_time) # app://communications.gaiamobile.org/ftu/index.html#step1 (first tutorial screen) file_name = 'step1-first_tutorial_screen' screenshot_entry = { "id": file_name, "script": app, "gaia": gaia_hash, "hg": hg_hash, "changed": False, "path": screenshot_path } test_flags = {} if check_flags(test_flags, device_flags): screenshot_entry.update(test_flags) if take_screenshot(locale, screenshot_path, client, file_name): screenshot_entry['changed'] = True log_displayed_l10n_strings(client, db, app, app_categ, screenshot_entry) # switch to app://communications.gaiamobile.org/ftu/index.html#step1 next = client.find_element('css selector', '#lets-go-button') next.tap() time.sleep(long_time) # app://communications.gaiamobile.org/ftu/index.html#step1 file_name = 'step1' screenshot_entry = { "id": file_name, "script": app, "gaia": gaia_hash, "hg": hg_hash, "changed": False, "path": screenshot_path } test_flags = {} if check_flags(test_flags, device_flags): screenshot_entry.update(test_flags) if take_screenshot(locale, screenshot_path, client, file_name): screenshot_entry['changed'] = True log_displayed_l10n_strings(client, db, app, app_categ, screenshot_entry) # switch to app://communications.gaiamobile.org/ftu/index.html#step2 next = client.find_element('css selector', '#forwardTutorial') next.tap() time.sleep(short_time) # app://communications.gaiamobile.org/ftu/index.html#step2 file_name = 'step2' screenshot_entry = { "id": file_name, "script": app, "gaia": gaia_hash, "hg": hg_hash, "changed": False, "path": screenshot_path } test_flags = {} if check_flags(test_flags, device_flags): screenshot_entry.update(test_flags) if take_screenshot(locale, screenshot_path, client, file_name): screenshot_entry['changed'] = True log_displayed_l10n_strings(client, db, app, app_categ, screenshot_entry) # switch to app://communications.gaiamobile.org/ftu/index.html#step3 next = client.find_element('css selector', '#forwardTutorial') next.tap() time.sleep(short_time) # app://communications.gaiamobile.org/ftu/index.html#step3 file_name = 'step3' screenshot_entry = { "id": file_name, "script": app, "gaia": gaia_hash, "hg": hg_hash, "changed": False, "path": screenshot_path } test_flags = {} if check_flags(test_flags, device_flags): screenshot_entry.update(test_flags) if take_screenshot(locale, screenshot_path, client, file_name): screenshot_entry['changed'] = True log_displayed_l10n_strings(client, db, app, app_categ, screenshot_entry) # switch to app://communications.gaiamobile.org/ftu/index.html#step4 next = client.find_element('css selector', '#forwardTutorial') next.tap() time.sleep(short_time) # app://communications.gaiamobile.org/ftu/index.html#step4 file_name = 'step4' screenshot_entry = { "id": file_name, "script": app, "gaia": gaia_hash, "hg": hg_hash, "changed": False, "path": screenshot_path } test_flags = {} if check_flags(test_flags, device_flags): screenshot_entry.update(test_flags) if take_screenshot(locale, screenshot_path, client, file_name): screenshot_entry['changed'] = True log_displayed_l10n_strings(client, db, app, app_categ, screenshot_entry) # switch to app://communications.gaiamobile.org/ftu/index.html#step4 (last tutorial screen) next = client.find_element('css selector', '#forwardTutorial') next.tap() time.sleep(long_time) # app://communications.gaiamobile.org/ftu/index.html#step4 (last tutorial screen) file_name = 'step4-last_tutorial_screen' screenshot_entry = { "id": file_name, "script": app, "gaia": gaia_hash, "hg": hg_hash, "changed": False, "path": screenshot_path } test_flags = {} if check_flags(test_flags, device_flags): screenshot_entry.update(test_flags) if take_screenshot(locale, screenshot_path, client, file_name): screenshot_entry['changed'] = True log_displayed_l10n_strings(client, db, app, app_categ, screenshot_entry) # Close ftu frame next = client.find_element('css selector', '#tutorialFinished') next.tap() time.sleep(short_time) set_db(locale, db) else: #TO DO raise proper error print "switch to ftu frame failed"
class Runner(object): _INPUT_NONE = '' _INPUT_EXIT_COMMAND = 'exit' _INPUT_MULTIPLE_LINE = ' \\' _INPUT_COMMAND_PREFIX = ':' _INPUT_SYSTEM_APP_KEYWORD = 'system' _KEYBOARD_FRAME_NAME = 'app://keyboard.gaiamobile.org/index.html' _is_async = False _sync_prompt = '>>> ' _async_prompt = 'a>> ' _prompt = _sync_prompt def __init__(self, **kwargs): # Added parser parser = OptionParser() parser.add_option( '-a', '--address', action='store', type='string', dest='address', default='localhost', help='The host address of b2g instance. Default=localhost') parser.add_option('-p', '--port', action='store', type='int', dest='port', default=2828, help='The port of b2g instance.') parser.add_option('-l', '--list', action='store_true', dest='enable_list', default='False', help='List all apps of b2g instance. Default=False') parser.add_option('-c', '--connect', action='store', type='string', dest='connect', default=None, help='Connect to the App iframe.' \ 'Use # ID or App URL to connect.') (options, args) = parser.parse_args() self.connect = options.connect # start marionette session self.m = Marionette(options.address, options.port) self.m.start_session() # list all iframes if options.enable_list: self.list_all_iframes() # list active iframes elif self.connect == None: self.list_active_iframes() # connect to App if self.connect == None: exit(0) else: # connect App print 'Start...' if self.open_app(self.connect): self.start_js() else: exit(-1) def switch_sync_async(self): self._is_async = not self._is_async self._prompt = self._async_prompt if self._is_async else self._sync_prompt print 'Swith to', ('Async' if self._is_async else 'Sync'), 'JS execution' def start_js(self): print 'Enter \'%s\' or Crtl+D to exit the shell.' % self._INPUT_EXIT_COMMAND print 'And enter \':h\' for more commands.' try: while True: input = raw_input(self._prompt) # if input is EXIT command, exit this program if input.lower() == self._INPUT_EXIT_COMMAND: self.goodbye() break # if input is NONE, then do nothing and keep going... elif input == self._INPUT_NONE: continue # if input start with ":", it should be the command. elif input.startswith(self._INPUT_COMMAND_PREFIX): CmdDispatcher(self, input) # if the postfix of input is MULTIPLE_LINE, then record this line and wait the next line until no input with MULTIPLE_LINE. elif input.endswith(self._INPUT_MULTIPLE_LINE): input_multiple = input[:len(input) - 1] + '; ' while True: next_input = raw_input('... ') if next_input.endswith(self._INPUT_MULTIPLE_LINE): input_multiple = input_multiple + next_input[:len( next_input) - 1] + '; ' pass else: input_multiple = input_multiple + next_input + '; ' print self.execute_script(input_multiple) break # if input is NOT above inputs, then run marionette.execute_script(INPUT)/marionette.execute_async_script(INPUT) # and print return value. else: print self.execute_script(input) except EOFError: self.goodbye() exit() except Exception as e: print e if self.open_app(-1): self.start_js() exit() def execute_script(self, script): try: if self._is_async: return self.m.execute_async_script(script) else: return self.m.execute_script(script) except Exception as ex: print str(ex.message) def goodbye(self): print 'End. Bye!!' def open_app(self, input): try: # connect App by ID app_id = int(input) if app_id < 0: print 'Connect to', self._get_system_URL() self.set_current_frame(self._get_system_URL()) self.m.switch_to_frame() else: iframes = self.get_all_iframes_id_name_pair() print 'Connect to', iframes[str(app_id)] self.set_current_frame(iframes[str(app_id)]) if iframes[str(app_id)] == self._KEYBOARD_FRAME_NAME: self.m.switch_to_frame(app_id, False) else: self.m.switch_to_frame(app_id) return True except (ValueError): # connect to System app if (input.lower() == self._INPUT_SYSTEM_APP_KEYWORD) or ( input.lower() in self._get_system_URL()): print 'Connect to', self._get_system_URL() self.set_current_frame(self._get_system_URL()) self.m.switch_to_frame() return True # connect App by substring iframes = self.get_all_iframes_id_name_pair() suitable_iframes = {} for k, v in iframes.items(): if input in v: suitable_iframes[k] = v # connect to App if there is one fit if len(suitable_iframes) == 1: target = suitable_iframes.keys()[0] print 'Connect to', suitable_iframes.values()[0] self.set_current_frame(suitable_iframes.values()[0]) if suitable_iframes.values()[0] == self._KEYBOARD_FRAME_NAME: self.m.switch_to_frame(int(target), False) else: self.m.switch_to_frame(int(target)) return True # exit if there are more than one app fit the query elif len(suitable_iframes) > 1: print 'There are more than one Apps fit the query string [', input, '].' print '{0:2s} {1:s}'.format('#', 'App URL') for k, v in sorted(suitable_iframes.items()): print '{0:2s} {1:s}'.format(k, v) return False # exit if there is no app fit the query else: print 'There is no App fit the query string [', input, '].' return False def set_current_frame(self, frame_name): self._current_frame = frame_name def get_current_frame(self): return self._current_frame def switch_to_system_frame(self): self.m.switch_to_frame() def _get_system_URL(self): self.switch_to_system_frame() system_URL = self.m.execute_script('return document.URL') return system_URL def _get_all_iframes(self): self.switch_to_system_frame() iframes = self.m.execute_script( 'return document.getElementsByTagName("iframe")') return iframes def get_all_iframes_id_name_pair(self): iframes = self._get_all_iframes() result = {} for idx in range(0, iframes['length']): iframe = iframes[str(idx)] result[str(idx)] = iframe.get_attribute('src') return result def list_all_iframes(self): iframes = self._get_all_iframes() print '{0:2s} {1:7s} {2:s}'.format('#', 'Status', 'App URL') print '{0:2s} {1:7s} {2:s}'.format('-1', '', self._get_system_URL()) for idx in range(0, iframes['length']): iframe = iframes[str(idx)] print '{0:2s} {1:7s} {2:s}'.format( str(idx), ('active' if iframe.is_displayed() else ''), iframe.get_attribute('src')) def list_active_iframes(self): iframes = self._get_all_iframes() print '{0:2s} {1:7s} {2:s}'.format('#', 'Status', 'App URL') result = {} for idx in range(0, iframes['length']): iframe = iframes[str(idx)] if iframe.is_displayed(): result[str(idx)] = iframe for idx, iframe in result.items(): print '{0:2s} {1:7s} {2:s}'.format( idx, ('active' if iframe.is_displayed() else ''), iframe.get_attribute('src')) # TODO: seems like should using Javascript to get the idx of each iframe!? def get_all_iframes_by_marionette(self): iframes = self.m.find_elements('css selector', 'iframe') return iframes def list_all_iframes_by_marionette(self): iframes = self.get_all_iframes_by_marionette() for iframe in iframes: print iframe.get_attribute('src') def list_active_iframes_by_marionette(self): iframes = self.get_all_iframes_by_marionette() result = [] for iframe in iframes: if iframe.is_displayed(): result.append(iframe) for iframe in result: print iframe.get_attribute('src')
assert(m.execute_js_script(server.TEST_EXECUTE_SCRIPT)) assert(m.execute_js_script(server.TEST_EXECUTE_SCRIPT, server.TEST_EXECUTE_SCRIPT_ARGS)) assert(m.execute_script(server.TEST_EXECUTE_SCRIPT, server.TEST_EXECUTE_SCRIPT_ARGS)) assert(m.execute_async_script(server.TEST_EXECUTE_SCRIPT)) assert(m.execute_async_script(server.TEST_EXECUTE_SCRIPT, server.TEST_EXECUTE_SCRIPT_ARGS)) assert(str(m.find_element(HTMLElement.CLASS, 'heading')) == server.TEST_FIND_ELEMENT) assert([str(x) for x in m.find_elements(HTMLElement.TAG, 'p')] == server.TEST_FIND_ELEMENTS) assert(str(m.find_element(HTMLElement.CLASS, 'heading').find_element(HTMLElement.TAG, 'h1')) == server.TEST_FIND_ELEMENT) assert([str(x) for x in m.find_element(HTMLElement.ID, 'div1').find_elements(HTMLElement.SELECTOR, '.main')] == \ server.TEST_FIND_ELEMENTS) assert(m.find_element(HTMLElement.ID, 'id1').click()) assert(m.find_element(HTMLElement.ID, 'id2').text() == server.TEST_GET_TEXT) assert(m.find_element(HTMLElement.ID, 'id3').send_keys('Mozilla Firefox')) assert(m.find_element(HTMLElement.ID, 'id3').value() == server.TEST_GET_VALUE) assert(m.find_element(HTMLElement.ID, 'id3').clear()) assert(m.find_element(HTMLElement.ID, 'id3').selected()) assert(m.find_element(HTMLElement.ID, 'id1').equals(m.find_element(HTMLElement.TAG, 'p'))) assert(m.find_element(HTMLElement.ID, 'id3').enabled()) assert(m.find_element(HTMLElement.ID, 'id3').displayed()) assert(m.find_element(HTMLElement.ID, 'id3').get_attribute('value') == server.TEST_GET_VALUE) assert(m.delete_session()) # verify a session is started automatically for us if needed assert(m.switch_to_frame('frame1')) assert(m.switch_to_frame(1)) assert(m.switch_to_frame(m.find_element(HTMLElement.ID, 'frameid'))) assert(m.switch_to_frame()) assert(m.get_window() == server.TEST_CURRENT_WINDOW) assert(m.set_context(m.CONTEXT_CHROME)) assert(m.delete_session())
class B2gExecutor(Executor): def __init__(self, app_name, app_id, device=False): self.device = device if self.device: call(['adb', 'forward', 'tcp:2828', 'tcp:2828']) self._app_name = app_name self._app_id = app_id self._marionette = Marionette() self._marionette.start_session() self._gaia_apps = GaiaApps(self._marionette) self._gaia_data = GaiaData(self._marionette) self._gaia_device = GaiaDevice(self._marionette) ''' Deprecated # https://github.com/mozilla-b2g/gaia/blob/b568b7ae8adb6ee3651bd75acbaaedff86a08912/tests/python/gaia-ui-tests/gaiatest/gaia_test.py js = os.path.abspath(os.path.join(__file__, os.path.pardir, 'atoms', "gaia_apps.js")) self._marionette.import_script(js) js = os.path.abspath(os.path.join(__file__, os.path.pardir, 'atoms', "gaia_data_layer.js")) self._marionette.set_context(self._marionette.CONTEXT_CHROME) self._marionette.import_script(js) self._marionette.set_context(self._marionette.CONTEXT_CONTENT) # C:\Users\Jun-Wei\Desktop\b2g\battery\manifest.webapp #app = GaiaApps(self._marionette).launch(self._app_name) #app = GaiaApps(self._marionette).launch('Battery', manifest_url='C:/Users/Jun-Wei/Desktop/b2g/battery/manifest.webapp', entry_point='/index.html') app = GaiaApps(self._marionette).launch('Battery') print app.frame print app.src print app.origin print app.name #print g_app.manifest_url #self._app_frame = g_app.frame self._app_frame_id = app.frame self._app_src = app.src self._app_origin = app.origin #self.app_manifest_url = g_app.manifest_url #self.gaia_apps = GaiaApps(self.__marionette) #print self.gaia_apps.displayed_app.name #print self.gaia_apps.installed_apps #print self.gaia_apps.running_apps() #js = os.path.abspath(os.path.join(__file__, os.path.pardir, 'atoms', "gaia_apps.js")) #self.__marionette.import_script(js) ''' def fire_event(self, clickable): logger.info('fire_event: id: %s (xpath: %s)', clickable.get_id(), clickable.get_xpath()) try: # id staring with DomAnalyzer.serial_prefix is given by our monkey and should be ignored when locating if clickable.get_id() and not clickable.get_id().startswith( DomAnalyzer.serial_prefix): self._marionette.find_element('id', clickable.get_id()).tap() elif clickable.get_xpath(): self._marionette.find_element('xpath', clickable.get_xpath()).tap() else: logger.error( 'No id nor xpath for the clickable: id: %s (xpath: %s)', clickable.get_id(), clickable.get_xpath()) sys.exit() except (ElementNotVisibleException, InvalidElementStateException, NoSuchElementException): logger.info( 'Element is not interactable in fire_event(): id: %s (xpath: %s)', clickable.get_id(), clickable.get_xpath()) except Exception as e: logger.error( 'Unknown Exception: %s in fire_event(): id: %s (xpath: %s)', str(e), clickable.get_id(), clickable.get_xpath()) sys.exit() def fill_form(self, clickable): for f in clickable.get_forms(): for input_field in f.get_inputs(): try: if input_field.get_id() and not input_field.get_id( ).startswith(DomAnalyzer.serial_prefix): self._marionette.find_element( 'id', input_field.get_id()).send_keys( input_field.get_value()) elif input_field.get_xpath(): self._marionette.find_element( 'xpath', input_field.get_xpath()).send_keys( input_field.get_value()) else: logger.error( 'No id nor xpath for an input field in the form id: %s (xpath: %s)', f.get_id(), f.get_xpath()) sys.exit() except (ElementNotVisibleException, InvalidElementStateException, NoSuchElementException): logger.info( 'Element is not interactable in fill_form(): id: %s (xpath: %s)', f.get_id(), f.get_xpath()) except Exception as e: logger.error( 'Unknown Exception: %s in fill_form(): id: %s (xpath: %s)', str(e), f.get_id(), f.get_xpath()) sys.exit() def empty_form(self, clickable): for f in clickable.get_forms(): for input_field in f.get_inputs(): try: if input_field.get_id() and not input_field.get_id( ).startswith(DomAnalyzer.serial_prefix): self._marionette.find_element( 'id', input_field.get_id()).clear() elif input_field.get_xpath(): self._marionette.find_element( 'xpath', input_field.get_xpath()).clear() else: logger.error( 'No id nor xpath for an input field in the form %s (%s)', f.get_id(), f.get_xpath()) sys.exit() except (ElementNotVisibleException, InvalidElementStateException, NoSuchElementException): logger.info( 'Element is not interactable in empty_form(): id: %s (xpath: %s)', f.get_id(), f.get_xpath()) except Exception as e: logger.error( 'Unknown Exception: %s in empty_form(): id: %s (xpath: %s)', str(e), f.get_id(), f.get_xpath()) sys.exit() def get_source(self): return self._marionette.page_source.encode(sys.stdout.encoding, 'ignore') def get_screenshot(self, clickable=None): element = None if clickable: try: if clickable.get_id() and not clickable.get_id().startswith( DomAnalyzer.serial_prefix): element = self._marionette.find_element( 'id', clickable.get_id()) elif clickable.get_xpath(): element = self._marionette.find_element( 'xpath', clickable.get_xpath()) else: logger.error( 'No id nor xpath for the clickable: id: %s (xpath: %s)', clickable.get_id(), clickable.get_xpath()) sys.exit() except (ElementNotVisibleException, InvalidElementStateException, NoSuchElementException): logger.info( 'Element is not interactable in get_screenshot(): id: %s (xpath: %s)', clickable.get_id(), clickable.get_xpath()) except Exception as e: logger.error( 'Unknown Exception: %s in get_screenshot(): id: %s (xpath: %s)', str(e), clickable.get_id(), clickable.get_xpath()) sys.exit() if not element: # set context to CHROME to capture whole screen # system frame e.g. FileNotFound cannot be captured without CONTEXT_CHROME (Don't know why) self._marionette.set_context(self._marionette.CONTEXT_CHROME) screenshot = self._marionette.screenshot(element) self._marionette.set_context(self._marionette.CONTEXT_CONTENT) return screenshot def switch_to_frame(self, by, frame_str): """ :param by: options: "id", "xpath", "link text", "partial link text", "name", "tag name", "class name", "css selector", "anon attribute" """ # self.switch_to_top_frame() frame = self._marionette.find_element(by, frame_str) self._marionette.switch_to_frame(frame) def switch_to_top_frame(self): self._marionette.switch_to_frame() # switch to the top-level frame def restart_app(self): # remember to disable screen timeout and screen lock before testing # todo: open b2g simulator, install app, # unlock_screen # self._marionette.execute_script('window.wrappedJSObject.lockScreen.unlock();') self.kill_all_apps() # kill_all_apps() will also kill the 'homescreen app' on real device # so trigger a home event to restore homescreen if self.device: self._dispatch_home_button_event() self.clear_data() self.touch_home_button() # launch the app self._gaia_apps.launch(self._app_name) ''' Deprecated if self.device: icon = self._marionette.find_element('xpath', "//li[contains(@aria-label, '" + self._app_name + "')]") else: icon = self._marionette.find_element('xpath', "//div[contains(@class, 'icon')]//span[contains(text(),'" + self._app_name + "')]") icon.tap() ''' time.sleep(5) # wait for app screen self._marionette.switch_to_frame() # this wait seems not working, need to find another useful one Wait(self._marionette).until(lambda m: m.find_element( 'css selector', "iframe[data-url*='" + self._app_id + "']"). is_displayed()) app_frame = self._marionette.find_element( 'css selector', "iframe[data-url*='" + self._app_id + "']") self._marionette.switch_to_frame(app_frame) def touch_home_button(self): # ref: https://github.com/mozilla-b2g/gaia/blob/master/tests/python/gaia-ui-tests/gaiatest/gaia_test.py#L751 apps = self._gaia_apps if apps.displayed_app.name.lower() != 'homescreen': # touching home button will return to homescreen self._dispatch_home_button_event() Wait(self._marionette).until( lambda m: apps.displayed_app.name.lower() == 'homescreen') apps.switch_to_displayed_app() else: apps.switch_to_displayed_app() mode = self._marionette.find_element(By.TAG_NAME, 'body').get_attribute('class') self._dispatch_home_button_event() apps.switch_to_displayed_app() if 'edit-mode' in mode: # touching home button will exit edit mode Wait(self._marionette).until(lambda m: m.find_element( By.TAG_NAME, 'body').get_attribute('class') != mode) else: # touching home button inside homescreen will scroll it to the top Wait(self._marionette).until(lambda m: m.execute_script( "return window.wrappedJSObject.scrollY") == 0) def _dispatch_home_button_event(self): self._gaia_device._dispatch_home_button_event() ''' Deprecated self._marionette.switch_to_frame() self._marionette.execute_script("window.wrappedJSObject.dispatchEvent(new Event('home'));") ''' time.sleep(0.5) def clear_data(self): # for now, clear contact data # https://github.com/mozilla-b2g/gaia/blob/v2.2/tests/python/gaia-ui-tests/gaiatest/gaia_test.py#L208 self._marionette.set_context(self._marionette.CONTEXT_CHROME) result = self._marionette.execute_async_script( 'return GaiaDataLayer.removeAllContacts();') assert result, 'Unable to remove all contacts' self._marionette.set_context(self._marionette.CONTEXT_CONTENT) time.sleep(0.5) def kill_all_apps(self): self._marionette.switch_to_frame() self._marionette.execute_async_script(""" // Kills all running apps, except the homescreen. function killAll() { let manager = window.wrappedJSObject.appWindowManager; let apps = manager.getApps(); for (let id in apps) { let origin = apps[id].origin; if (origin.indexOf('verticalhome') == -1) { manager.kill(origin); } } }; killAll(); // return true so execute_async_script knows the script is complete marionetteScriptFinished(true); """) time.sleep(0.5)
assert m.execute_async_script(server.TEST_EXECUTE_SCRIPT, server.TEST_EXECUTE_SCRIPT_ARGS) assert str(m.find_element(HTMLElement.CLASS, "heading")) == server.TEST_FIND_ELEMENT assert [str(x) for x in m.find_elements(HTMLElement.TAG, "p")] == server.TEST_FIND_ELEMENTS assert ( str(m.find_element(HTMLElement.CLASS, "heading").find_element(HTMLElement.TAG, "h1")) == server.TEST_FIND_ELEMENT ) assert [ str(x) for x in m.find_element(HTMLElement.ID, "div1").find_elements(HTMLElement.SELECTOR, ".main") ] == server.TEST_FIND_ELEMENTS assert m.find_element(HTMLElement.ID, "id1").click() assert m.find_element(HTMLElement.ID, "id2").text() == server.TEST_GET_TEXT assert m.find_element(HTMLElement.ID, "id3").send_keys("Mozilla Firefox") assert m.find_element(HTMLElement.ID, "id3").value() == server.TEST_GET_VALUE assert m.find_element(HTMLElement.ID, "id3").clear() assert m.find_element(HTMLElement.ID, "id3").selected() assert m.find_element(HTMLElement.ID, "id1").equals(m.find_element(HTMLElement.TAG, "p")) assert m.find_element(HTMLElement.ID, "id3").enabled() assert m.find_element(HTMLElement.ID, "id3").displayed() assert m.find_element(HTMLElement.ID, "id3").get_attribute("value") == server.TEST_GET_VALUE assert m.delete_session() # verify a session is started automatically for us if needed assert m.switch_to_frame("frame1") assert m.switch_to_frame(1) assert m.switch_to_frame(m.find_element(HTMLElement.ID, "frameid")) assert m.switch_to_frame() assert m.get_window() == server.TEST_CURRENT_WINDOW assert m.set_context(m.CONTEXT_CHROME) assert m.delete_session()
def ftu(locale, device_flags, hashes): db = get_db(locale) app = 'ftu' app_categ = 'communications' app_type = 'apps' gaia_hash = hashes[0] hg_hash = hashes[1] screenshot_path = app_type + '/' + app_categ + '/' + app create_screenshot_dir(locale, screenshot_path) client = Marionette('localhost', 2828) client.start_session() change_screen_timeout(client) ftu_iframe = client.find_element('css selector',"iframe[src='app://communications.gaiamobile.org/ftu/index.html']") if client.switch_to_frame(ftu_iframe): time.sleep(short_time) # app://communications.gaiamobile.org/ftu/index.html#languages file_name = 'languages' screenshot_entry = { "id" : file_name, "script" : app, "gaia" : gaia_hash, "hg" : hg_hash, "changed" : False, "path" : screenshot_path} test_flags = {} if check_flags(test_flags, device_flags): screenshot_entry.update(test_flags) if take_screenshot(locale, screenshot_path, client, file_name): screenshot_entry['changed'] = True log_displayed_l10n_strings(client, db, app, app_categ, screenshot_entry, '#activation-screen') # switch to app://communications.gaiamobile.org/ftu/index.html#data_3g (unlock-sim-screen screen) next = client.find_element('css selector', '#forward') next.tap() time.sleep(short_time) # app://communications.gaiamobile.org/ftu/index.html#data_3g (sim pin screen - unlock-sim-screen - 1st attempt) file_name = 'data_3g-unlock_sim_screen-pin_screen' screenshot_entry = { "id" : file_name, "script" : app, "gaia" : gaia_hash, "hg" : hg_hash, "changed" : False, "path" : screenshot_path} test_flags = { "sim": True, "no-sim": False} if check_flags(test_flags, device_flags): screenshot_entry.update(test_flags) if take_screenshot(locale, screenshot_path, client, file_name): screenshot_entry['changed'] = True log_displayed_l10n_strings(client, db, app, app_categ, screenshot_entry, '#unlock-sim-screen') # invalid pin -> error about pin characters # stay at app://communications.gaiamobile.org/ftu/index.html#data_3g (unlock-sim-screen screen) next = client.find_element('css selector', '#unlock-sim-button') next.tap() time.sleep(short_time) # app://communications.gaiamobile.org/ftu/index.html#data_3g (sim pin screen - unlock-sim-screen - pin error) file_name = 'data_3g-unlock_sim_screen-pin_screen-invalid_pin' screenshot_entry = { "id" : file_name, "script" : app, "gaia" : gaia_hash, "hg" : hg_hash, "changed" : False, "path" : screenshot_path} test_flags = { "sim": True, "no-sim": False} if check_flags(test_flags, device_flags): screenshot_entry.update(test_flags) if take_screenshot(locale, screenshot_path, client, file_name): screenshot_entry['changed'] = True log_displayed_l10n_strings(client, db, app, app_categ, screenshot_entry, '#unlock-sim-screen') # insert wrong pin (attempt 1 of 3) pin_input = client.find_element('css selector', '#pin-input') pin_input.send_keys(wrong_sim_pin) # stay at app://communications.gaiamobile.org/ftu/index.html#data_3g (unlock-sim-screen screen) next = client.find_element('css selector', '#unlock-sim-button') next.tap() time.sleep(short_time) # app://communications.gaiamobile.org/ftu/index.html#data_3g (sim pin screen - unlock-sim-screen - 2nd attempt) file_name = 'data_3g-unlock_sim_screen-pin_screen-wrong_pin-1st_time' screenshot_entry = { "id" : file_name, "script" : app, "gaia" : gaia_hash, "hg" : hg_hash, "changed" : False, "path" : screenshot_path} test_flags = { "sim": True, "no-sim": False} if check_flags(test_flags, device_flags): screenshot_entry.update(test_flags) if take_screenshot(locale, screenshot_path, client, file_name): screenshot_entry['changed'] = True log_displayed_l10n_strings(client, db, app, app_categ, screenshot_entry, '#unlock-sim-screen') # insert wrong pin (attempt 2 of 3) pin_input = client.find_element('css selector', '#pin-input') pin_input.send_keys(wrong_sim_pin) # stay at app://communications.gaiamobile.org/ftu/index.html#data_3g (unlock-sim-screen screen) next = client.find_element('css selector', '#unlock-sim-button') next.tap() time.sleep(short_time) # app://communications.gaiamobile.org/ftu/index.html#data_3g (sim pin screen - unlock-sim-screen - 3rd attempt) file_name = 'data_3g-unlock_sim_screen-pin_screen-wrong_pin-2nd_time' screenshot_entry = { "id" : file_name, "script" : app, "gaia" : gaia_hash, "hg" : hg_hash, "changed" : False, "path" : screenshot_path} test_flags = { "sim": True, "no-sim": False} if check_flags(test_flags, device_flags): screenshot_entry.update(test_flags) if take_screenshot(locale, screenshot_path, client, file_name): screenshot_entry['changed'] = True log_displayed_l10n_strings(client, db, app, app_categ, screenshot_entry, '#unlock-sim-screen') # insert wrong pin (atempt 3 of 3) - continues to puk screen pin_input = client.find_element('css selector', '#pin-input') pin_input.send_keys(wrong_sim_pin) # switch to app://communications.gaiamobile.org/ftu/index.html#data_3g (sim puk screen - unlock-sim-screen) next = client.find_element('css selector', '#unlock-sim-button') next.tap() time.sleep(short_time) # tap the header in order to hide keyboard and get full screenshot of the puk screen header = client.find_element('css selector', '#unlock-sim-header') header.tap() # app://communications.gaiamobile.org/ftu/index.html#data_3g (sim puk screen - unlock-sim-screen - 1st attempt) file_name = 'data_3g-unlock_sim_screen-puk_screen' screenshot_entry = { "id" : file_name, "script" : app, "gaia" : gaia_hash, "hg" : hg_hash, "changed" : False, "path" : screenshot_path} test_flags = { "sim": True, "no-sim": False} if check_flags(test_flags, device_flags): screenshot_entry.update(test_flags) if take_screenshot(locale, screenshot_path, client, file_name): screenshot_entry['changed'] = True log_displayed_l10n_strings(client, db, app, app_categ, screenshot_entry, '#unlock-sim-screen') # invalid puk -> error about puk characters # stay at app://communications.gaiamobile.org/ftu/index.html#data_3g (sim puk screen - unlock-sim-screen) next = client.find_element('css selector', '#unlock-sim-button') next.tap() time.sleep(short_time) # app://communications.gaiamobile.org/ftu/index.html#data_3g (sim puk screen - unlock-sim-screen - puk error) file_name = 'data_3g-unlock_sim_screen-puk_screen-invalid_puk' screenshot_entry = { "id" : file_name, "script" : app, "gaia" : gaia_hash, "hg" : hg_hash, "changed" : False, "path" : screenshot_path} test_flags = { "sim": True, "no-sim": False} if check_flags(test_flags, device_flags): screenshot_entry.update(test_flags) if take_screenshot(locale, screenshot_path, client, file_name): screenshot_entry['changed'] = True log_displayed_l10n_strings(client, db, app, app_categ, screenshot_entry, '#unlock-sim-screen') # insert wrong puk - invalid new pin -> error about pin characters puk_input = client.find_element('css selector', '#puk-input') puk_input.send_keys(wrong_sim_puk) # stay at app://communications.gaiamobile.org/ftu/index.html#data_3g (sim puk screen - unlock-sim-screen) next = client.find_element('css selector', '#unlock-sim-button') next.tap() time.sleep(short_time) # app://communications.gaiamobile.org/ftu/index.html#data_3g (sim puk screen - unlock-sim-screen - pin error) file_name = 'data_3g-unlock_sim_screen-puk_screen-invalid_new_pin' screenshot_entry = { "id" : file_name, "script" : app, "gaia" : gaia_hash, "hg" : hg_hash, "changed" : False, "path" : screenshot_path} test_flags = { "sim": True, "no-sim": False} if check_flags(test_flags, device_flags): screenshot_entry.update(test_flags) if take_screenshot(locale, screenshot_path, client, file_name): screenshot_entry['changed'] = True log_displayed_l10n_strings(client, db, app, app_categ, screenshot_entry, '#unlock-sim-screen') # insert new pin without confirmed it -> error about pin confirmation (wrong puk is preserved at its input) newpin_input = client.find_element('css selector', '#newpin-input') newpin_input.send_keys(sim_pin) # stay at app://communications.gaiamobile.org/ftu/index.html#data_3g (sim puk screen - unlock-sim-screen) next = client.find_element('css selector', '#unlock-sim-button') next.tap() time.sleep(short_time) # app://communications.gaiamobile.org/ftu/index.html#data_3g (sim puk screen - unlock-sim-screen - pin error) file_name = 'data_3g-unlock_sim_screen-puk_screen-invalid_new_pin_confirmation' screenshot_entry = { "id" : file_name, "script" : app, "gaia" : gaia_hash, "hg" : hg_hash, "changed" : False, "path" : screenshot_path} test_flags = { "sim": True, "no-sim": False} if check_flags(test_flags, device_flags): screenshot_entry.update(test_flags) if take_screenshot(locale, screenshot_path, client, file_name): screenshot_entry['changed'] = True log_displayed_l10n_strings(client, db, app, app_categ, screenshot_entry, '#unlock-sim-screen') # insert confirmation of the new pin (wrong puk and new pin are preserved at their inputs) newpin_input = client.find_element('css selector', '#confirm-newpin-input') newpin_input.send_keys(sim_pin) # wrong puk (attempt 1 of 9) # stay at app://communications.gaiamobile.org/ftu/index.html#data_3g (sim puk screen - unlock-sim-screen) next = client.find_element('css selector', '#unlock-sim-button') next.tap() time.sleep(short_time) # app://communications.gaiamobile.org/ftu/index.html#data_3g (sim puk screen - unlock-sim-screen - puk error) file_name = 'data_3g-unlock_sim_screen-puk_screen-wrong_puk-1st_time' screenshot_entry = { "id" : file_name, "script" : app, "gaia" : gaia_hash, "hg" : hg_hash, "changed" : False, "path" : screenshot_path} test_flags = { "sim": True, "no-sim": False} if check_flags(test_flags, device_flags): screenshot_entry.update(test_flags) if take_screenshot(locale, screenshot_path, client, file_name): screenshot_entry['changed'] = True log_displayed_l10n_strings(client, db, app, app_categ, screenshot_entry, '#unlock-sim-screen') # insert wrong puk (attempt 2 of 9) (new pin and its confirmation are preserved at their inputs) puk_input = client.find_element('css selector', '#puk-input') puk_input.send_keys(wrong_sim_puk) # stay at app://communications.gaiamobile.org/ftu/index.html#data_3g (sim puk screen - unlock-sim-screen) next = client.find_element('css selector', '#unlock-sim-button') next.tap() time.sleep(short_time) # app://communications.gaiamobile.org/ftu/index.html#data_3g (sim puk screen - unlock-sim-screen - 2nd attempt) file_name = 'data_3g-unlock_sim_screen-puk_screen-wrong_puk-2nd_time' screenshot_entry = { "id" : file_name, "script" : app, "gaia" : gaia_hash, "hg" : hg_hash, "changed" : False, "path" : screenshot_path} test_flags = { "sim": True, "no-sim": False} if check_flags(test_flags, device_flags): screenshot_entry.update(test_flags) if take_screenshot(locale, screenshot_path, client, file_name): screenshot_entry['changed'] = True log_displayed_l10n_strings(client, db, app, app_categ, screenshot_entry, '#unlock-sim-screen') # insert right puk (attempt 2 of 9) (new pin and its confirmation are preserved at their inputs) puk_input = client.find_element('css selector', '#puk-input') puk_input.send_keys(sim_puk) # switch to app://communications.gaiamobile.org/ftu/index.html#data_3g next = client.find_element('css selector', '#unlock-sim-button') next.tap() time.sleep(short_time) # app://communications.gaiamobile.org/ftu/index.html#data_3g file_name = 'data_3g' screenshot_entry = { "id" : file_name, "script" : app, "gaia" : gaia_hash, "hg" : hg_hash, "changed" : False, "path" : screenshot_path} test_flags = { "sim": True, "no-sim": False} if check_flags(test_flags, device_flags): screenshot_entry.update(test_flags) if take_screenshot(locale, screenshot_path, client, file_name): screenshot_entry['changed'] = True log_displayed_l10n_strings(client, db, app, app_categ, screenshot_entry, '#activation-screen') # switch to app://communications.gaiamobile.org/ftu/index.html#wifi next = client.find_element('css selector', '#forward') next.tap() time.sleep(long_time) # enable overlay "scanningNetworks" spinner screen (loading-overlay) client.execute_script("window.wrappedJSObject.utils.overlay.show('scanningNetworks', 'spinner');") time.sleep(middle_time) # overlay "scanningNetworks" spinner screen file_name = 'wifi-loading_overlay-scanning_networks' screenshot_entry = { "id" : file_name, "script" : app, "gaia" : gaia_hash, "hg" : hg_hash, "changed" : False, "path" : screenshot_path} test_flags = {} if check_flags(test_flags, device_flags): screenshot_entry.update(test_flags) if take_screenshot(locale, screenshot_path, client, file_name): screenshot_entry['changed'] = True log_displayed_l10n_strings(client, db, app, app_categ, screenshot_entry, '#loading-overlay') # disable overlay "scanningNetworks" spinner screen client.execute_script("window.wrappedJSObject.utils.overlay.hide('scanningNetworks', 'spinner');") time.sleep(middle_time) # app://communications.gaiamobile.org/ftu/index.html#wifi file_name = 'wifi' screenshot_entry = { "id" : file_name, "script" : app, "gaia" : gaia_hash, "hg" : hg_hash, "changed" : False, "path" : screenshot_path} test_flags = {} if check_flags(test_flags, device_flags): screenshot_entry.update(test_flags) if take_screenshot(locale, screenshot_path, client, file_name): screenshot_entry['changed'] = True log_displayed_l10n_strings(client, db, app, app_categ, screenshot_entry, '#wifi') # switch to app://communications.gaiamobile.org/ftu/index.html#date_and_time next = client.find_element('css selector', '#forward') next.tap() time.sleep(short_time) # Set time in order to be the same at every screenshot set_time(client) # app://communications.gaiamobile.org/ftu/index.html#date_and_time file_name = 'date_and_time' screenshot_entry = { "id" : file_name, "script" : app, "gaia" : gaia_hash, "hg" : hg_hash, "changed" : False, "path" : screenshot_path} test_flags = {} if check_flags(test_flags, device_flags): screenshot_entry.update(test_flags) if take_screenshot(locale, screenshot_path, client, file_name): screenshot_entry['changed'] = True log_displayed_l10n_strings(client, db, app, app_categ, screenshot_entry, '#date_and_time') # switch to app://communications.gaiamobile.org/ftu/index.html#geolocation next = client.find_element('css selector', '#forward') next.tap() time.sleep(short_time) # app://communications.gaiamobile.org/ftu/index.html#geolocation file_name = 'geolocation' screenshot_entry = { "id" : file_name, "script" : app, "gaia" : gaia_hash, "hg" : hg_hash, "changed" : False, "path" : screenshot_path} test_flags = {} if check_flags(test_flags, device_flags): screenshot_entry.update(test_flags) if take_screenshot(locale, screenshot_path, client, file_name): screenshot_entry['changed'] = True log_displayed_l10n_strings(client, db, app, app_categ, screenshot_entry, '#geolocation') # switch to app://communications.gaiamobile.org/ftu/index.html#import_contacts next = client.find_element('css selector', '#forward') next.tap() time.sleep(middle_time) # app://communications.gaiamobile.org/ftu/index.html#import_contacts file_name = 'import_contacts' screenshot_entry = { "id" : file_name, "script" : app, "gaia" : gaia_hash, "hg" : hg_hash, "changed" : False, "path" : screenshot_path} test_flags = {} if check_flags(test_flags, device_flags): screenshot_entry.update(test_flags) if take_screenshot(locale, screenshot_path, client, file_name): screenshot_entry['changed'] = True log_displayed_l10n_strings(client, db, app, app_categ, screenshot_entry, '#import_contacts') # switch to app://communications.gaiamobile.org/ftu/index.html#welcome_browser next = client.find_element('css selector', '#forward') next.tap() time.sleep(short_time) # app://communications.gaiamobile.org/ftu/index.html#welcome_browser file_name = 'welcome_browser' screenshot_entry = { "id" : file_name, "script" : app, "gaia" : gaia_hash, "hg" : hg_hash, "changed" : False, "path" : screenshot_path} test_flags = {} if check_flags(test_flags, device_flags): screenshot_entry.update(test_flags) if take_screenshot(locale, screenshot_path, client, file_name): screenshot_entry['changed'] = True log_displayed_l10n_strings(client, db, app, app_categ, screenshot_entry) # switch to app://communications.gaiamobile.org/ftu/index.html#browser_privacy next = client.find_element('css selector', '#forward') next.tap() time.sleep(short_time) # app://communications.gaiamobile.org/ftu/index.html#browser_privacy file_name = 'browser_privacy' screenshot_entry = { "id" : file_name, "script" : app, "gaia" : gaia_hash, "hg" : hg_hash, "changed" : False, "path" : screenshot_path} test_flags = {} if check_flags(test_flags, device_flags): screenshot_entry.update(test_flags) if take_screenshot(locale, screenshot_path, client, file_name): screenshot_entry['changed'] = True log_displayed_l10n_strings(client, db, app, app_categ, screenshot_entry) # switch to app://communications.gaiamobile.org/ftu/index.html#step1 (first tutorial screen) next = client.find_element('css selector', '#forward') next.tap() time.sleep(long_time) # app://communications.gaiamobile.org/ftu/index.html#step1 (first tutorial screen) file_name = 'step1-first_tutorial_screen' screenshot_entry = { "id" : file_name, "script" : app, "gaia" : gaia_hash, "hg" : hg_hash, "changed" : False, "path" : screenshot_path} test_flags = {} if check_flags(test_flags, device_flags): screenshot_entry.update(test_flags) if take_screenshot(locale, screenshot_path, client, file_name): screenshot_entry['changed'] = True log_displayed_l10n_strings(client, db, app, app_categ, screenshot_entry) # switch to app://communications.gaiamobile.org/ftu/index.html#step1 next = client.find_element('css selector', '#lets-go-button') next.tap() time.sleep(long_time) # app://communications.gaiamobile.org/ftu/index.html#step1 file_name = 'step1' screenshot_entry = { "id" : file_name, "script" : app, "gaia" : gaia_hash, "hg" : hg_hash, "changed" : False, "path" : screenshot_path} test_flags = {} if check_flags(test_flags, device_flags): screenshot_entry.update(test_flags) if take_screenshot(locale, screenshot_path, client, file_name): screenshot_entry['changed'] = True log_displayed_l10n_strings(client, db, app, app_categ, screenshot_entry) # switch to app://communications.gaiamobile.org/ftu/index.html#step2 next = client.find_element('css selector', '#forwardTutorial') next.tap() time.sleep(short_time) # app://communications.gaiamobile.org/ftu/index.html#step2 file_name = 'step2' screenshot_entry = { "id" : file_name, "script" : app, "gaia" : gaia_hash, "hg" : hg_hash, "changed" : False, "path" : screenshot_path} test_flags = {} if check_flags(test_flags, device_flags): screenshot_entry.update(test_flags) if take_screenshot(locale, screenshot_path, client, file_name): screenshot_entry['changed'] = True log_displayed_l10n_strings(client, db, app, app_categ, screenshot_entry) # switch to app://communications.gaiamobile.org/ftu/index.html#step3 next = client.find_element('css selector', '#forwardTutorial') next.tap() time.sleep(short_time) # app://communications.gaiamobile.org/ftu/index.html#step3 file_name = 'step3' screenshot_entry = { "id" : file_name, "script" : app, "gaia" : gaia_hash, "hg" : hg_hash, "changed" : False, "path" : screenshot_path} test_flags = {} if check_flags(test_flags, device_flags): screenshot_entry.update(test_flags) if take_screenshot(locale, screenshot_path, client, file_name): screenshot_entry['changed'] = True log_displayed_l10n_strings(client, db, app, app_categ, screenshot_entry) # switch to app://communications.gaiamobile.org/ftu/index.html#step4 next = client.find_element('css selector', '#forwardTutorial') next.tap() time.sleep(short_time) # app://communications.gaiamobile.org/ftu/index.html#step4 file_name = 'step4' screenshot_entry = { "id" : file_name, "script" : app, "gaia" : gaia_hash, "hg" : hg_hash, "changed" : False, "path" : screenshot_path} test_flags = {} if check_flags(test_flags, device_flags): screenshot_entry.update(test_flags) if take_screenshot(locale, screenshot_path, client, file_name): screenshot_entry['changed'] = True log_displayed_l10n_strings(client, db, app, app_categ, screenshot_entry) # switch to app://communications.gaiamobile.org/ftu/index.html#step4 (last tutorial screen) next = client.find_element('css selector', '#forwardTutorial') next.tap() time.sleep(long_time) # app://communications.gaiamobile.org/ftu/index.html#step4 (last tutorial screen) file_name = 'step4-last_tutorial_screen' screenshot_entry = { "id" : file_name, "script" : app, "gaia" : gaia_hash, "hg" : hg_hash, "changed" : False, "path" : screenshot_path} test_flags = {} if check_flags(test_flags, device_flags): screenshot_entry.update(test_flags) if take_screenshot(locale, screenshot_path, client, file_name): screenshot_entry['changed'] = True log_displayed_l10n_strings(client, db, app, app_categ, screenshot_entry) # Close ftu frame next = client.find_element('css selector', '#tutorialFinished') next.tap() time.sleep(short_time) set_db(locale, db) else: #TO DO raise proper error print "switch to ftu frame failed"
class current_frame(): filename_screenshot = "" filename_htmldump = "" def main(self, LOGDIR): # # The first variable is the log directory. # ucount = 0 self.marionette = Marionette(host='localhost', port=2828) self.marionette.start_session() self.marionette.set_search_timeout(1000) # # Now loop through all the iframes, gathering details about each one. # print "" print "Iframe for 'top level' () ..." self.filename_screenshot = LOGDIR + "top_level" + ".png" self.filename_htmldump = LOGDIR + "top_level" + ".html" self.marionette.switch_to_frame() self.record_frame() frames = self.marionette.find_elements("tag name", "iframe") for fnum in range (0, len(frames)): # # App name is usually in the "src" attribute, so it's worth a shot.. # frame_src = frames[fnum].get_attribute("src") if frame_src != "": startpos = frame_src.index('/') + 2 stoppos = frame_src.index('.') appname = frame_src[startpos:stoppos] filename = appname else: ucount = ucount + 1 appname = "(unknown)" filename = "unknown_" + str(ucount) # # Because we call this script sometimes when we hit a Marionette issue, # these filenames may already exist (and we'd overwrite them!), so # add 'DEBUG_' to the start of the filename. # filename = "DEBUG_" + filename filename_details = LOGDIR + filename + "_iframe_details.txt" self.filename_screenshot = LOGDIR + filename + ".png" self.filename_htmldump = LOGDIR + filename + ".html" # # This iframe gives me problems sometimes, so I'm ignoring it for now. # if appname == "costcontrol": continue print "" print "Iframe for app \"" + appname + "\" ..." # # Record the iframe details (pretty verbose, but 'execute_script' # wasn't letting me use 'for' loops in js for some reason). # print " |_ iframe details saved to : " + filename_details f = open(filename_details, 'w') f.write("Attributes for this iframe ...\n") num_attribs = self.marionette.execute_script("return document.getElementsByTagName('iframe')[" + str(fnum) + "].attributes.length;") for i in range(0,num_attribs): attrib_name = self.marionette.execute_script("return document.getElementsByTagName('iframe')[" + str(fnum) + "].attributes[" + str(i) + "].nodeName;") attrib_value = self.marionette.execute_script("return document.getElementsByTagName('iframe')[" + str(fnum) + "].attributes[" + str(i) + "].nodeValue;") f.write(" |_ " + attrib_name.ljust(20) + ": \"" + attrib_value + "\"\n") f.close() # # Switch to this frame. # self.marionette.switch_to_frame(fnum) self.record_frame() self.marionette.switch_to_frame() def record_frame(self): # # Take the screenshot and save it to the file. # print " |_ screenshot saved to : " + self.filename_screenshot screenshot = self.marionette.screenshot()[22:] with open(self.filename_screenshot, 'w') as f: f.write(base64.decodestring(screenshot)) f.close() # # Take the html dump and save it to the file. # print " |_ html dump saved to : " + self.filename_htmldump f = open(self.filename_htmldump, 'w') f.write(self.marionette.page_source.encode('ascii', 'ignore') ) f.close()
def uninstall_app(app_name, adb_path="adb", script_timeout=5000, marionette=None, device_serial=None): """ Uninstalls the given app. NOTE: if a marionette session is passed, this function switches to the top-most frame. """ def check_uninstall(marionette): uninstall = marionette.execute_script("return window.wrappedJSObject.uninstall;") return uninstall != 'none' def check_click_uninstall(marionette): button = marionette.find_element('css selector', 'gaia-confirm .confirm') try: button.click() not_displayed = not button.is_displayed() except StaleElementException: not_displayed = True return not_displayed dm = mozdevice.DeviceManagerADB(adbPath=adb_path, deviceSerial=device_serial) installed_app_name = app_name.lower() installed_app_name = installed_app_name.replace(" ", "-") dm.forward("tcp:2828", "tcp:2828") print 'requesting uninstall of app', app_name if not marionette: m = Marionette() m.start_session() else: m = marionette m.switch_to_frame() m.set_context("chrome") m.execute_script(""" Components.utils.import("resource://gre/modules/Services.jsm"); window.wrappedJSObject.uninstall = 'none'; Services.obs.addObserver(function observer(subject, topic) { Services.obs.removeObserver(observer, topic); window.wrappedJSObject.uninstall = 'ask'; }, "webapps-ask-uninstall", false); Services.obs.addObserver(function observer(subject, topic) { Services.obs.removeObserver(observer, topic); window.wrappedJSObject.uninstall = 'uninstall'; }, "webapps-uninstall", false); """) m.set_context("content") uninstall_app = """ var uninstallWithName = function(name) { let apps = window.wrappedJSObject.applications || window.wrappedJSObject.Applications; let installedApps = apps.installedApps; for (let manifestURL in installedApps) { let app = installedApps[manifestURL]; let origin = null; let entryPoints = app.manifest.entry_points; if (entryPoints) { for (let ep in entryPoints) { let currentEntryPoint = entryPoints[ep]; let appName = currentEntryPoint.name; if (name == appName.toLowerCase()) { window.wrappedJSObject.navigator.mozApps.mgmt.uninstall(app); return true; } } } else { let appName = app.manifest.name; if (name == appName.toLowerCase()) { window.wrappedJSObject.navigator.mozApps.mgmt.uninstall(app); return true; } } } return false; }; return uninstallWithName("%s"); """ m.set_script_timeout(script_timeout) result = m.execute_script(uninstall_app % app_name.lower()) if result: m.set_context("chrome") Wait(m, 10).until(check_uninstall) uninstall = m.execute_script("return window.wrappedJSObject.uninstall;") m.set_context("content") if uninstall == 'ask': m.switch_to_frame() Wait(m, 20).until(element_displayed(m.find_element('css selector', 'gaia-confirm .confirm'))) Wait(m, 20).until(check_click_uninstall) if not marionette: m.delete_session()
class TestCase(tornado.testing.AsyncTestCase): def __init__(self, *args, **kwargs): #self.config = kwargs.pop("config") self.handler = kwargs.pop('handler') self.io_loop = kwargs.pop('io_loop') self.cert_test_app = None super(TestCase, self).__init__(*args, **kwargs) def setUp(self): super(TestCase, self).setUp() # import environment # from environment import InProcessTestEnvironment # self.environment = environment.get(InProcessTestEnvironment) # self.server = self.environment.server self.marionette = None self.create_marionette() self.io_loop.run_sync(self.use_cert_app) def tearDown(self): super(TestCase, self).tearDown() self.io_loop.run_sync(self.close_cert_app) def create_marionette(self): if not self.marionette or not self.marionette.session: self.marionette = Marionette() self.marionette.start_session() @tornado.gen.coroutine def use_cert_app(self): # app management is done in the system app self.marionette.switch_to_frame() self.marionette.import_script("tests/app_management.js") script = "GaiaApps.launchWithName('CertTest App');" try: self.cert_test_app = self.marionette.execute_async_script(script, script_timeout=5000) self.marionette.switch_to_frame(self.cert_test_app["frame"]) self.assertTrue('certtest' in self.marionette.get_url()) except MarionetteException as e: ok = yield self.instruct("Could not launch CertTest app automatically." \ "Please launch by hand then hit OK to continue.") self.assertTrue(ok, "Could not launch CertTest app") except Exception as e: message = "Unexpected exception: %s" % e yield self.instruct(message) self.fail(message) @tornado.gen.coroutine def close_cert_app(self): self.marionette.import_script("tests/app_management.js") # app management is done in the system app self.marionette.switch_to_frame() script = "GaiaApps.kill('%s');" % self.cert_test_app["origin"] try: self.marionette.execute_async_script(script, script_timeout=5000) self.assertTrue('certtest' not in self.marionette.get_url()) except MarionetteException as e: ok = yield self.instruct("Could not close CertTest app automatically." \ "Please close by hand then hit OK to continue.") self.assertTrue(ok, "Could not close CertTest app") except Exception as e: message = "Unexpected exception: %s" % e yield self.instruct(message) self.fail(message) def get_new_ioloop(self): return self.io_loop def prompt(self, message): """Prompt the user for a reply. Returns a future which must be yielded. This will trigger an overlay in the host browser window which can be used to tell the user to perform an action or to input some manual data for us to work on. Sample usage:: answer = yield prompt("What's the meaning of life?") assert answer == 42 This function is a simple wrapper for ``tornado.gen.Task``, and is equivalent to the usage of that. :param message: The question to ask or message to give the user. :returns: A generator which must be yielded. Once yielded, the return value will be the value of the prompt, or False if the user hit 'Cancel' """ return tornado.gen.Task(self.handler.get_user_input, message) def instruct(self, message): """Presents the user with an instruction. Returns a future which must be yielded. This will trigger an overlay in the host browser window which can be used to tell the user to perform an action or to input some manual data for us to work on. Sample usage:: answer = yield prompt("What's the meaning of life?") assert answer == 42 This function is a simple wrapper for ``tornado.gen.Task``, and is equivalent to the usage of that. :param message: The instruction you want to give the user :returns: A generator which must be yielded. Once yielded, the reutrn value will be either True if they succeeded or False if they did not. """ return tornado.gen.Task(self.handler.instruct_user, message)
waitFor( function() { window.wrappedJSObject.LockScreen.unlock(); waitFor( function() { finish(window.wrappedJSObject.LockScreen.locked); }, function() { return !window.wrappedJSObject.LockScreen.locked; } ); }, function() { return !!window.wrappedJSObject.LockScreen; } ); """ from marionette import Marionette marionette = Marionette('localhost', 2828) marionette.start_session() marionette.import_script('gaia_apps.js') marionette.set_script_timeout(60000) marionette.execute_script(unlock) result = marionette.execute_async_script("GaiaApps.launchWithName('%s')" % "MozCampAsia-QualityApps") marionette.switch_to_frame(result.get("frame")) pdb.set_trace()
class TestRun(object): def __init__(self, adb="adb", serial=None): self.test_results = {} self.test_results_file = None self.m = None self.gaia_apps = None self.screenshot_path = None self.logcat_path = None self.app_name = None self.attempt = None self.num_apps = None self.device = None self.serial = serial self.port = None self.run_log = logging.getLogger('marketplace-test') if self.serial: self.dm = DeviceManagerADB(adbPath=adb, deviceSerial=serial) else: self.dm = DeviceManagerADB(adbPath=adb) def reset_marionette(self): try: self.m.delete_session() except Exception: pass self.m = None self.get_marionette() def get_marionette(self): if not self.m: self.m = Marionette(port=self.port) self.m.start_session() self.device = GaiaDevice(self.m) self.device.add_device_manager(self.dm) self.gaia_apps = GaiaApps(self.m) else: tries = 5 while tries > 0: try: self.m.get_url() break except MarionetteException as e: if "Please start a session" in str(e): time.sleep(5) self.m = Marionette(port=self.port) self.m.start_session() self.device = GaiaDevice(self.m) self.device.add_device_manager(self.dm) self.gaia_apps = GaiaApps(self.m) tries -= 1 else: raise e else: self.run_log.error("Can't connect to marionette, rebooting") self.restart_device() return self.m def write_to_file(self, data): with open("%s.tmp" % self.test_results_file, "w") as f: f.write(data) shutil.copyfile("%s.tmp" % self.test_results_file, self.test_results_file) def add_values(self, key, value): if self.serial: self.test_results["%s_%s" % (key, self.serial)] = value else: self.test_results["%s" % key] = value def add_result(self, passed=False, status=None, uninstalled_failure=False): values = {} if status: if not passed: values["status"] = "FAILED: %s" % status else: values["status"] = "PASS" if self.screenshot_path: values["screenshot"] = self.screenshot_path if self.logcat_path: values["logcat"] = self.logcat_path if uninstalled_failure: values["uninstalled_failure"] = uninstalled_failure entry = "%s_%s" % (self.app_name, self.attempt) self.test_results[entry] = values def launch_with_manifest(self, manifest): self.m.switch_to_frame() result = self.m.execute_async_script("GaiaApps.launchWithManifestURL('%s')" % manifest, script_timeout=30000) if result == False: raise Exception("launch timed out") app = GaiaApp(frame=result.get('frame'), src=result.get('src'), name=result.get('name'), origin=result.get('origin')) if app.frame_id is None: raise Exception("failed to launch; there is no app frame") self.m.switch_to_frame(app.frame_id) return app def uninstall_with_manifest(self, manifest): self.m.switch_to_frame() script = """ GaiaApps.locateWithManifestURL('%s', null, function uninstall(app) { navigator.mozApps.mgmt.uninstall(app); marionetteScriptFinished(true); }); """ result = self.m.execute_async_script(script % manifest, script_timeout=60000) if result != True: self.add_result(status="Failed to uninstall app with url '%s'" % manifest) return app def forward_port(self): # get unused port s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.bind(('localhost', 0)) addr, port = s.getsockname() s.close() dm_tries = 0 self.run_log.info("using port %s" % port) while dm_tries < 20: if self.dm.forward("tcp:%d" % port, "tcp:2828") == 0: break dm_tries += 1 time.sleep(3) else: return False self.port = port return True def restart_device(self, restart_tries=0): self.run_log.info("rebooting") # TODO restarting b2g doesn't seem to work... reboot then while restart_tries < 3: restart_tries += 1 self.dm.reboot(wait=True) self.run_log.info("forwarding") if not self.forward_port(): self.run_log.error("couldn't forward port in time, rebooting") continue self.m = Marionette(port=self.port) if not self.m.wait_for_port(180): self.run_log.error("couldn't contact marionette in time, rebooting") continue time.sleep(1) self.m.start_session() try: Wait(self.m, timeout=240).until(lambda m: m.find_element("id", "lockscreen-container").is_displayed()) # It retuns a little early time.sleep(2) self.device = GaiaDevice(self.m) self.device.add_device_manager(self.dm) self.device.unlock() self.gaia_apps = GaiaApps(self.m) except (MarionetteException, IOError, socket.error) as e: self.run_log.error("got exception: %s, going to retry" % e) try: self.m.delete_session() except: # at least attempt to clear the session if possible pass continue break else: raise Exception("Couldn't restart the device in time, even after 3 tries") def readystate_wait(self, app): try: Wait(self.get_marionette(), timeout=30).until(lambda m: m.execute_script("return window.document.readyState;") == "complete") except ScriptTimeoutException as e: return False return True def record_icons(self): self.device.touch_home_button() icons = self.m.find_elements("class name", "icon") self.num_apps = len(icons) def check_if_app_installed(self, timeout=180): # TODO: Find a better way to do this than checking homescreen # I hope there is one... self.device.touch_home_button() icons = self.m.find_elements("class name", "icon") start = time.time() end = start + 180 found_icon = None claims_its_loaded = 0 # this is used in case 'loading' isn't applied immediately to the icon while time.time() < end: if not found_icon: icons = self.m.find_elements("class name", "icon") # We can't do set comparison b/c references change if len(icons) > self.num_apps: for icon in icons: if "loading" in icon.get_attribute("innerHTML"): found_icon = icon break else: claims_its_loaded += 1 if claims_its_loaded == 3: return True else: if "loading" not in found_icon.get_attribute("innerHTML"): return True time.sleep(2) return False
class TestRun(object): def __init__(self, adb="adb", serial=None): self.test_results = {} self.test_results_file = None self.m = None self.gaia_apps = None self.screenshot_path = None self.logcat_path = None self.app_name = None self.attempt = None self.num_apps = None self.device = None self.serial = serial self.port = None self.run_log = logging.getLogger('marketplace-test') if self.serial: self.dm = DeviceManagerADB(adbPath=adb, deviceSerial=serial) else: self.dm = DeviceManagerADB(adbPath=adb) def reset_marionette(self): try: self.m.delete_session() except Exception: pass self.m = None self.get_marionette() def get_marionette(self): if not self.m: self.m = Marionette(port=self.port) self.m.start_session() self.device = GaiaDevice(self.m) self.device.add_device_manager(self.dm) self.gaia_apps = GaiaApps(self.m) else: tries = 5 while tries > 0: try: self.m.get_url() break except MarionetteException as e: if "Please start a session" in str(e): time.sleep(5) self.m = Marionette(port=self.port) self.m.start_session() self.device = GaiaDevice(self.m) self.device.add_device_manager(self.dm) self.gaia_apps = GaiaApps(self.m) tries -= 1 else: raise e else: self.run_log.error("Can't connect to marionette, rebooting") self.restart_device() return self.m def write_to_file(self, data): with open("%s.tmp" % self.test_results_file, "w") as f: f.write(data) shutil.copyfile("%s.tmp" % self.test_results_file, self.test_results_file) def add_values(self, key, value): if self.serial: self.test_results["%s_%s" % (key, self.serial)] = value else: self.test_results["%s" % key] = value def add_result(self, passed=False, status=None, uninstalled_failure=False): values = {} if status: if not passed: values["status"] = "FAILED: %s" % status else: values["status"] = "PASS" if self.screenshot_path: values["screenshot"] = self.screenshot_path if self.logcat_path: values["logcat"] = self.logcat_path if uninstalled_failure: values["uninstalled_failure"] = uninstalled_failure entry = "%s_%s" % (self.app_name, self.attempt) self.test_results[entry] = values def launch_with_manifest(self, manifest): self.m.switch_to_frame() result = self.m.execute_async_script( "GaiaApps.launchWithManifestURL('%s')" % manifest, script_timeout=30000) if result == False: raise Exception("launch timed out") app = GaiaApp(frame=result.get('frame'), src=result.get('src'), name=result.get('name'), origin=result.get('origin')) if app.frame_id is None: raise Exception("failed to launch; there is no app frame") self.m.switch_to_frame(app.frame_id) return app def uninstall_with_manifest(self, manifest): self.m.switch_to_frame() script = """ GaiaApps.locateWithManifestURL('%s', null, function uninstall(app) { navigator.mozApps.mgmt.uninstall(app); marionetteScriptFinished(true); }); """ result = self.m.execute_async_script(script % manifest, script_timeout=60000) if result != True: self.add_result(status="Failed to uninstall app with url '%s'" % manifest) return app def forward_port(self): # get unused port s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.bind(('localhost', 0)) addr, port = s.getsockname() s.close() dm_tries = 0 self.run_log.info("using port %s" % port) while dm_tries < 20: if self.dm.forward("tcp:%d" % port, "tcp:2828") == 0: break dm_tries += 1 time.sleep(3) else: return False self.port = port return True def restart_device(self, restart_tries=0): self.run_log.info("rebooting") # TODO restarting b2g doesn't seem to work... reboot then while restart_tries < 3: restart_tries += 1 self.dm.reboot(wait=True) self.run_log.info("forwarding") if not self.forward_port(): self.run_log.error("couldn't forward port in time, rebooting") continue self.m = Marionette(port=self.port) if not self.m.wait_for_port(180): self.run_log.error( "couldn't contact marionette in time, rebooting") continue time.sleep(1) self.m.start_session() try: Wait(self.m, timeout=240).until(lambda m: m.find_element( "id", "lockscreen-container").is_displayed()) # It retuns a little early time.sleep(2) self.device = GaiaDevice(self.m) self.device.add_device_manager(self.dm) self.device.unlock() self.gaia_apps = GaiaApps(self.m) except (MarionetteException, IOError, socket.error) as e: self.run_log.error("got exception: %s, going to retry" % e) try: self.m.delete_session() except: # at least attempt to clear the session if possible pass continue break else: raise Exception( "Couldn't restart the device in time, even after 3 tries") def readystate_wait(self, app): try: Wait(self.get_marionette(), timeout=30).until(lambda m: m.execute_script( "return window.document.readyState;") == "complete") except ScriptTimeoutException as e: return False return True def record_icons(self): self.device.touch_home_button() icons = self.m.find_elements("class name", "icon") self.num_apps = len(icons) def check_if_app_installed(self, timeout=180): # TODO: Find a better way to do this than checking homescreen # I hope there is one... self.device.touch_home_button() icons = self.m.find_elements("class name", "icon") start = time.time() end = start + 180 found_icon = None claims_its_loaded = 0 # this is used in case 'loading' isn't applied immediately to the icon while time.time() < end: if not found_icon: icons = self.m.find_elements("class name", "icon") # We can't do set comparison b/c references change if len(icons) > self.num_apps: for icon in icons: if "loading" in icon.get_attribute("innerHTML"): found_icon = icon break else: claims_its_loaded += 1 if claims_its_loaded == 3: return True else: if "loading" not in found_icon.get_attribute("innerHTML"): return True time.sleep(2) return False
class current_frame(): def main(self, LOGDIR, p_el, p_frame_array=False): # # p_el is an array for the element. # p_frame_array is a list of iframes to iterate through (optional). # self.marionette = Marionette(host='localhost', port=2828) self.marionette.start_session() self.marionette.set_search_timeout(1000) # # Switch to the correct iframe (unless it's "()"). # self.marionette.switch_to_frame() first_iframe = True for x in p_frame_array: # (just to make it look nice ;) typ_str = "'" + x[0] + "'" if first_iframe: first_iframe = False print "" print "Switching to iframe with " + typ_str.rjust(10) + " = '" + x[1] + "'" else: print "... then to iframe with " + typ_str.rjust(10) + " = '" + x[1] + "'" my_iframe = self.marionette.find_element("xpath", "//iframe[@" + x[0] + "='" + x[1] + "']") self.marionette.switch_to_frame(my_iframe) if first_iframe: print "" print "Using 'top level' iframe () ..." # # Grab a screenshot and html dump of this frame. # p_sfnam = LOGDIR + "screenshot.png" p_hfnam = LOGDIR + "html_dump.html" print "" print "Screenshot of this frame saved to: " + p_sfnam screenshot = self.marionette.screenshot()[22:] with open(p_sfnam, 'w') as f: f.write(base64.decodestring(screenshot)) f.close() print "HTML dump of this frame saved to : " + p_hfnam f = open(p_hfnam, 'w') f.write(self.marionette.page_source.encode('ascii', 'ignore') ) f.close() # # Test to see if the element is present / displayed / etc... # print "" print "Checking for element: " + str(p_el) b_present = False b_displayed = False b_enabled = False try: x = self.marionette.find_element(*p_el) if x: b_present = True if x.is_displayed(): b_displayed = True if x.is_enabled(): b_enabled = True except: pass print "" print "Present : " + str(b_present) print "Displayed: " + str(b_displayed) print "Enabled : " + str(b_enabled) print ""
#!/usr/bin/python2.7 # # Script to work around Marionette bug 879816 (cannot click the modal 'ok' button # following clicking something else). # from marionette import Marionette marionette = Marionette(host='localhost', port=2828) marionette.start_session() marionette.switch_to_frame() marionette.execute_script("document.getElementById('modal-dialog-prompt-ok').click();")