def __init__(self, marionette): self.marionette = marionette self.apps = GaiaApps(self.marionette) self.accessibility = Accessibility(self.marionette) self.frame = None self.entry_point = hasattr(self, 'entry_point') and self.entry_point or None
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 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 set_up_device(args): mc = get_marionette(args) device = GaiaDevice(mc) try: device.restart_b2g() except Exception: print ' ** Check to make sure you don\'t have desktop B2G running' raise apps = GaiaApps(mc) data_layer = GaiaData(mc) lockscreen = LockScreen(mc) mc.setup_touch() lockscreen.unlock() apps.kill_all() if args.wifi_ssid: print 'Configuring WiFi' if not args.wifi_key or not args.wifi_pass: args.error('Missing --wifi_key or --wifi_pass option') args.wifi_key = args.wifi_key.upper() data_layer.enable_wifi() if args.wifi_key == 'WPA-PSK': pass_key = 'psk' elif args.wifi_key == 'WEP': pass_key = 'wep' else: args.error('not sure what key to use for %r' % args.wifi_key) data = {'ssid': args.wifi_ssid, 'keyManagement': args.wifi_key, pass_key: args.wifi_pass} data_layer.connect_to_wifi(data) for manifest in args.apps: # There is probably a way easier way to do this by adb pushing # something. Send me a patch! mc.switch_to_frame() try: data = requests.get(manifest).json() app_name = data['name'] all_apps = set(a['manifest']['name'] for a in get_installed(apps)) if app_name not in all_apps: print 'Installing %s from %s' % (app_name, manifest) mc.execute_script('navigator.mozApps.install("%s");' % manifest) wait_for_element_displayed(mc, 'id', 'app-install-install-button') yes = mc.find_element('id', 'app-install-install-button') mc.tap(yes) # This still works but the id check broke. # See https://bugzilla.mozilla.org/show_bug.cgi?id=853878 wait_for_element_displayed(mc, 'id', 'system-banner') except Exception, exc: print ' ** installing manifest %s failed (maybe?)' % manifest print ' ** error: %s: %s' % (exc.__class__.__name__, exc) continue
def __init__(self, marionette): Base.__init__(self, marionette) GaiaApps(marionette).switch_to_displayed_app() header = self.marionette.find_element( *self._ice_settings_header_locator) Wait(self.marionette).until( lambda m: header.rect['x'] == 0 and header.is_displayed())
def __init__(self, marionette): self.marionette = marionette self.apps = GaiaApps(self.marionette) self.accessibility = Accessibility(self.marionette) self.frame = None self.manifest_url = None self.entry_point = None
def __init__(self, marionette): self.marionette = marionette self.apps = GaiaApps(self.marionette) self.accessibility = Accessibility(self.marionette) self.frame = None self.manifest_url = hasattr(self, 'manifest_url') and self.manifest_url or None self.entry_point = hasattr(self, 'entry_point') and self.entry_point or None
def install_apps(): mc = get_marionette(args) device = GaiaDevice(mc) try: device.restart_b2g() print 'Your device is rebooting.' except Exception: print ' ** Check to make sure you don\'t have desktop B2G running' raise apps = GaiaApps(mc) apps.kill_all() lockscreen = LockScreen(mc) lockscreen.unlock() if args.wifi_ssid: print 'Configuring WiFi' if not args.wifi_key or not args.wifi_pass: args.error('Missing --wifi_key or --wifi_pass option') args.wifi_key = args.wifi_key.upper() data_layer = GaiaData(mc) data_layer.enable_wifi() if args.wifi_key == 'WPA-PSK': pass_key = 'psk' elif args.wifi_key == 'WEP': pass_key = 'wep' else: args.error('not sure what key to use for %r' % args.wifi_key) data = { 'ssid': args.wifi_ssid, 'keyManagement': args.wifi_key, pass_key: args.wifi_pass } data_layer.connect_to_wifi(data) # disconnect marionette client because install_app would need it mc.client.close() # install apps one by one for manifest in args.apps: args.manifest = manifest args.app = None install_app(args)
def install_apps(): mc = get_marionette(args) device = GaiaDevice(mc) try: device.restart_b2g() print 'Your device is rebooting.' except Exception: print ' ** Check to make sure you don\'t have desktop B2G running' raise apps = GaiaApps(mc) apps.kill_all() lockscreen = LockScreen(mc) lockscreen.unlock() if args.wifi_ssid: print 'Configuring WiFi' if not args.wifi_key or not args.wifi_pass: args.error('Missing --wifi_key or --wifi_pass option') args.wifi_key = args.wifi_key.upper() data_layer = GaiaData(mc) data_layer.enable_wifi() if args.wifi_key == 'WPA-PSK': pass_key = 'psk' elif args.wifi_key == 'WEP': pass_key = 'wep' else: args.error('not sure what key to use for %r' % args.wifi_key) data = {'ssid': args.wifi_ssid, 'keyManagement': args.wifi_key, pass_key: args.wifi_pass} data_layer.connect_to_wifi(data) # disconnect marionette client because install_app would need it mc.client.close() # install apps one by one for manifest in args.apps: args.manifest = manifest args.app = None install_app(args)
def __init__(self, marionette): GaiaApps(marionette).switch_to_displayed_app() root = Wait(marionette).until( expected.element_present(*self._bottom_bar_locator)) Wait(marionette).until(expected.element_displayed(root)) window_height = marionette.execute_script( 'return window.wrappedJSObject.innerHeight') Wait(marionette).until(lambda m: int(root.rect['y'] + root.size[ 'height']) == window_height) PageRegion.__init__(self, marionette, root)
def restart(self): self.parent.reporting.logResult('info', 'Restarting the device...') # Lockscreen does not get on very well with restarts lock_enabled = self.parent.data_layer.get_setting("lockscreen.enabled") if lock_enabled: self.parent.data_layer.set_setting("lockscreen.enabled", False) # After restarting we need to re-instantiate javascript objects self.parent.device.restart_b2g() self.apps = GaiaApps(self.marionette) self.parent.data_layer = GaiaData(self.marionette, self.parent.parent.testvars) # Restore lockscreen status self.parent.data_layer.set_setting("lockscreen.enabled", lock_enabled)
class Base(object): def __init__(self, marionette, name=None): self.marionette = marionette self.apps = GaiaApps(self.marionette) self.name = name or self.name def launch(self): self.app = self.apps.launch(self.name) def wait_for_element_present(self, by, locator, timeout=10): timeout = float(timeout) + time.time() while time.time() < timeout: time.sleep(0.5) try: return self.marionette.find_element(by, locator) except NoSuchElementException: pass else: raise TimeoutException( 'Element %s not found before timeout' % locator) def wait_for_element_displayed(self, by, locator, timeout=10): timeout = float(timeout) + time.time() while time.time() < timeout: time.sleep(0.5) try: if self.marionette.find_element(by, locator).is_displayed(): break except NoSuchElementException: pass else: raise TimeoutException( 'Element %s not visible before timeout' % locator) def wait_for_condition(self, method, timeout=10, message="Condition timed out"): """Calls the method provided with the driver as an argument until the return value is not False.""" end_time = time.time() + timeout while time.time() < end_time: try: value = method(self.marionette) if value: return value except NoSuchElementException: pass time.sleep(0.5) else: raise TimeoutException(message)
def install_app(args): def confirm_installation(): _yes_button_locator = ('id', 'app-install-install-button') wait_for_element_displayed(mc, *_yes_button_locator) mc.find_element(*_yes_button_locator).tap() wait_for_element_not_displayed(mc, *_yes_button_locator) print 'App successfully installed.' # marketplace loading fragment locator _loading_fragment_locator = ('css selector', 'div#splash-overlay') _search_locator = ('id', 'search-q') if not args.app and not args.manifest and not args.app_url: args.error('Provide either app name (using --app), URL of app\'s ' 'manifest file (using --manifest) or URL of the app ' 'on marketpalce (using --app_url).') mc = get_marionette(args) lockscreen = LockScreen(mc) lockscreen.unlock() apps = GaiaApps(mc) apps.kill_all() no_internet_error = ('Unable to download app.\nReason: You are probably ' 'not connected to internet on your device.') if args.manifest: mc.execute_script('navigator.mozApps.install("%s")' % args.manifest) try: confirm_installation() except TimeoutException, exc: print '** %s: %s' % (exc.__class__.__name__, exc) args.error(no_internet_error) return
def setup(self): if not self.serial or not self.port: logger.error("Fail to get device") raise DMError self.config_raptor() self.marionette and self.marionette.session and self.marionette.cleanup( ) self.dm = mozdevice.DeviceManagerADB(deviceSerial=self.serial, port=self.port) self.marionette = Marionette(device_serial=self.serial, port=self.port) self.marionette.wait_for_port() self.marionette.start_session() self.device = GaiaDevice(marionette=self.marionette, manager=self.dm) self.apps = GaiaApps(self.marionette) self.data_layer = GaiaData(self.marionette) if self.flashed: self.device.wait_for_b2g_ready()
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 run(self, script, address='localhost:2828', symbols=None, treeherder='https://treeherder.mozilla.org/', reset=False, **kwargs): try: host, port = address.split(':') except ValueError: raise ValueError('--address must be in the format host:port') # Check that Orangutan is installed self.adb_device = ADBDevice(self.device_serial) orng_path = posixpath.join('data', 'local', 'orng') if not self.adb_device.exists(orng_path): raise Exception('Orangutan not found! Please install it according ' 'to the documentation.') self.runner = B2GDeviceRunner( serial=self.device_serial, process_args={'stream': None}, symbols_path=symbols, logdir=self.temp_dir) if reset: self.runner.start() else: self.runner.device.connect() port = self.runner.device.setup_port_forwarding(remote_port=port) assert self.runner.device.wait_for_port(port), \ 'Timed out waiting for port!' marionette = Marionette(host=host, port=port) marionette.start_session() try: marionette.set_context(marionette.CONTEXT_CHROME) self.is_debug = marionette.execute_script( 'return Components.classes["@mozilla.org/xpcom/debug;1"].' 'getService(Components.interfaces.nsIDebug2).isDebugBuild;') marionette.set_context(marionette.CONTEXT_CONTENT) if reset: gaia_device = GaiaDevice(marionette) gaia_device.wait_for_b2g_ready(timeout=120) gaia_device.unlock() gaia_apps = GaiaApps(marionette) gaia_apps.kill_all() # TODO: Disable bluetooth, emergency calls, carrier, etc # Run Orangutan script remote_script = posixpath.join(self.adb_device.test_root, 'orng.script') self.adb_device.push(script, remote_script) self.start_time = time.time() # TODO: Kill remote process on keyboard interrupt self.adb_device.shell('%s %s %s' % (orng_path, self.device_properties['input'], remote_script)) self.end_time = time.time() self.adb_device.rm(remote_script) except (MarionetteException, IOError): if self.runner.crashed: # Crash has been detected pass else: raise self.runner.check_for_crashes(test_name='b2gmonkey') # Report results to Treeherder required_envs = ['TREEHERDER_KEY', 'TREEHERDER_SECRET'] if all([os.environ.get(v) for v in required_envs]): self.post_to_treeherder(script, treeherder) else: self._logger.info( 'Results will not be posted to Treeherder. Please set the ' 'following environment variables to enable Treeherder ' 'reports: %s' % ', '.join([ v for v in required_envs if not os.environ.get(v)]))
def __init__(self, marionette): self.marionette = marionette self.apps = GaiaApps(self.marionette) self.accessibility = Accessibility(self.marionette) self.frame = None
def __init__(self, marionette): self.marionette = marionette self.apps = GaiaApps(self.marionette) self.data_layer = GaiaData(self.marionette) self.frame = None
def __init__(self, marionette): self.marionette = marionette self.apps = GaiaApps(self.marionette) self.frame = None
def set_up_device(args): mc = get_marionette(args) device = GaiaDevice(mc) try: device.restart_b2g() except Exception: print ' ** Check to make sure you don\'t have desktop B2G running' raise apps = GaiaApps(mc) data_layer = GaiaData(mc) lockscreen = LockScreen(mc) mc.setup_touch() lockscreen.unlock() apps.kill_all() if args.wifi_ssid: print 'Configuring WiFi' if not args.wifi_key or not args.wifi_pass: args.error('Missing --wifi_key or --wifi_pass option') args.wifi_key = args.wifi_key.upper() data_layer.enable_wifi() if args.wifi_key == 'WPA-PSK': pass_key = 'psk' elif args.wifi_key == 'WEP': pass_key = 'wep' else: args.error('not sure what key to use for %r' % args.wifi_key) data = { 'ssid': args.wifi_ssid, 'keyManagement': args.wifi_key, pass_key: args.wifi_pass } data_layer.connect_to_wifi(data) for manifest in args.apps: # There is probably a way easier way to do this by adb pushing # something. Send me a patch! mc.switch_to_frame() try: data = requests.get(manifest).json() app_name = data['name'] all_apps = set(a['manifest']['name'] for a in get_installed(apps)) if app_name not in all_apps: print 'Installing %s from %s' % (app_name, manifest) mc.execute_script('navigator.mozApps.install("%s");' % manifest) wait_for_element_displayed(mc, 'id', 'app-install-install-button') yes = mc.find_element('id', 'app-install-install-button') mc.tap(yes) # This still works but the id check broke. # See https://bugzilla.mozilla.org/show_bug.cgi?id=853878 wait_for_element_displayed(mc, 'id', 'system-banner') except Exception, exc: print ' ** installing manifest %s failed (maybe?)' % manifest print ' ** error: %s: %s' % (exc.__class__.__name__, exc) continue
class Base(object): def __init__(self, marionette): self.marionette = marionette self.apps = GaiaApps(self.marionette) self.accessibility = Accessibility(self.marionette) self.frame = None self.manifest_url = hasattr(self, 'manifest_url') and self.manifest_url or None self.entry_point = hasattr(self, 'entry_point') and self.entry_point or None def launch(self, launch_timeout=None): self.app = self.apps.launch(self.name, self.manifest_url, self.entry_point, launch_timeout=launch_timeout) def wait_for_element_present(self, by, locator, timeout=None): return Wait(self.marionette, timeout, ignored_exceptions=NoSuchElementException).until( lambda m: m.find_element(by, locator)) def wait_for_element_not_present(self, by, locator, timeout=None): self.marionette.set_search_timeout(0) try: return Wait(self.marionette, timeout).until( lambda m: not m.find_element(by, locator)) except NoSuchElementException: pass self.marionette.set_search_timeout(self.marionette.timeout or 10000) def wait_for_element_displayed(self, by, locator, timeout=None): Wait(self.marionette, timeout, ignored_exceptions=[NoSuchElementException, StaleElementException]).until( lambda m: m.find_element(by, locator).is_displayed()) def wait_for_element_not_displayed(self, by, locator, timeout=None): self.marionette.set_search_timeout(0) try: Wait(self.marionette, timeout, ignored_exceptions=StaleElementException).until( lambda m: not m.find_element(by, locator).is_displayed()) except NoSuchElementException: pass self.marionette.set_search_timeout(self.marionette.timeout or 10000) def wait_for_condition(self, method, timeout=None, message=None): Wait(self.marionette, timeout).until(method, message=message) def is_element_present(self, by, locator): self.marionette.set_search_timeout(0) try: self.marionette.find_element(by, locator) return True except NoSuchElementException: return False finally: self.marionette.set_search_timeout(self.marionette.timeout or 10000) def is_element_displayed(self, by, locator): self.marionette.set_search_timeout(0) try: return self.marionette.find_element(by, locator).is_displayed() except NoSuchElementException: return False finally: self.marionette.set_search_timeout(self.marionette.timeout or 10000) def is_custom_element_checked(self, element): return self.marionette.execute_script("return arguments[0].wrappedJSObject.checked", [element]) # TODO: Remove me once bug 1113742 is fixed def wait_for_custom_element_checked_state(self, element, checked=True): Wait(self.marionette).until(lambda m: self.is_custom_element_checked(element) is checked) def find_select_item(self, match_string): _list_item_locator = ( By.XPATH, "//section[contains(@class,'value-selector-container')]/descendant::li[descendant::span[.='%s']]" % match_string) # have to go back to top level to get the B2G select box wrapper self.marionette.switch_to_frame() # TODO we should find something suitable to wait for, but this goes too # fast against desktop builds causing intermittent failures time.sleep(0.2) li = self.wait_for_element_present(*_list_item_locator) # We need to keep this because the Ok button may hang over the element and stop # Marionette from scrolling the element entirely into view self.marionette.execute_script( 'arguments[0].scrollIntoView(false);', [li]) return li def wait_for_select_closed(self, by, locator): self.wait_for_element_not_displayed(by, locator) # now back to app self.apps.switch_to_displayed_app() # TODO we should find something suitable to wait for, but this goes too # fast against desktop builds causing intermittent failures # This sleep is necessary to make sure the select is completely faded out, # see bug 1148154 time.sleep(1) def select(self, match_string, tap_close=True): # cheeky Select wrapper until Marionette has its own # due to the way B2G wraps the app's select box we match on text _close_button_locator = (By.CSS_SELECTOR, 'button.value-option-confirm') li = self.find_select_item(match_string) li.tap() # Tap close and wait for it to hide if tap_close: self.marionette.find_element(*_close_button_locator).tap() self.wait_for_select_closed(*_close_button_locator) def a11y_select(self, match_string): # Accessibility specific select method _close_button_locator = (By.CSS_SELECTOR, 'button.value-option-confirm') li = self.find_select_item(match_string) self.accessibility.click(li) # A11y click close and wait for it to hide self.accessibility.click(self.marionette.find_element(*_close_button_locator)) self.wait_for_select_closed(*_close_button_locator) def tap_element_from_system_app(self, element=None, add_statusbar_height=False): # Workaround for bug 1109213, where tapping on the button inside the app itself # makes Marionette spew out NoSuchWindowException errors x = element.rect['x'] + element.rect['width']//2 y = element.rect['y'] + element.rect['height']//2 from gaiatest.apps.system.app import System system = System(self.marionette) if add_statusbar_height: y = y + system.status_bar.height system.tap(x, y) @property def keyboard(self): from gaiatest.apps.keyboard.app import Keyboard return Keyboard(self.marionette)
def __init__(self, marionette, name=None): self.marionette = marionette self.apps = GaiaApps(self.marionette) self.name = name or self.name
class Base(object): def __init__(self, marionette): self.marionette = marionette self.apps = GaiaApps(self.marionette) self.accessibility = Accessibility(self.marionette) self.frame = None self.manifest_url = hasattr(self, 'manifest_url') and self.manifest_url or None self.entry_point = hasattr(self, 'entry_point') and self.entry_point or None def launch(self, launch_timeout=None): self.app = self.apps.launch(self.name, self.manifest_url, self.entry_point, launch_timeout=launch_timeout) def wait_for_element_present(self, by, locator, timeout=None): return Wait(self.marionette, timeout, ignored_exceptions=NoSuchElementException).until( lambda m: m.find_element(by, locator)) def wait_for_element_not_present(self, by, locator, timeout=None): self.marionette.set_search_timeout(0) try: return Wait(self.marionette, timeout).until( lambda m: not m.find_element(by, locator)) except NoSuchElementException: pass self.marionette.set_search_timeout(self.marionette.timeout or 10000) def wait_for_element_displayed(self, by, locator, timeout=None): Wait(self.marionette, timeout, ignored_exceptions=[NoSuchElementException, StaleElementException]).until( lambda m: m.find_element(by, locator).is_displayed()) def wait_for_element_not_displayed(self, by, locator, timeout=None): self.marionette.set_search_timeout(0) try: Wait(self.marionette, timeout, ignored_exceptions=StaleElementException).until( lambda m: not m.find_element(by, locator).is_displayed()) except NoSuchElementException: pass self.marionette.set_search_timeout(self.marionette.timeout or 10000) def wait_for_condition(self, method, timeout=None, message=None): Wait(self.marionette, timeout).until(method, message=message) def is_element_present(self, by, locator): self.marionette.set_search_timeout(0) try: self.marionette.find_element(by, locator) return True except NoSuchElementException: return False finally: self.marionette.set_search_timeout(self.marionette.timeout or 10000) def is_element_displayed(self, by, locator): self.marionette.set_search_timeout(0) try: return self.marionette.find_element(by, locator).is_displayed() except NoSuchElementException: return False finally: self.marionette.set_search_timeout(self.marionette.timeout or 10000) def find_select_item(self, match_string): _list_item_locator = ( By.XPATH, "//section[contains(@class,'value-selector-container')]/descendant::li[descendant::span[.='%s']]" % match_string) # have to go back to top level to get the B2G select box wrapper self.marionette.switch_to_frame() # TODO we should find something suitable to wait for, but this goes too # fast against desktop builds causing intermittent failures time.sleep(0.2) li = self.wait_for_element_present(*_list_item_locator) # We need to keep this because the Ok button may hang over the element and stop # Marionette from scrolling the element entirely into view self.marionette.execute_script( 'arguments[0].scrollIntoView(false);', [li]) return li def wait_for_select_closed(self, by, locator): self.wait_for_element_not_displayed(by, locator) # TODO we should find something suitable to wait for, but this goes too # fast against desktop builds causing intermittent failures time.sleep(0.2) # now back to app self.apps.switch_to_displayed_app() def select(self, match_string, tap_close=True): # cheeky Select wrapper until Marionette has its own # due to the way B2G wraps the app's select box we match on text _close_button_locator = (By.CSS_SELECTOR, 'button.value-option-confirm') li = self.find_select_item(match_string) li.tap() # Tap close and wait for it to hide if tap_close: self.marionette.find_element(*_close_button_locator).tap() self.wait_for_select_closed(*_close_button_locator) def a11y_select(self, match_string): # Accessibility specific select method _close_button_locator = (By.CSS_SELECTOR, 'button.value-option-confirm') li = self.find_select_item(match_string) self.accessibility.click(li) # A11y click close and wait for it to hide self.accessibility.click(self.marionette.find_element(*_close_button_locator)) self.wait_for_select_closed(*_close_button_locator) @property def keyboard(self): from gaiatest.apps.keyboard.app import Keyboard return Keyboard(self.marionette)
def run(self, script, address='localhost:2828', symbols=None, treeherder='https://treeherder.mozilla.org/', reset=False, **kwargs): try: host, port = address.split(':') except ValueError: raise ValueError('--address must be in the format host:port') # Check that Orangutan is installed self.adb_device = ADBDevice(self.device_serial) orng_path = posixpath.join('data', 'local', 'orng') if not self.adb_device.exists(orng_path): raise Exception('Orangutan not found! Please install it according ' 'to the documentation.') self.runner = B2GDeviceRunner(serial=self.device_serial, process_args={'stream': None}, symbols_path=symbols, logdir=self.temp_dir) if reset: self.runner.start() else: self.runner.device.connect() port = self.runner.device.setup_port_forwarding(remote_port=port) assert self.runner.device.wait_for_port(port), \ 'Timed out waiting for port!' marionette = Marionette(host=host, port=port) marionette.start_session() try: marionette.set_context(marionette.CONTEXT_CHROME) self.is_debug = marionette.execute_script( 'return Components.classes["@mozilla.org/xpcom/debug;1"].' 'getService(Components.interfaces.nsIDebug2).isDebugBuild;') marionette.set_context(marionette.CONTEXT_CONTENT) if reset: gaia_device = GaiaDevice(marionette) gaia_device.wait_for_b2g_ready(timeout=120) gaia_device.unlock() gaia_apps = GaiaApps(marionette) gaia_apps.kill_all() # TODO: Disable bluetooth, emergency calls, carrier, etc # Run Orangutan script remote_script = posixpath.join(self.adb_device.test_root, 'orng.script') self.adb_device.push(script, remote_script) self.start_time = time.time() # TODO: Kill remote process on keyboard interrupt self.adb_device.shell( '%s %s %s' % (orng_path, self.device_properties['input'], remote_script)) self.end_time = time.time() self.adb_device.rm(remote_script) except (MarionetteException, IOError): if self.runner.crashed: # Crash has been detected pass else: raise self.runner.check_for_crashes(test_name='b2gmonkey') # Report results to Treeherder required_envs = ['TREEHERDER_KEY', 'TREEHERDER_SECRET'] if all([os.environ.get(v) for v in required_envs]): self.post_to_treeherder(script, treeherder) else: self._logger.info( 'Results will not be posted to Treeherder. Please set the ' 'following environment variables to enable Treeherder ' 'reports: %s' % ', '.join([v for v in required_envs if not os.environ.get(v)]))
class Base(object): # deafult timeout in seconds for the wait_for methods _default_timeout = 30 def __init__(self, marionette): self.marionette = marionette self.apps = GaiaApps(self.marionette) def launch(self): self.app = self.apps.launch(self.name) def wait_for_element_present(self, by, locator, timeout=_default_timeout): timeout = float(timeout) + time.time() while time.time() < timeout: time.sleep(0.5) try: return self.marionette.find_element(by, locator) except NoSuchElementException: pass else: raise TimeoutException( 'Element %s not found before timeout' % locator) def wait_for_element_not_present(self, by, locator, timeout=_default_timeout): timeout = float(timeout) + time.time() while time.time() < timeout: time.sleep(0.5) try: self.marionette.find_element(by, locator) except NoSuchElementException: break else: raise TimeoutException( 'Element %s still present after timeout' % locator) def wait_for_element_displayed(self, by, locator, timeout=_default_timeout): timeout = float(timeout) + time.time() while time.time() < timeout: time.sleep(0.5) try: if self.marionette.find_element(by, locator).is_displayed(): break except NoSuchElementException: pass else: raise TimeoutException( 'Element %s not visible before timeout' % locator) def wait_for_element_not_displayed(self, by, locator, timeout=_default_timeout): timeout = float(timeout) + time.time() while time.time() < timeout: time.sleep(0.5) try: if not self.marionette.find_element(by, locator).is_displayed(): break except NoSuchElementException: break else: raise TimeoutException( 'Element %s still visible after timeout' % locator) def wait_for_condition(self, method, timeout=_default_timeout, message="Condition timed out"): """Calls the method provided with the driver as an argument until the return value is not False.""" end_time = time.time() + timeout while time.time() < end_time: try: value = method(self.marionette) if value: return value except NoSuchElementException: pass time.sleep(0.5) else: raise TimeoutException(message) def is_element_present(self, by, locator): try: self.marionette.find_element(by, locator) return True except NoSuchElementException: return False def is_element_displayed(self, by, locator): try: return self.marionette.find_element(by, locator).is_displayed() except (NoSuchElementException, ElementNotVisibleException): return False
def kill_all_apps(args): mc = get_marionette(args) mc.setup_touch() apps = GaiaApps(mc) apps.kill_all() print 'Killed all apps'
class Base(object): def __init__(self, marionette): self.marionette = marionette self.apps = GaiaApps(self.marionette) self.accessibility = Accessibility(self.marionette) self.frame = None self.manifest_url = hasattr(self, 'manifest_url') and self.manifest_url or None self.entry_point = hasattr(self, 'entry_point') and self.entry_point or None def launch(self, launch_timeout=None): self.app = self.apps.launch(self.name, self.manifest_url, self.entry_point, launch_timeout=launch_timeout) def wait_for_element_present(self, by, locator, timeout=None): return Wait(self.marionette, timeout, ignored_exceptions=NoSuchElementException).until( lambda m: m.find_element(by, locator)) def wait_for_element_not_present(self, by, locator, timeout=None): self.marionette.set_search_timeout(0) try: return Wait(self.marionette, timeout).until( lambda m: not m.find_element(by, locator)) except NoSuchElementException: pass self.marionette.set_search_timeout(self.marionette.timeout or 10000) def wait_for_element_displayed(self, by, locator, timeout=None): Wait(self.marionette, timeout, ignored_exceptions=[NoSuchElementException, StaleElementException]).until( lambda m: m.find_element(by, locator).is_displayed()) def wait_for_element_not_displayed(self, by, locator, timeout=None): self.marionette.set_search_timeout(0) try: Wait(self.marionette, timeout, ignored_exceptions=StaleElementException).until( lambda m: not m.find_element(by, locator).is_displayed()) except NoSuchElementException: pass self.marionette.set_search_timeout(self.marionette.timeout or 10000) def wait_for_condition(self, method, timeout=None, message=None): Wait(self.marionette, timeout).until(method, message=message) def is_element_present(self, by, locator): self.marionette.set_search_timeout(0) try: self.marionette.find_element(by, locator) return True except NoSuchElementException: return False finally: self.marionette.set_search_timeout(self.marionette.timeout or 10000) def is_element_displayed(self, by, locator): self.marionette.set_search_timeout(0) try: return self.marionette.find_element(by, locator).is_displayed() except NoSuchElementException: return False finally: self.marionette.set_search_timeout(self.marionette.timeout or 10000) def find_select_item(self, match_string): _list_item_locator = ( By.XPATH, "//section[contains(@class,'value-selector-container')]/descendant::li[descendant::span[.='%s']]" % match_string) # have to go back to top level to get the B2G select box wrapper self.marionette.switch_to_frame() # TODO we should find something suitable to wait for, but this goes too # fast against desktop builds causing intermittent failures time.sleep(0.2) li = self.wait_for_element_present(*_list_item_locator) # We need to keep this because the Ok button may hang over the element and stop # Marionette from scrolling the element entirely into view self.marionette.execute_script( 'arguments[0].scrollIntoView(false);', [li]) return li def wait_for_select_closed(self, by, locator): self.wait_for_element_not_displayed(by, locator) # TODO we should find something suitable to wait for, but this goes too # fast against desktop builds causing intermittent failures time.sleep(0.2) # now back to app self.apps.switch_to_displayed_app() def select(self, match_string): # cheeky Select wrapper until Marionette has its own # due to the way B2G wraps the app's select box we match on text _close_button_locator = (By.CSS_SELECTOR, 'button.value-option-confirm') li = self.find_select_item(match_string) li.tap() # Tap close and wait for it to hide self.marionette.find_element(*_close_button_locator).tap() self.wait_for_select_closed(*_close_button_locator) def a11y_select(self, match_string): # Accessibility specific select method _close_button_locator = (By.CSS_SELECTOR, 'button.value-option-confirm') li = self.find_select_item(match_string) self.accessibility.click(li) # A11y click close and wait for it to hide self.accessibility.click(self.marionette.find_element(*_close_button_locator)) self.wait_for_select_closed(*_close_button_locator) @property def keyboard(self): from gaiatest.apps.keyboard.app import Keyboard return Keyboard(self.marionette)
class Base(object): # deafult timeout in seconds for the wait_for methods _default_timeout = 30 def __init__(self, marionette): self.marionette = marionette self.apps = GaiaApps(self.marionette) self.data_layer = GaiaData(self.marionette) self.frame = None def launch(self, launch_timeout=None): self.app = self.apps.launch(self.name, launch_timeout=launch_timeout) def wait_for_element_present(self, by, locator, timeout=_default_timeout): timeout = float(timeout) + time.time() while time.time() < timeout: time.sleep(0.5) try: return self.marionette.find_element(by, locator) except NoSuchElementException: pass else: raise TimeoutException("Element %s not found before timeout" % locator) def wait_for_element_not_present(self, by, locator, timeout=_default_timeout): timeout = float(timeout) + time.time() while time.time() < timeout: time.sleep(0.5) try: self.marionette.find_element(by, locator) except NoSuchElementException: break else: raise TimeoutException("Element %s still present after timeout" % locator) def wait_for_element_displayed(self, by, locator, timeout=_default_timeout): timeout = float(timeout) + time.time() e = None while time.time() < timeout: time.sleep(0.5) try: if self.marionette.find_element(by, locator).is_displayed(): break except (NoSuchElementException, StaleElementException, ElementNotVisibleException) as e: pass else: if isinstance(e, NoSuchElementException): raise TimeoutException("Element %s not present before timeout" % locator) else: raise TimeoutException("Element %s present but not displayed before timeout" % locator) def wait_for_element_not_displayed(self, by, locator, timeout=_default_timeout): timeout = float(timeout) + time.time() while time.time() < timeout: time.sleep(0.5) try: if not self.marionette.find_element(by, locator).is_displayed(): break except StaleElementException: pass except NoSuchElementException: break else: raise TimeoutException("Element %s still visible after timeout" % locator) def wait_for_condition(self, method, timeout=_default_timeout, message="Condition timed out"): """Calls the method provided with the driver as an argument until the return value is not False.""" end_time = time.time() + timeout while time.time() < end_time: try: value = method(self.marionette) if value: return value except (NoSuchElementException, StaleElementException): pass time.sleep(0.5) else: raise TimeoutException(message) def is_element_present(self, by, locator): self.marionette.set_search_timeout(0) try: self.marionette.find_element(by, locator) return True except NoSuchElementException: return False finally: self.marionette.set_search_timeout(10000) def is_element_displayed(self, by, locator): try: return self.marionette.find_element(by, locator).is_displayed() except (NoSuchElementException, ElementNotVisibleException): return False def select(self, match_string): # cheeky Select wrapper until Marionette has its own # due to the way B2G wraps the app's select box we match on text _list_item_locator = ( By.XPATH, "id('value-selector-container')/descendant::li[descendant::span[.='%s']]" % match_string, ) _close_button_locator = (By.CSS_SELECTOR, "button.value-option-confirm") # have to go back to top level to get the B2G select box wrapper self.marionette.switch_to_frame() li = self.wait_for_element_present(*_list_item_locator) # TODO Remove scrollintoView upon resolution of bug 877651 self.marionette.execute_script("arguments[0].scrollIntoView(false);", [li]) li.tap() close_button = self.marionette.find_element(*_close_button_locator) # Tap close and wait for it to hide close_button.tap() self.wait_for_element_not_displayed(*_close_button_locator) # now back to app self.marionette.switch_to_frame(self.apps.displayed_app.frame) @property def keyboard(self): from gaiatest.apps.keyboard.app import Keyboard return Keyboard(self.marionette)
def do_login(args): mc = get_marionette(args) device = GaiaDevice(mc) apps = GaiaApps(mc) data_layer = GaiaData(mc) mc.setup_touch() _persona_frame_locator = ('css selector', "iframe") # Trusty UI on home screen _tui_container_locator = ('id', 'trustedui-frame-container') # Persona dialog _waiting_locator = ('css selector', 'body.waiting') _email_input_locator = ('id', 'authentication_email') _password_input_locator = ('id', 'authentication_password') _new_password = ('id', 'password') _verify_new_password = ('id', 'vpassword') _next_button_locator = ('css selector', 'button.start') _verify_start_button = ('css selector', 'button#verify_user') _returning_button_locator = ('css selector', 'button.returning') _sign_in_button_locator = ('id', 'signInButton') _this_session_only_button_locator = ('id', 'this_is_not_my_computer') # Switch to top level frame then Persona frame mc.switch_to_frame() wait_for_element_present(mc, *_tui_container_locator) trustyUI = mc.find_element(*_tui_container_locator) wait_for_condition( mc, lambda m: trustyUI.find_element(*_persona_frame_locator)) personaDialog = trustyUI.find_element(*_persona_frame_locator) mc.switch_to_frame(personaDialog) try: ready = mc.find_element(*_email_input_locator).is_displayed() except NoSuchElementException: ready = False if not ready: print 'Persona email input is not present.' print 'Are you on a new login screen?' return done = False while not done: username = raw_input('Persona username: '******'password: '******'Not a new account? Trying to log in to existing account' # Logging into an exisiting account: password_field = mc.find_element(*_password_input_locator) password_field.send_keys(password) wait_for_element_displayed(mc, *_returning_button_locator) mc.tap(mc.find_element(*_returning_button_locator)) #.click() print 'You should be logged in now'
class Base(object): def __init__(self, marionette): self.marionette = marionette self.apps = GaiaApps(self.marionette) self.accessibility = Accessibility(self.marionette) self.frame = None def launch(self, launch_timeout=None): self.app = self.apps.launch(self.name, launch_timeout=launch_timeout) def wait_for_element_present(self, by, locator, timeout=None): return Wait(self.marionette, timeout, ignored_exceptions=NoSuchElementException).until( lambda m: m.find_element(by, locator)) def wait_for_element_not_present(self, by, locator, timeout=None): self.marionette.set_search_timeout(0) try: return Wait(self.marionette, timeout).until( lambda m: not m.find_element(by, locator)) except NoSuchElementException: pass self.marionette.set_search_timeout(self.marionette.timeout or 10000) def wait_for_element_displayed(self, by, locator, timeout=None): Wait(self.marionette, timeout, ignored_exceptions=[NoSuchElementException, StaleElementException]).until( lambda m: m.find_element(by, locator).is_displayed()) def wait_for_element_not_displayed(self, by, locator, timeout=None): self.marionette.set_search_timeout(0) try: Wait(self.marionette, timeout, ignored_exceptions=StaleElementException).until( lambda m: not m.find_element(by, locator).is_displayed()) except NoSuchElementException: pass self.marionette.set_search_timeout(self.marionette.timeout or 10000) def wait_for_condition(self, method, timeout=None, message=None): Wait(self.marionette, timeout).until(method, message=message) def is_element_present(self, by, locator): self.marionette.set_search_timeout(0) try: self.marionette.find_element(by, locator) return True except NoSuchElementException: return False finally: self.marionette.set_search_timeout(self.marionette.timeout or 10000) def is_element_displayed(self, by, locator): self.marionette.set_search_timeout(0) try: return self.marionette.find_element(by, locator).is_displayed() except NoSuchElementException: return False finally: self.marionette.set_search_timeout(self.marionette.timeout or 10000) def select(self, match_string): # cheeky Select wrapper until Marionette has its own # due to the way B2G wraps the app's select box we match on text _list_item_locator = (By.XPATH, "id('value-selector-container')/descendant::li[descendant::span[.='%s']]" % match_string) _close_button_locator = (By.CSS_SELECTOR, 'button.value-option-confirm') # have to go back to top level to get the B2G select box wrapper self.marionette.switch_to_frame() # TODO we should find something suitable to wait for, but this goes too # fast against desktop builds causing intermittent failures time.sleep(0.2) li = self.wait_for_element_present(*_list_item_locator) # TODO Remove scrollintoView upon resolution of bug 877651 self.marionette.execute_script( 'arguments[0].scrollIntoView(false);', [li]) li.tap() # Tap close and wait for it to hide close_button = self.marionette.find_element(*_close_button_locator) close_button.tap() self.wait_for_element_not_displayed(*_close_button_locator) # TODO we should find something suitable to wait for, but this goes too # fast against desktop builds causing intermittent failures time.sleep(0.2) # now back to app self.apps.switch_to_displayed_app() @property def keyboard(self): from gaiatest.apps.keyboard.app import Keyboard return Keyboard(self.marionette)
class Base(object): def __init__(self, marionette): self.marionette = marionette self.apps = GaiaApps(self.marionette) self.accessibility = Accessibility(self.marionette) self.frame = None self.manifest_url = hasattr(self, 'manifest_url') and self.manifest_url or None self.entry_point = hasattr(self, 'entry_point') and self.entry_point or None def launch(self, launch_timeout=None): self.app = self.apps.launch(self.name, self.manifest_url, self.entry_point, launch_timeout=launch_timeout) def is_element_present(self, by, locator): self.marionette.set_search_timeout(0) try: self.marionette.find_element(by, locator) return True except NoSuchElementException: return False finally: self.marionette.set_search_timeout(self.marionette.timeout or 10000) def is_element_displayed(self, by, locator): self.marionette.set_search_timeout(0) try: return self.marionette.find_element(by, locator).is_displayed() except NoSuchElementException: return False finally: self.marionette.set_search_timeout(self.marionette.timeout or 10000) def find_select_item(self, match_string): _list_item_locator = ( By.XPATH, "//section[contains(@class,'value-selector-container')]/descendant::li[descendant::span[.='%s']]" % match_string) # have to go back to top level to get the B2G select box wrapper self.marionette.switch_to_frame() # TODO we should find something suitable to wait for, but this goes too # fast against desktop builds causing intermittent failures time.sleep(0.2) li = Wait(self.marionette).until(expected.element_present(*_list_item_locator)) # We need to keep this because the Ok button may hang over the element and stop # Marionette from scrolling the element entirely into view self.marionette.execute_script( 'arguments[0].scrollIntoView(false);', [li]) return li def wait_for_select_closed(self, by, locator): Wait(self.marionette).until(expected.element_not_displayed(by, locator)) # now back to app self.apps.switch_to_displayed_app() # TODO we should find something suitable to wait for, but this goes too # fast against desktop builds causing intermittent failures # This sleep is necessary to make sure the select is completely faded out, # see bug 1148154 time.sleep(1) def select(self, match_string, tap_close=True): # cheeky Select wrapper until Marionette has its own # due to the way B2G wraps the app's select box we match on text _close_button_locator = (By.CSS_SELECTOR, 'button.value-option-confirm') li = self.find_select_item(match_string) li.tap() # Tap close and wait for it to hide if tap_close: self.marionette.find_element(*_close_button_locator).tap() self.wait_for_select_closed(*_close_button_locator) def a11y_select(self, match_string): # Accessibility specific select method _close_button_locator = (By.CSS_SELECTOR, 'button.value-option-confirm') li = self.find_select_item(match_string) self.accessibility.click(li) # A11y click close and wait for it to hide self.accessibility.click(self.marionette.find_element(*_close_button_locator)) self.wait_for_select_closed(*_close_button_locator) def tap_element_from_system_app(self, element=None, add_statusbar_height=False, x=None, y=None): # Workaround for bug 1109213, where tapping on the button inside the app itself # makes Marionette spew out NoSuchWindowException errors cx = element.rect['x'] cy = element.rect['y'] cx += element.rect['width']//2 if x is None else x cy += element.rect['height']//2 if y is None else y from gaiatest.apps.system.app import System system = System(self.marionette) if add_statusbar_height: cy = cy + system.status_bar.height system.tap(cx, cy) @property def keyboard(self): from gaiatest.apps.keyboard.app import Keyboard return Keyboard(self.marionette)
class Base(object): # deafult timeout in seconds for the wait_for methods _default_timeout = 30 def __init__(self, marionette): self.marionette = marionette self.apps = GaiaApps(self.marionette) def launch(self): self.app = self.apps.launch(self.name) def wait_for_element_present(self, by, locator, timeout=_default_timeout): timeout = float(timeout) + time.time() while time.time() < timeout: time.sleep(0.5) try: return self.marionette.find_element(by, locator) except NoSuchElementException: pass else: raise TimeoutException("Element %s not found before timeout" % locator) def wait_for_element_not_present(self, by, locator, timeout=_default_timeout): timeout = float(timeout) + time.time() while time.time() < timeout: time.sleep(0.5) try: self.marionette.find_element(by, locator) except NoSuchElementException: break else: raise TimeoutException("Element %s still present after timeout" % locator) def wait_for_element_displayed(self, by, locator, timeout=_default_timeout): timeout = float(timeout) + time.time() while time.time() < timeout: time.sleep(0.5) try: if self.marionette.find_element(by, locator).is_displayed(): break except (NoSuchElementException, StaleElementException): pass else: raise TimeoutException("Element %s not visible before timeout" % locator) def wait_for_element_not_displayed(self, by, locator, timeout=_default_timeout): timeout = float(timeout) + time.time() while time.time() < timeout: time.sleep(0.5) try: if not self.marionette.find_element(by, locator).is_displayed(): break except StaleElementException: pass except NoSuchElementException: break else: raise TimeoutException("Element %s still visible after timeout" % locator) def wait_for_condition(self, method, timeout=_default_timeout, message="Condition timed out"): """Calls the method provided with the driver as an argument until the return value is not False.""" end_time = time.time() + timeout while time.time() < end_time: try: value = method(self.marionette) if value: return value except (NoSuchElementException, StaleElementException): pass time.sleep(0.5) else: raise TimeoutException(message) def is_element_present(self, by, locator): try: self.marionette.find_element(by, locator) return True except NoSuchElementException: return False def is_element_displayed(self, by, locator): try: return self.marionette.find_element(by, locator).is_displayed() except (NoSuchElementException, ElementNotVisibleException): return False def select(self, match_string): # cheeky Select wrapper until Marionette has its own # due to the way B2G wraps the app's select box we match on text # have to go back to top level to get the B2G select box wrapper self.marionette.switch_to_frame() self.wait_for_condition( lambda m: len(self.marionette.find_elements("css selector", "#value-selector-container li")) > 0 ) options = self.marionette.find_elements("css selector", "#value-selector-container li") close_button = self.marionette.find_element("css selector", "button.value-option-confirm") # loop options until we find the match for li in options: if li.text == match_string: li.click() break close_button.click() # now back to app self.launch()
class Base(object): # deafult timeout in seconds for the wait_for methods _default_timeout = 30 def __init__(self, marionette): self.marionette = marionette self.apps = GaiaApps(self.marionette) self.frame = None def launch(self, launch_timeout=None): self.app = self.apps.launch(self.name, launch_timeout=launch_timeout) def wait_for_element_present(self, by, locator, timeout=_default_timeout): timeout = float(timeout) + time.time() while time.time() < timeout: time.sleep(0.5) try: return self.marionette.find_element(by, locator) except NoSuchElementException: pass else: raise TimeoutException('Element %s not found before timeout' % locator) def wait_for_element_not_present(self, by, locator, timeout=_default_timeout): timeout = float(timeout) + time.time() while time.time() < timeout: time.sleep(0.5) try: self.marionette.find_element(by, locator) except NoSuchElementException: break else: raise TimeoutException('Element %s still present after timeout' % locator) def wait_for_element_displayed(self, by, locator, timeout=_default_timeout): timeout = float(timeout) + time.time() e = None while time.time() < timeout: time.sleep(0.5) try: if self.marionette.find_element(by, locator).is_displayed(): break except (NoSuchElementException, StaleElementException, ElementNotVisibleException) as e: pass else: if isinstance(e, NoSuchElementException): raise TimeoutException( 'Element %s not present before timeout' % locator) else: raise TimeoutException( 'Element %s present but not displayed before timeout' % locator) def wait_for_element_not_displayed(self, by, locator, timeout=_default_timeout): timeout = float(timeout) + time.time() while time.time() < timeout: time.sleep(0.5) try: if not self.marionette.find_element(by, locator).is_displayed(): break except StaleElementException: pass except NoSuchElementException: break else: raise TimeoutException('Element %s still visible after timeout' % locator) def wait_for_condition(self, method, timeout=_default_timeout, message="Condition timed out"): """Calls the method provided with the driver as an argument until the return value is not False.""" end_time = time.time() + timeout while time.time() < end_time: try: value = method(self.marionette) if value: return value except (NoSuchElementException, StaleElementException): pass time.sleep(0.5) else: raise TimeoutException(message) def is_element_present(self, by, locator): self.marionette.set_search_timeout(0) try: self.marionette.find_element(by, locator) return True except NoSuchElementException: return False finally: self.marionette.set_search_timeout(10000) def is_element_displayed(self, by, locator): try: return self.marionette.find_element(by, locator).is_displayed() except (NoSuchElementException, ElementNotVisibleException): return False def select(self, match_string): # cheeky Select wrapper until Marionette has its own # due to the way B2G wraps the app's select box we match on text # have to go back to top level to get the B2G select box wrapper self.marionette.switch_to_frame() self.wait_for_condition(lambda m: len( self.marionette.find_elements(By.CSS_SELECTOR, '#value-selector-container li')) > 0) options = self.marionette.find_elements( By.CSS_SELECTOR, '#value-selector-container li') close_button = self.marionette.find_element( By.CSS_SELECTOR, 'button.value-option-confirm') # loop options until we find the match for li in options: if li.text == match_string: # TODO Remove scrollintoView upon resolution of bug 877651 self.marionette.execute_script( 'arguments[0].scrollIntoView(false);', [li]) li.tap() break close_button.tap() # now back to app self.launch() @property def keyboard(self): from gaiatest.apps.keyboard.app import Keyboard return Keyboard(self.marionette)
def __init__(self, marionette): self.marionette = marionette self.apps = GaiaApps(self.marionette)
class Base(object): def __init__(self, marionette): self.marionette = marionette self.apps = GaiaApps(self.marionette) self.data_layer = GaiaData(self.marionette) self.frame = None def launch(self, launch_timeout=None): self.app = self.apps.launch(self.name, launch_timeout=launch_timeout) def wait_for_element_present(self, by, locator, timeout=None): timeout = timeout or (self.marionette.timeout and self.marionette.timeout / 1000) or 30 end_time = float(timeout) + time.time() while time.time() < end_time: time.sleep(0.5) try: return self.marionette.find_element(by, locator) except NoSuchElementException: pass else: raise TimeoutException('Element %s not found before timeout' % locator) def wait_for_element_not_present(self, by, locator, timeout=None): timeout = timeout or (self.marionette.timeout and self.marionette.timeout / 1000) or 30 end_time = float(timeout) + time.time() while time.time() < end_time: time.sleep(0.5) try: self.marionette.find_element(by, locator) except NoSuchElementException: break else: raise TimeoutException('Element %s still present after timeout' % locator) def wait_for_element_displayed(self, by, locator, timeout=None): timeout = timeout or (self.marionette.timeout and self.marionette.timeout / 1000) or 30 end_time = float(timeout) + time.time() e = None while time.time() < end_time: time.sleep(0.5) try: if self.marionette.find_element(by, locator).is_displayed(): break except (NoSuchElementException, StaleElementException, ElementNotVisibleException) as e: pass else: if isinstance(e, NoSuchElementException): raise TimeoutException( 'Element %s not present before timeout' % locator) else: raise TimeoutException( 'Element %s present but not displayed before timeout' % locator) def wait_for_element_not_displayed(self, by, locator, timeout=None): timeout = timeout or (self.marionette.timeout and self.marionette.timeout / 1000) or 30 end_time = float(timeout) + time.time() while time.time() < end_time: time.sleep(0.5) try: if not self.marionette.find_element(by, locator).is_displayed(): break except StaleElementException: pass except NoSuchElementException: break else: raise TimeoutException('Element %s still visible after timeout' % locator) def wait_for_condition(self, method, timeout=None, message="Condition timed out"): """Calls the method provided with the driver as an argument until the return value is not False.""" timeout = timeout or (self.marionette.timeout and self.marionette.timeout / 1000) or 30 end_time = float(timeout) + time.time() while time.time() < end_time: try: value = method(self.marionette) if value: return value except (NoSuchElementException, StaleElementException): pass time.sleep(0.5) else: raise TimeoutException(message) def is_element_present(self, by, locator): self.marionette.set_search_timeout(0) try: self.marionette.find_element(by, locator) return True except NoSuchElementException: return False finally: self.marionette.set_search_timeout(self.marionette.timeout or 10000) def is_element_displayed(self, by, locator): try: return self.marionette.find_element(by, locator).is_displayed() except (NoSuchElementException, ElementNotVisibleException): return False def select(self, match_string): # cheeky Select wrapper until Marionette has its own # due to the way B2G wraps the app's select box we match on text _list_item_locator = ( By.XPATH, "id('value-selector-container')/descendant::li[descendant::span[.='%s']]" % match_string) _close_button_locator = (By.CSS_SELECTOR, 'button.value-option-confirm') # have to go back to top level to get the B2G select box wrapper self.marionette.switch_to_frame() li = self.wait_for_element_present(*_list_item_locator) # TODO Remove scrollintoView upon resolution of bug 877651 self.marionette.execute_script('arguments[0].scrollIntoView(false);', [li]) li.tap() close_button = self.marionette.find_element(*_close_button_locator) # Tap close and wait for it to hide close_button.tap() self.wait_for_element_not_displayed(*_close_button_locator) # now back to app self.apps.switch_to_displayed_app() @property def keyboard(self): from gaiatest.apps.keyboard.app import Keyboard return Keyboard(self.marionette)
def __init__(self, marionette): self.marionette = marionette self.apps = GaiaApps(self.marionette) self.accessibility = Accessibility(self.marionette) self.frame = None self.entry_point = hasattr(self, "entry_point") and self.entry_point or None
class Base(object): def __init__(self, marionette): self.marionette = marionette self.apps = GaiaApps(self.marionette) self.accessibility = Accessibility(self.marionette) self.frame = None def launch(self, launch_timeout=None): self.app = self.apps.launch(self.name, launch_timeout=launch_timeout) def wait_for_element_present(self, by, locator, timeout=None): return Wait(self.marionette, timeout, ignored_exceptions=NoSuchElementException).until( lambda m: m.find_element(by, locator)) def wait_for_element_not_present(self, by, locator, timeout=None): try: return Wait( self.marionette, timeout).until(lambda m: not m.find_element(by, locator)) except NoSuchElementException: pass def wait_for_element_displayed(self, by, locator, timeout=None): Wait(self.marionette, timeout, ignored_exceptions=[ NoSuchElementException, StaleElementException ]).until(lambda m: m.find_element(by, locator).is_displayed()) def wait_for_element_not_displayed(self, by, locator, timeout=None): try: Wait(self.marionette, timeout, ignored_exceptions=StaleElementException).until( lambda m: not m.find_element(by, locator).is_displayed()) except NoSuchElementException: pass def wait_for_condition(self, method, timeout=None, message=None): Wait(self.marionette, timeout).until(method, message=message) def is_element_present(self, by, locator): self.marionette.set_search_timeout(0) try: self.marionette.find_element(by, locator) return True except NoSuchElementException: return False finally: self.marionette.set_search_timeout(self.marionette.timeout or 10000) def is_element_displayed(self, by, locator): self.marionette.set_search_timeout(0) try: return self.marionette.find_element(by, locator).is_displayed() except NoSuchElementException: return False finally: self.marionette.set_search_timeout(self.marionette.timeout or 10000) def select(self, match_string): # cheeky Select wrapper until Marionette has its own # due to the way B2G wraps the app's select box we match on text _list_item_locator = ( By.XPATH, "id('value-selector-container')/descendant::li[descendant::span[.='%s']]" % match_string) _close_button_locator = (By.CSS_SELECTOR, 'button.value-option-confirm') # have to go back to top level to get the B2G select box wrapper self.marionette.switch_to_frame() # TODO we should find something suitable to wait for, but this goes too # fast against desktop builds causing intermittent failures time.sleep(0.2) li = self.wait_for_element_present(*_list_item_locator) # TODO Remove scrollintoView upon resolution of bug 877651 self.marionette.execute_script('arguments[0].scrollIntoView(false);', [li]) li.tap() # Tap close and wait for it to hide close_button = self.marionette.find_element(*_close_button_locator) close_button.tap() self.wait_for_element_not_displayed(*_close_button_locator) # TODO we should find something suitable to wait for, but this goes too # fast against desktop builds causing intermittent failures time.sleep(0.2) # now back to app self.apps.switch_to_displayed_app() @property def keyboard(self): from gaiatest.apps.keyboard.app import Keyboard return Keyboard(self.marionette)
class Base(object): DEFAULT_APP_HOSTNAME = '.gaiamobile.org' DEFAULT_PROTOCOL = 'app://' def __init__(self, marionette): self.marionette = marionette self.apps = GaiaApps(self.marionette) self.accessibility = Accessibility(self.marionette) self.frame = None self.entry_point = hasattr(self, 'entry_point') and self.entry_point or None def launch(self, launch_timeout=None): self.app = self.apps.launch(self.name, self.manifest_url, self.entry_point, launch_timeout=launch_timeout) def is_element_present(self, by, locator): self.marionette.set_search_timeout(0) try: self.marionette.find_element(by, locator) return True except NoSuchElementException: return False finally: self.marionette.set_search_timeout(self.marionette.timeout or 10000) def is_element_displayed(self, by, locator): self.marionette.set_search_timeout(0) try: return self.marionette.find_element(by, locator).is_displayed() except NoSuchElementException: return False finally: self.marionette.set_search_timeout(self.marionette.timeout or 10000) def find_select_item(self, match_string): _list_item_locator = ( By.XPATH, "//section[contains(@class,'value-selector-container')]/descendant::li[descendant::span[.='%s']]" % match_string) # have to go back to top level to get the B2G select box wrapper self.marionette.switch_to_frame() # TODO we should find something suitable to wait for, but this goes too # fast against desktop builds causing intermittent failures time.sleep(0.2) li = Wait(self.marionette).until( expected.element_present(*_list_item_locator)) # We need to keep this because the Ok button may hang over the element and stop # Marionette from scrolling the element entirely into view self.marionette.execute_script('arguments[0].scrollIntoView(false);', [li]) return li def wait_for_select_closed(self, by, locator): Wait(self.marionette).until(expected.element_not_displayed( by, locator)) # now back to app self.apps.switch_to_displayed_app() # TODO we should find something suitable to wait for, but this goes too # fast against desktop builds causing intermittent failures # This sleep is necessary to make sure the select is completely faded out, # see bug 1148154 time.sleep(1) def select(self, match_string, tap_close=True): # cheeky Select wrapper until Marionette has its own # due to the way B2G wraps the app's select box we match on text _close_button_locator = (By.CSS_SELECTOR, 'button.value-option-confirm') li = self.find_select_item(match_string) li.tap() # Tap close and wait for it to hide if tap_close: self.marionette.find_element(*_close_button_locator).tap() self.wait_for_select_closed(*_close_button_locator) def a11y_select(self, match_string): # Accessibility specific select method _close_button_locator = (By.CSS_SELECTOR, 'button.value-option-confirm') li = self.find_select_item(match_string) self.accessibility.click(li) # A11y click close and wait for it to hide self.accessibility.click( self.marionette.find_element(*_close_button_locator)) self.wait_for_select_closed(*_close_button_locator) def tap_element_from_system_app(self, element=None, add_statusbar_height=False, x=None, y=None): # Workaround for bug 1109213, where tapping on the button inside the app itself # makes Marionette spew out NoSuchWindowException errors, see bug 1164078 cx = element.rect['x'] cy = element.rect['y'] cx += element.rect['width'] // 2 if x is None else x cy += element.rect['height'] // 2 if y is None else y from gaiatest.apps.system.app import System system = System(self.marionette) if add_statusbar_height: cy = cy + system.status_bar.height system.tap(cx, cy) @property def keyboard(self): from gaiatest.apps.keyboard.app import Keyboard return Keyboard(self.marionette) @property def manifest_url(self): return '{}{}{}/manifest.webapp'.format(self.DEFAULT_PROTOCOL, self.__class__.__name__.lower(), self.DEFAULT_APP_HOSTNAME) def wait_to_be_displayed(self): Wait(self.marionette).until( lambda m: self.apps.displayed_app.manifest_url == self.manifest_url and self.apps.displayed_app.entry_point == self.entry_point) def wait_to_not_be_displayed(self): Wait(self.marionette).until( lambda m: self.apps.displayed_app.manifest_url != self.manifest_url or self.apps.displayed_app.entry_point != self.entry_point)
def set_up_device(args): mc = get_marionette(args) device = GaiaDevice(mc) try: device.restart_b2g() except Exception: print ' ** Check to make sure you don\'t have desktop B2G running' raise apps = GaiaApps(mc) data_layer = GaiaData(mc) lockscreen = LockScreen(mc) lockscreen.unlock() apps.kill_all() if args.wifi_ssid: print 'Configuring WiFi' if not args.wifi_key or not args.wifi_pass: args.error('Missing --wifi_key or --wifi_pass option') args.wifi_key = args.wifi_key.upper() data_layer.enable_wifi() if args.wifi_key == 'WPA-PSK': pass_key = 'psk' elif args.wifi_key == 'WEP': pass_key = 'wep' else: args.error('not sure what key to use for %r' % args.wifi_key) data = {'ssid': args.wifi_ssid, 'keyManagement': args.wifi_key, pass_key: args.wifi_pass} data_layer.connect_to_wifi(data) for manifest in args.apps: # There is probably a way easier way to do this by adb pushing # something. Send me a patch! mc.switch_to_frame() try: data = requests.get(manifest).json() app_name = data['name'] all_apps = set(a['manifest']['name'] for a in get_installed(apps)) if app_name not in all_apps: print 'Installing %s from %s' % (app_name, manifest) mc.execute_script('navigator.mozApps.install("%s");' % manifest) wait_for_element_displayed(mc, 'id', 'app-install-install-button') mc.find_element('id', 'app-install-install-button').tap() wait_for_element_not_displayed(mc, 'id', 'app-install-install-button') # confirm that app got installed homescreen_frame = mc.find_element(*('css selector', 'div.homescreen iframe')) mc.switch_to_frame(homescreen_frame) _app_icon_locator = ('xpath', "//li[@class='icon']//span[text()='%s']" % app_name) try: mc.find_element(*_app_icon_locator) except NoSuchElementException: args.error('Error: app could not be installed.') except Exception, exc: print ' ** installing manifest %s failed (maybe?)' % manifest print ' ** error: %s: %s' % (exc.__class__.__name__, exc) continue
class Base(object): # deafult timeout in seconds for the wait_for methods _default_timeout = 30 def __init__(self, marionette): self.marionette = marionette self.apps = GaiaApps(self.marionette) self.frame = None def launch(self, launch_timeout=None): self.app = self.apps.launch(self.name, launch_timeout=launch_timeout) def wait_for_element_present(self, by, locator, timeout=_default_timeout): timeout = float(timeout) + time.time() while time.time() < timeout: time.sleep(0.5) try: return self.marionette.find_element(by, locator) except NoSuchElementException: pass else: raise TimeoutException( 'Element %s not found before timeout' % locator) def wait_for_element_not_present(self, by, locator, timeout=_default_timeout): timeout = float(timeout) + time.time() while time.time() < timeout: time.sleep(0.5) try: self.marionette.find_element(by, locator) except NoSuchElementException: break else: raise TimeoutException( 'Element %s still present after timeout' % locator) def wait_for_element_displayed(self, by, locator, timeout=_default_timeout): timeout = float(timeout) + time.time() e = None while time.time() < timeout: time.sleep(0.5) try: if self.marionette.find_element(by, locator).is_displayed(): break except (NoSuchElementException, StaleElementException, ElementNotVisibleException) as e: pass else: if isinstance(e, NoSuchElementException): raise TimeoutException('Element %s not present before timeout' % locator) else: raise TimeoutException('Element %s present but not displayed before timeout' % locator) def wait_for_element_not_displayed(self, by, locator, timeout=_default_timeout): timeout = float(timeout) + time.time() while time.time() < timeout: time.sleep(0.5) try: if not self.marionette.find_element(by, locator).is_displayed(): break except StaleElementException: pass except NoSuchElementException: break else: raise TimeoutException( 'Element %s still visible after timeout' % locator) def wait_for_condition(self, method, timeout=_default_timeout, message="Condition timed out"): """Calls the method provided with the driver as an argument until the return value is not False.""" end_time = time.time() + timeout while time.time() < end_time: try: value = method(self.marionette) if value: return value except (NoSuchElementException, StaleElementException): pass time.sleep(0.5) else: raise TimeoutException(message) def is_element_present(self, by, locator): self.marionette.set_search_timeout(0) try: self.marionette.find_element(by, locator) return True except NoSuchElementException: return False finally: self.marionette.set_search_timeout(10000) def is_element_displayed(self, by, locator): try: return self.marionette.find_element(by, locator).is_displayed() except (NoSuchElementException, ElementNotVisibleException): return False def select(self, match_string): # cheeky Select wrapper until Marionette has its own # due to the way B2G wraps the app's select box we match on text # have to go back to top level to get the B2G select box wrapper self.marionette.switch_to_frame() self.wait_for_condition(lambda m: len(self.marionette.find_elements(By.CSS_SELECTOR, '#value-selector-container li')) > 0) options = self.marionette.find_elements(By.CSS_SELECTOR, '#value-selector-container li') close_button = self.marionette.find_element(By.CSS_SELECTOR, 'button.value-option-confirm') # loop options until we find the match for li in options: if li.text == match_string: # TODO Remove scrollintoView upon resolution of bug 877651 self.marionette.execute_script( 'arguments[0].scrollIntoView(false);', [li]) li.tap() break close_button.tap() # now back to app self.launch() @property def keyboard(self): from gaiatest.apps.keyboard.app import Keyboard return Keyboard(self.marionette)