示例#1
0
    def run(self):
        apps = GaiaApps(self.device.marionette)
        # open two apps
        for name in [ 'Contacts', 'Clock', 'Music' ]:
            app = apps.launch(name)
            assert app.frame_id is not None

        # switch back to main frame
        self.device.marionette.switch_to_frame()

        # open cards view
        self.device.marionette.execute_script("window.dispatchEvent(new Event('holdhome'));")

        # launching apps can reset orientation to the wrong value, since some
        # apps only support portrait mode. reset it here.
        self.device.resetOrientation()

        self.start_capture()
        self.test_started()
        for i in range(3):
            for command in [ 'swipe_left', 'swipe_left', 'swipe_right', 'swipe_right' ]:
                self.device.executeCommand(command, [])
                time.sleep(0.5)
        self.test_finished()
        self.end_capture()
示例#2
0
    def run(self):
        apps = GaiaApps(self.device.marionette)
        # open two apps
        for name in ['Contacts', 'Clock', 'Music']:
            app = apps.launch(name)
            assert app.frame_id is not None

        # switch back to main frame
        self.device.marionette.switch_to_frame()

        # open cards view
        self.device.marionette.execute_script(
            "window.dispatchEvent(new Event('holdhome'));")

        # launching apps can reset orientation to the wrong value, since some
        # apps only support portrait mode. reset it here.
        self.device.resetOrientation()

        self.start_capture()
        self.test_started()
        for i in range(3):
            for command in ['swipe_left', 'swipe_left', 'swipe_right',
                            'swipe_right']:
                self.device.executeCommand(command, [])
                time.sleep(0.5)
        self.test_finished()
        self.end_capture()
示例#3
0
 def launch_app(self):
     # launch app and wait for it to "settle" so that it's ready for use
     # (this is a naive implementation that just assumes that we're done
     # "loading" after 5 seconds -- feel free to override this method in
     # your test)
     apps = GaiaApps(self.device.marionette)
     app = apps.launch(self.appname)
     assert app.frame_id is not None
     time.sleep(5)
示例#4
0
 def launch_app(self):
     # launch app and wait for it to "settle" so that it's ready for use
     # (this is a naive implementation that just assumes that we're done
     # "loading" after 5 seconds -- feel free to override this method in
     # your test)
     apps = GaiaApps(self.device.marionette)
     app = apps.launch(self.appname)
     assert app.frame_id is not None
     time.sleep(5)
示例#5
0
 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
示例#6
0
    def wait_for_content_ready(self):
        apps = GaiaApps(self.device.marionette)
        contacts = Contacts(self.device.marionette)

        Wait(self.device.marionette).until(
            lambda m: apps.displayed_app.name.lower() == 'contacts')
        apps.switch_to_displayed_app()

        Wait(self.device.marionette, 120, ignored_exceptions=(
            NoSuchElementException, ElementNotVisibleException)).until(
            lambda m: m.find_element(
                *contacts._contact_locator).is_displayed())
示例#7
0
    def run(self):
        apps = GaiaApps(self.device.marionette)

        self.start_capture()
        self.test_started()
        app = apps.launch(self.appname)
        assert app.frame_id is not None
        time.sleep(5)
        self.test_finished()
        self.end_capture()

        # cleanup: switch back to main frame
        self.device.marionette.switch_to_frame()
示例#8
0
    def wait_for_content_ready(self):
        apps = GaiaApps(self.device.marionette)
        contacts = Contacts(self.device.marionette)

        Wait(self.device.marionette).until(
            lambda m: apps.displayed_app.name.lower() == 'contacts')
        apps.switch_to_displayed_app()

        Wait(self.device.marionette,
             120,
             ignored_exceptions=(
                 NoSuchElementException,
                 ElementNotVisibleException)).until(lambda m: m.find_element(
                     *contacts._contact_locator).is_displayed())
示例#9
0
 def wait_for_content_ready(self):
     apps = GaiaApps(self.device.marionette)
     Wait(self.device.marionette).until(
         lambda m: apps.displayed_app.name.lower() == 'marketplace')
     apps.switch_to_displayed_app()
     if 'index.html' in self.device.marionette.get_url():
         # only switch to iframe if Marketplace is not packaged
         iframe = Wait(self.device.marionette).until(
             expected.element_present(
                 By.CSS_SELECTOR, 'iframe[src*="marketplace"]'))
         self.device.marionette.switch_to_frame(iframe)
     Wait(self.device.marionette, timeout=30).until(
         lambda m: 'loaded' in m.find_element(
             By.TAG_NAME, 'body').get_attribute('class').split())
示例#10
0
 def wait_for_content_ready(self):
     apps = GaiaApps(self.device.marionette)
     Wait(self.device.marionette).until(
         lambda m: apps.displayed_app.name.lower() == 'marketplace')
     apps.switch_to_displayed_app()
     iframe = Wait(self.device.marionette).until(
         expected.element_present(By.CSS_SELECTOR,
                                  'iframe[src*="marketplace"]'))
     self.device.marionette.switch_to_frame(iframe)
     # FIXME: The below *should* work, but doesn't... just doing an
     # arbitrary
     #Wait(self.device.marionette).until(
     #    lambda m: 'loaded' in m.find_element(
     #        By.TAG_NAME, 'body').get_attribute('class').split()
     time.sleep(30)
示例#11
0
    def run(self):
        apps = GaiaApps(self.device.marionette)

        app = apps.launch(self.appname)
        assert app.frame_id is not None
        time.sleep(5)
        self.start_capture()
        self.test_started()
        self.log("Running commands")
        self.device.executeCommands(self.cmds)
        self.log("Executed commands, finishing test")
        self.test_finished()
        self.end_capture()

        # cleanup: switch back to main frame
        self.device.marionette.switch_to_frame()
示例#12
0
    def setupMarionette(self):
        self.marionette = marionette.Marionette()
        self._logger.info("Waiting for Marionette...")
        self.marionette.wait_for_port()
        self._logger.info("Marionette ready, starting session")
        self.marionette.start_session()
        if 'b2g' not in self.marionette.session:
            raise mozdevice.DMError(
                "bad session value %s returned by start_session" %
                self.marionette.session)
        self.marionette.set_script_timeout(60000)
        self.marionette.timeouts(self.marionette.TIMEOUT_SEARCH, 10000)
        self._logger.info("Marionette ready!")

        self.b2gpopulate = B2GPopulate(self.marionette)
        self.gaiaApps = GaiaApps(self.marionette)
        self.gaiaDevice = GaiaDevice(self.marionette)
示例#13
0
    def run(self):
        apps = GaiaApps(self.device.marionette)

        # theoretically it would be cleaner to set this specifically for the
        # camera test, but that seemed additional complication for no real
        # gain
        apps.set_permission('Camera', 'geolocation', 'deny')

        self.start_capture()
        self.test_started()
        app = apps.launch(self.appname)
        assert app.frame_id is not None
        self.log("Waiting %s seconds for app to finish starting" %
                 self.capture_timeout)
        time.sleep(self.capture_timeout)
        self.test_finished()
        self.end_capture()

        # cleanup: switch back to main frame
        self.device.marionette.switch_to_frame()
示例#14
0
 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
示例#15
0
    def run(self):
        self.device.gaiaApps.switch_to_displayed_app()  # switch to homescreen
        appicon = None

        # HACK: Bug 1026527 - perform a no-op swipe before running test to
        # workaround flame not processing input events properly
        self.device.executeCommands([['swipe_right']])

        icons = self.device.marionette.find_elements(
            By.CSS_SELECTOR, 'gaia-grid .icon:not(.placeholder)')
        for icon in icons:
            if icon.text == self.appname:
                self.device.marionette.execute_script(
                    'arguments[0].scrollIntoView(false);', [icon])
                appicon = icon
        if appicon is None:
            raise TestException("Cannot find icon for app with name "
                                "'%s'" % self.appname)

        tap_x = appicon.location['x'] + (appicon.size['width'] / 2)
        tap_y = appicon.location['y'] + (appicon.size['height'] / 2)

        self.start_capture()
        self.execute_actions([['tap', tap_x, tap_y]],
                             test_finished_after_actions=False)

        # wait for the app to be displayed
        apps = GaiaApps(self.device.marionette)
        Wait(self.device.marionette).until(
            lambda m: apps.displayed_app.name.lower() == self.appname.lower())
        apps.switch_to_displayed_app()

        self.wait_for_content_ready()

        self.logger.info("Content ready. Waiting an additional second to make "
                         "sure it has settled")
        time.sleep(1)

        self.test_finished()
        self.end_capture()
示例#16
0
    def run(self):
        self.device.gaiaApps.switch_to_displayed_app()  # switch to homescreen
        appicon = None

        # HACK: Bug 1026527 - perform a no-op swipe before running test to
        # workaround flame not processing input events properly
        self.device.executeCommands([['swipe_right']])

        icons = self.device.marionette.find_elements(
            By.CSS_SELECTOR, 'gaia-grid .icon:not(.placeholder)')
        for icon in icons:
            if icon.text == self.appname:
                self.device.marionette.execute_script(
                    'arguments[0].scrollIntoView(false);', [icon])
                appicon = icon
        if appicon is None:
            raise TestException("Cannot find icon for app with name "
                                "'%s'" % self.appname)

        tap_x = appicon.location['x'] + (appicon.size['width'] / 2)
        tap_y = appicon.location['y'] + (appicon.size['height'] / 2)

        self.start_capture()
        self.execute_actions([['tap', tap_x, tap_y]],
                             test_finished_after_actions=False)

        # wait for the app to be displayed
        apps = GaiaApps(self.device.marionette)
        Wait(self.device.marionette).until(
            lambda m: apps.displayed_app.name.lower() == self.appname.lower())
        apps.switch_to_displayed_app()

        self.wait_for_content_ready()

        self.logger.info("Content ready. Waiting an additional second to make "
                         "sure it has settled")
        time.sleep(1)

        self.test_finished()
        self.end_capture()
示例#17
0
    def setupMarionette(self):
        self.marionette = marionette.Marionette()
        self._logger.info("Waiting for Marionette...")
        self.marionette.wait_for_port()
        self.marionette.start_session()
        if 'b2g' not in self.marionette.session:
            raise mozdevice.DMError("bad session value %s returned by start_session" %
                            self.marionette.session)
        self.marionette.set_script_timeout(60000)
        self.marionette.timeouts(self.marionette.TIMEOUT_SEARCH, 10000)
        self._logger.info("Marionette ready!")

        self.b2gpopulate = B2GPopulate(self.marionette)
        self.gaiaApps = GaiaApps(self.marionette)
        self.gaiaDevice = GaiaDevice(self.marionette)
示例#18
0
 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 = GaiaApps(self._marionette)
     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)
示例#19
0
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)
示例#20
0
class EidetickerB2GMixin(EidetickerMixin):
    """B2G-specific extensions to the eideticker mixin"""

    marionette = None

    def setupMarionette(self):
        self.marionette = marionette.Marionette()
        self._logger.info("Waiting for Marionette...")
        self.marionette.wait_for_port()
        self._logger.info("Marionette ready, starting session")
        self.marionette.start_session()
        if 'b2g' not in self.marionette.session:
            raise mozdevice.DMError(
                "bad session value %s returned by start_session" %
                self.marionette.session)
        self.marionette.set_script_timeout(60000)
        self.marionette.timeouts(self.marionette.TIMEOUT_SEARCH, 10000)
        self._logger.info("Marionette ready!")

        self.b2gpopulate = B2GPopulate(self.marionette)
        self.gaiaApps = GaiaApps(self.marionette)
        self.gaiaData = GaiaData(self.marionette)
        self.gaiaDevice = GaiaDevice(self.marionette)

    def connectWIFI(self, wifiSettings):
        """
        Tries to connect to the wifi network
        """
        self._logger.info("Setting up wifi...")
        self.gaiaData.connect_to_wifi(wifiSettings)
        self._logger.info("WIFI ready!")

    def cleanup(self):
        self.removeDir('/data/local/storage/persistent')
        self.removeDir('/data/b2g/mozilla')
        for item in self.listFiles('/sdcard/'):
            self.removeDir('/'.join(['/sdcard', item]))

    def stopB2G(self):
        self._logger.info("Stopping B2G")

        if self.marionette and self.marionette.session:
            self.marionette.delete_session()
            self.marionette = None

        self.shellCheckOutput(['stop', 'b2g'])
        # Wait for a bit to make sure B2G has completely shut down.
        tries = 100
        while "b2g" in self.shellCheckOutput(['ps', 'b2g']) and tries > 0:
            tries -= 1
            time.sleep(0.1)
        if tries == 0:
            raise mozdevice.DMError("Could not kill b2g process")

    def startB2G(self):
        self._logger.info("Starting B2G")
        self.shellCheckOutput(['start', 'b2g'])
        self.setupMarionette()

        self.marionette.execute_async_script("""
window.addEventListener('mozbrowserloadend', function loaded(aEvent) {
if (aEvent.target.src.indexOf('ftu') != -1 || aEvent.target.src.indexOf('homescreen') != -1) {
window.removeEventListener('mozbrowserloadend', loaded);
marionetteScriptFinished();
}
});""",
                                             script_timeout=60000)

        # TODO: Remove this sleep when Bug 924912 is addressed
        time.sleep(5)

        # run the fake update checker
        FakeUpdateChecker(self.marionette).check_updates()

        # unlock device, so it doesn't go to sleep
        self._logger.info("Unlocking screen...")
        self.gaiaDevice.unlock()

        # turn off automatic brightness adjustments and set to 100%
        self.gaiaData.set_setting('screen.automatic-brightness', '')
        self.gaiaData.set_setting('screen.brightness', 1)

        # kill running apps so they don't interfere with the test
        self._logger.info("Killing all running apps...")
        self.gaiaApps.kill_all()

        # set correct orientation
        self._logger.info("Setting orientation")
        self.marionette.execute_script(
            "screen.mozLockOrientation('%s');" %
            self.deviceProperties['defaultOrientation'])

    def restartB2G(self):
        """
        Restarts the b2g process on the device.
        """
        self.stopB2G()
        self.startB2G()
示例#21
0
 def launch_app(self):
     apps = GaiaApps(self.device.marionette)
     apps.launch('Marketplace')
     self.wait_for_content_ready()
示例#22
0
class EidetickerB2GMixin(EidetickerMixin):
    """B2G-specific extensions to the eideticker mixin"""

    marionette = None

    def setupMarionette(self):
        self.marionette = marionette.Marionette()
        self._logger.info("Waiting for Marionette...")
        self.marionette.wait_for_port()
        self._logger.info("Marionette ready, starting session")
        self.marionette.start_session()
        if 'b2g' not in self.marionette.session:
            raise mozdevice.DMError(
                "bad session value %s returned by start_session" %
                self.marionette.session)
        self.marionette.set_script_timeout(60000)
        self.marionette.timeouts(self.marionette.TIMEOUT_SEARCH, 10000)
        self._logger.info("Marionette ready!")

        self.b2gpopulate = B2GPopulate(self.marionette)
        self.gaiaApps = GaiaApps(self.marionette)
        self.gaiaDevice = GaiaDevice(self.marionette)

    def connectWIFI(self, wifiSettings):
        """
        Tries to connect to the wifi network
        """
        self._logger.info("Setting up wifi...")
        data = GaiaData(self.marionette)
        data.connect_to_wifi(wifiSettings)
        self._logger.info("WIFI ready!")

    def cleanup(self):
        self.removeDir('/data/local/storage/persistent')
        self.removeDir('/data/b2g/mozilla')
        for item in self.listFiles('/sdcard/'):
            self.removeDir('/'.join(['/sdcard', item]))

    def stopB2G(self):
        self._logger.info("Stopping B2G")

        if self.marionette and self.marionette.session:
            self.marionette.delete_session()
            self.marionette = None

        self.shellCheckOutput(['stop', 'b2g'])
        # Wait for a bit to make sure B2G has completely shut down.
        tries = 100
        while "b2g" in self.shellCheckOutput(['ps', 'b2g']) and tries > 0:
            tries -= 1
            time.sleep(0.1)
        if tries == 0:
            raise mozdevice.DMError("Could not kill b2g process")

    def startB2G(self):
        self.shellCheckOutput(['start', 'b2g'])
        self.setupMarionette()

        self.marionette.execute_async_script("""
window.addEventListener('mozbrowserloadend', function loaded(aEvent) {
if (aEvent.target.src.indexOf('ftu') != -1 || aEvent.target.src.indexOf('homescreen') != -1) {
window.removeEventListener('mozbrowserloadend', loaded);
marionetteScriptFinished();
}
});""", script_timeout=60000)

        # TODO: Remove this sleep when Bug 924912 is addressed
        time.sleep(5)

    def restartB2G(self):
        """
        Restarts the b2g process on the device.
        """
        self.stopB2G()
        self.startB2G()

    def resetOrientation(self):
        self.setOrientation(self.deviceProperties['defaultOrientation'])

    def setOrientation(self, orientation):
        # set landscape or portrait mode
        self._logger.info("Setting orientation: %s" % orientation)
        self.marionette.execute_script("screen.mozLockOrientation('%s');" %
                                       orientation)

    def unlock(self):
        # unlock device, so it doesn't go to sleep
        self._logger.info("Unlocking screen...")
        self.gaiaDevice.unlock()

    def killApps(self):
        self._logger.info("Killing all running apps...")
        self.gaiaApps.kill_all()
示例#23
0
 def launch_app(self):
     apps = GaiaApps(self.device.marionette)
     apps.launch('Marketplace')
     self.wait_for_content_ready()
示例#24
0
class EidetickerB2GMixin(EidetickerMixin):
    """B2G-specific extensions to the eideticker mixin"""

    marionette = None
    _devicePixelRatio = None

    def setupMarionette(self):
        self.marionette = marionette.Marionette()
        self._logger.info("Waiting for Marionette...")
        self.marionette.wait_for_port()
        self._logger.info("Marionette ready, starting session")
        self.marionette.start_session()
        if 'b2g' not in self.marionette.session:
            raise mozdevice.DMError(
                "bad session value %s returned by start_session" %
                self.marionette.session)
        self.marionette.set_script_timeout(60000)
        self.marionette.timeouts(self.marionette.TIMEOUT_SEARCH, 10000)
        self._logger.info("Marionette ready!")

        self.b2gpopulate = B2GPopulate(self.marionette)
        self.gaiaApps = GaiaApps(self.marionette)
        self.gaiaData = GaiaData(self.marionette)
        self.gaiaDevice = GaiaDevice(self.marionette)
        self.gaiaCompat = GaiaCompat()

    def connectWIFI(self, wifiSettings):
        """
        Tries to connect to the wifi network
        """
        self._logger.info("Setting up wifi...")
        self.gaiaData.connect_to_wifi(wifiSettings)
        self._logger.info("WIFI ready!")

    def cleanup(self):
        self.removeDir('/data/local/storage/persistent')
        self.removeDir('/data/b2g/mozilla')
        for item in self.listFiles('/sdcard/'):
            self.removeDir('/'.join(['/sdcard', item]))

    def stopB2G(self):
        self._logger.info("Stopping B2G")

        if self.marionette and self.marionette.session:
            self.marionette.delete_session()
            self.marionette = None

        self.shellCheckOutput(['stop', 'b2g'])
        # Wait for a bit to make sure B2G has completely shut down.
        tries = 100
        while "b2g" in self.shellCheckOutput(['ps', 'b2g']) and tries > 0:
            tries -= 1
            time.sleep(0.1)
        if tries == 0:
            raise mozdevice.DMError("Could not kill b2g process")

    def startB2G(self):
        self._logger.info("Starting B2G")
        self.shellCheckOutput(['start', 'b2g'])
        self.setupMarionette()
        self.gaiaCompat.wait_for_b2g(self.marionette)

        # run the fake update checker
        self.gaiaCompat.supress_update_check(self.marionette)

        # unlock device, so it doesn't go to sleep
        self._logger.info("Unlocking screen...")
        self.gaiaDevice.unlock()

        # turn off automatic brightness adjustments and set to 100%
        self.gaiaData.set_setting('screen.automatic-brightness', '')
        self.gaiaData.set_setting('screen.brightness', 1)

        # kill running apps so they don't interfere with the test
        self._logger.info("Killing all running apps...")
        self.gaiaApps.kill_all()

        # set correct orientation
        self._logger.info("Setting orientation")
        self.marionette.execute_script("screen.mozLockOrientation('%s');" %
                                       self.deviceProperties['defaultOrientation'])

    def restartB2G(self):
        """
        Restarts the b2g process on the device.
        """
        self.stopB2G()
        self.startB2G()

    @property
    def devicePixelRatio(self):
        if not self._devicePixelRatio:
            if self.marionette and self.marionette.session:
                self._devicePixelRatio = self.marionette.execute_script(
                    'return window.wrappedJSObject.devicePixelRatio;')
        return self._devicePixelRatio or 1
示例#25
0
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)
示例#26
0
 def prepare_app(self):
     apps = GaiaApps(self.device.marionette)
     apps.set_permission('Camera', 'geolocation', 'deny')
示例#27
0
class EidetickerB2GMixin(EidetickerMixin):
    """B2G-specific extensions to the eideticker mixin"""

    marionette = None
    _devicePixelRatio = None

    def setupMarionette(self):
        self.marionette = marionette.Marionette()
        self._logger.info("Waiting for Marionette...")
        self.marionette.wait_for_port()
        self._logger.info("Marionette ready, starting session")
        self.marionette.start_session()
        if 'b2g' not in self.marionette.session:
            raise mozdevice.DMError(
                "bad session value %s returned by start_session" %
                self.marionette.session)
        self.marionette.set_script_timeout(60000)
        self.marionette.timeouts(self.marionette.TIMEOUT_SEARCH, 10000)
        self._logger.info("Marionette ready!")

        self.b2gpopulate = B2GPopulate(self.marionette)
        self.gaiaApps = GaiaApps(self.marionette)
        self.gaiaData = GaiaData(self.marionette)
        self.gaiaDevice = GaiaDevice(self.marionette)
        self.gaiaCompat = GaiaCompat()

    def connectWIFI(self, wifiSettings):
        """
        Tries to connect to the wifi network
        """
        self._logger.info("Setting up wifi...")
        self.gaiaData.connect_to_wifi(wifiSettings)
        self._logger.info("WIFI ready!")

    def cleanup(self):
        self.removeDir('/data/local/storage/persistent')
        self.removeDir('/data/b2g/mozilla')
        for item in self.listFiles('/sdcard/'):
            self.removeDir('/'.join(['/sdcard', item]))

    def stopB2G(self):
        self._logger.info("Stopping B2G")

        if self.marionette and self.marionette.session:
            self.marionette.delete_session()
            self.marionette = None

        self.shellCheckOutput(['stop', 'b2g'])
        # Wait for a bit to make sure B2G has completely shut down.
        tries = 100
        while "b2g" in self.shellCheckOutput(['ps', 'b2g']) and tries > 0:
            tries -= 1
            time.sleep(0.1)
        if tries == 0:
            raise mozdevice.DMError("Could not kill b2g process")

    def startB2G(self):
        self._logger.info("Starting B2G")
        self.shellCheckOutput(['start', 'b2g'])
        self.setupMarionette()
        self.gaiaCompat.wait_for_b2g(self.marionette)

        # run the fake update checker
        self.gaiaCompat.supress_update_check(self.marionette)

        # unlock device, so it doesn't go to sleep
        self._logger.info("Unlocking screen...")
        self.gaiaDevice.unlock()

        # turn off automatic brightness adjustments and set to 100%
        self.gaiaData.set_setting('screen.automatic-brightness', '')
        self.gaiaData.set_setting('screen.brightness', 1)

        # kill running apps so they don't interfere with the test
        self._logger.info("Killing all running apps...")
        self.gaiaApps.kill_all()

        # set correct orientation
        self._logger.info("Setting orientation")
        self.marionette.execute_script(
            "screen.mozLockOrientation('%s');" %
            self.deviceProperties['defaultOrientation'])

    def restartB2G(self):
        """
        Restarts the b2g process on the device.
        """
        self.stopB2G()
        self.startB2G()

    @property
    def devicePixelRatio(self):
        if not self._devicePixelRatio:
            if self.marionette and self.marionette.session:
                self._devicePixelRatio = self.marionette.execute_script(
                    'return window.wrappedJSObject.devicePixelRatio;')
        return self._devicePixelRatio or 1
示例#28
0
文件: test.py 项目: wlach/eideticker
    def run(self):
        self.device.gaiaApps.switch_to_displayed_app()  # switch to homescreen
        appicon = None

        # HACK: Bug 1026527 - perform a no-op swipe before running test to
        # workaround flame not processing input events properly
        self.device.executeCommands([['swipe_right']])

        try:
            # look for the application icon in the dock first
            self.logger.info('Looking for app icon in dock')
            appicon = self.device.marionette.find_element(
                By.CSS_SELECTOR,
                '#footer .icon[aria-label="%s"]' % self.appname)
        except NoSuchElementException:
            # skip the everything.me page
            self.device.marionette.execute_async_script(
                'return window.wrappedJSObject.GridManager.goToPage(1, marionetteScriptFinished);')
            page_count = self.device.marionette.execute_script(
                'return window.wrappedJSObject.GridManager.pageHelper.getTotalPagesNumber();')
            for i in range(1, page_count):
                current_page = self.device.marionette.find_element(
                    By.CSS_SELECTOR, '#icongrid .page:not([aria-hidden=true])')
                try:
                    self.logger.info('Looking for app icon on page %s' % (i + 1))
                    appicon = current_page.find_element(
                        By.CSS_SELECTOR, '.icon[aria-label="%s"]' %
                        self.appname)
                    break
                except NoSuchElementException:
                    current_page_index = self.device.marionette.execute_script(
                        'return window.wrappedJSObject.GridManager.pageHelper.getCurrentPageNumber();')
                    if current_page_index < (page_count - 1):
                        self.device.marionette.execute_script(
                            'window.wrappedJSObject.GridManager.goToNextPage();')
                        Wait(self.device.marionette).until(
                            lambda m: m.find_element(By.TAG_NAME, 'body').get_attribute(
                                'data-transitioning') != 'true')
                    else:
                        raise TestException("Cannot find icon for app with name "
                                            "'%s'" % self.appname)

        tap_x = appicon.location['x'] + (appicon.size['width'] / 2)
        tap_y = appicon.location['y'] + (appicon.size['height'] / 2)

        self.start_capture()
        self.execute_actions([['tap', tap_x, tap_y]],
                             test_finished_after_actions=False)

        # wait for the app to be displayed
        apps = GaiaApps(self.device.marionette)
        Wait(self.device.marionette).until(
            lambda m: apps.displayed_app.name.lower() == self.appname.lower())
        apps.switch_to_displayed_app()

        self.wait_for_content_ready()

        self.logger.info("Content ready. Waiting an additional second to make "
                         "sure it has settled")
        time.sleep(1)

        self.test_finished()
        self.end_capture()