Source code for gaiatest.apps.base

# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.

import time

from marionette_driver import expected, By, Wait
from marionette_driver.errors import NoSuchElementException

from gaiatest import GaiaApps
from gaiatest import Accessibility


[docs]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
[docs] def launch(self, launch_timeout=None): self.app = self.apps.launch(self.name, self.manifest_url, self.entry_point, launch_timeout=launch_timeout)
[docs] 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)
[docs] 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)
[docs] def find_select_item(self, match_string): _list_item_locator = (By.CSS_SELECTOR, 'section.value-selector-container li label') # 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) Wait(self.marionette).until(expected.element_present(*_list_item_locator)) for item in self.marionette.find_elements(*_list_item_locator): if match_string == item.text.encode('ascii','ignore').strip(): # 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);', [item]) return item
[docs] 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)
[docs] 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)
[docs] 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)
[docs] 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) @property def is_displayed(self): return (self.apps.displayed_app.manifest_url == self.manifest_url and self.apps.displayed_app.entry_point == self.entry_point)
[docs] def wait_to_be_displayed(self): Wait(self.marionette).until(lambda m: self.is_displayed == True)
[docs] def wait_to_not_be_displayed(self): Wait(self.marionette).until(lambda m: self.is_displayed == False)
[docs]class PageRegion(Base): def __init__(self, marionette, element): self.root_element = element Base.__init__(self, marionette)