Example #1
0
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'
Example #2
0
    def _StartProcess(self):
        if not self.isEmulatorInitialized:
            print("Starting Emulator ...")
            self.emulatorProcess = subprocess.Popen(
                [self.emulatorStartScript],
                cwd=os.path.dirname(self.emulatorStartScript),
                shell=True)

            # adb shell setprop net.dns1 10.0.2.3

            self._isBootFinished()
            self.monitoringProcessId = self.adb.getPID(
                self.monitoredProcessName)

            print("Forwarding TCP port %d ..." % self.forwardedPortADB)
            self.adb.command([
                "forward",
                "tcp:%d" % self.forwardedPortADB,
                "tcp:%d" % self.forwardedPortADB
            ])

            self.isEmulatorInitialized = True

        time.sleep(20)

        if self.crashSuccess:
            print("Restarting %s ..." % self.monitoredProcessName)
            self.adb.killProcess(self.monitoredProcessName, True)
            time.sleep(40)
            self.monitoringProcessId = self.adb.getPID(
                self.monitoredProcessName)
            self.crashSuccess = False
            self.debugLogData = str()
            self.adb.checkCmd(["logcat", "-c"])

        print("Starting Marionette session ...")
        marionette = Marionette('localhost', self.forwardedPortADB)
        print(marionette.status())
        marionette.start_session()
        marionette.set_script_timeout(self.scriptTimeout)
        marionette.switch_to_frame()

        lock = gaia.LockScreen(marionette)
        lock.unlock()

        apps = gaia.GaiaApps(marionette)
        print(apps.runningApps())

        print("Launching Browser application")
        apps.launch(self.appName, switch_to_frame=True)

        print("Navigating to %s ..." % self.publisherURL)
        marionette.execute_script(
            "return window.wrappedJSObject.Browser.navigate('%s')" %
            self.publisherURL)

        self.isMonitorInitialized = True
Example #3
0
def launch_app(app_name,
               adb_path="adb",
               script_timeout=5000,
               marionette=None,
               device_serial=None):
    """
    Launches the given app
    NOTE: if a marionette session is passed, this function switches to the top-most frame.
    """
    dm = mozdevice.DeviceManagerADB(adbPath=adb_path,
                                    deviceSerial=device_serial)
    installed_app_name = app_name.lower()
    installed_app_name = installed_app_name.replace(" ", "-")
    dm.forward("tcp:2828", "tcp:2828")

    if not marionette:
        m = Marionette()
        m.start_session()
    else:
        m = marionette
        m.switch_to_frame()
    launch_app = """
    var launchWithName = function(name) {
        let apps = window.wrappedJSObject.applications || window.wrappedJSObject.Applications;
        let installedApps = apps.installedApps;
        for (let manifestURL in installedApps) {
          let app = installedApps[manifestURL];
          let origin = null;
          let entryPoints = app.manifest.entry_points;
          if (entryPoints) {
            for (let ep in entryPoints) {
              let currentEntryPoint = entryPoints[ep];
              let appName = currentEntryPoint.name;
              if (name == appName.toLowerCase()) {
                app.launch();
                return true;
              }
            }
          } else {
            let appName = app.manifest.name;
            if (name == appName.toLowerCase()) {
              app.launch();
              return true;
            }
          }
        }
        return false;
      };
    return launchWithName("%s");
    """
    m.set_script_timeout(script_timeout)
    m.execute_script(launch_app % app_name.lower())
    if not marionette:
        m.delete_session()
Example #4
0
def uninstall_app(app_name, adb_path="adb", script_timeout=5000, marionette=None):
    """
    Uninstalls the given app.

    NOTE: if a marionette session is passed, this function switches to the top-most frame.
    """
    dm = mozdevice.DeviceManagerADB(adbPath=adb_path)
    installed_app_name = app_name.lower()
    installed_app_name = installed_app_name.replace(" ", "-")
    if dm.forward("tcp:2828", "tcp:2828") != 0:
        raise Exception("Can't use localhost:2828 for port forwarding." \
                    "Is something else using port 2828?")

    if not marionette:
        m = Marionette()
        m.start_session()
    else: 
        m = marionette
        m.switch_to_frame()
    uninstall_app = """
    var uninstallWithName = function(name) {
        let apps = window.wrappedJSObject.applications || window.wrappedJSObject.Applications;
        let installedApps = apps.installedApps;
        for (let manifestURL in installedApps) {
          let app = installedApps[manifestURL];
          let origin = null;
          let entryPoints = app.manifest.entry_points;
          if (entryPoints) {
            for (let ep in entryPoints) {
              let currentEntryPoint = entryPoints[ep];
              let appName = currentEntryPoint.name;
              if (name == appName.toLowerCase()) {
                window.wrappedJSObject.navigator.mozApps.mgmt.uninstall(app);
                return true;
              }
            }
          } else {
            let appName = app.manifest.name;
            if (name == appName.toLowerCase()) {
              window.wrappedJSObject.navigator.mozApps.mgmt.uninstall(app);
              return true;
            }
          }
        }
        return false;
      };
    return uninstallWithName("%s");
    """
    m.set_script_timeout(script_timeout)
    m.execute_script(uninstall_app % app_name.lower())
    if not marionette:
        m.delete_session()
Example #5
0
def launch_app(app_name, adb_path="adb", script_timeout=5000, marionette=None, device_serial=None):
    """
    Launches the given app
    NOTE: if a marionette session is passed, this function switches to the top-most frame.
    """
    dm = mozdevice.DeviceManagerADB(adbPath=adb_path,deviceSerial=device_serial)
    installed_app_name = app_name.lower()
    installed_app_name = installed_app_name.replace(" ", "-")
    dm.forward("tcp:2828", "tcp:2828")

    if not marionette:
        m = Marionette()
        m.start_session()
    else:
        m = marionette
        m.switch_to_frame()
    launch_app = """
    var launchWithName = function(name) {
        let apps = window.wrappedJSObject.applications || window.wrappedJSObject.Applications;
        let installedApps = apps.installedApps;
        for (let manifestURL in installedApps) {
          let app = installedApps[manifestURL];
          let origin = null;
          let entryPoints = app.manifest.entry_points;
          if (entryPoints) {
            for (let ep in entryPoints) {
              let currentEntryPoint = entryPoints[ep];
              let appName = currentEntryPoint.name;
              if (name == appName.toLowerCase()) {
                app.launch();
                return true;
              }
            }
          } else {
            let appName = app.manifest.name;
            if (name == appName.toLowerCase()) {
              app.launch();
              return true;
            }
          }
        }
        return false;
      };
    return launchWithName("%s");
    """
    m.set_script_timeout(script_timeout)
    m.execute_script(launch_app % app_name.lower())
    if not marionette:
        m.delete_session()
Example #6
0
    def _StartProcess(self):
        if not self.isDeviceInitialized:
            print("Starting ...")
            self.monitoringProcessId = self.adb.getPID(
                self.monitoredProcessName)
            print("Forwarding TCP port %d ..." % self.forwardedPortADB)
            self.adb.command([
                "forward",
                "tcp:%d" % self.forwardedPortADB,
                "tcp:%d" % self.forwardedPortADB
            ])
            self.isDeviceInitialized = True

        print("Sleeping ...")
        time.sleep(20)

        if self.crashSuccess:
            print("Restarting %s" % self.monitoredProcessName)
            self.adb.killProcess(self.monitoredProcessName, True)
            time.sleep(40)
            self.monitoringProcessId = self.adb.getPID(
                self.monitoredProcessName)
            self.crashSuccess = False
            self.debugLogData = str()
            self.adb.checkCmd(["logcat", "-c"])

        print("Starting Marionette session")
        marionette = Marionette('localhost', self.forwardedPortADB)
        print(marionette.status())
        marionette.start_session()
        marionette.set_script_timeout(self.scriptTimeout)
        marionette.switch_to_frame()

        lock = gaia.LockScreen(marionette)
        assert (lock.unlock())

        apps = gaia.GaiaApps(marionette)
        print(apps.runningApps())

        print("Launching Browser application")
        apps.launch(self.appName, switch_to_frame=True)

        print("Navigating to %s ..." % self.publisherURL)
        marionette.execute_script(
            "return window.wrappedJSObject.Browser.navigate('%s')" %
            self.publisherURL)

        self.isMonitorInitialized = True
Example #7
0
File: b2g.py Project: KurSh/peach
    def _StartProcess(self):
        if not self.isEmulatorInitialized:
            print("Starting Emulator ...")
            self.emulatorProcess = subprocess.Popen(
                [self.emulatorStartScript], cwd=os.path.dirname(self.emulatorStartScript), shell=True)

            # adb shell setprop net.dns1 10.0.2.3

            self._isBootFinished()
            self.monitoringProcessId = self.adb.getPID(self.monitoredProcessName)

            print("Forwarding TCP port %d ..." % self.forwardedPortADB)
            self.adb.command(["forward", "tcp:%d" % self.forwardedPortADB, "tcp:%d" % self.forwardedPortADB])

            self.isEmulatorInitialized = True

        time.sleep(20)

        if self.crashSuccess:
            print("Restarting %s ..." % self.monitoredProcessName)
            self.adb.killProcess(self.monitoredProcessName, True)
            time.sleep(40)
            self.monitoringProcessId = self.adb.getPID(self.monitoredProcessName)
            self.crashSuccess = False
            self.debugLogData = str()
            self.adb.checkCmd(["logcat", "-c"])

        print("Starting Marionette session ...")
        marionette = Marionette('localhost', self.forwardedPortADB)
        print(marionette.status())
        marionette.start_session()
        marionette.set_script_timeout(self.scriptTimeout)
        marionette.switch_to_frame()

        lock = gaia.LockScreen(marionette)
        lock.unlock()

        apps = gaia.GaiaApps(marionette)
        print(apps.runningApps())

        print("Launching Browser application")
        apps.launch(self.appName, switch_to_frame=True)

        print("Navigating to %s ..." % self.publisherURL)
        marionette.execute_script("return window.wrappedJSObject.Browser.navigate('%s')" % self.publisherURL)

        self.isMonitorInitialized = True
Example #8
0
def install_app(app_name,
                app_path,
                adb_path="adb",
                script_timeout=5000,
                marionette=None,
                device_serial=None):
    """
    This installs the given application.

    NOTE: if a marionette session is passed, this function switches to
    'content' context and will be at the top-most frame.
    """
    if is_installed(app_name, adb_path=adb_path, device_serial=device_serial):
        raise Exception("%s is already installed" % app_name)
        sys.exit(1)

    app_zip = os.path.basename(app_path)
    dm = mozdevice.DeviceManagerADB(adbPath=adb_path,
                                    deviceSerial=device_serial)
    dm.pushFile("%s" % app_path, "/data/local/%s" % app_zip)
    # forward the marionette port
    dm.forward("tcp:2828", "tcp:2828")

    # install the app
    install_js = pkg_resources.resource_filename(
        __name__, os.path.sep.join(['app_install.js']))
    with open(install_js, "r") as f:
        script = f.read()
    installed_app_name = app_name.lower().replace(" ", "-")
    script = script.replace("YOURAPPID", installed_app_name)
    script = script.replace("YOURAPPZIP", app_zip)

    if not marionette:
        m = Marionette()
        m.start_session()
    else:
        m = marionette
        m.switch_to_frame()
    m.set_context("chrome")
    m.set_script_timeout(script_timeout)
    m.execute_async_script(script)
    if not marionette:
        m.delete_session()
    else:
        m.set_context("content")
Example #9
0
def install_app(app_name, app_path, adb_path="adb", script_timeout=5000, marionette=None):
    """
    This installs the given application.

    NOTE: if a marionette session is passed, this function switches to
    'content' context and will be at the top-most frame.
    """
    if is_installed(app_name, adb_path=adb_path):
        raise Exception("%s is already installed" % app_name)
        sys.exit(1)

    app_zip = os.path.basename(app_path)
    dm = mozdevice.DeviceManagerADB(adbPath=adb_path)
    dm.pushFile("%s" % app_path, "/data/local/%s" % app_zip)
    # forward the marionette port
    if dm.forward("tcp:2828", "tcp:2828") != 0:
        raise Exception("Can't use localhost:2828 for port forwarding." \
                        "Is something else using port 2828?")

    # install the app
    install_js = pkg_resources.resource_filename(__name__,
                                                 os.path.sep.join([
                                                   'app_install.js']))
    with open(install_js, "r") as f:
        script = f.read()
    installed_app_name = app_name.lower().replace(" ", "-")
    script = script.replace("YOURAPPID", installed_app_name)
    script = script.replace("YOURAPPZIP", app_zip)

    if not marionette:
        m = Marionette()
        m.start_session()
    else: 
        m = marionette
        m.switch_to_frame()
    m.set_context("chrome")
    m.set_script_timeout(script_timeout)
    m.execute_async_script(script)
    if not marionette:
        m.delete_session()
    else:
        m.set_context("content")
class current_frame():
    
    def main(self, p_snippet, p_frame_array=False):
        #
        # p_el is an array for the element.
        # p_frame_array is a list of iframes to iterate through (optional).
        #
        self.marionette = Marionette(host='localhost', port=2828)  
        self.marionette.start_session()
        self.marionette.set_search_timeout(1000)
        self.actions    = Actions(self.marionette)
        
        #
        # Switch to the correct iframe (unless it's "()").
        #
        self.marionette.switch_to_frame()
        
        first_iframe = True
        for x in p_frame_array:
            # (just to make it look nice ;)
            typ_str = "'" + x[0] + "'"
            
            if first_iframe:
                first_iframe = False
                print ""
                print "Switching to iframe with " + typ_str.rjust(10) + " = '" + x[1] + "'"
            else:
                print "... then to iframe with  " + typ_str.rjust(10) + " = '" + x[1] + "'"
            
            my_iframe = self.marionette.find_element("xpath", "//iframe[@" + x[0] + "='" + x[1] + "']")
            self.marionette.switch_to_frame(my_iframe)
            
        if first_iframe:
            print ""
            print "Using 'top level' iframe () ..."
            
        
        # Run the code snippet.
        print ""
        print "Running code snippet from this location ..."
        print ""
        execfile(p_snippet)
Example #11
0
File: b2g.py Project: KurSh/peach
    def _StartProcess(self):
        if not self.isDeviceInitialized:
            print("Starting ...")
            self.monitoringProcessId = self.adb.getPID(self.monitoredProcessName)
            print("Forwarding TCP port %d ..." % self.forwardedPortADB)
            self.adb.command(["forward", "tcp:%d" % self.forwardedPortADB, "tcp:%d" % self.forwardedPortADB])
            self.isDeviceInitialized = True

        print("Sleeping ...")
        time.sleep(20)

        if self.crashSuccess:
            print("Restarting %s" % self.monitoredProcessName)
            self.adb.killProcess(self.monitoredProcessName, True)
            time.sleep(40)
            self.monitoringProcessId = self.adb.getPID(self.monitoredProcessName)
            self.crashSuccess = False
            self.debugLogData = str()
            self.adb.checkCmd(["logcat", "-c"])

        print("Starting Marionette session")
        marionette = Marionette('localhost', self.forwardedPortADB)
        print(marionette.status())
        marionette.start_session()
        marionette.set_script_timeout(self.scriptTimeout)
        marionette.switch_to_frame()

        lock = gaia.LockScreen(marionette)
        assert(lock.unlock())

        apps = gaia.GaiaApps(marionette)
        print(apps.runningApps())

        print("Launching Browser application")
        apps.launch(self.appName, switch_to_frame=True)

        print("Navigating to %s ..." % self.publisherURL)
        marionette.execute_script("return window.wrappedJSObject.Browser.navigate('%s')" % self.publisherURL)

        self.isMonitorInitialized = True
Example #12
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)
Example #13
0
class Runner(object):

    _INPUT_NONE = ''
    _INPUT_EXIT_COMMAND = 'exit'
    _INPUT_MULTIPLE_LINE = ' \\'
    _INPUT_COMMAND_PREFIX = ':'
    _INPUT_SYSTEM_APP_KEYWORD = 'system'

    _is_async = False
    _sync_prompt = '>>> '
    _async_prompt = 'a>> '
    _prompt = _sync_prompt

    def __init__(self, **kwargs):
        # Added parser
        parser = OptionParser()
        parser.add_option('-a', '--address',
                          action='store', type='string', dest='address',
                          default='localhost',
                          help='The host address of b2g instance. Default=localhost')
        parser.add_option('-p', '--port',
                          action='store', type='int', dest='port',
                          default=2828,
                          help='The port of b2g instance.')
        parser.add_option('-l', '--list',
                          action='store_true', dest='enable_list',
                          default='False',
                          help='List all apps of b2g instance. Default=False')
        parser.add_option('-c', '--connect',
                          action='store', type='string', dest='connect',
                          default=None,
                          help='Connect to the App iframe.' \
                               'Use # ID or App URL to connect.')

        (options, args) = parser.parse_args()
        self.connect = options.connect

        # start marionette session
        self.m = Marionette(options.address, options.port)
        self.m.start_session()

        # list all iframes
        if options.enable_list:
            self.list_all_iframes()
        # list active iframes
        elif self.connect == None:
            self.list_active_iframes()

        # connect to App
        if self.connect == None:
            exit(0)
        else:
            # connect App
            print 'Start...'
            if self.open_app(self.connect):
                self.start_js()
            else:
                exit(-1)

    def switch_sync_async(self):
        self._is_async = not self._is_async
        self._prompt = self._async_prompt if self._is_async else self._sync_prompt
        print 'Swith to', ('Async' if self._is_async else 'Sync'), 'JS execution'

    def start_js(self):
        print 'Enter \'%s\' or Crtl+D to exit the shell.' % self._INPUT_EXIT_COMMAND
        print 'And enter \':h\' for more commands.'
        try:
            while True:
                input = raw_input(self._prompt)
                # if input is EXIT command, exit this program
                if input.lower() == self._INPUT_EXIT_COMMAND:
                    self.goodbye()
                    break

                # if input is NONE, then do nothing and keep going...
                elif input == self._INPUT_NONE:
                    continue

                # if input start with ":", it should be the command.
                elif input.startswith(self._INPUT_COMMAND_PREFIX):
                    CmdDispatcher(self, input)

                # if the postfix of input is MULTIPLE_LINE, then record this line and wait the next line until no input with MULTIPLE_LINE.
                elif input.endswith(self._INPUT_MULTIPLE_LINE):
                    input_multiple = input[:len(input) - 1] + '; '
                    while True:
                        next_input = raw_input('... ')
                        if next_input.endswith(self._INPUT_MULTIPLE_LINE):
                            input_multiple = input_multiple + next_input[:len(next_input) - 1] + '; '
                            pass
                        else:
                            input_multiple = input_multiple + next_input + '; '
                            print self.execute_script(input_multiple)
                            break

                # if input is NOT above inputs, then run marionette.execute_script(INPUT)/marionette.execute_async_script(INPUT)
                # and print return value.
                else:
                    print self.execute_script(input)

        except EOFError:
            self.goodbye()
            exit()
        except Exception as e:
            print e
            if self.open_app(-1):
                self.start_js()
        exit()

    def execute_script(self, script):
        try:
            if self._is_async:
                return self.m.execute_async_script(script)
            else:
                return self.m.execute_script(script)
        except Exception as ex:
            print str(ex.message)

    def goodbye(self):
        print 'End. Bye!!'

    def open_app(self, input):
        try:
            # connect App by ID
            app_id = int(input)
            if app_id < 0:
                print 'Connect to', self._get_system_URL()
                self.set_current_frame(self._get_system_URL())
                self.m.switch_to_frame()
            else:
                iframes = self.get_all_iframes_id_name_pair()
                print 'Connect to', iframes[str(app_id)]
                self.set_current_frame(iframes[str(app_id)])
                self.m.switch_to_frame(app_id)
            return True

        except(ValueError):
            # connect to System app
            if (input.lower() == self._INPUT_SYSTEM_APP_KEYWORD) or (input.lower() in self._get_system_URL()):
                print 'Connect to', self._get_system_URL()
                self.set_current_frame(self._get_system_URL())
                self.m.switch_to_frame()
                return True

            # connect App by substring
            iframes = self.get_all_iframes_id_name_pair()
            suitable_iframes = {}
            for k, v in iframes.items():
                if input in v:
                    suitable_iframes[k] = v
            # connect to App if there is one fit
            if len(suitable_iframes) == 1:
                target = suitable_iframes.keys()[0]
                print 'Connect to', suitable_iframes.values()[0]
                self.set_current_frame(suitable_iframes.values()[0])
                self.m.switch_to_frame(int(target))
                return True
            # exit if there are more than one app fit the query
            elif len(suitable_iframes) > 1:
                print 'There are more than one Apps fit the query string [', input, '].'
                print '{0:2s} {1:s}'.format('#', 'App URL')
                for k, v in sorted(suitable_iframes.items()):
                    print '{0:2s} {1:s}'.format(k, v)
                return False
            # exit if there is no app fit the query
            else:
                print 'There is no App fit the query string [', input, '].'
                return False

    def set_current_frame(self, frame_name):
        self._current_frame = frame_name

    def get_current_frame(self):
        return self._current_frame

    def switch_to_system_frame(self):
        self.m.switch_to_frame()

    def _get_system_URL(self):
        self.switch_to_system_frame()
        system_URL = self.m.execute_script('return document.URL')
        return system_URL

    def _get_all_iframes(self):
        self.switch_to_system_frame()
        iframes = self.m.execute_script('return document.getElementsByTagName("iframe")')
        return iframes

    def get_all_iframes_id_name_pair(self):
        iframes = self._get_all_iframes()
        result = {}
        for idx in range(0, iframes['length']):
            iframe = iframes[str(idx)]
            result[str(idx)] = iframe.get_attribute('src')
        return result

    def list_all_iframes(self):
        iframes = self._get_all_iframes()
        print '{0:2s} {1:7s} {2:s}'.format('#', 'Status', 'App URL')
        print '{0:2s} {1:7s} {2:s}'.format('-1', '', self._get_system_URL())
        for idx in range(0, iframes['length']):
            iframe = iframes[str(idx)]
            print '{0:2s} {1:7s} {2:s}'.format(str(idx), ('active' if iframe.is_displayed() else ''), iframe.get_attribute('src'))

    def list_active_iframes(self):
        iframes = self._get_all_iframes()
        print '{0:2s} {1:7s} {2:s}'.format('#', 'Status', 'App URL')
        result = {}
        for idx in range(0, iframes['length']):
            iframe = iframes[str(idx)]
            if iframe.is_displayed():
                result[str(idx)] = iframe
        for idx, iframe in result.items():
            print '{0:2s} {1:7s} {2:s}'.format(idx, ('active' if iframe.is_displayed() else ''), iframe.get_attribute('src'))

    # TODO: seems like should using Javascript to get the idx of each iframe!?
    def get_all_iframes_by_marionette(self):
        iframes = self.m.find_elements('css selector', 'iframe')
        return iframes

    def list_all_iframes_by_marionette(self):
        iframes = self.get_all_iframes_by_marionette()
        for iframe in iframes:
            print iframe.get_attribute('src')

    def list_active_iframes_by_marionette(self):
        iframes = self.get_all_iframes_by_marionette()
        result = []
        for iframe in iframes:
            if iframe.is_displayed():
                result.append(iframe)
        for iframe in result:
            print iframe.get_attribute('src')
Example #14
0
def ftu(locale, device_flags, hashes):

    db = get_db(locale)

    app = 'ftu'
    app_categ = 'communications'
    app_type = 'apps'
    gaia_hash = hashes[0]
    hg_hash = hashes[1]
    screenshot_path = app_type + '/' + app_categ + '/' + app

    create_screenshot_dir(locale, screenshot_path)

    client = Marionette('localhost', 2828)
    client.start_session()

    change_screen_timeout(client)

    ftu_iframe = client.find_element(
        'css selector',
        "iframe[src='app://communications.gaiamobile.org/ftu/index.html']")

    if client.switch_to_frame(ftu_iframe):

        time.sleep(short_time)

        # app://communications.gaiamobile.org/ftu/index.html#languages
        file_name = 'languages'
        screenshot_entry = {
            "id": file_name,
            "script": app,
            "gaia": gaia_hash,
            "hg": hg_hash,
            "changed": False,
            "path": screenshot_path
        }
        test_flags = {}
        if check_flags(test_flags, device_flags):
            screenshot_entry.update(test_flags)
            if take_screenshot(locale, screenshot_path, client, file_name):
                screenshot_entry['changed'] = True
            log_displayed_l10n_strings(client, db, app, app_categ,
                                       screenshot_entry, '#activation-screen')

            # switch to app://communications.gaiamobile.org/ftu/index.html#data_3g (unlock-sim-screen screen)
            next = client.find_element('css selector', '#forward')
            next.tap()
            time.sleep(short_time)

        # app://communications.gaiamobile.org/ftu/index.html#data_3g (sim pin screen - unlock-sim-screen - 1st attempt)
        file_name = 'data_3g-unlock_sim_screen-pin_screen'
        screenshot_entry = {
            "id": file_name,
            "script": app,
            "gaia": gaia_hash,
            "hg": hg_hash,
            "changed": False,
            "path": screenshot_path
        }
        test_flags = {"sim": True, "no-sim": False}
        if check_flags(test_flags, device_flags):
            screenshot_entry.update(test_flags)
            if take_screenshot(locale, screenshot_path, client, file_name):
                screenshot_entry['changed'] = True
            log_displayed_l10n_strings(client, db, app, app_categ,
                                       screenshot_entry, '#unlock-sim-screen')

            # invalid pin -> error about pin characters
            # stay at app://communications.gaiamobile.org/ftu/index.html#data_3g (unlock-sim-screen screen)
            next = client.find_element('css selector', '#unlock-sim-button')
            next.tap()
            time.sleep(short_time)

        # app://communications.gaiamobile.org/ftu/index.html#data_3g (sim pin screen - unlock-sim-screen - pin error)
        file_name = 'data_3g-unlock_sim_screen-pin_screen-invalid_pin'
        screenshot_entry = {
            "id": file_name,
            "script": app,
            "gaia": gaia_hash,
            "hg": hg_hash,
            "changed": False,
            "path": screenshot_path
        }
        test_flags = {"sim": True, "no-sim": False}
        if check_flags(test_flags, device_flags):
            screenshot_entry.update(test_flags)
            if take_screenshot(locale, screenshot_path, client, file_name):
                screenshot_entry['changed'] = True
            log_displayed_l10n_strings(client, db, app, app_categ,
                                       screenshot_entry, '#unlock-sim-screen')

            # insert wrong pin (attempt 1 of 3)
            pin_input = client.find_element('css selector', '#pin-input')
            pin_input.send_keys(wrong_sim_pin)

            # stay at app://communications.gaiamobile.org/ftu/index.html#data_3g (unlock-sim-screen screen)
            next = client.find_element('css selector', '#unlock-sim-button')
            next.tap()
            time.sleep(short_time)

        # app://communications.gaiamobile.org/ftu/index.html#data_3g (sim pin screen - unlock-sim-screen - 2nd attempt)
        file_name = 'data_3g-unlock_sim_screen-pin_screen-wrong_pin-1st_time'
        screenshot_entry = {
            "id": file_name,
            "script": app,
            "gaia": gaia_hash,
            "hg": hg_hash,
            "changed": False,
            "path": screenshot_path
        }
        test_flags = {"sim": True, "no-sim": False}
        if check_flags(test_flags, device_flags):
            screenshot_entry.update(test_flags)
            if take_screenshot(locale, screenshot_path, client, file_name):
                screenshot_entry['changed'] = True
            log_displayed_l10n_strings(client, db, app, app_categ,
                                       screenshot_entry, '#unlock-sim-screen')

            # insert wrong pin (attempt 2 of 3)
            pin_input = client.find_element('css selector', '#pin-input')
            pin_input.send_keys(wrong_sim_pin)

            # stay at app://communications.gaiamobile.org/ftu/index.html#data_3g (unlock-sim-screen screen)
            next = client.find_element('css selector', '#unlock-sim-button')
            next.tap()
            time.sleep(short_time)

        # app://communications.gaiamobile.org/ftu/index.html#data_3g (sim pin screen - unlock-sim-screen - 3rd attempt)
        file_name = 'data_3g-unlock_sim_screen-pin_screen-wrong_pin-2nd_time'
        screenshot_entry = {
            "id": file_name,
            "script": app,
            "gaia": gaia_hash,
            "hg": hg_hash,
            "changed": False,
            "path": screenshot_path
        }
        test_flags = {"sim": True, "no-sim": False}
        if check_flags(test_flags, device_flags):
            screenshot_entry.update(test_flags)
            if take_screenshot(locale, screenshot_path, client, file_name):
                screenshot_entry['changed'] = True
            log_displayed_l10n_strings(client, db, app, app_categ,
                                       screenshot_entry, '#unlock-sim-screen')

            # insert wrong pin (atempt 3 of 3) - continues to puk screen
            pin_input = client.find_element('css selector', '#pin-input')
            pin_input.send_keys(wrong_sim_pin)

            # switch to app://communications.gaiamobile.org/ftu/index.html#data_3g (sim puk screen - unlock-sim-screen)
            next = client.find_element('css selector', '#unlock-sim-button')
            next.tap()
            time.sleep(short_time)

            # tap the header in order to hide keyboard and get full screenshot of the puk screen
            header = client.find_element('css selector', '#unlock-sim-header')
            header.tap()

        # app://communications.gaiamobile.org/ftu/index.html#data_3g (sim puk screen - unlock-sim-screen - 1st attempt)
        file_name = 'data_3g-unlock_sim_screen-puk_screen'
        screenshot_entry = {
            "id": file_name,
            "script": app,
            "gaia": gaia_hash,
            "hg": hg_hash,
            "changed": False,
            "path": screenshot_path
        }
        test_flags = {"sim": True, "no-sim": False}
        if check_flags(test_flags, device_flags):
            screenshot_entry.update(test_flags)
            if take_screenshot(locale, screenshot_path, client, file_name):
                screenshot_entry['changed'] = True
            log_displayed_l10n_strings(client, db, app, app_categ,
                                       screenshot_entry, '#unlock-sim-screen')

            # invalid puk -> error about puk characters
            # stay at app://communications.gaiamobile.org/ftu/index.html#data_3g (sim puk screen - unlock-sim-screen)
            next = client.find_element('css selector', '#unlock-sim-button')
            next.tap()
            time.sleep(short_time)

        # app://communications.gaiamobile.org/ftu/index.html#data_3g (sim puk screen - unlock-sim-screen - puk error)
        file_name = 'data_3g-unlock_sim_screen-puk_screen-invalid_puk'
        screenshot_entry = {
            "id": file_name,
            "script": app,
            "gaia": gaia_hash,
            "hg": hg_hash,
            "changed": False,
            "path": screenshot_path
        }
        test_flags = {"sim": True, "no-sim": False}
        if check_flags(test_flags, device_flags):
            screenshot_entry.update(test_flags)
            if take_screenshot(locale, screenshot_path, client, file_name):
                screenshot_entry['changed'] = True
            log_displayed_l10n_strings(client, db, app, app_categ,
                                       screenshot_entry, '#unlock-sim-screen')

            # insert wrong puk - invalid new pin -> error about pin characters
            puk_input = client.find_element('css selector', '#puk-input')
            puk_input.send_keys(wrong_sim_puk)

            # stay at app://communications.gaiamobile.org/ftu/index.html#data_3g (sim puk screen - unlock-sim-screen)
            next = client.find_element('css selector', '#unlock-sim-button')
            next.tap()
            time.sleep(short_time)

        # app://communications.gaiamobile.org/ftu/index.html#data_3g (sim puk screen - unlock-sim-screen - pin error)
        file_name = 'data_3g-unlock_sim_screen-puk_screen-invalid_new_pin'
        screenshot_entry = {
            "id": file_name,
            "script": app,
            "gaia": gaia_hash,
            "hg": hg_hash,
            "changed": False,
            "path": screenshot_path
        }
        test_flags = {"sim": True, "no-sim": False}
        if check_flags(test_flags, device_flags):
            screenshot_entry.update(test_flags)
            if take_screenshot(locale, screenshot_path, client, file_name):
                screenshot_entry['changed'] = True
            log_displayed_l10n_strings(client, db, app, app_categ,
                                       screenshot_entry, '#unlock-sim-screen')

            # insert new pin without confirmed it -> error about pin confirmation (wrong puk is preserved at its input)
            newpin_input = client.find_element('css selector', '#newpin-input')
            newpin_input.send_keys(sim_pin)

            # stay at app://communications.gaiamobile.org/ftu/index.html#data_3g (sim puk screen - unlock-sim-screen)
            next = client.find_element('css selector', '#unlock-sim-button')
            next.tap()
            time.sleep(short_time)

        # app://communications.gaiamobile.org/ftu/index.html#data_3g (sim puk screen - unlock-sim-screen - pin error)
        file_name = 'data_3g-unlock_sim_screen-puk_screen-invalid_new_pin_confirmation'
        screenshot_entry = {
            "id": file_name,
            "script": app,
            "gaia": gaia_hash,
            "hg": hg_hash,
            "changed": False,
            "path": screenshot_path
        }
        test_flags = {"sim": True, "no-sim": False}
        if check_flags(test_flags, device_flags):
            screenshot_entry.update(test_flags)
            if take_screenshot(locale, screenshot_path, client, file_name):
                screenshot_entry['changed'] = True
            log_displayed_l10n_strings(client, db, app, app_categ,
                                       screenshot_entry, '#unlock-sim-screen')

            # insert confirmation of the new pin (wrong puk and new pin are preserved at their inputs)
            newpin_input = client.find_element('css selector',
                                               '#confirm-newpin-input')
            newpin_input.send_keys(sim_pin)

            # wrong puk (attempt 1 of 9)
            # stay at app://communications.gaiamobile.org/ftu/index.html#data_3g (sim puk screen - unlock-sim-screen)
            next = client.find_element('css selector', '#unlock-sim-button')
            next.tap()
            time.sleep(short_time)

        # app://communications.gaiamobile.org/ftu/index.html#data_3g (sim puk screen - unlock-sim-screen - puk error)
        file_name = 'data_3g-unlock_sim_screen-puk_screen-wrong_puk-1st_time'
        screenshot_entry = {
            "id": file_name,
            "script": app,
            "gaia": gaia_hash,
            "hg": hg_hash,
            "changed": False,
            "path": screenshot_path
        }
        test_flags = {"sim": True, "no-sim": False}
        if check_flags(test_flags, device_flags):
            screenshot_entry.update(test_flags)
            if take_screenshot(locale, screenshot_path, client, file_name):
                screenshot_entry['changed'] = True
            log_displayed_l10n_strings(client, db, app, app_categ,
                                       screenshot_entry, '#unlock-sim-screen')

            # insert wrong puk (attempt 2 of 9) (new pin and its confirmation are preserved at their inputs)
            puk_input = client.find_element('css selector', '#puk-input')
            puk_input.send_keys(wrong_sim_puk)

            # stay at app://communications.gaiamobile.org/ftu/index.html#data_3g (sim puk screen - unlock-sim-screen)
            next = client.find_element('css selector', '#unlock-sim-button')
            next.tap()
            time.sleep(short_time)

        # app://communications.gaiamobile.org/ftu/index.html#data_3g (sim puk screen - unlock-sim-screen - 2nd attempt)
        file_name = 'data_3g-unlock_sim_screen-puk_screen-wrong_puk-2nd_time'
        screenshot_entry = {
            "id": file_name,
            "script": app,
            "gaia": gaia_hash,
            "hg": hg_hash,
            "changed": False,
            "path": screenshot_path
        }
        test_flags = {"sim": True, "no-sim": False}
        if check_flags(test_flags, device_flags):
            screenshot_entry.update(test_flags)
            if take_screenshot(locale, screenshot_path, client, file_name):
                screenshot_entry['changed'] = True
            log_displayed_l10n_strings(client, db, app, app_categ,
                                       screenshot_entry, '#unlock-sim-screen')

            # insert right puk (attempt 2 of 9) (new pin and its confirmation are preserved at their inputs)
            puk_input = client.find_element('css selector', '#puk-input')
            puk_input.send_keys(sim_puk)

            # switch to app://communications.gaiamobile.org/ftu/index.html#data_3g
            next = client.find_element('css selector', '#unlock-sim-button')
            next.tap()
            time.sleep(short_time)

        # app://communications.gaiamobile.org/ftu/index.html#data_3g
        file_name = 'data_3g'
        screenshot_entry = {
            "id": file_name,
            "script": app,
            "gaia": gaia_hash,
            "hg": hg_hash,
            "changed": False,
            "path": screenshot_path
        }
        test_flags = {"sim": True, "no-sim": False}
        if check_flags(test_flags, device_flags):
            screenshot_entry.update(test_flags)
            if take_screenshot(locale, screenshot_path, client, file_name):
                screenshot_entry['changed'] = True
            log_displayed_l10n_strings(client, db, app, app_categ,
                                       screenshot_entry, '#activation-screen')

            # switch to app://communications.gaiamobile.org/ftu/index.html#wifi
            next = client.find_element('css selector', '#forward')
            next.tap()
            time.sleep(long_time)

            # enable overlay "scanningNetworks" spinner screen (loading-overlay)
            client.execute_script(
                "window.wrappedJSObject.utils.overlay.show('scanningNetworks', 'spinner');"
            )
            time.sleep(middle_time)

        # overlay "scanningNetworks" spinner screen
        file_name = 'wifi-loading_overlay-scanning_networks'
        screenshot_entry = {
            "id": file_name,
            "script": app,
            "gaia": gaia_hash,
            "hg": hg_hash,
            "changed": False,
            "path": screenshot_path
        }
        test_flags = {}
        if check_flags(test_flags, device_flags):
            screenshot_entry.update(test_flags)
            if take_screenshot(locale, screenshot_path, client, file_name):
                screenshot_entry['changed'] = True
            log_displayed_l10n_strings(client, db, app, app_categ,
                                       screenshot_entry, '#loading-overlay')

            # disable overlay "scanningNetworks" spinner screen
            client.execute_script(
                "window.wrappedJSObject.utils.overlay.hide('scanningNetworks', 'spinner');"
            )
            time.sleep(middle_time)

        # app://communications.gaiamobile.org/ftu/index.html#wifi
        file_name = 'wifi'
        screenshot_entry = {
            "id": file_name,
            "script": app,
            "gaia": gaia_hash,
            "hg": hg_hash,
            "changed": False,
            "path": screenshot_path
        }
        test_flags = {}
        if check_flags(test_flags, device_flags):
            screenshot_entry.update(test_flags)
            if take_screenshot(locale, screenshot_path, client, file_name):
                screenshot_entry['changed'] = True
            log_displayed_l10n_strings(client, db, app, app_categ,
                                       screenshot_entry, '#wifi')

            # switch to app://communications.gaiamobile.org/ftu/index.html#date_and_time
            next = client.find_element('css selector', '#forward')
            next.tap()
            time.sleep(short_time)

        # Set time in order to be the same at every screenshot
        set_time(client)

        # app://communications.gaiamobile.org/ftu/index.html#date_and_time
        file_name = 'date_and_time'
        screenshot_entry = {
            "id": file_name,
            "script": app,
            "gaia": gaia_hash,
            "hg": hg_hash,
            "changed": False,
            "path": screenshot_path
        }
        test_flags = {}
        if check_flags(test_flags, device_flags):
            screenshot_entry.update(test_flags)
            if take_screenshot(locale, screenshot_path, client, file_name):
                screenshot_entry['changed'] = True
            log_displayed_l10n_strings(client, db, app, app_categ,
                                       screenshot_entry, '#date_and_time')

            # switch to app://communications.gaiamobile.org/ftu/index.html#geolocation
            next = client.find_element('css selector', '#forward')
            next.tap()
            time.sleep(short_time)

        # app://communications.gaiamobile.org/ftu/index.html#geolocation
        file_name = 'geolocation'
        screenshot_entry = {
            "id": file_name,
            "script": app,
            "gaia": gaia_hash,
            "hg": hg_hash,
            "changed": False,
            "path": screenshot_path
        }
        test_flags = {}
        if check_flags(test_flags, device_flags):
            screenshot_entry.update(test_flags)
            if take_screenshot(locale, screenshot_path, client, file_name):
                screenshot_entry['changed'] = True
            log_displayed_l10n_strings(client, db, app, app_categ,
                                       screenshot_entry, '#geolocation')

            # switch to app://communications.gaiamobile.org/ftu/index.html#import_contacts
            next = client.find_element('css selector', '#forward')
            next.tap()
            time.sleep(middle_time)

        # app://communications.gaiamobile.org/ftu/index.html#import_contacts
        file_name = 'import_contacts'
        screenshot_entry = {
            "id": file_name,
            "script": app,
            "gaia": gaia_hash,
            "hg": hg_hash,
            "changed": False,
            "path": screenshot_path
        }
        test_flags = {}
        if check_flags(test_flags, device_flags):
            screenshot_entry.update(test_flags)
            if take_screenshot(locale, screenshot_path, client, file_name):
                screenshot_entry['changed'] = True
            log_displayed_l10n_strings(client, db, app, app_categ,
                                       screenshot_entry, '#import_contacts')

            # switch to app://communications.gaiamobile.org/ftu/index.html#welcome_browser
            next = client.find_element('css selector', '#forward')
            next.tap()
            time.sleep(short_time)

        # app://communications.gaiamobile.org/ftu/index.html#welcome_browser
        file_name = 'welcome_browser'
        screenshot_entry = {
            "id": file_name,
            "script": app,
            "gaia": gaia_hash,
            "hg": hg_hash,
            "changed": False,
            "path": screenshot_path
        }
        test_flags = {}
        if check_flags(test_flags, device_flags):
            screenshot_entry.update(test_flags)
            if take_screenshot(locale, screenshot_path, client, file_name):
                screenshot_entry['changed'] = True
            log_displayed_l10n_strings(client, db, app, app_categ,
                                       screenshot_entry)

            # switch to app://communications.gaiamobile.org/ftu/index.html#browser_privacy
            next = client.find_element('css selector', '#forward')
            next.tap()
            time.sleep(short_time)

        # app://communications.gaiamobile.org/ftu/index.html#browser_privacy
        file_name = 'browser_privacy'
        screenshot_entry = {
            "id": file_name,
            "script": app,
            "gaia": gaia_hash,
            "hg": hg_hash,
            "changed": False,
            "path": screenshot_path
        }
        test_flags = {}
        if check_flags(test_flags, device_flags):
            screenshot_entry.update(test_flags)
            if take_screenshot(locale, screenshot_path, client, file_name):
                screenshot_entry['changed'] = True
            log_displayed_l10n_strings(client, db, app, app_categ,
                                       screenshot_entry)

            # switch to app://communications.gaiamobile.org/ftu/index.html#step1 (first tutorial screen)
            next = client.find_element('css selector', '#forward')
            next.tap()
            time.sleep(long_time)

        # app://communications.gaiamobile.org/ftu/index.html#step1 (first tutorial screen)
        file_name = 'step1-first_tutorial_screen'
        screenshot_entry = {
            "id": file_name,
            "script": app,
            "gaia": gaia_hash,
            "hg": hg_hash,
            "changed": False,
            "path": screenshot_path
        }
        test_flags = {}
        if check_flags(test_flags, device_flags):
            screenshot_entry.update(test_flags)
            if take_screenshot(locale, screenshot_path, client, file_name):
                screenshot_entry['changed'] = True
            log_displayed_l10n_strings(client, db, app, app_categ,
                                       screenshot_entry)

            # switch to app://communications.gaiamobile.org/ftu/index.html#step1
            next = client.find_element('css selector', '#lets-go-button')
            next.tap()
            time.sleep(long_time)

        # app://communications.gaiamobile.org/ftu/index.html#step1
        file_name = 'step1'
        screenshot_entry = {
            "id": file_name,
            "script": app,
            "gaia": gaia_hash,
            "hg": hg_hash,
            "changed": False,
            "path": screenshot_path
        }
        test_flags = {}
        if check_flags(test_flags, device_flags):
            screenshot_entry.update(test_flags)
            if take_screenshot(locale, screenshot_path, client, file_name):
                screenshot_entry['changed'] = True
            log_displayed_l10n_strings(client, db, app, app_categ,
                                       screenshot_entry)

            # switch to app://communications.gaiamobile.org/ftu/index.html#step2
            next = client.find_element('css selector', '#forwardTutorial')
            next.tap()
            time.sleep(short_time)

        # app://communications.gaiamobile.org/ftu/index.html#step2
        file_name = 'step2'
        screenshot_entry = {
            "id": file_name,
            "script": app,
            "gaia": gaia_hash,
            "hg": hg_hash,
            "changed": False,
            "path": screenshot_path
        }
        test_flags = {}
        if check_flags(test_flags, device_flags):
            screenshot_entry.update(test_flags)
            if take_screenshot(locale, screenshot_path, client, file_name):
                screenshot_entry['changed'] = True
            log_displayed_l10n_strings(client, db, app, app_categ,
                                       screenshot_entry)

            # switch to app://communications.gaiamobile.org/ftu/index.html#step3
            next = client.find_element('css selector', '#forwardTutorial')
            next.tap()
            time.sleep(short_time)

        # app://communications.gaiamobile.org/ftu/index.html#step3
        file_name = 'step3'
        screenshot_entry = {
            "id": file_name,
            "script": app,
            "gaia": gaia_hash,
            "hg": hg_hash,
            "changed": False,
            "path": screenshot_path
        }
        test_flags = {}
        if check_flags(test_flags, device_flags):
            screenshot_entry.update(test_flags)
            if take_screenshot(locale, screenshot_path, client, file_name):
                screenshot_entry['changed'] = True
            log_displayed_l10n_strings(client, db, app, app_categ,
                                       screenshot_entry)

            # switch to app://communications.gaiamobile.org/ftu/index.html#step4
            next = client.find_element('css selector', '#forwardTutorial')
            next.tap()
            time.sleep(short_time)

        # app://communications.gaiamobile.org/ftu/index.html#step4
        file_name = 'step4'
        screenshot_entry = {
            "id": file_name,
            "script": app,
            "gaia": gaia_hash,
            "hg": hg_hash,
            "changed": False,
            "path": screenshot_path
        }
        test_flags = {}
        if check_flags(test_flags, device_flags):
            screenshot_entry.update(test_flags)
            if take_screenshot(locale, screenshot_path, client, file_name):
                screenshot_entry['changed'] = True
            log_displayed_l10n_strings(client, db, app, app_categ,
                                       screenshot_entry)

            # switch to app://communications.gaiamobile.org/ftu/index.html#step4 (last tutorial screen)
            next = client.find_element('css selector', '#forwardTutorial')
            next.tap()
            time.sleep(long_time)

        # app://communications.gaiamobile.org/ftu/index.html#step4 (last tutorial screen)
        file_name = 'step4-last_tutorial_screen'
        screenshot_entry = {
            "id": file_name,
            "script": app,
            "gaia": gaia_hash,
            "hg": hg_hash,
            "changed": False,
            "path": screenshot_path
        }
        test_flags = {}
        if check_flags(test_flags, device_flags):
            screenshot_entry.update(test_flags)
            if take_screenshot(locale, screenshot_path, client, file_name):
                screenshot_entry['changed'] = True
            log_displayed_l10n_strings(client, db, app, app_categ,
                                       screenshot_entry)

            # Close ftu frame
            next = client.find_element('css selector', '#tutorialFinished')
            next.tap()
            time.sleep(short_time)

        set_db(locale, db)

    else:
        #TO DO raise proper error
        print "switch to ftu frame failed"
Example #15
0
class Runner(object):

    _INPUT_NONE = ''
    _INPUT_EXIT_COMMAND = 'exit'
    _INPUT_MULTIPLE_LINE = ' \\'
    _INPUT_COMMAND_PREFIX = ':'
    _INPUT_SYSTEM_APP_KEYWORD = 'system'

    _KEYBOARD_FRAME_NAME = 'app://keyboard.gaiamobile.org/index.html'

    _is_async = False
    _sync_prompt = '>>> '
    _async_prompt = 'a>> '
    _prompt = _sync_prompt

    def __init__(self, **kwargs):
        # Added parser
        parser = OptionParser()
        parser.add_option(
            '-a',
            '--address',
            action='store',
            type='string',
            dest='address',
            default='localhost',
            help='The host address of b2g instance. Default=localhost')
        parser.add_option('-p',
                          '--port',
                          action='store',
                          type='int',
                          dest='port',
                          default=2828,
                          help='The port of b2g instance.')
        parser.add_option('-l',
                          '--list',
                          action='store_true',
                          dest='enable_list',
                          default='False',
                          help='List all apps of b2g instance. Default=False')
        parser.add_option('-c', '--connect',
                          action='store', type='string', dest='connect',
                          default=None,
                          help='Connect to the App iframe.' \
                               'Use # ID or App URL to connect.')

        (options, args) = parser.parse_args()
        self.connect = options.connect

        # start marionette session
        self.m = Marionette(options.address, options.port)
        self.m.start_session()

        # list all iframes
        if options.enable_list:
            self.list_all_iframes()
        # list active iframes
        elif self.connect == None:
            self.list_active_iframes()

        # connect to App
        if self.connect == None:
            exit(0)
        else:
            # connect App
            print 'Start...'
            if self.open_app(self.connect):
                self.start_js()
            else:
                exit(-1)

    def switch_sync_async(self):
        self._is_async = not self._is_async
        self._prompt = self._async_prompt if self._is_async else self._sync_prompt
        print 'Swith to', ('Async'
                           if self._is_async else 'Sync'), 'JS execution'

    def start_js(self):
        print 'Enter \'%s\' or Crtl+D to exit the shell.' % self._INPUT_EXIT_COMMAND
        print 'And enter \':h\' for more commands.'
        try:
            while True:
                input = raw_input(self._prompt)
                # if input is EXIT command, exit this program
                if input.lower() == self._INPUT_EXIT_COMMAND:
                    self.goodbye()
                    break

                # if input is NONE, then do nothing and keep going...
                elif input == self._INPUT_NONE:
                    continue

                # if input start with ":", it should be the command.
                elif input.startswith(self._INPUT_COMMAND_PREFIX):
                    CmdDispatcher(self, input)

                # if the postfix of input is MULTIPLE_LINE, then record this line and wait the next line until no input with MULTIPLE_LINE.
                elif input.endswith(self._INPUT_MULTIPLE_LINE):
                    input_multiple = input[:len(input) - 1] + '; '
                    while True:
                        next_input = raw_input('... ')
                        if next_input.endswith(self._INPUT_MULTIPLE_LINE):
                            input_multiple = input_multiple + next_input[:len(
                                next_input) - 1] + '; '
                            pass
                        else:
                            input_multiple = input_multiple + next_input + '; '
                            print self.execute_script(input_multiple)
                            break

                # if input is NOT above inputs, then run marionette.execute_script(INPUT)/marionette.execute_async_script(INPUT)
                # and print return value.
                else:
                    print self.execute_script(input)

        except EOFError:
            self.goodbye()
            exit()
        except Exception as e:
            print e
            if self.open_app(-1):
                self.start_js()
        exit()

    def execute_script(self, script):
        try:
            if self._is_async:
                return self.m.execute_async_script(script)
            else:
                return self.m.execute_script(script)
        except Exception as ex:
            print str(ex.message)

    def goodbye(self):
        print 'End. Bye!!'

    def open_app(self, input):
        try:
            # connect App by ID
            app_id = int(input)
            if app_id < 0:
                print 'Connect to', self._get_system_URL()
                self.set_current_frame(self._get_system_URL())
                self.m.switch_to_frame()
            else:
                iframes = self.get_all_iframes_id_name_pair()
                print 'Connect to', iframes[str(app_id)]
                self.set_current_frame(iframes[str(app_id)])
                if iframes[str(app_id)] == self._KEYBOARD_FRAME_NAME:
                    self.m.switch_to_frame(app_id, False)
                else:
                    self.m.switch_to_frame(app_id)
            return True

        except (ValueError):
            # connect to System app
            if (input.lower() == self._INPUT_SYSTEM_APP_KEYWORD) or (
                    input.lower() in self._get_system_URL()):
                print 'Connect to', self._get_system_URL()
                self.set_current_frame(self._get_system_URL())
                self.m.switch_to_frame()
                return True

            # connect App by substring
            iframes = self.get_all_iframes_id_name_pair()
            suitable_iframes = {}
            for k, v in iframes.items():
                if input in v:
                    suitable_iframes[k] = v
            # connect to App if there is one fit
            if len(suitable_iframes) == 1:
                target = suitable_iframes.keys()[0]
                print 'Connect to', suitable_iframes.values()[0]
                self.set_current_frame(suitable_iframes.values()[0])
                if suitable_iframes.values()[0] == self._KEYBOARD_FRAME_NAME:
                    self.m.switch_to_frame(int(target), False)
                else:
                    self.m.switch_to_frame(int(target))
                return True
            # exit if there are more than one app fit the query
            elif len(suitable_iframes) > 1:
                print 'There are more than one Apps fit the query string [', input, '].'
                print '{0:2s} {1:s}'.format('#', 'App URL')
                for k, v in sorted(suitable_iframes.items()):
                    print '{0:2s} {1:s}'.format(k, v)
                return False
            # exit if there is no app fit the query
            else:
                print 'There is no App fit the query string [', input, '].'
                return False

    def set_current_frame(self, frame_name):
        self._current_frame = frame_name

    def get_current_frame(self):
        return self._current_frame

    def switch_to_system_frame(self):
        self.m.switch_to_frame()

    def _get_system_URL(self):
        self.switch_to_system_frame()
        system_URL = self.m.execute_script('return document.URL')
        return system_URL

    def _get_all_iframes(self):
        self.switch_to_system_frame()
        iframes = self.m.execute_script(
            'return document.getElementsByTagName("iframe")')
        return iframes

    def get_all_iframes_id_name_pair(self):
        iframes = self._get_all_iframes()
        result = {}
        for idx in range(0, iframes['length']):
            iframe = iframes[str(idx)]
            result[str(idx)] = iframe.get_attribute('src')
        return result

    def list_all_iframes(self):
        iframes = self._get_all_iframes()
        print '{0:2s} {1:7s} {2:s}'.format('#', 'Status', 'App URL')
        print '{0:2s} {1:7s} {2:s}'.format('-1', '', self._get_system_URL())
        for idx in range(0, iframes['length']):
            iframe = iframes[str(idx)]
            print '{0:2s} {1:7s} {2:s}'.format(
                str(idx), ('active' if iframe.is_displayed() else ''),
                iframe.get_attribute('src'))

    def list_active_iframes(self):
        iframes = self._get_all_iframes()
        print '{0:2s} {1:7s} {2:s}'.format('#', 'Status', 'App URL')
        result = {}
        for idx in range(0, iframes['length']):
            iframe = iframes[str(idx)]
            if iframe.is_displayed():
                result[str(idx)] = iframe
        for idx, iframe in result.items():
            print '{0:2s} {1:7s} {2:s}'.format(
                idx, ('active' if iframe.is_displayed() else ''),
                iframe.get_attribute('src'))

    # TODO: seems like should using Javascript to get the idx of each iframe!?
    def get_all_iframes_by_marionette(self):
        iframes = self.m.find_elements('css selector', 'iframe')
        return iframes

    def list_all_iframes_by_marionette(self):
        iframes = self.get_all_iframes_by_marionette()
        for iframe in iframes:
            print iframe.get_attribute('src')

    def list_active_iframes_by_marionette(self):
        iframes = self.get_all_iframes_by_marionette()
        result = []
        for iframe in iframes:
            if iframe.is_displayed():
                result.append(iframe)
        for iframe in result:
            print iframe.get_attribute('src')
Example #16
0
    assert(m.execute_js_script(server.TEST_EXECUTE_SCRIPT))
    assert(m.execute_js_script(server.TEST_EXECUTE_SCRIPT, server.TEST_EXECUTE_SCRIPT_ARGS))
    assert(m.execute_script(server.TEST_EXECUTE_SCRIPT, server.TEST_EXECUTE_SCRIPT_ARGS))
    assert(m.execute_async_script(server.TEST_EXECUTE_SCRIPT))
    assert(m.execute_async_script(server.TEST_EXECUTE_SCRIPT, server.TEST_EXECUTE_SCRIPT_ARGS))
    assert(str(m.find_element(HTMLElement.CLASS, 'heading')) == server.TEST_FIND_ELEMENT)
    assert([str(x) for x in m.find_elements(HTMLElement.TAG, 'p')] == server.TEST_FIND_ELEMENTS)
    assert(str(m.find_element(HTMLElement.CLASS, 'heading').find_element(HTMLElement.TAG, 'h1')) == server.TEST_FIND_ELEMENT)
    assert([str(x) for x in m.find_element(HTMLElement.ID, 'div1').find_elements(HTMLElement.SELECTOR, '.main')] == \
        server.TEST_FIND_ELEMENTS)
    assert(m.find_element(HTMLElement.ID, 'id1').click())
    assert(m.find_element(HTMLElement.ID, 'id2').text() == server.TEST_GET_TEXT)
    assert(m.find_element(HTMLElement.ID, 'id3').send_keys('Mozilla Firefox'))
    assert(m.find_element(HTMLElement.ID, 'id3').value() == server.TEST_GET_VALUE)
    assert(m.find_element(HTMLElement.ID, 'id3').clear())
    assert(m.find_element(HTMLElement.ID, 'id3').selected())
    assert(m.find_element(HTMLElement.ID, 'id1').equals(m.find_element(HTMLElement.TAG, 'p')))
    assert(m.find_element(HTMLElement.ID, 'id3').enabled())
    assert(m.find_element(HTMLElement.ID, 'id3').displayed())
    assert(m.find_element(HTMLElement.ID, 'id3').get_attribute('value') == server.TEST_GET_VALUE)
    assert(m.delete_session())

    # verify a session is started automatically for us if needed
    assert(m.switch_to_frame('frame1'))
    assert(m.switch_to_frame(1))
    assert(m.switch_to_frame(m.find_element(HTMLElement.ID, 'frameid')))
    assert(m.switch_to_frame())
    assert(m.get_window() == server.TEST_CURRENT_WINDOW)
    assert(m.set_context(m.CONTEXT_CHROME))
    assert(m.delete_session())
Example #17
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)
Example #18
0
    assert m.execute_async_script(server.TEST_EXECUTE_SCRIPT, server.TEST_EXECUTE_SCRIPT_ARGS)
    assert str(m.find_element(HTMLElement.CLASS, "heading")) == server.TEST_FIND_ELEMENT
    assert [str(x) for x in m.find_elements(HTMLElement.TAG, "p")] == server.TEST_FIND_ELEMENTS
    assert (
        str(m.find_element(HTMLElement.CLASS, "heading").find_element(HTMLElement.TAG, "h1"))
        == server.TEST_FIND_ELEMENT
    )
    assert [
        str(x) for x in m.find_element(HTMLElement.ID, "div1").find_elements(HTMLElement.SELECTOR, ".main")
    ] == server.TEST_FIND_ELEMENTS
    assert m.find_element(HTMLElement.ID, "id1").click()
    assert m.find_element(HTMLElement.ID, "id2").text() == server.TEST_GET_TEXT
    assert m.find_element(HTMLElement.ID, "id3").send_keys("Mozilla Firefox")
    assert m.find_element(HTMLElement.ID, "id3").value() == server.TEST_GET_VALUE
    assert m.find_element(HTMLElement.ID, "id3").clear()
    assert m.find_element(HTMLElement.ID, "id3").selected()
    assert m.find_element(HTMLElement.ID, "id1").equals(m.find_element(HTMLElement.TAG, "p"))
    assert m.find_element(HTMLElement.ID, "id3").enabled()
    assert m.find_element(HTMLElement.ID, "id3").displayed()
    assert m.find_element(HTMLElement.ID, "id3").get_attribute("value") == server.TEST_GET_VALUE
    assert m.delete_session()

    # verify a session is started automatically for us if needed
    assert m.switch_to_frame("frame1")
    assert m.switch_to_frame(1)
    assert m.switch_to_frame(m.find_element(HTMLElement.ID, "frameid"))
    assert m.switch_to_frame()
    assert m.get_window() == server.TEST_CURRENT_WINDOW
    assert m.set_context(m.CONTEXT_CHROME)
    assert m.delete_session()
Example #19
0
def ftu(locale, device_flags, hashes):

  db = get_db(locale)

  app = 'ftu'
  app_categ = 'communications'
  app_type = 'apps'
  gaia_hash = hashes[0]
  hg_hash = hashes[1]
  screenshot_path = app_type + '/' + app_categ + '/' + app

  create_screenshot_dir(locale, screenshot_path)

  client = Marionette('localhost', 2828)
  client.start_session()

  change_screen_timeout(client) 

  ftu_iframe = client.find_element('css selector',"iframe[src='app://communications.gaiamobile.org/ftu/index.html']")

  if client.switch_to_frame(ftu_iframe):

    time.sleep(short_time)

    # app://communications.gaiamobile.org/ftu/index.html#languages 
    file_name = 'languages'
    screenshot_entry = {
      "id" : file_name,
      "script" : app,
      "gaia" : gaia_hash,
      "hg" : hg_hash,
      "changed" : False,
      "path" : screenshot_path}
    test_flags = {}
    if check_flags(test_flags, device_flags):
      screenshot_entry.update(test_flags)
      if take_screenshot(locale, screenshot_path, client, file_name):
        screenshot_entry['changed'] = True
      log_displayed_l10n_strings(client, db, app, app_categ, screenshot_entry, '#activation-screen')


      # switch to app://communications.gaiamobile.org/ftu/index.html#data_3g (unlock-sim-screen screen)
      next = client.find_element('css selector', '#forward')
      next.tap()
      time.sleep(short_time)

    # app://communications.gaiamobile.org/ftu/index.html#data_3g (sim pin screen - unlock-sim-screen - 1st attempt)
    file_name = 'data_3g-unlock_sim_screen-pin_screen'
    screenshot_entry = {
      "id" : file_name,
      "script" : app,
      "gaia" : gaia_hash,
      "hg" : hg_hash,
      "changed" : False,
      "path" : screenshot_path}
    test_flags = {
      "sim": True,
      "no-sim": False}
    if check_flags(test_flags, device_flags):
      screenshot_entry.update(test_flags)
      if take_screenshot(locale, screenshot_path, client, file_name):
        screenshot_entry['changed'] = True
      log_displayed_l10n_strings(client, db, app, app_categ, screenshot_entry, '#unlock-sim-screen')


      # invalid pin -> error about pin characters
      # stay at app://communications.gaiamobile.org/ftu/index.html#data_3g (unlock-sim-screen screen)
      next = client.find_element('css selector', '#unlock-sim-button')
      next.tap()
      time.sleep(short_time)

    # app://communications.gaiamobile.org/ftu/index.html#data_3g (sim pin screen - unlock-sim-screen - pin error)
    file_name = 'data_3g-unlock_sim_screen-pin_screen-invalid_pin'
    screenshot_entry = {
      "id" : file_name,
      "script" : app,
      "gaia" : gaia_hash,
      "hg" : hg_hash,
      "changed" : False,
      "path" : screenshot_path}
    test_flags = {
      "sim": True,
      "no-sim": False}
    if check_flags(test_flags, device_flags):
      screenshot_entry.update(test_flags)
      if take_screenshot(locale, screenshot_path, client, file_name):
        screenshot_entry['changed'] = True
      log_displayed_l10n_strings(client, db, app, app_categ, screenshot_entry, '#unlock-sim-screen')


      # insert wrong pin (attempt 1 of 3)
      pin_input = client.find_element('css selector', '#pin-input')
      pin_input.send_keys(wrong_sim_pin)

      # stay at app://communications.gaiamobile.org/ftu/index.html#data_3g (unlock-sim-screen screen)
      next = client.find_element('css selector', '#unlock-sim-button')
      next.tap()
      time.sleep(short_time)
    
    # app://communications.gaiamobile.org/ftu/index.html#data_3g (sim pin screen - unlock-sim-screen - 2nd attempt)
    file_name = 'data_3g-unlock_sim_screen-pin_screen-wrong_pin-1st_time'
    screenshot_entry = {
      "id" : file_name,
      "script" : app,
      "gaia" : gaia_hash,
      "hg" : hg_hash,
      "changed" : False,
      "path" : screenshot_path}
    test_flags = {
      "sim": True,
      "no-sim": False}
    if check_flags(test_flags, device_flags):
      screenshot_entry.update(test_flags)
      if take_screenshot(locale, screenshot_path, client, file_name):
        screenshot_entry['changed'] = True
      log_displayed_l10n_strings(client, db, app, app_categ, screenshot_entry, '#unlock-sim-screen')


      # insert wrong pin (attempt 2 of 3)
      pin_input = client.find_element('css selector', '#pin-input')
      pin_input.send_keys(wrong_sim_pin)

      # stay at app://communications.gaiamobile.org/ftu/index.html#data_3g (unlock-sim-screen screen)
      next = client.find_element('css selector', '#unlock-sim-button')
      next.tap()
      time.sleep(short_time)

    # app://communications.gaiamobile.org/ftu/index.html#data_3g (sim pin screen - unlock-sim-screen - 3rd attempt)
    file_name = 'data_3g-unlock_sim_screen-pin_screen-wrong_pin-2nd_time'
    screenshot_entry = {
      "id" : file_name,
      "script" : app,
      "gaia" : gaia_hash,
      "hg" : hg_hash,
      "changed" : False,
      "path" : screenshot_path}
    test_flags = {
      "sim": True,
      "no-sim": False}
    if check_flags(test_flags, device_flags):
      screenshot_entry.update(test_flags)
      if take_screenshot(locale, screenshot_path, client, file_name):
        screenshot_entry['changed'] = True
      log_displayed_l10n_strings(client, db, app, app_categ, screenshot_entry, '#unlock-sim-screen')


      # insert wrong pin (atempt 3 of 3) - continues to puk screen
      pin_input = client.find_element('css selector', '#pin-input')
      pin_input.send_keys(wrong_sim_pin)

      # switch to app://communications.gaiamobile.org/ftu/index.html#data_3g (sim puk screen - unlock-sim-screen)
      next = client.find_element('css selector', '#unlock-sim-button')
      next.tap()
      time.sleep(short_time)

      # tap the header in order to hide keyboard and get full screenshot of the puk screen
      header = client.find_element('css selector', '#unlock-sim-header')
      header.tap()

    # app://communications.gaiamobile.org/ftu/index.html#data_3g (sim puk screen - unlock-sim-screen - 1st attempt)
    file_name = 'data_3g-unlock_sim_screen-puk_screen'
    screenshot_entry = {
      "id" : file_name,
      "script" : app,
      "gaia" : gaia_hash,
      "hg" : hg_hash,
      "changed" : False,
      "path" : screenshot_path}
    test_flags = {
      "sim": True,
      "no-sim": False}
    if check_flags(test_flags, device_flags):
      screenshot_entry.update(test_flags)
      if take_screenshot(locale, screenshot_path, client, file_name):
        screenshot_entry['changed'] = True
      log_displayed_l10n_strings(client, db, app, app_categ, screenshot_entry, '#unlock-sim-screen')


      # invalid puk -> error about puk characters
      # stay at app://communications.gaiamobile.org/ftu/index.html#data_3g (sim puk screen - unlock-sim-screen)
      next = client.find_element('css selector', '#unlock-sim-button')
      next.tap()
      time.sleep(short_time)

    # app://communications.gaiamobile.org/ftu/index.html#data_3g (sim puk screen - unlock-sim-screen - puk error)
    file_name = 'data_3g-unlock_sim_screen-puk_screen-invalid_puk'
    screenshot_entry = {
      "id" : file_name,
      "script" : app,
      "gaia" : gaia_hash,
      "hg" : hg_hash,
      "changed" : False,
      "path" : screenshot_path}
    test_flags = {
      "sim": True,
      "no-sim": False}
    if check_flags(test_flags, device_flags):
      screenshot_entry.update(test_flags)
      if take_screenshot(locale, screenshot_path, client, file_name):
        screenshot_entry['changed'] = True
      log_displayed_l10n_strings(client, db, app, app_categ, screenshot_entry, '#unlock-sim-screen')


      # insert wrong puk - invalid new pin -> error about pin characters
      puk_input = client.find_element('css selector', '#puk-input')
      puk_input.send_keys(wrong_sim_puk)

      # stay at app://communications.gaiamobile.org/ftu/index.html#data_3g (sim puk screen - unlock-sim-screen)
      next = client.find_element('css selector', '#unlock-sim-button')
      next.tap()
      time.sleep(short_time)

    # app://communications.gaiamobile.org/ftu/index.html#data_3g (sim puk screen - unlock-sim-screen - pin error)
    file_name = 'data_3g-unlock_sim_screen-puk_screen-invalid_new_pin'
    screenshot_entry = {
      "id" : file_name,
      "script" : app,
      "gaia" : gaia_hash,
      "hg" : hg_hash,
      "changed" : False,
      "path" : screenshot_path}
    test_flags = {
      "sim": True,
      "no-sim": False}
    if check_flags(test_flags, device_flags):
      screenshot_entry.update(test_flags)
      if take_screenshot(locale, screenshot_path, client, file_name):
        screenshot_entry['changed'] = True
      log_displayed_l10n_strings(client, db, app, app_categ, screenshot_entry, '#unlock-sim-screen')


      # insert new pin without confirmed it -> error about pin confirmation (wrong puk is preserved at its input)
      newpin_input = client.find_element('css selector', '#newpin-input')
      newpin_input.send_keys(sim_pin)

      # stay at app://communications.gaiamobile.org/ftu/index.html#data_3g (sim puk screen - unlock-sim-screen)
      next = client.find_element('css selector', '#unlock-sim-button')
      next.tap()
      time.sleep(short_time)

    # app://communications.gaiamobile.org/ftu/index.html#data_3g (sim puk screen - unlock-sim-screen - pin error)
    file_name = 'data_3g-unlock_sim_screen-puk_screen-invalid_new_pin_confirmation'
    screenshot_entry = {
      "id" : file_name,
      "script" : app,
      "gaia" : gaia_hash,
      "hg" : hg_hash,
      "changed" : False,
      "path" : screenshot_path}
    test_flags = {
      "sim": True,
      "no-sim": False}
    if check_flags(test_flags, device_flags):
      screenshot_entry.update(test_flags)
      if take_screenshot(locale, screenshot_path, client, file_name):
        screenshot_entry['changed'] = True
      log_displayed_l10n_strings(client, db, app, app_categ, screenshot_entry, '#unlock-sim-screen')


      # insert confirmation of the new pin (wrong puk and new pin are preserved at their inputs)
      newpin_input = client.find_element('css selector', '#confirm-newpin-input')
      newpin_input.send_keys(sim_pin)

      # wrong puk (attempt 1 of 9)
      # stay at app://communications.gaiamobile.org/ftu/index.html#data_3g (sim puk screen - unlock-sim-screen)
      next = client.find_element('css selector', '#unlock-sim-button')
      next.tap()
      time.sleep(short_time)

    # app://communications.gaiamobile.org/ftu/index.html#data_3g (sim puk screen - unlock-sim-screen - puk error)
    file_name = 'data_3g-unlock_sim_screen-puk_screen-wrong_puk-1st_time'
    screenshot_entry = {
      "id" : file_name,
      "script" : app,
      "gaia" : gaia_hash,
      "hg" : hg_hash,
      "changed" : False,
      "path" : screenshot_path}
    test_flags = {
      "sim": True,
      "no-sim": False}
    if check_flags(test_flags, device_flags):
      screenshot_entry.update(test_flags)
      if take_screenshot(locale, screenshot_path, client, file_name):
        screenshot_entry['changed'] = True
      log_displayed_l10n_strings(client, db, app, app_categ, screenshot_entry, '#unlock-sim-screen')


      # insert wrong puk (attempt 2 of 9) (new pin and its confirmation are preserved at their inputs)
      puk_input = client.find_element('css selector', '#puk-input')
      puk_input.send_keys(wrong_sim_puk)

      # stay at app://communications.gaiamobile.org/ftu/index.html#data_3g (sim puk screen - unlock-sim-screen)
      next = client.find_element('css selector', '#unlock-sim-button')
      next.tap()
      time.sleep(short_time)

    # app://communications.gaiamobile.org/ftu/index.html#data_3g (sim puk screen - unlock-sim-screen - 2nd attempt)
    file_name = 'data_3g-unlock_sim_screen-puk_screen-wrong_puk-2nd_time'
    screenshot_entry = {
      "id" : file_name,
      "script" : app,
      "gaia" : gaia_hash,
      "hg" : hg_hash,
      "changed" : False,
      "path" : screenshot_path}
    test_flags = {
      "sim": True,
      "no-sim": False}
    if check_flags(test_flags, device_flags):
      screenshot_entry.update(test_flags)
      if take_screenshot(locale, screenshot_path, client, file_name):
        screenshot_entry['changed'] = True
      log_displayed_l10n_strings(client, db, app, app_categ, screenshot_entry, '#unlock-sim-screen')


      # insert right puk (attempt 2 of 9) (new pin and its confirmation are preserved at their inputs)
      puk_input = client.find_element('css selector', '#puk-input')
      puk_input.send_keys(sim_puk)

      # switch to app://communications.gaiamobile.org/ftu/index.html#data_3g
      next = client.find_element('css selector', '#unlock-sim-button')
      next.tap()
      time.sleep(short_time)

    # app://communications.gaiamobile.org/ftu/index.html#data_3g
    file_name = 'data_3g'
    screenshot_entry = {
      "id" : file_name,
      "script" : app,
      "gaia" : gaia_hash,
      "hg" : hg_hash,
      "changed" : False,
      "path" : screenshot_path}
    test_flags = {
      "sim": True,
      "no-sim": False}
    if check_flags(test_flags, device_flags):
      screenshot_entry.update(test_flags)
      if take_screenshot(locale, screenshot_path, client, file_name):
        screenshot_entry['changed'] = True
      log_displayed_l10n_strings(client, db, app, app_categ, screenshot_entry, '#activation-screen')


      # switch to app://communications.gaiamobile.org/ftu/index.html#wifi
      next = client.find_element('css selector', '#forward')
      next.tap()
      time.sleep(long_time)

      # enable overlay "scanningNetworks" spinner screen (loading-overlay)
      client.execute_script("window.wrappedJSObject.utils.overlay.show('scanningNetworks', 'spinner');")
      time.sleep(middle_time)
    
    # overlay "scanningNetworks" spinner screen
    file_name = 'wifi-loading_overlay-scanning_networks'
    screenshot_entry = {
      "id" : file_name,
      "script" : app,
      "gaia" : gaia_hash,
      "hg" : hg_hash,
      "changed" : False,
      "path" : screenshot_path}
    test_flags = {}
    if check_flags(test_flags, device_flags):
      screenshot_entry.update(test_flags)
      if take_screenshot(locale, screenshot_path, client, file_name):
        screenshot_entry['changed'] = True
      log_displayed_l10n_strings(client, db, app, app_categ, screenshot_entry, '#loading-overlay')


      # disable overlay "scanningNetworks" spinner screen
      client.execute_script("window.wrappedJSObject.utils.overlay.hide('scanningNetworks', 'spinner');")
      time.sleep(middle_time)

    # app://communications.gaiamobile.org/ftu/index.html#wifi
    file_name = 'wifi'
    screenshot_entry = {
      "id" : file_name,
      "script" : app,
      "gaia" : gaia_hash,
      "hg" : hg_hash,
      "changed" : False,
      "path" : screenshot_path}
    test_flags = {}
    if check_flags(test_flags, device_flags):
      screenshot_entry.update(test_flags)
      if take_screenshot(locale, screenshot_path, client, file_name):
        screenshot_entry['changed'] = True
      log_displayed_l10n_strings(client, db, app, app_categ, screenshot_entry, '#wifi')


      # switch to app://communications.gaiamobile.org/ftu/index.html#date_and_time
      next = client.find_element('css selector', '#forward')
      next.tap()
      time.sleep(short_time)

    # Set time in order to be the same at every screenshot
    set_time(client)

    # app://communications.gaiamobile.org/ftu/index.html#date_and_time
    file_name = 'date_and_time'
    screenshot_entry = {
      "id" : file_name,
      "script" : app,
      "gaia" : gaia_hash,
      "hg" : hg_hash,
      "changed" : False,
      "path" : screenshot_path}
    test_flags = {}
    if check_flags(test_flags, device_flags):
      screenshot_entry.update(test_flags)
      if take_screenshot(locale, screenshot_path, client, file_name):
        screenshot_entry['changed'] = True
      log_displayed_l10n_strings(client, db, app, app_categ, screenshot_entry, '#date_and_time')


      # switch to app://communications.gaiamobile.org/ftu/index.html#geolocation
      next = client.find_element('css selector', '#forward')
      next.tap()
      time.sleep(short_time)

    # app://communications.gaiamobile.org/ftu/index.html#geolocation
    file_name = 'geolocation'
    screenshot_entry = {
      "id" : file_name,
      "script" : app,
      "gaia" : gaia_hash,
      "hg" : hg_hash,
      "changed" : False,
      "path" : screenshot_path}
    test_flags = {}
    if check_flags(test_flags, device_flags):
      screenshot_entry.update(test_flags)
      if take_screenshot(locale, screenshot_path, client, file_name):
        screenshot_entry['changed'] = True
      log_displayed_l10n_strings(client, db, app, app_categ, screenshot_entry, '#geolocation')


      # switch to app://communications.gaiamobile.org/ftu/index.html#import_contacts
      next = client.find_element('css selector', '#forward')
      next.tap()
      time.sleep(middle_time)

    # app://communications.gaiamobile.org/ftu/index.html#import_contacts
    file_name = 'import_contacts'
    screenshot_entry = {
      "id" : file_name,
      "script" : app,
      "gaia" : gaia_hash,
      "hg" : hg_hash,
      "changed" : False,
      "path" : screenshot_path}
    test_flags = {}
    if check_flags(test_flags, device_flags):
      screenshot_entry.update(test_flags)
      if take_screenshot(locale, screenshot_path, client, file_name):
        screenshot_entry['changed'] = True
      log_displayed_l10n_strings(client, db, app, app_categ, screenshot_entry, '#import_contacts')


      # switch to app://communications.gaiamobile.org/ftu/index.html#welcome_browser
      next = client.find_element('css selector', '#forward')
      next.tap()
      time.sleep(short_time)

    # app://communications.gaiamobile.org/ftu/index.html#welcome_browser
    file_name = 'welcome_browser'
    screenshot_entry = {
      "id" : file_name,
      "script" : app,
      "gaia" : gaia_hash,
      "hg" : hg_hash,
      "changed" : False,
      "path" : screenshot_path}
    test_flags = {}
    if check_flags(test_flags, device_flags):
      screenshot_entry.update(test_flags)
      if take_screenshot(locale, screenshot_path, client, file_name):
        screenshot_entry['changed'] = True
      log_displayed_l10n_strings(client, db, app, app_categ, screenshot_entry)


      # switch to app://communications.gaiamobile.org/ftu/index.html#browser_privacy
      next = client.find_element('css selector', '#forward')
      next.tap()
      time.sleep(short_time)

    # app://communications.gaiamobile.org/ftu/index.html#browser_privacy
    file_name = 'browser_privacy'
    screenshot_entry = {
      "id" : file_name,
      "script" : app,
      "gaia" : gaia_hash,
      "hg" : hg_hash,
      "changed" : False,
      "path" : screenshot_path}
    test_flags = {}
    if check_flags(test_flags, device_flags):
      screenshot_entry.update(test_flags)
      if take_screenshot(locale, screenshot_path, client, file_name):
        screenshot_entry['changed'] = True
      log_displayed_l10n_strings(client, db, app, app_categ, screenshot_entry)


      # switch to app://communications.gaiamobile.org/ftu/index.html#step1 (first tutorial screen)
      next = client.find_element('css selector', '#forward')
      next.tap()
      time.sleep(long_time)

    # app://communications.gaiamobile.org/ftu/index.html#step1 (first tutorial screen)
    file_name = 'step1-first_tutorial_screen'
    screenshot_entry = {
      "id" : file_name,
      "script" : app,
      "gaia" : gaia_hash,
      "hg" : hg_hash,
      "changed" : False,
      "path" : screenshot_path}
    test_flags = {}
    if check_flags(test_flags, device_flags):
      screenshot_entry.update(test_flags)
      if take_screenshot(locale, screenshot_path, client, file_name):
        screenshot_entry['changed'] = True
      log_displayed_l10n_strings(client, db, app, app_categ, screenshot_entry)


      # switch to app://communications.gaiamobile.org/ftu/index.html#step1
      next = client.find_element('css selector', '#lets-go-button')
      next.tap()
      time.sleep(long_time)

    # app://communications.gaiamobile.org/ftu/index.html#step1
    file_name = 'step1'
    screenshot_entry = {
      "id" : file_name,
      "script" : app,
      "gaia" : gaia_hash,
      "hg" : hg_hash,
      "changed" : False,
      "path" : screenshot_path}
    test_flags = {}
    if check_flags(test_flags, device_flags):
      screenshot_entry.update(test_flags)
      if take_screenshot(locale, screenshot_path, client, file_name):
        screenshot_entry['changed'] = True
      log_displayed_l10n_strings(client, db, app, app_categ, screenshot_entry)


      # switch to app://communications.gaiamobile.org/ftu/index.html#step2
      next = client.find_element('css selector', '#forwardTutorial')
      next.tap()
      time.sleep(short_time)

    # app://communications.gaiamobile.org/ftu/index.html#step2
    file_name = 'step2'
    screenshot_entry = {
      "id" : file_name,
      "script" : app,
      "gaia" : gaia_hash,
      "hg" : hg_hash,
      "changed" : False,
      "path" : screenshot_path}
    test_flags = {}
    if check_flags(test_flags, device_flags):
      screenshot_entry.update(test_flags)
      if take_screenshot(locale, screenshot_path, client, file_name):
        screenshot_entry['changed'] = True
      log_displayed_l10n_strings(client, db, app, app_categ, screenshot_entry)


      # switch to app://communications.gaiamobile.org/ftu/index.html#step3
      next = client.find_element('css selector', '#forwardTutorial')
      next.tap()
      time.sleep(short_time)

    # app://communications.gaiamobile.org/ftu/index.html#step3
    file_name = 'step3'
    screenshot_entry = {
      "id" : file_name,
      "script" : app,
      "gaia" : gaia_hash,
      "hg" : hg_hash,
      "changed" : False,
      "path" : screenshot_path}
    test_flags = {}
    if check_flags(test_flags, device_flags):
      screenshot_entry.update(test_flags)
      if take_screenshot(locale, screenshot_path, client, file_name):
        screenshot_entry['changed'] = True
      log_displayed_l10n_strings(client, db, app, app_categ, screenshot_entry)


      # switch to app://communications.gaiamobile.org/ftu/index.html#step4
      next = client.find_element('css selector', '#forwardTutorial')
      next.tap()
      time.sleep(short_time)

    # app://communications.gaiamobile.org/ftu/index.html#step4
    file_name = 'step4'
    screenshot_entry = {
      "id" : file_name,
      "script" : app,
      "gaia" : gaia_hash,
      "hg" : hg_hash,
      "changed" : False,
      "path" : screenshot_path}
    test_flags = {}
    if check_flags(test_flags, device_flags):
      screenshot_entry.update(test_flags)
      if take_screenshot(locale, screenshot_path, client, file_name):
        screenshot_entry['changed'] = True
      log_displayed_l10n_strings(client, db, app, app_categ, screenshot_entry)


      # switch to app://communications.gaiamobile.org/ftu/index.html#step4 (last tutorial screen)
      next = client.find_element('css selector', '#forwardTutorial')
      next.tap()
      time.sleep(long_time)

    # app://communications.gaiamobile.org/ftu/index.html#step4 (last tutorial screen)
    file_name = 'step4-last_tutorial_screen'
    screenshot_entry = {
      "id" : file_name,
      "script" : app,
      "gaia" : gaia_hash,
      "hg" : hg_hash,
      "changed" : False,
      "path" : screenshot_path}
    test_flags = {}
    if check_flags(test_flags, device_flags):
      screenshot_entry.update(test_flags)
      if take_screenshot(locale, screenshot_path, client, file_name):
        screenshot_entry['changed'] = True
      log_displayed_l10n_strings(client, db, app, app_categ, screenshot_entry)


      # Close ftu frame
      next = client.find_element('css selector', '#tutorialFinished')
      next.tap()
      time.sleep(short_time)

    set_db(locale, db)

  else:
  #TO DO raise proper error
    print "switch to ftu frame failed"
class current_frame():
    
    filename_screenshot = ""
    filename_htmldump   = ""
    
    def main(self, LOGDIR):
        #
        # The first variable is the log directory.
        #
        ucount  = 0
        self.marionette = Marionette(host='localhost', port=2828)  
        self.marionette.start_session()
        self.marionette.set_search_timeout(1000)
        
        #
        # Now loop through all the iframes, gathering details about each one.
        #
        print ""
        print "Iframe for 'top level' () ..."
        self.filename_screenshot = LOGDIR + "top_level" + ".png"
        self.filename_htmldump   = LOGDIR + "top_level" + ".html"
        self.marionette.switch_to_frame()
        self.record_frame()
        
        frames = self.marionette.find_elements("tag name", "iframe")
        for fnum in range (0, len(frames)):
          
            #
            # App name is usually in the "src" attribute, so it's worth a shot..
            #
            frame_src = frames[fnum].get_attribute("src")
              
            if frame_src != "":
                startpos = frame_src.index('/') + 2
                stoppos  = frame_src.index('.')
                appname  = frame_src[startpos:stoppos]
                filename = appname
            else:
                ucount = ucount + 1
                appname  = "(unknown)"
                filename = "unknown_" + str(ucount)
            
            #
            # Because we call this script sometimes when we hit a Marionette issue,
            # these filenames may already exist (and we'd overwrite them!), so
            # add 'DEBUG_' to the start of the filename.
            #
            filename = "DEBUG_" + filename
                 
            filename_details         = LOGDIR + filename + "_iframe_details.txt"
            self.filename_screenshot = LOGDIR + filename + ".png"
            self.filename_htmldump   = LOGDIR + filename + ".html"
            
            #
            # This iframe gives me problems sometimes, so I'm ignoring it for now.
            #
            if appname == "costcontrol":
                continue
            
            print ""
            print "Iframe for app \"" + appname + "\" ..."
        
            #
            # Record the iframe details (pretty verbose, but 'execute_script' 
            # wasn't letting me use 'for' loops in js for some reason).
            #
            print "    |_ iframe details saved to : " + filename_details
            f = open(filename_details, 'w')
            f.write("Attributes for this iframe ...\n")
            num_attribs = self.marionette.execute_script("return document.getElementsByTagName('iframe')[" + str(fnum) + "].attributes.length;")
            for i in range(0,num_attribs):
                attrib_name  = self.marionette.execute_script("return document.getElementsByTagName('iframe')[" + str(fnum) + "].attributes[" + str(i) + "].nodeName;")
                attrib_value = self.marionette.execute_script("return document.getElementsByTagName('iframe')[" + str(fnum) + "].attributes[" + str(i) + "].nodeValue;")
        
                f.write("    |_ " + attrib_name.ljust(20) + ": \"" + attrib_value + "\"\n")   
            f.close()
            
            #
            # Switch to this frame.
            #
            self.marionette.switch_to_frame(fnum)
                   
            self.record_frame()
         
            self.marionette.switch_to_frame()


    def record_frame(self):
        #
        # Take the screenshot and save it to the file.
        #
        print "    |_ screenshot saved to     : " + self.filename_screenshot
        screenshot = self.marionette.screenshot()[22:]
        with open(self.filename_screenshot, 'w') as f:
            f.write(base64.decodestring(screenshot))
        f.close()
              
        #
        # Take the html dump and save it to the file.
        #
        print "    |_ html dump saved to      : " + self.filename_htmldump
        f = open(self.filename_htmldump, 'w')
        f.write(self.marionette.page_source.encode('ascii', 'ignore') )
        f.close()
Example #21
0
def uninstall_app(app_name, adb_path="adb", script_timeout=5000, marionette=None, device_serial=None):
    """
    Uninstalls the given app.

    NOTE: if a marionette session is passed, this function switches to the top-most frame.
    """

    def check_uninstall(marionette):
        uninstall = marionette.execute_script("return window.wrappedJSObject.uninstall;")
        return uninstall != 'none'

    def check_click_uninstall(marionette):
        button = marionette.find_element('css selector', 'gaia-confirm .confirm')
        try:
            button.click()
            not_displayed = not button.is_displayed()
        except StaleElementException:
            not_displayed = True
        return not_displayed

    dm = mozdevice.DeviceManagerADB(adbPath=adb_path, deviceSerial=device_serial)
    installed_app_name = app_name.lower()
    installed_app_name = installed_app_name.replace(" ", "-")
    dm.forward("tcp:2828", "tcp:2828")

    print 'requesting uninstall of app', app_name
    if not marionette:
        m = Marionette()
        m.start_session()
    else:
        m = marionette
        m.switch_to_frame()

    m.set_context("chrome")
    m.execute_script("""
    Components.utils.import("resource://gre/modules/Services.jsm");
    window.wrappedJSObject.uninstall = 'none';
    Services.obs.addObserver(function observer(subject, topic) {
        Services.obs.removeObserver(observer, topic);
        window.wrappedJSObject.uninstall = 'ask';
        }, "webapps-ask-uninstall", false);
    Services.obs.addObserver(function observer(subject, topic) {
        Services.obs.removeObserver(observer, topic);
        window.wrappedJSObject.uninstall = 'uninstall';
        }, "webapps-uninstall", false);
        """)
    m.set_context("content")

    uninstall_app = """
    var uninstallWithName = function(name) {
        let apps = window.wrappedJSObject.applications || window.wrappedJSObject.Applications;
        let installedApps = apps.installedApps;
        for (let manifestURL in installedApps) {
          let app = installedApps[manifestURL];
          let origin = null;
          let entryPoints = app.manifest.entry_points;
          if (entryPoints) {
            for (let ep in entryPoints) {
              let currentEntryPoint = entryPoints[ep];
              let appName = currentEntryPoint.name;
              if (name == appName.toLowerCase()) {
                window.wrappedJSObject.navigator.mozApps.mgmt.uninstall(app);
                return true;
              }
            }
          } else {
            let appName = app.manifest.name;
            if (name == appName.toLowerCase()) {
              window.wrappedJSObject.navigator.mozApps.mgmt.uninstall(app);
              return true;
            }
          }
        }
        return false;
      };
    return uninstallWithName("%s");
    """
    m.set_script_timeout(script_timeout)
    result = m.execute_script(uninstall_app % app_name.lower())

    if result:
        m.set_context("chrome")
        Wait(m, 10).until(check_uninstall)
        uninstall = m.execute_script("return window.wrappedJSObject.uninstall;")
        m.set_context("content")
        if uninstall == 'ask':
            m.switch_to_frame()
            Wait(m, 20).until(element_displayed(m.find_element('css selector', 'gaia-confirm .confirm')))
            Wait(m, 20).until(check_click_uninstall)

    if not marionette:
        m.delete_session()
Example #22
0
class TestCase(tornado.testing.AsyncTestCase):
    def __init__(self, *args, **kwargs):
        #self.config = kwargs.pop("config")
        self.handler = kwargs.pop('handler')
        self.io_loop = kwargs.pop('io_loop')
        self.cert_test_app = None
        super(TestCase, self).__init__(*args, **kwargs)

    def setUp(self):
        super(TestCase, self).setUp()
        # import environment
        # from environment import InProcessTestEnvironment
        # self.environment = environment.get(InProcessTestEnvironment)
        # self.server = self.environment.server
        self.marionette = None

        self.create_marionette()
        self.io_loop.run_sync(self.use_cert_app)

    def tearDown(self):
        super(TestCase, self).tearDown()
        self.io_loop.run_sync(self.close_cert_app)

    def create_marionette(self):
        if not self.marionette or not self.marionette.session:
            self.marionette = Marionette()
            self.marionette.start_session()

    @tornado.gen.coroutine
    def use_cert_app(self):
        # app management is done in the system app
        self.marionette.switch_to_frame()
        self.marionette.import_script("tests/app_management.js")
        script = "GaiaApps.launchWithName('CertTest App');"
        try:
            self.cert_test_app = self.marionette.execute_async_script(script, script_timeout=5000)
            self.marionette.switch_to_frame(self.cert_test_app["frame"])
            self.assertTrue('certtest' in self.marionette.get_url())
        except MarionetteException as e:
            ok = yield self.instruct("Could not launch CertTest app automatically." \
                                     "Please launch by hand then hit OK to continue.")
            self.assertTrue(ok, "Could not launch CertTest app")
        except Exception as e:
            message = "Unexpected exception: %s" % e
            yield self.instruct(message)
            self.fail(message)

    @tornado.gen.coroutine
    def close_cert_app(self):
        self.marionette.import_script("tests/app_management.js")
        # app management is done in the system app
        self.marionette.switch_to_frame()
        script = "GaiaApps.kill('%s');" % self.cert_test_app["origin"]
        try:
            self.marionette.execute_async_script(script, script_timeout=5000)
            self.assertTrue('certtest' not in self.marionette.get_url())
        except MarionetteException as e:
            ok = yield self.instruct("Could not close CertTest app automatically." \
                                     "Please close by hand then hit OK to continue.")
            self.assertTrue(ok, "Could not close CertTest app")
        except Exception as e:
            message = "Unexpected exception: %s" % e
            yield self.instruct(message)
            self.fail(message)

    def get_new_ioloop(self):
        return self.io_loop

    def prompt(self, message):
        """Prompt the user for a reply.  Returns a future which must be
        yielded.

        This will trigger an overlay  in the host browser window
        which can be used to tell the user to perform an action or to
        input some manual data for us to work on.

        Sample usage::

            answer = yield prompt("What's the meaning of life?")
            assert answer == 42

        This function is a simple wrapper for ``tornado.gen.Task``,
        and is equivalent to the usage of that.

        :param message: The question to ask or message to give the
            user.

        :returns: A generator which must be yielded. Once yielded,
                  the return value will be the value of the prompt,
                  or False if the user hit 'Cancel'

        """

        return tornado.gen.Task(self.handler.get_user_input, message)

    def instruct(self, message):
        """Presents the user with an instruction.  Returns a future which
        must be yielded.

        This will trigger an overlay in the host browser window
        which can be used to tell the user to perform an action or to
        input some manual data for us to work on.

        Sample usage::

            answer = yield prompt("What's the meaning of life?")
            assert answer == 42

        This function is a simple wrapper for ``tornado.gen.Task``,
        and is equivalent to the usage of that.

        :param message: The instruction you want to give the user

        :returns: A generator which must be yielded. Once yielded,
                  the reutrn value will be either True if they 
                  succeeded or False if they did not.

        """

        return tornado.gen.Task(self.handler.instruct_user, message)
  waitFor(
    function() {
      window.wrappedJSObject.LockScreen.unlock();
      waitFor(
        function() {
          finish(window.wrappedJSObject.LockScreen.locked);
        },
        function() {
          return !window.wrappedJSObject.LockScreen.locked;
        }
      );
    },
    function() {
      return !!window.wrappedJSObject.LockScreen;
    }
  );
"""

from marionette import Marionette 

marionette = Marionette('localhost', 2828)
marionette.start_session()
marionette.import_script('gaia_apps.js')
marionette.set_script_timeout(60000)

marionette.execute_script(unlock)
result = marionette.execute_async_script("GaiaApps.launchWithName('%s')" % "MozCampAsia-QualityApps")

marionette.switch_to_frame(result.get("frame"))
pdb.set_trace()
Example #24
0
class TestRun(object):
    def __init__(self, adb="adb", serial=None):
        self.test_results = {}
        self.test_results_file = None
        self.m = None
        self.gaia_apps = None
        self.screenshot_path = None
        self.logcat_path = None
        self.app_name = None
        self.attempt = None
        self.num_apps = None
        self.device = None
        self.serial = serial
        self.port = None
        self.run_log = logging.getLogger('marketplace-test')
        if self.serial:
            self.dm = DeviceManagerADB(adbPath=adb, deviceSerial=serial)
        else:
            self.dm = DeviceManagerADB(adbPath=adb)

    def reset_marionette(self):
        try:
            self.m.delete_session()
        except Exception:
            pass
        self.m = None
        self.get_marionette()

    def get_marionette(self):
        if not self.m:
            self.m = Marionette(port=self.port)
            self.m.start_session()
            self.device = GaiaDevice(self.m)
            self.device.add_device_manager(self.dm)
            self.gaia_apps = GaiaApps(self.m)
        else:
            tries = 5
            while tries > 0:
                try:
                    self.m.get_url()
                    break
                except MarionetteException as e:
                    if "Please start a session" in str(e):
                        time.sleep(5)
                        self.m = Marionette(port=self.port)
                        self.m.start_session()
                        self.device = GaiaDevice(self.m)
                        self.device.add_device_manager(self.dm)
                        self.gaia_apps = GaiaApps(self.m)
                        tries -= 1
                    else:
                        raise e
            else:
                self.run_log.error("Can't connect to marionette, rebooting")
                self.restart_device()
        return self.m

    def write_to_file(self, data):
        with open("%s.tmp" % self.test_results_file, "w") as f:
            f.write(data)
        shutil.copyfile("%s.tmp" % self.test_results_file, self.test_results_file)

    def add_values(self, key, value):
        if self.serial:
            self.test_results["%s_%s" % (key, self.serial)] = value
        else:
            self.test_results["%s" % key] = value

    def add_result(self, passed=False, status=None, uninstalled_failure=False):
        values = {}
        if status:
            if not passed:
                values["status"] = "FAILED: %s" % status
            else:
                values["status"] = "PASS"
        if self.screenshot_path:
            values["screenshot"] = self.screenshot_path
        if self.logcat_path:
            values["logcat"] = self.logcat_path
        if uninstalled_failure:
            values["uninstalled_failure"] = uninstalled_failure
        entry = "%s_%s" % (self.app_name, self.attempt)
        self.test_results[entry] = values

    def launch_with_manifest(self, manifest):
        self.m.switch_to_frame() 
        result = self.m.execute_async_script("GaiaApps.launchWithManifestURL('%s')" % manifest, script_timeout=30000)
        if result == False:
            raise Exception("launch timed out")
        app = GaiaApp(frame=result.get('frame'),
                      src=result.get('src'),
                      name=result.get('name'),
                      origin=result.get('origin'))
        if app.frame_id is None:
            raise Exception("failed to launch; there is no app frame")
        self.m.switch_to_frame(app.frame_id)
        return app


    def uninstall_with_manifest(self, manifest):
        self.m.switch_to_frame() 
        script = """
        GaiaApps.locateWithManifestURL('%s',
                                       null,
                                       function uninstall(app) {
                                       navigator.mozApps.mgmt.uninstall(app);
                                       marionetteScriptFinished(true);
                                       });
        """
        result = self.m.execute_async_script(script % manifest, script_timeout=60000)
        if result != True:
            self.add_result(status="Failed to uninstall app with url '%s'" % manifest)
        return app

    def forward_port(self):
        # get unused port
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.bind(('localhost', 0))
        addr, port = s.getsockname()
        s.close()

        dm_tries = 0
        self.run_log.info("using port %s" % port)
        while dm_tries < 20:
            if self.dm.forward("tcp:%d" % port, "tcp:2828") == 0:
                break
            dm_tries += 1
            time.sleep(3)
        else:
            return False
        self.port = port
        return True

    def restart_device(self, restart_tries=0):
        self.run_log.info("rebooting")
        # TODO restarting b2g doesn't seem to work... reboot then
        while restart_tries < 3:
            restart_tries += 1
            self.dm.reboot(wait=True)
            self.run_log.info("forwarding")
            if not self.forward_port():
                self.run_log.error("couldn't forward port in time, rebooting")
                continue
            self.m = Marionette(port=self.port)
            if not self.m.wait_for_port(180):
                self.run_log.error("couldn't contact marionette in time, rebooting")
                continue
            time.sleep(1)
            self.m.start_session()
            try:
                Wait(self.m, timeout=240).until(lambda m: m.find_element("id", "lockscreen-container").is_displayed())
                # It retuns a little early
                time.sleep(2)
                self.device = GaiaDevice(self.m)
                self.device.add_device_manager(self.dm)
                self.device.unlock()
                self.gaia_apps = GaiaApps(self.m)
            except (MarionetteException, IOError, socket.error) as e:
                self.run_log.error("got exception: %s, going to retry" % e)
                try:
                    self.m.delete_session()
                except:
                    # at least attempt to clear the session if possible
                    pass
                continue
            break
        else:
            raise Exception("Couldn't restart the device in time, even after 3 tries")

    def readystate_wait(self, app):
        try:
            Wait(self.get_marionette(), timeout=30).until(lambda m: m.execute_script("return window.document.readyState;") == "complete")
        except ScriptTimeoutException as e:
            return False
        return True  

    def record_icons(self):
        self.device.touch_home_button()
        icons = self.m.find_elements("class name", "icon")
        self.num_apps = len(icons)

    def check_if_app_installed(self, timeout=180):
        # TODO: Find a better way to do this than checking homescreen
        # I hope there is one...
        self.device.touch_home_button()
        icons = self.m.find_elements("class name", "icon")
        start = time.time()
        end = start + 180
        found_icon = None
        claims_its_loaded = 0 # this is used in case 'loading' isn't applied immediately to the icon
        while time.time() < end:
            if not found_icon:
                icons = self.m.find_elements("class name", "icon")
                # We can't do set comparison b/c references change
                if len(icons) > self.num_apps:
                    for icon in icons:
                        if "loading" in icon.get_attribute("innerHTML"):
                            found_icon = icon
                            break 
                    else:
                        claims_its_loaded += 1
                        if claims_its_loaded == 3:
                            return True
            else:
                if "loading" not in found_icon.get_attribute("innerHTML"):
                    return True
            time.sleep(2)
        return False
class TestRun(object):
    def __init__(self, adb="adb", serial=None):
        self.test_results = {}
        self.test_results_file = None
        self.m = None
        self.gaia_apps = None
        self.screenshot_path = None
        self.logcat_path = None
        self.app_name = None
        self.attempt = None
        self.num_apps = None
        self.device = None
        self.serial = serial
        self.port = None
        self.run_log = logging.getLogger('marketplace-test')
        if self.serial:
            self.dm = DeviceManagerADB(adbPath=adb, deviceSerial=serial)
        else:
            self.dm = DeviceManagerADB(adbPath=adb)

    def reset_marionette(self):
        try:
            self.m.delete_session()
        except Exception:
            pass
        self.m = None
        self.get_marionette()

    def get_marionette(self):
        if not self.m:
            self.m = Marionette(port=self.port)
            self.m.start_session()
            self.device = GaiaDevice(self.m)
            self.device.add_device_manager(self.dm)
            self.gaia_apps = GaiaApps(self.m)
        else:
            tries = 5
            while tries > 0:
                try:
                    self.m.get_url()
                    break
                except MarionetteException as e:
                    if "Please start a session" in str(e):
                        time.sleep(5)
                        self.m = Marionette(port=self.port)
                        self.m.start_session()
                        self.device = GaiaDevice(self.m)
                        self.device.add_device_manager(self.dm)
                        self.gaia_apps = GaiaApps(self.m)
                        tries -= 1
                    else:
                        raise e
            else:
                self.run_log.error("Can't connect to marionette, rebooting")
                self.restart_device()
        return self.m

    def write_to_file(self, data):
        with open("%s.tmp" % self.test_results_file, "w") as f:
            f.write(data)
        shutil.copyfile("%s.tmp" % self.test_results_file,
                        self.test_results_file)

    def add_values(self, key, value):
        if self.serial:
            self.test_results["%s_%s" % (key, self.serial)] = value
        else:
            self.test_results["%s" % key] = value

    def add_result(self, passed=False, status=None, uninstalled_failure=False):
        values = {}
        if status:
            if not passed:
                values["status"] = "FAILED: %s" % status
            else:
                values["status"] = "PASS"
        if self.screenshot_path:
            values["screenshot"] = self.screenshot_path
        if self.logcat_path:
            values["logcat"] = self.logcat_path
        if uninstalled_failure:
            values["uninstalled_failure"] = uninstalled_failure
        entry = "%s_%s" % (self.app_name, self.attempt)
        self.test_results[entry] = values

    def launch_with_manifest(self, manifest):
        self.m.switch_to_frame()
        result = self.m.execute_async_script(
            "GaiaApps.launchWithManifestURL('%s')" % manifest,
            script_timeout=30000)
        if result == False:
            raise Exception("launch timed out")
        app = GaiaApp(frame=result.get('frame'),
                      src=result.get('src'),
                      name=result.get('name'),
                      origin=result.get('origin'))
        if app.frame_id is None:
            raise Exception("failed to launch; there is no app frame")
        self.m.switch_to_frame(app.frame_id)
        return app

    def uninstall_with_manifest(self, manifest):
        self.m.switch_to_frame()
        script = """
        GaiaApps.locateWithManifestURL('%s',
                                       null,
                                       function uninstall(app) {
                                       navigator.mozApps.mgmt.uninstall(app);
                                       marionetteScriptFinished(true);
                                       });
        """
        result = self.m.execute_async_script(script % manifest,
                                             script_timeout=60000)
        if result != True:
            self.add_result(status="Failed to uninstall app with url '%s'" %
                            manifest)
        return app

    def forward_port(self):
        # get unused port
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.bind(('localhost', 0))
        addr, port = s.getsockname()
        s.close()

        dm_tries = 0
        self.run_log.info("using port %s" % port)
        while dm_tries < 20:
            if self.dm.forward("tcp:%d" % port, "tcp:2828") == 0:
                break
            dm_tries += 1
            time.sleep(3)
        else:
            return False
        self.port = port
        return True

    def restart_device(self, restart_tries=0):
        self.run_log.info("rebooting")
        # TODO restarting b2g doesn't seem to work... reboot then
        while restart_tries < 3:
            restart_tries += 1
            self.dm.reboot(wait=True)
            self.run_log.info("forwarding")
            if not self.forward_port():
                self.run_log.error("couldn't forward port in time, rebooting")
                continue
            self.m = Marionette(port=self.port)
            if not self.m.wait_for_port(180):
                self.run_log.error(
                    "couldn't contact marionette in time, rebooting")
                continue
            time.sleep(1)
            self.m.start_session()
            try:
                Wait(self.m, timeout=240).until(lambda m: m.find_element(
                    "id", "lockscreen-container").is_displayed())
                # It retuns a little early
                time.sleep(2)
                self.device = GaiaDevice(self.m)
                self.device.add_device_manager(self.dm)
                self.device.unlock()
                self.gaia_apps = GaiaApps(self.m)
            except (MarionetteException, IOError, socket.error) as e:
                self.run_log.error("got exception: %s, going to retry" % e)
                try:
                    self.m.delete_session()
                except:
                    # at least attempt to clear the session if possible
                    pass
                continue
            break
        else:
            raise Exception(
                "Couldn't restart the device in time, even after 3 tries")

    def readystate_wait(self, app):
        try:
            Wait(self.get_marionette(),
                 timeout=30).until(lambda m: m.execute_script(
                     "return window.document.readyState;") == "complete")
        except ScriptTimeoutException as e:
            return False
        return True

    def record_icons(self):
        self.device.touch_home_button()
        icons = self.m.find_elements("class name", "icon")
        self.num_apps = len(icons)

    def check_if_app_installed(self, timeout=180):
        # TODO: Find a better way to do this than checking homescreen
        # I hope there is one...
        self.device.touch_home_button()
        icons = self.m.find_elements("class name", "icon")
        start = time.time()
        end = start + 180
        found_icon = None
        claims_its_loaded = 0  # this is used in case 'loading' isn't applied immediately to the icon
        while time.time() < end:
            if not found_icon:
                icons = self.m.find_elements("class name", "icon")
                # We can't do set comparison b/c references change
                if len(icons) > self.num_apps:
                    for icon in icons:
                        if "loading" in icon.get_attribute("innerHTML"):
                            found_icon = icon
                            break
                    else:
                        claims_its_loaded += 1
                        if claims_its_loaded == 3:
                            return True
            else:
                if "loading" not in found_icon.get_attribute("innerHTML"):
                    return True
            time.sleep(2)
        return False
class current_frame():
    
    def main(self, LOGDIR, p_el, p_frame_array=False):
        #
        # p_el is an array for the element.
        # p_frame_array is a list of iframes to iterate through (optional).
        #
        self.marionette = Marionette(host='localhost', port=2828)  
        self.marionette.start_session()
        self.marionette.set_search_timeout(1000)
        
        #
        # Switch to the correct iframe (unless it's "()").
        #
        self.marionette.switch_to_frame()
        
        first_iframe = True
        for x in p_frame_array:
            # (just to make it look nice ;)
            typ_str = "'" + x[0] + "'"
            
            if first_iframe:
                first_iframe = False
                print ""
                print "Switching to iframe with " + typ_str.rjust(10) + " = '" + x[1] + "'"
            else:
                print "... then to iframe with  " + typ_str.rjust(10) + " = '" + x[1] + "'"
            
            my_iframe = self.marionette.find_element("xpath", "//iframe[@" + x[0] + "='" + x[1] + "']")
            self.marionette.switch_to_frame(my_iframe)
            
        if first_iframe:
            print ""
            print "Using 'top level' iframe () ..."
        
        #
        # Grab a screenshot and html dump of this frame.
        #
        p_sfnam = LOGDIR + "screenshot.png"
        p_hfnam = LOGDIR + "html_dump.html"
        print ""
        print "Screenshot of this frame saved to: " + p_sfnam
        screenshot = self.marionette.screenshot()[22:]
        with open(p_sfnam, 'w') as f:
            f.write(base64.decodestring(screenshot))
        f.close()

        print "HTML dump of this frame saved to : " + p_hfnam
        f = open(p_hfnam, 'w')
        f.write(self.marionette.page_source.encode('ascii', 'ignore') )
        f.close()

        #
        # Test to see if the element is present / displayed / etc...
        #
        print ""
        print "Checking for element: " + str(p_el)
        b_present   = False
        b_displayed = False
        b_enabled   = False
        try:
            x = self.marionette.find_element(*p_el)
            if x:
                b_present = True
                
                if x.is_displayed():
                    b_displayed = True
                    
                if x.is_enabled():
                    b_enabled = True
        except:
            pass
        
        print ""
        print "Present  : " + str(b_present)
        print "Displayed: " + str(b_displayed)
        print "Enabled  : " + str(b_enabled)
        print ""
#!/usr/bin/python2.7
#
# Script to work around Marionette bug 879816 (cannot click the modal 'ok' button
# following clicking something else).
#
from marionette import Marionette
marionette = Marionette(host='localhost', port=2828)
marionette.start_session()
marionette.switch_to_frame()
marionette.execute_script("document.getElementById('modal-dialog-prompt-ok').click();")