Beispiel #1
0
def get_base_url():
    if os.environ.get('BROWSER') != 'firefox':
        return PB_EXT_BG_URL_BASE
    from marionette_driver.marionette import Marionette

    marionette_client = Marionette('localhost', port=MARIONETTE_PORT)
    marionette_client.start_session()
    uuid_pref = marionette_client.get_pref('extensions.webextensions.uuids')
    uuid = json.loads(uuid_pref).values().pop()
    marionette_client.delete_session()

    return 'moz-extension://' + uuid + '/'
Beispiel #2
0
class CommonTestCase(unittest.TestCase):

    __metaclass__ = MetaParameterized
    match_re = None
    failureException = AssertionError
    pydebugger = None

    def __init__(self, methodName, **kwargs):
        unittest.TestCase.__init__(self, methodName)
        self.loglines = []
        self.duration = 0
        self.expected = kwargs.pop("expected", "pass")
        self.logger = get_default_logger()
        self.profile = FirefoxProfile()
        self.binary = kwargs.pop("binary", None)

    def _enter_pm(self):
        if self.pydebugger:
            self.pydebugger.post_mortem(sys.exc_info()[2])

    def _addSkip(self, result, reason):
        addSkip = getattr(result, "addSkip", None)
        if addSkip is not None:
            addSkip(self, reason)
        else:
            warnings.warn("TestResult has no addSkip method, skips not reported", RuntimeWarning, 2)
            result.addSuccess(self)

    def run(self, result=None):
        # Bug 967566 suggests refactoring run, which would hopefully
        # mean getting rid of this inner function, which only sits
        # here to reduce code duplication:
        def expected_failure(result, exc_info):
            addExpectedFailure = getattr(result, "addExpectedFailure", None)
            if addExpectedFailure is not None:
                addExpectedFailure(self, exc_info)
            else:
                warnings.warn("TestResult has no addExpectedFailure method, " "reporting as passes", RuntimeWarning)
                result.addSuccess(self)

        self.start_time = time.time()
        orig_result = result
        if result is None:
            result = self.defaultTestResult()
            startTestRun = getattr(result, "startTestRun", None)
            if startTestRun is not None:
                startTestRun()

        result.startTest(self)

        testMethod = getattr(self, self._testMethodName)
        if getattr(self.__class__, "__unittest_skip__", False) or getattr(testMethod, "__unittest_skip__", False):
            # If the class or method was skipped.
            try:
                skip_why = getattr(self.__class__, "__unittest_skip_why__", "") or getattr(
                    testMethod, "__unittest_skip_why__", ""
                )
                self._addSkip(result, skip_why)
            finally:
                result.stopTest(self)
            self.stop_time = time.time()
            return
        try:
            success = False
            try:
                if self.expected == "fail":
                    try:
                        self.setUp()
                    except Exception:
                        raise _ExpectedFailure(sys.exc_info())
                else:
                    self.setUp()
            except SkipTest as e:
                self._addSkip(result, str(e))
            except KeyboardInterrupt:
                raise
            except _ExpectedFailure as e:
                expected_failure(result, e.exc_info)
            except:
                self._enter_pm()
                result.addError(self, sys.exc_info())
            else:
                try:
                    if self.expected == "fail":
                        try:
                            testMethod()
                        except:
                            raise _ExpectedFailure(sys.exc_info())
                        raise _UnexpectedSuccess
                    else:
                        testMethod()
                except self.failureException:
                    self._enter_pm()
                    result.addFailure(self, sys.exc_info())
                except KeyboardInterrupt:
                    raise
                except _ExpectedFailure as e:
                    expected_failure(result, e.exc_info)
                except _UnexpectedSuccess:
                    addUnexpectedSuccess = getattr(result, "addUnexpectedSuccess", None)
                    if addUnexpectedSuccess is not None:
                        addUnexpectedSuccess(self)
                    else:
                        warnings.warn(
                            "TestResult has no addUnexpectedSuccess method, reporting as failures", RuntimeWarning
                        )
                        result.addFailure(self, sys.exc_info())
                except SkipTest as e:
                    self._addSkip(result, str(e))
                except:
                    self._enter_pm()
                    result.addError(self, sys.exc_info())
                else:
                    success = True
                try:
                    if self.expected == "fail":
                        try:
                            self.tearDown()
                        except:
                            raise _ExpectedFailure(sys.exc_info())
                    else:
                        self.tearDown()
                except KeyboardInterrupt:
                    raise
                except _ExpectedFailure as e:
                    expected_failure(result, e.exc_info)
                except:
                    self._enter_pm()
                    result.addError(self, sys.exc_info())
                    success = False
            # Here we could handle doCleanups() instead of calling cleanTest directly
            self.cleanTest()

            if success:
                result.addSuccess(self)

        finally:
            result.stopTest(self)
            if orig_result is None:
                stopTestRun = getattr(result, "stopTestRun", None)
                if stopTestRun is not None:
                    stopTestRun()

    @classmethod
    def match(cls, filename):
        """
        Determines if the specified filename should be handled by this
        test class; this is done by looking for a match for the filename
        using cls.match_re.
        """
        if not cls.match_re:
            return False
        m = cls.match_re.match(filename)
        return m is not None

    @classmethod
    def add_tests_to_suite(cls, mod_name, filepath, suite, testloader, testvars):
        """
        Adds all the tests in the specified file to the specified suite.
        """
        raise NotImplementedError

    @property
    def test_name(self):
        if hasattr(self, "jsFile"):
            return os.path.basename(self.jsFile)
        else:
            return "%s.py %s.%s" % (self.__class__.__module__, self.__class__.__name__, self._testMethodName)

    def id(self):
        # TBPL starring requires that the "test name" field of a failure message
        # not differ over time. The test name to be used is passed to
        # mozlog via the test id, so this is overriden to maintain
        # consistency.
        return self.test_name

    def setUp(self):
        # Convert the marionette weakref to an object, just for the
        # duration of the test; this is deleted in tearDown() to prevent
        # a persistent circular reference which in turn would prevent
        # proper garbage collection.
        self.start_time = time.time()
        self.pingServer = PingServer()
        self.pingServer.start()
        self.marionette = Marionette(bin=self.binary, profile=self.profile)
        if self.marionette.session is None:
            self.marionette.start_session()
        if self.marionette.timeout is not None:
            self.marionette.timeouts(self.marionette.TIMEOUT_SEARCH, self.marionette.timeout)
            self.marionette.timeouts(self.marionette.TIMEOUT_SCRIPT, self.marionette.timeout)
            self.marionette.timeouts(self.marionette.TIMEOUT_PAGE, self.marionette.timeout)
        else:
            self.marionette.timeouts(self.marionette.TIMEOUT_PAGE, 30000)

    def tearDown(self):
        self.marionette.cleanup()
        self.pingServer.stop()

    def cleanTest(self):
        self._deleteSession()

    def _deleteSession(self):
        if hasattr(self, "start_time"):
            self.duration = time.time() - self.start_time
        if hasattr(self.marionette, "session"):
            if self.marionette.session is not None:
                try:
                    self.loglines.extend(self.marionette.get_logs())
                except Exception, inst:
                    self.loglines = [["Error getting log: %s" % inst]]
                try:
                    self.marionette.delete_session()
                except (socket.error, MarionetteException, IOError):
                    # Gecko has crashed?
                    self.marionette.session = None
                    try:
                        self.marionette.client.close()
                    except socket.error:
                        pass
        self.marionette = None
Beispiel #3
0
class CommonTestCase(unittest.TestCase):

    __metaclass__ = MetaParameterized
    match_re = None
    failureException = AssertionError
    pydebugger = None

    def __init__(self, methodName, **kwargs):
        unittest.TestCase.__init__(self, methodName)
        self.loglines = []
        self.duration = 0
        self.expected = kwargs.pop('expected', 'pass')
        self.logger = get_default_logger()
        self.profile = FirefoxProfile()
        self.binary = kwargs.pop('binary', None)

    def _enter_pm(self):
        if self.pydebugger:
            self.pydebugger.post_mortem(sys.exc_info()[2])

    def _addSkip(self, result, reason):
        addSkip = getattr(result, 'addSkip', None)
        if addSkip is not None:
            addSkip(self, reason)
        else:
            warnings.warn(
                "TestResult has no addSkip method, skips not reported",
                RuntimeWarning, 2)
            result.addSuccess(self)

    def run(self, result=None):
        # Bug 967566 suggests refactoring run, which would hopefully
        # mean getting rid of this inner function, which only sits
        # here to reduce code duplication:
        def expected_failure(result, exc_info):
            addExpectedFailure = getattr(result, "addExpectedFailure", None)
            if addExpectedFailure is not None:
                addExpectedFailure(self, exc_info)
            else:
                warnings.warn(
                    "TestResult has no addExpectedFailure method, "
                    "reporting as passes", RuntimeWarning)
                result.addSuccess(self)

        self.start_time = time.time()
        orig_result = result
        if result is None:
            result = self.defaultTestResult()
            startTestRun = getattr(result, 'startTestRun', None)
            if startTestRun is not None:
                startTestRun()

        result.startTest(self)

        testMethod = getattr(self, self._testMethodName)
        if (getattr(self.__class__, "__unittest_skip__", False)
                or getattr(testMethod, "__unittest_skip__", False)):
            # If the class or method was skipped.
            try:
                skip_why = (
                    getattr(self.__class__, '__unittest_skip_why__', '')
                    or getattr(testMethod, '__unittest_skip_why__', ''))
                self._addSkip(result, skip_why)
            finally:
                result.stopTest(self)
            self.stop_time = time.time()
            return
        try:
            success = False
            try:
                if self.expected == "fail":
                    try:
                        self.setUp()
                    except Exception:
                        raise _ExpectedFailure(sys.exc_info())
                else:
                    self.setUp()
            except SkipTest as e:
                self._addSkip(result, str(e))
            except KeyboardInterrupt:
                raise
            except _ExpectedFailure as e:
                expected_failure(result, e.exc_info)
            except:
                self._enter_pm()
                result.addError(self, sys.exc_info())
            else:
                try:
                    if self.expected == 'fail':
                        try:
                            testMethod()
                        except:
                            raise _ExpectedFailure(sys.exc_info())
                        raise _UnexpectedSuccess
                    else:
                        testMethod()
                except self.failureException:
                    self._enter_pm()
                    result.addFailure(self, sys.exc_info())
                except KeyboardInterrupt:
                    raise
                except _ExpectedFailure as e:
                    expected_failure(result, e.exc_info)
                except _UnexpectedSuccess:
                    addUnexpectedSuccess = getattr(result,
                                                   'addUnexpectedSuccess',
                                                   None)
                    if addUnexpectedSuccess is not None:
                        addUnexpectedSuccess(self)
                    else:
                        warnings.warn(
                            "TestResult has no addUnexpectedSuccess method, reporting as failures",
                            RuntimeWarning)
                        result.addFailure(self, sys.exc_info())
                except SkipTest as e:
                    self._addSkip(result, str(e))
                except:
                    self._enter_pm()
                    result.addError(self, sys.exc_info())
                else:
                    success = True
                try:
                    if self.expected == "fail":
                        try:
                            self.tearDown()
                        except:
                            raise _ExpectedFailure(sys.exc_info())
                    else:
                        self.tearDown()
                except KeyboardInterrupt:
                    raise
                except _ExpectedFailure as e:
                    expected_failure(result, e.exc_info)
                except:
                    self._enter_pm()
                    result.addError(self, sys.exc_info())
                    success = False
            # Here we could handle doCleanups() instead of calling cleanTest directly
            self.cleanTest()

            if success:
                result.addSuccess(self)

        finally:
            result.stopTest(self)
            if orig_result is None:
                stopTestRun = getattr(result, 'stopTestRun', None)
                if stopTestRun is not None:
                    stopTestRun()

    @classmethod
    def match(cls, filename):
        """
        Determines if the specified filename should be handled by this
        test class; this is done by looking for a match for the filename
        using cls.match_re.
        """
        if not cls.match_re:
            return False
        m = cls.match_re.match(filename)
        return m is not None

    @classmethod
    def add_tests_to_suite(cls, mod_name, filepath, suite, testloader,
                           testvars):
        """
        Adds all the tests in the specified file to the specified suite.
        """
        raise NotImplementedError

    @property
    def test_name(self):
        if hasattr(self, 'jsFile'):
            return os.path.basename(self.jsFile)
        else:
            return '{0}.py {1}.{2}'.format(self.__class__.__module__,
                                           self.__class__.__name__,
                                           self._testMethodName)

    def id(self):
        # TBPL starring requires that the "test name" field of a failure message
        # not differ over time. The test name to be used is passed to
        # mozlog via the test id, so this is overriden to maintain
        # consistency.
        return self.test_name

    def setUp(self):
        # Convert the marionette weakref to an object, just for the
        # duration of the test; this is deleted in tearDown() to prevent
        # a persistent circular reference which in turn would prevent
        # proper garbage collection.
        self.start_time = time.time()
        self.pingServer = PingServer()
        self.pingServer.start()
        self.marionette = Marionette(bin=self.binary, profile=self.profile)
        if self.marionette.session is None:
            self.marionette.start_session()
        self.marionette.reset_timeouts()

    def tearDown(self):
        self.marionette.cleanup()
        self.pingServer.stop()

    def cleanTest(self):
        self._deleteSession()

    def _deleteSession(self):
        if hasattr(self, 'start_time'):
            self.duration = time.time() - self.start_time
        if hasattr(self.marionette, 'session'):
            if self.marionette.session is not None:
                try:
                    self.loglines.extend(self.marionette.get_logs())
                except Exception, inst:
                    self.loglines = [['Error getting log: {}'.format(inst)]]
                try:
                    self.marionette.delete_session()
                except (socket.error, MarionetteException, IOError):
                    # Gecko has crashed?
                    self.marionette.session = None
                    try:
                        self.marionette.client.close()
                    except socket.error:
                        pass
        self.marionette = None
Beispiel #4
0
class GCli(object):

    def __init__(self):
        self.commands = {
            'connectwifi': {
                'function': self.connect_to_wifi,
                'args': [
                    {'name': 'ssid',
                     'help': 'SSID of the network to connect to'},
                    {'name': '--security',
                     'choices': ['WPA-PSK', 'WEP'],
                     'help': 'Security model of the network'},
                    {'name': '--password',
                     'help': 'Password to access the network'}],
                'help': 'Connect to a WiFi network'},
            'disablewifi': {
                'function': self.disable_wifi,
                'help': 'Disable WiFi'},
            'enablewifi': {
                'function': self.enable_wifi,
                'help': 'Enable WiFi'},
            'forgetallwifi': {
                'function': self.forget_all_wifi_networks,
                'help': 'Forget all WiFi networks'},
            'getknownwifi': {
                'function': self.known_wifi_networks,
                'help': 'Show known WiFi networks'},
            'getsetting': {
                'function': self.get_setting,
                'args': [{
                    'name': 'name',
                    'help': 'Name of the setting to retrieve'}],
                'help': 'Show the current value of a setting'},
            'holdhome': {
                'function': self.hold_home,
                'help': 'Simulate holding the home button'},
            'holdsleep': {
                'function': self.hold_sleep,
                'help': 'Simulate holding the sleep button'},
            'home': {
                'function': self.home,
                'help': 'Simulate pressing the home button'},
            'killapps': {
                'function': self.kill_all_apps,
                'help': 'Kill all running apps'},
            'launchapp': {
                'function': self.launch_app,
                'args': [
                    {'name': 'name',
                     'nargs': argparse.REMAINDER,
                     'help': 'Name of app to launch'}],
                'help': 'Launch an application'},
            'listallapps': {
                'function': self.list_all_apps,
                'help': 'List all apps'},
            'listrunningapps': {
                'function': self.list_running_apps,
                'help': 'List the running apps'},
            'lock': {
                'function': self.lock,
                'help': 'Lock screen'},
            'screenshot': {
                'function': self.screenshot,
                'help': 'Take a screenshot'},
            'sendsms': {
                'function': self.send_sms,
                'args': [
                    {'name': 'number',
                     'help': 'Phone number of recipient'},
                    {'name': 'message',
                     'help': 'Message content'}],
                'help': 'Send an SMS'},
            'setsetting': {
                'function': self.set_setting,
                'args': [
                    {'name': 'name',
                     'help': 'Name of setting to change'},
                    {'name': 'value',
                     'help': 'New value for setting'}],
                'help': 'Change the value of a setting'},
            'sleep': {
                'function': self.sleep,
                'help': 'Enter sleep mode'},
            'unlock': {
                'function': self.unlock,
                'help': 'Unlock screen'},
            'volume': {
                'function': self.volume,
                'args': [
                    {'name': 'direction',
                     'choices': ['down', 'up'],
                     'help': 'Direction to change the volume'}],
                'help': 'Change the volume'},
            'wake': {
                'function': self.wake,
                'help': 'Wake from sleep mode'}}

        self.parser = argparse.ArgumentParser()
        self.add_options(self.parser)
        self.add_commands(self.parser)

    def run(self, args=sys.argv[1:]):
        args = self.parser.parse_args()

        host, port = args.address.split(':')
        self.marionette = Marionette(host=host, port=int(port))
        self.marionette.start_session()

        self.apps = gaiatest.GaiaApps(self.marionette)
        self.data_layer = gaiatest.GaiaData(self.marionette)
        self.device = gaiatest.GaiaDevice(self.marionette)

        ret = args.func(args)
        if ret is None:
            ret = 0

        self.marionette.delete_session()

        sys.exit(ret)

    def add_options(self, parser):
        parser.add_argument(
            '--address',
            default='localhost:2828',
            help='Address (host:port) of running Gecko instance to connect to '
                 '(default: %(default)s)')

    def add_commands(self, parser):
        subparsers = parser.add_subparsers(
            title='Commands', metavar='<command>')
        for (name, props) in sorted(self.commands.iteritems()):
            subparser = subparsers.add_parser(name, help=props['help'])
            if props.get('args'):
                for arg in props['args']:
                    kwargs = {k: v for k, v in arg.items() if k is not 'name'}
                    subparser.add_argument(arg['name'], **kwargs)
            subparser.set_defaults(func=props['function'])

    def connect_to_wifi(self, args):
        network = {
            'ssid': args.ssid,
            'keyManagement': args.security or 'NONE'}
        if args.security == 'WEP':
            network['wep'] = args.password
        elif args.security == 'WPA-PSK':
            network['psk'] = args.password
        self.data_layer.connect_to_wifi(network)

    def disable_wifi(self, args):
        self.data_layer.disable_wifi()

    def enable_wifi(self, args):
        self.data_layer.enable_wifi()

    def forget_all_wifi_networks(self, args):
        self.data_layer.forget_all_networks()

    def get_setting(self, args):
        print '%s: %s' % (
            args.name,
            self.data_layer.get_setting(args.name))

    def home(self, args):
        self.device.touch_home_button()

    def hold_home(self, args):
        self.device.hold_home_button()

    def hold_sleep(self, args):
        self.marionette.execute_script(
            "window.wrappedJSObject.dispatchEvent(new Event('holdsleep'));")

    def kill_all_apps(self, args):
        self.apps.kill_all()

    def known_wifi_networks(self, args):
        networks = [n for n in self.data_layer.known_networks if 'ssid' in n]
        if len(networks) > 0:
            for i, network in enumerate(networks):
                print '%s: %s' % (i + 1, network['ssid'])
        else:
            print 'No known networks.'

    def launch_app(self, args):
        for name in args.name:
            self.apps.launch(name)

    def list_all_apps(self, args):
        for i, app in enumerate(sorted(self.apps.installed_apps,
                                       key=lambda a: a.name.lower())):
            print '%d: %s' % (i + 1, app.name)

    def list_running_apps(self, args):
        for i, app in enumerate(sorted(self.apps.running_apps,
                                       key=lambda a: a.name.lower())):
            print '%d: %s' % (i + 1, app.name)

    def lock(self, args):
        self.device.lock()

    def screenshot(self, args):
        self.marionette.execute_script(
            "window.wrappedJSObject.dispatchEvent(new Event('volumedown+sleep'));")

    def send_sms(self, args):
        self.data_layer.send_sms(args.number, args.message)

    def set_setting(self, args):
        self.data_layer.set_setting(args.name, args.value)

    def sleep(self, args):
        self.marionette.execute_script(
            "window.wrappedJSObject.dispatchEvent(new Event('sleep'));")

    def unlock(self, args):
        self.device.unlock()

    def volume(self, args):
        self.marionette.execute_script(
            "window.wrappedJSObject.dispatchEvent(new Event('volume%s'));" %
            args.direction)

    def wake(self, args):
        self.marionette.execute_script(
            "window.wrappedJSObject.dispatchEvent(new Event('wake'));")
Beispiel #5
0
class MarionetteHelper:
    """ Helper for starting firefox and for remote browsing

    """

    def __init__(self, firefox_path, logger=None):
        self.logger = logger  # type: logging.Logger
        self.client = None  # type: Marionette
        self.ffpopen = None  # type: subprocess.Popen
        self.ffpath = firefox_path  # type: str
        if logger is None:
            self.logger = logging.getLogger("MarionetteHelper")
        self.logger.debug("Marionette helper init done")

    def _open_session(self, host='localhost', port=2828):
        """ Opens the session for marionette"""
        caps = {u'acceptInsecureCerts': True, }
        self.client = Marionette(host, port=port)
        self.client.start_session(capabilities=caps)

    def run_firefox(self):
        """ Start the firefox process"""
        self.logger.debug("Starting firefox process")
        self.ffpopen = subprocess.Popen([self.ffpath, "-marionette"])
        self.logger.debug("Opening marionette session")
        self._open_session()

    def quit_firefox(self):
        """ Close the firefox process and close marionette session"""
        #self.logger.debug("Closing firefox")
        #self.client._send_message("Marionette:Quit")
        self.client._request_in_app_shutdown("eForceQuit")
        self.client.delete_session(False)
        self.client.cleanup()
        self.client = None # reset client state
        #try:
        #    self.client.close()  # try to close the window anyway
        #except InvalidSessionIdException:
        #    pass
        #except socket.error:
        #    pass
        #finally:
        #    try:
        #        self.logger.debug("Closing marionette session")
        #        self.client.delete_session(False)  # close client session
        #    except InvalidSessionIdException:
        #        pass
        #    except socket.error:
        #        pass
        #    self.client = None  # reset client state
        #self.logger.debug("Waiting for firefox to close")
        #for _ in range(3):  # give the process 3 seconds to terminate
        #    time.sleep(1)
        #    self.ffpopen.poll()
        #    if self.ffpopen.returncode is not None:
        #        break
        #self.ffpopen.poll()
        #if self.ffpopen.returncode is None:
        #    self.logger.warning("Firefox not closed in time, killing it!")
        #    self.ffpopen.kill()  # process was not quit in time, kill it
        #self.ffpopen = None  # reset popen state
        #self.logger.debug("Firefox is closed")

    def ___get_client(self):
        """ Returns the internal marionette client object"""
        return self.client

    def navigate_to_url(self, url):
        """ Open an url in format of http[s]://example.com"""
        try:
            if "http" not in url:
                url = "http://" + url
            self.client.navigate(url)
        except TimeoutException:
            self.logger.warning("Error: Timeout")
            return False
        except InsecureCertificateException:
            self.logger.warning("Warning: Insecure Certificate")
            return True
        except UnknownException as e:
            if "Reached error page" in str(e):
                self.logger.warning("Reached error page, ignoring...")
            else: # reraise, something very unexpected happened here
                t, v, tb = sys.exc_info()
                raise t, v, tb
            return False
        return True

    def back(self):
        """ Go a page backward"""
        try:
            self.client.go_back()
        except TimeoutException:
            self.logger.warning("Error: Timeout")
            return False
        except InsecureCertificateException:
            self.logger.warning("Warning: Insecure Certificate")
            return True
        except UnknownException as e:
            if "Reached error page" in str(e):
                self.logger.warning("Reached error page, ignoring...")
            else: # reraise, something very unexpected happened here
                t, v, tb = sys.exc_info()
                raise t, v, tb
            return False
        return True

    def forward(self):
        """ Go a page forward"""
        try:
            self.client.go_forward()
        except TimeoutException:
            self.logger.warning("Error: Timeout")
            return False
        except InsecureCertificateException:
            self.logger.warning("Warning: Insecure Certificate")
            return True
        except UnknownException as e:
            if "Reached error page" in str(e):
                self.logger.warning("Reached error page, ignoring...")
            else: # reraise, something very unexpected happened here
                t, v, tb = sys.exc_info()
                raise t, v, tb
            return False
        return True

    def follow_link(self, index=0):
        """ Click on a link"""
        try:
            links = self.client.find_elements(By.TAG_NAME, "a")
            links[index].click()
        except ElementNotVisibleException:
            self.logger.warning("Error: Element not visible")
            return False
        except ElementNotSelectableException:
            self.logger.warning("Error: Element not selectable")
            return False
        except ElementNotAccessibleException:
            self.logger.warning("Error: Element not accessible")
            return False
        except ElementNotInteractableException:
            self.logger.warning("Error: Element not interactable")
            return False
        except NoSuchElementException:
            self.logger.warning("Error: Element does not exist")
            return False
        except TimeoutException:
            self.logger.warning("Error: Timeout")
            return False
        except IndexError:
            self.logger.warning("Error: Out of bound")
            return False
        except InsecureCertificateException:
            self.logger.warning("Warning: Insecure Certificate")
            return True
        except UnknownException as e:
            if "Reached error page" in str(e):
                self.logger.warning("Reached error page, ignoring...")
            else: # reraise, something very unexpected happened here
                t, v, tb = sys.exc_info()
                raise t, v, tb
            return False
        return True

    def click_element_by_class_name(self, html_class_name):
        """ Click on first element via class name"""
        try:
            e = self.client.find_element(By.CLASS_NAME, html_class_name)
            e.click()
        except ElementNotVisibleException:
            self.logger.warning("Error: Element not visible")
            return False
        except ElementNotSelectableException:
            self.logger.warning("Error: Element not selectable")
            return False
        except ElementNotAccessibleException:
            self.logger.warning("Error: Element not accessible")
            return False
        except ElementNotInteractableException:
            self.logger.warning("Error: Element not interactable")
            return False
        except NoSuchElementException:
            self.logger.warning("Error: Element does not exist")
            return False
        except TimeoutException:
            self.logger.warning("Error: Timeout")
            return False
        except InsecureCertificateException:
            self.logger.warning("Warning: Insecure Certificate")
            return True
        except UnknownException as e:
            if "Reached error page" in str(e):
                self.logger.warning("Reached error page, ignoring...")
            else: # reraise, something very unexpected happened here
                t, v, tb = sys.exc_info()
                raise t, v, tb
            return False
        return True

    def click_element_by_css_selector(self, css_selector):
        """ Click on first element via css selector"""
        try:
            e = self.client.find_element(By.CSS_SELECTOR, css_selector)
            e.click()
        except ElementNotVisibleException:
            self.logger.warning("Error: Element not visible")
            return False
        except ElementNotSelectableException:
            self.logger.warning("Error: Element not selectable")
            return False
        except ElementNotAccessibleException:
            self.logger.warning("Error: Element not accessible")
            return False
        except ElementNotInteractableException:
            self.logger.warning("Error: Element not interactable")
            return False
        except NoSuchElementException:
            self.logger.warning("Error: Element does not exist")
            return False
        except TimeoutException:
            self.logger.warning("Error: Timeout")
            return False
        except InsecureCertificateException:
            self.logger.warning("Warning: Insecure Certificate")
            return True
        except UnknownException as e:
            if "Reached error page" in str(e):
                self.logger.warning("Reached error page, ignoring...")
            else: # reraise, something very unexpected happened here
                t, v, tb = sys.exc_info()
                raise t, v, tb
            return False
        return True

    def click_element_by_id(self, html_id):
        """ Click on first element via element id"""
        try:
            e = self.client.find_element(By.ID, html_id)
            e.click()
        except ElementNotVisibleException:
            self.logger.warning("Error: Element not visible")
            return False
        except ElementNotSelectableException:
            self.logger.warning("Error: Element not selectable")
            return False
        except ElementNotAccessibleException:
            self.logger.warning("Error: Element not accessible")
            return False
        except ElementNotInteractableException:
            self.logger.warning("Error: Element not interactable")
            return False
        except NoSuchElementException:
            self.logger.warning("Error: Element does not exist")
            return False
        except TimeoutException:
            self.logger.warning("Error: Timeout")
            return False
        except InsecureCertificateException:
            self.logger.warning("Warning: Insecure Certificate")
            return True
        except UnknownException as e:
            if "Reached error page" in str(e):
                self.logger.warning("Reached error page, ignoring...")
            else: # reraise, something very unexpected happened here
                t, v, tb = sys.exc_info()
                raise t, v, tb
            return False
        return True

    def click_element_by_name(self, html_name):
        """ Click on first element via element name"""
        try:
            e = self.client.find_element(By.NAME, html_name)
            e.click()
        except ElementNotVisibleException:
            self.logger.warning("Error: Element not visible")
            return False
        except ElementNotSelectableException:
            self.logger.warning("Error: Element not selectable")
            return False
        except ElementNotAccessibleException:
            self.logger.warning("Error: Element not accessible")
            return False
        except ElementNotInteractableException:
            self.logger.warning("Error: Element not interactable")
            return False
        except NoSuchElementException:
            self.logger.warning("Error: Element does not exist")
            return False
        except TimeoutException:
            self.logger.warning("Error: Timeout")
            return False
        except InsecureCertificateException:
            self.logger.warning("Warning: Insecure Certificate")
            return True
        except UnknownException as e:
            if "Reached error page" in str(e):
                self.logger.warning("Reached error page, ignoring...")
            else: # reraise, something very unexpected happened here
                t, v, tb = sys.exc_info()
                raise t, v, tb
            return False
        return True

    def click_element_by_tag_name(self, html_tag_name):
        """ Click on first element via tag name"""
        try:
            e = self.client.find_element(By.TAG_NAME, html_tag_name)
            e.click()
        except ElementNotVisibleException:
            self.logger.warning("Error: Element not visible")
            return False
        except ElementNotSelectableException:
            self.logger.warning("Error: Element not selectable")
            return False
        except ElementNotAccessibleException:
            self.logger.warning("Error: Element not accessible")
            return False
        except ElementNotInteractableException:
            self.logger.warning("Error: Element not interactable")
            return False
        except NoSuchElementException:
            self.logger.warning("Error: Element does not exist")
            return False
        except TimeoutException:
            self.logger.warning("Error: Timeout")
            return False
        except InsecureCertificateException:
            self.logger.warning("Warning: Insecure Certificate")
            return True
        except UnknownException as e:
            if "Reached error page" in str(e):
                self.logger.warning("Reached error page, ignoring...")
            else: # reraise, something very unexpected happened here
                t, v, tb = sys.exc_info()
                raise t, v, tb
            return False
        return True

    def click_element_by_xpath(self, xpath):
        """ Click on first element via xpath"""
        try:
            e = self.client.find_element(By.XPATH, xpath)
            e.click()
        except ElementNotVisibleException:
            self.logger.warning("Error: Element not visible")
            return False
        except ElementNotSelectableException:
            self.logger.warning("Error: Element not selectable")
            return False
        except ElementNotAccessibleException:
            self.logger.warning("Error: Element not accessible")
            return False
        except ElementNotInteractableException:
            self.logger.warning("Error: Element not interactable")
            return False
        except NoSuchElementException:
            self.logger.warning("Error: Element does not exist")
            return False
        except TimeoutException:
            self.logger.warning("Error: Timeout")
            return False
        except InsecureCertificateException:
            self.logger.warning("Warning: Insecure Certificate")
            return True
        except UnknownException as e:
            if "Reached error page" in str(e):
                self.logger.warning("Reached error page, ignoring...")
            else: # reraise, something very unexpected happened here
                t, v, tb = sys.exc_info()
                raise t, v, tb
            return False
        return True

    def click_element_by_link_text(self, html_link_text):
        """ Click on first element via link text"""
        try:
            e = self.client.find_element(By.LINK_TEXT, html_link_text)
            e.click()
        except ElementNotVisibleException:
            self.logger.warning("Error: Element not visible")
            return False
        except ElementNotSelectableException:
            self.logger.warning("Error: Element not selectable")
            return False
        except ElementNotAccessibleException:
            self.logger.warning("Error: Element not accessible")
            return False
        except ElementNotInteractableException:
            self.logger.warning("Error: Element not interactable")
            return False
        except NoSuchElementException:
            self.logger.warning("Error: Element does not exist")
            return False
        except TimeoutException:
            self.logger.warning("Error: Timeout")
            return False
        except InsecureCertificateException:
            self.logger.warning("Warning: Insecure Certificate")
            return True
        except UnknownException as e:
            if "Reached error page" in str(e):
                self.logger.warning("Reached error page, ignoring...")
            else: # reraise, something very unexpected happened here
                t, v, tb = sys.exc_info()
                raise t, v, tb
            return False
        return True

    def send_keys_to_element_by_name(self, name, text):
        """ Sends text to an element via name"""
        try:
            e = self.client.find_element(By.NAME, name)
            e.send_keys(text)
        except ElementNotVisibleException:
            self.logger.warning("Error: Element not visible")
            return False
        except ElementNotSelectableException:
            self.logger.warning("Error: Element not selectable")
            return False
        except ElementNotAccessibleException:
            self.logger.warning("Error: Element not accessible")
            return False
        except ElementNotInteractableException:
            self.logger.warning("Error: Element not interactable")
            return False
        except NoSuchElementException:
            self.logger.warning("Error: Element does not exist")
            return False
        except TimeoutException:
            self.logger.warning("Error: Timeout")
            return False
        return True

    def select_window(self, index):
        """ Switch window via index"""
        try:
            self.client.switch_to_window(self.client.window_handles[index])
        except NoSuchWindowException:
            self.logger.warning("Error: Window does not exist")
            return False
        return True

    def close_window(self):
        """ Close the current window"""
        self.client.close()  # this won't close the last window, call quit_firefox instead

    def get_current_window_index(self):
        """ Get current windows index"""
        return self.client.window_handles.index(self.client.current_window_handle)

    def new_tab(self):
        """ Open a new empty tab"""
        with self.client.using_context("chrome"):
            self.client.find_element(By.ID, "menu_newNavigatorTab").click()

    def new_window(self):
        """ Open a new empty window"""
        with self.client.using_context("chrome"):
            self.client.execute_script("window.open();")

    def close_tab(self):
        """ Close the current tab"""
        self.close_window()  # basically the same as close windows
Beispiel #6
0
    def runApp(self,
               options,
               cmdargs=None,
               timeout=None,
               debuggerInfo=None,
               symbolsPath=None,
               valgrindPath=None,
               valgrindArgs=None,
               valgrindSuppFiles=None,
               **profileArgs):

        if cmdargs is None:
            cmdargs = []
        cmdargs = cmdargs[:]

        if self.use_marionette:
            cmdargs.append("-marionette")

        binary = options.app
        profile = self.createReftestProfile(options, **profileArgs)

        # browser environment
        env = self.buildBrowserEnv(options, profile.profile)

        self.log.info("Running with e10s: {}".format(options.e10s))
        self.log.info("Running with fission: {}".format(options.fission))

        def timeoutHandler():
            self.handleTimeout(timeout, proc, options.utilityPath,
                               debuggerInfo)

        interactive = False
        debug_args = None
        if debuggerInfo:
            interactive = debuggerInfo.interactive
            debug_args = [debuggerInfo.path] + debuggerInfo.args

        def record_last_test(message):
            """Records the last test seen by this harness for the benefit of crash logging."""
            def testid(test):
                if " " in test:
                    return test.split(" ")[0]
                return test

            if message["action"] == "test_start":
                self.lastTestSeen = testid(message["test"])
            elif message["action"] == "test_end":
                if self.lastTest and message["test"] == self.lastTest:
                    self.lastTestSeen = "Last test finished"
                else:
                    self.lastTestSeen = "{} (finished)".format(
                        testid(message["test"]))

        self.log.add_handler(record_last_test)

        kp_kwargs = {
            "kill_on_timeout": False,
            "cwd": SCRIPT_DIRECTORY,
            "onTimeout": [timeoutHandler],
            "processOutputLine": [self.outputHandler],
        }

        if mozinfo.isWin or mozinfo.isMac:
            # Prevents log interleaving on Windows at the expense of losing
            # true log order. See bug 798300 and bug 1324961 for more details.
            kp_kwargs["processStderrLine"] = [self.outputHandler]

        if interactive:
            # If an interactive debugger is attached,
            # don't use timeouts, and don't capture ctrl-c.
            timeout = None
            signal.signal(signal.SIGINT, lambda sigid, frame: None)

        runner_cls = mozrunner.runners.get(
            mozinfo.info.get("appname", "firefox"), mozrunner.Runner)
        runner = runner_cls(
            profile=profile,
            binary=binary,
            process_class=mozprocess.ProcessHandlerMixin,
            cmdargs=cmdargs,
            env=env,
            process_args=kp_kwargs,
        )
        runner.start(debug_args=debug_args,
                     interactive=interactive,
                     outputTimeout=timeout)
        proc = runner.process_handler
        self.outputHandler.proc_name = "GECKO({})".format(proc.pid)

        # Used to defer a possible IOError exception from Marionette
        marionette_exception = None

        if self.use_marionette:
            marionette_args = {
                "socket_timeout": options.marionette_socket_timeout,
                "startup_timeout": options.marionette_startup_timeout,
                "symbols_path": options.symbolsPath,
            }
            if options.marionette:
                host, port = options.marionette.split(":")
                marionette_args["host"] = host
                marionette_args["port"] = int(port)

            try:
                marionette = Marionette(**marionette_args)
                marionette.start_session()

                addons = Addons(marionette)
                if options.specialPowersExtensionPath:
                    addons.install(options.specialPowersExtensionPath,
                                   temp=True)

                addons.install(options.reftestExtensionPath, temp=True)

                marionette.delete_session()
            except IOError:
                # Any IOError as thrown by Marionette means that something is
                # wrong with the process, like a crash or the socket is no
                # longer open. We defer raising this specific error so that
                # post-test checks for leaks and crashes are performed and
                # reported first.
                marionette_exception = sys.exc_info()

        status = runner.wait()
        runner.process_handler = None
        self.outputHandler.proc_name = None

        if status:
            msg = (
                "TEST-UNEXPECTED-FAIL | %s | application terminated with exit code %s"
                % (self.lastTestSeen, status))
            # use process_output so message is logged verbatim
            self.log.process_output(None, msg)

        crashed = mozcrash.log_crashes(
            self.log,
            os.path.join(profile.profile, "minidumps"),
            options.symbolsPath,
            test=self.lastTestSeen,
        )
        if not status and crashed:
            status = 1

        runner.cleanup()
        self.cleanup(profile.profile)

        if marionette_exception is not None:
            exc, value, tb = marionette_exception
            raise reraise(exc, value, tb)

        self.log.info(
            "Process mode: {}".format("e10s" if options.e10s else "non-e10s"))
        return status