Esempio n. 1
0
    def train(self, request, run_id):
        training_run = get_object_or_404(TrainingRun, id=run_id)

        with open(os.path.join(settings.BASE_DIR, 'build',
                               'train.bundle.js')) as f:
            train_script = f.read()

        fd, ruleset_path = mkstemp()
        with os.fdopen(fd, 'w') as f:
            f.write(training_run.ruleset.code.encode('utf8'))

        facts = training_run.ruleset.fact_set.facts.all()

        client = None
        try:
            client = Marionette(bin=settings.FIREFOX_BIN, headless=True)
            client.start_session()

            webpages = list(
                map(
                    lambda webpage: {
                        'url': webpage.url,
                        'facts': {
                            fact.fact.key: fact.fact_answer
                            for fact in webpage.webpagefact_set.filter(fact__in
                                                                       =facts)
                        },
                    },
                    training_run.training_pages.all(),
                ))

            results = client.execute_async_script(
                train_script,
                script_args=(
                    ruleset_path,
                    list(map(lambda fact: fact.key, facts)),
                    webpages,
                    json.loads(training_run.initial_coefficients),
                ),
                sandbox='system',
                script_timeout=1000 * 60 * 5,
            )

            training_run.final_coefficients = json.dumps(results[0])
            training_run.save()
        finally:
            if client:
                client.cleanup()
            os.remove(ruleset_path)

        messages.add_message(request, messages.SUCCESS,
                             'Training run completed.')
        return redirect('admin:training_trainingrun_change', run_id)
Esempio n. 2
0
def main(firefox_bin):
    if not firefox_bin:
        raise click.BadParameter(
            'No Firefox binary found; configure the path to Firefox with `npm config`.'
        )
    elif not os.path.exists(firefox_bin):
        raise click.BadParameter('Path to Firefox binary does not exist.')

    click.echo('== Building test bundle with Webpack')
    bundle_handle, bundle_path = mkstemp()
    try:
        webpack_config_path = os.path.join(ROOT, 'webpack/test.config.js')
        check_call([
            'webpack',
            '--bail',
            '--config',
            webpack_config_path,
            '--output',
            bundle_path,
        ])
        with open(bundle_path) as f:
            test_code = f.read()
    finally:
        os.remove(bundle_path)

    click.echo('== Running tests')
    client = None
    try:
        client = Marionette(bin=firefox_bin, headless=True)
        client.start_session()
        results = client.execute_async_script(test_code)
    finally:
        if client:
            client.cleanup()

    # Pipe output through formatter to make it readable.
    reporter_env = os.environ.copy()
    reporter_env.setdefault('TAP_COLORS', '1')  # Support color outpput
    reporter = Popen(
        ['tap-mocha-reporter', 'spec'],
        stdout=PIPE,
        stderr=STDOUT,
        stdin=PIPE,
        env=reporter_env,
    )
    formatted_output, stderr = reporter.communicate(results['output'])
    click.echo(formatted_output)

    # Exit with an error code if there were any failures
    if results['failures'] > 0:
        sys.exit(1)
Esempio n. 3
0
    def freeze(self, request, queryset):
        with open(os.path.join(settings.BASE_DIR, 'build',
                               'freeze.bundle.js')) as f:
            freeze_script = f.read()

        client = None
        try:
            client = Marionette(bin=settings.FIREFOX_BIN, headless=True)
            client.start_session()

            for webpage in queryset:
                print('Freezing {}...'.format(webpage.url))
                client.navigate(webpage.url)
                results = client.execute_async_script(
                    freeze_script,
                    script_timeout=1000 * 60 * 5,
                )
                webpage.frozen_html.save(webpage.url,
                                         ContentFile(results['html']))
                webpage.save()
        finally:
            if client:
                client.cleanup()
Esempio n. 4
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
Esempio n. 5
0
def run_tests(firefox_path=None):
    basedir = os.path.dirname(__file__)

    if sys.platform == 'darwin' and os.path.isdir(firefox_path):
        firefox_path = os.path.join(firefox_path,
                                    'Contents', 'MacOS', 'firefox')

    driver = Marionette(app='fxdesktop', bin=firefox_path, gecko_log='-',
                        prefs={'xpinstall.signatures.required': False})
    driver.start_session()

    try:
        build1 = tempfile.NamedTemporaryFile(mode='wb', suffix='.xpi',
                                             delete=False)
        build2 = tempfile.NamedTemporaryFile(mode='wb', suffix='.xpi',
                                             delete=False)
        try:
            jpm_build(basedir, build1.name)
            jpm_build(os.path.join(basedir, 'testhelper'), build2.name)

            addons = Addons(driver)
            addons.install(build1.name, temp=True)
            addons.install(build2.name, temp=True)
        finally:
            os.unlink(build1.name)
            os.unlink(build2.name)

        driver.expected = expected
        driver.keys = Keys

        class restore_url:
            def __enter__(self):
                self.url = driver.get_url()

            def __exit__(self, type, value, traceback):
                driver.navigate('about:blank')
                driver.navigate(self.url)
        driver.restore_url = restore_url

        def wait_until(method):
            Wait(driver, default_timeout).until(lambda d: method())
        driver.wait_until = wait_until

        def accept_alert():
            driver.switch_to_alert().accept()
        driver.accept_alert = accept_alert

        max_timestamp = {'value': 0}

        def get_urls():
            result = []
            prefix = '[testhelper] Loading: '
            new_timestamp = max_timestamp['value']
            with driver.using_context(driver.CONTEXT_CHROME):
                messages = driver.execute_script(
                    'return ' +
                    'Cc["@mozilla.org/consoleservice;1"]' +
                    '.getService(Ci.nsIConsoleService).getMessageArray()' +
                    '.map(m => m instanceof Ci.nsIScriptError ? ' +
                    '[m.timeStamp, m.errorMessage] : [null, null])'
                )
            for timestamp, message in messages:
                if timestamp <= max_timestamp['value']:
                    continue
                if not message.startswith(prefix):
                    continue
                if timestamp > new_timestamp:
                    new_timestamp = timestamp
                result.append(message[len(prefix):])
            max_timestamp['value'] = new_timestamp
            return result
        driver.get_urls = get_urls

        def close_windows(keep):
            for h in [h for h in driver.chrome_window_handles if h != keep]:
                driver.switch_to_window(h)
                driver.close_chrome_window()
            driver.switch_to_window(keep)
        driver.close_windows = close_windows

        def close_background_tabs():
            current_tab = driver.current_window_handle
            for h in [h for h in driver.window_handles if h != current_tab]:
                driver.switch_to_window(h)
                driver.close()
            driver.switch_to_window(current_tab)
        driver.close_background_tabs = close_background_tabs

        def wait_for_load():
            code = 'return document.readyState == "complete";'
            driver.wait_until(lambda: driver.execute_script(code))
        driver.wait_for_load = wait_for_load

        def click(self):
            action = Actions(driver)
            action.click(self)
            action.perform()
        HTMLElement.click = click

        def middle_click(self):
            action = Actions(driver)
            action.middle_click(self)
            action.perform()
        HTMLElement.middle_click = middle_click

        def context_click(self):
            action = Actions(driver)
            action.context_click(self)
            action.perform()
        HTMLElement.context_click = context_click

        testdir = os.path.join(basedir, 'tests')
        for filename in os.listdir(testdir):
            if filename.startswith('.') or not filename.endswith('.py'):
                continue
            filepath = os.path.join(testdir, filename)
            globals = {}
            execfile(filepath, globals)
            globals['run'](driver)
    finally:
        driver.cleanup()
Esempio n. 6
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
Esempio n. 7
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
Esempio n. 8
0
    '}')

# The location of the Firefox binary, will depend on system.
# Be careful to use the actual binary and not a wrapper script.
binary = '/usr/lib/firefox/firefox'

# Loop through the four different configurations.
for mode in ['headless', 'graphical']:
    # Set up the client with the appropriate settings.
    if mode == 'headless':
        os.environ['MOZ_HEADLESS'] = '1'
    else:
        os.environ.pop('MOZ_HEADLESS', None)
    client = Marionette('localhost', bin=binary, port=2828)
    client.start_session()

    # Navigate to the test page and inject the JavaScript.
    client.navigate(
        'https://intoli.com/blog/javascript-injection/test-page.html')
    client.execute_async_script(injected_javascript)

    # Save the results as an image.
    filename = os.path.join(
        'img', 'marionette-execute-async-scripy-firefox-%s-results.png' % mode)
    with open(filename, 'wb') as f:
        f.write(client.screenshot(format='binary'))
    print 'Saved "%s".' % filename

    # Cleanup the client before the next test.
    client.cleanup()
Esempio n. 9
0
def marionette(request):
    marionette = Marionette(bin=request.config.getoption('firefox_path'))
    marionette.start_session()
    request.node._marionette = marionette
    yield marionette
    marionette.cleanup()
Esempio n. 10
0
def run_tests(firefox_path=None):
    basedir = os.path.dirname(__file__)

    if sys.platform == 'darwin' and os.path.isdir(firefox_path):
        firefox_path = os.path.join(firefox_path, 'Contents', 'MacOS',
                                    'firefox')

    driver = Marionette(app='fxdesktop',
                        bin=firefox_path,
                        gecko_log='-',
                        prefs={'xpinstall.signatures.required': False})
    driver.start_session()

    try:
        build1 = tempfile.NamedTemporaryFile(mode='wb',
                                             suffix='.xpi',
                                             delete=False)
        build2 = tempfile.NamedTemporaryFile(mode='wb',
                                             suffix='.xpi',
                                             delete=False)
        try:
            gulp_build(basedir, build1.name)
            jpm_build(basedir, os.path.join(basedir, 'testhelper'),
                      build2.name)

            addons = Addons(driver)
            addons.install(build1.name, temp=True)
            addons.install(build2.name, temp=True)
        finally:
            os.unlink(build1.name)
            os.unlink(build2.name)

        driver.expected = expected
        driver.keys = Keys

        class restore_url:
            def __enter__(self):
                self.url = driver.get_url()

            def __exit__(self, type, value, traceback):
                driver.navigate('about:blank')
                driver.navigate(self.url)

        driver.restore_url = restore_url

        def wait_until(method):
            Wait(driver, default_timeout).until(lambda d: method())

        driver.wait_until = wait_until

        def accept_alert():
            driver.switch_to_alert().accept()

        driver.accept_alert = accept_alert

        max_timestamp = {'value': 0}

        def get_urls():
            result = []
            prefix = '[testhelper] Loading: '
            new_timestamp = max_timestamp['value']
            with driver.using_context(driver.CONTEXT_CHROME):
                messages = driver.execute_script(
                    'return ' + 'Cc["@mozilla.org/consoleservice;1"]' +
                    '.getService(Ci.nsIConsoleService).getMessageArray()' +
                    '.map(m => m instanceof Ci.nsIScriptError ? ' +
                    '[m.timeStamp, m.errorMessage] : [null, null])')
            for timestamp, message in messages:
                if timestamp <= max_timestamp['value']:
                    continue
                if not message.startswith(prefix):
                    continue
                if timestamp > new_timestamp:
                    new_timestamp = timestamp
                result.append(message[len(prefix):])
            max_timestamp['value'] = new_timestamp
            return result

        driver.get_urls = get_urls

        def close_windows(keep):
            for h in [h for h in driver.chrome_window_handles if h != keep]:
                driver.switch_to_window(h)
                driver.close_chrome_window()
            driver.switch_to_window(keep)

        driver.close_windows = close_windows

        def close_background_tabs():
            current_tab = driver.current_window_handle
            for h in [h for h in driver.window_handles if h != current_tab]:
                driver.switch_to_window(h)
                driver.close()
            driver.switch_to_window(current_tab)

        driver.close_background_tabs = close_background_tabs

        def wait_for_load():
            code = 'return document.readyState == "complete";'
            driver.wait_until(lambda: driver.execute_script(code))

        driver.wait_for_load = wait_for_load

        def click(self):
            action = Actions(driver)
            action.click(self)
            action.perform()

        HTMLElement.click = click

        def middle_click(self):
            action = Actions(driver)
            action.middle_click(self)
            action.perform()

        HTMLElement.middle_click = middle_click

        def context_click(self):
            action = Actions(driver)
            action.context_click(self)
            action.perform()

        HTMLElement.context_click = context_click

        testdir = os.path.join(basedir, 'tests')
        for filename in os.listdir(testdir):
            if filename.startswith('.') or not filename.endswith('.py'):
                continue
            filepath = os.path.join(testdir, filename)
            globals = {}
            execfile(filepath, globals)
            globals['run'](driver)
    finally:
        driver.cleanup()