Esempio n. 1
0
    def install(self, profile):
        """Install the handler for glimpse:// URLs on the given profile."""
        if QWebEngineUrlScheme is not None:
            assert QWebEngineUrlScheme.schemeByName(b'glimpse') is not None

        profile.installUrlSchemeHandler(b'glimpse', self)
        if (qtutils.version_check('5.11', compiled=False)
                and not qtutils.version_check('5.12', compiled=False)):
            # WORKAROUND for https://bugreports.qt.io/browse/QTBUG-63378
            profile.installUrlSchemeHandler(b'chrome-error', self)
            profile.installUrlSchemeHandler(b'chrome-extension', self)
Esempio n. 2
0
def _apply_platform_markers(config, item):
    """Apply a skip marker to a given item."""
    markers = [
        ('posix', not utils.is_posix, "Requires a POSIX os"),
        ('windows', not utils.is_windows, "Requires Windows"),
        ('linux', not utils.is_linux, "Requires Linux"),
        ('mac', not utils.is_mac, "Requires macOS"),
        ('not_mac', utils.is_mac, "Skipped on macOS"),
        ('not_frozen', getattr(sys, 'frozen', False),
         "Can't be run when frozen"),
        ('frozen', not getattr(sys, 'frozen', False),
         "Can only run when frozen"),
        ('ci', not ON_CI, "Only runs on CI."),
        ('no_ci', ON_CI, "Skipped on CI."),
        ('issue2478', utils.is_windows and config.webengine,
         "Broken with QtWebEngine on Windows"),
        ('issue3572',
         (qtutils.version_check('5.10', compiled=False, exact=True) or
          qtutils.version_check('5.10.1', compiled=False, exact=True)) and
         config.webengine and 'TRAVIS' in os.environ,
         "Broken with QtWebEngine with Qt 5.10 on Travis"),
        ('qtbug60673',
         qtutils.version_check('5.8') and
         not qtutils.version_check('5.10') and
         config.webengine,
         "Broken on webengine due to "
         "https://bugreports.qt.io/browse/QTBUG-60673"),
        ('unicode_locale', sys.getfilesystemencoding() == 'ascii',
         "Skipped because of ASCII locale"),
        ('qtwebkit6021_skip',
         version.qWebKitVersion and
         version.qWebKitVersion() == '602.1',
         "Broken on WebKit 602.1")
    ]

    for searched_marker, condition, default_reason in markers:
        marker = item.get_closest_marker(searched_marker)
        if not marker or not condition:
            continue

        if 'reason' in marker.kwargs:
            reason = '{}: {}'.format(default_reason, marker.kwargs['reason'])
            del marker.kwargs['reason']
        else:
            reason = default_reason + '.'
        skipif_marker = pytest.mark.skipif(condition, *marker.args,
                                           reason=reason, **marker.kwargs)
        item.add_marker(skipif_marker)
def _handle_wayland():
    assert objects.backend == usertypes.Backend.QtWebEngine, objects.backend

    if os.environ.get('QUTE_SKIP_WAYLAND_CHECK'):
        return

    platform = QApplication.instance().platformName()
    if platform not in ['wayland', 'wayland-egl']:
        return

    has_qt511 = qtutils.version_check('5.11', compiled=False)
    if has_qt511 and config.val.qt.force_software_rendering == 'chromium':
        return

    if qtutils.version_check('5.11.2', compiled=False):
        return

    buttons = []
    text = "<p>You can work around this in one of the following ways:</p>"

    if 'DISPLAY' in os.environ:
        # XWayland is available, but QT_QPA_PLATFORM=wayland is set
        buttons.append(_Button("Force XWayland", 'qt.force_platform', 'xcb'))
        text += ("<p><b>Force Qt to use XWayland</b></p>"
                 "<p>This allows you to use the newer QtWebEngine backend "
                 "(based on Chromium). "
                 "This sets the <i>qt.force_platform = 'xcb'</i> option "
                 "(if you have a <i>config.py</i> file, you'll need to set "
                 "this manually).</p>")
    else:
        text += ("<p><b>Set up XWayland</b></p>"
                 "<p>This allows you to use the newer QtWebEngine backend "
                 "(based on Chromium). ")

    if has_qt511:
        buttons.append(_Button("Force software rendering",
                               'qt.force_software_rendering',
                               'chromium'))
        text += ("<p><b>Forcing software rendering</b></p>"
                 "<p>This allows you to use the newer QtWebEngine backend "
                 "(based on Chromium) but could have noticeable performance "
                 "impact (depending on your hardware). This sets the "
                 "<i>qt.force_software_rendering = 'chromium'</i> option "
                 "(if you have a <i>config.py</i> file, you'll need to set "
                 "this manually).</p>")

    _show_dialog(backend=usertypes.Backend.QtWebEngine,
                 because="you're using Wayland", text=text, buttons=buttons)
Esempio n. 4
0
def can_use_data_path():
    """Whether the current Qt version can use a customized path.

    Qt >= 5.10 understands QTWEBENGINE_DICTIONARIES_PATH which means we don't
    need to put them to a fixed root-only folder.
    """
    return qtutils.version_check('5.10', compiled=False)
Esempio n. 5
0
def pytest_collection_modifyitems(config, items):
    """Apply @qtwebengine_* markers; skip unittests with QUTE_BDD_WEBENGINE."""
    markers = [
        ('qtwebengine_todo', 'QtWebEngine TODO', pytest.mark.xfail,
         config.webengine),
        ('qtwebengine_skip', 'Skipped with QtWebEngine', pytest.mark.skipif,
         config.webengine),
        ('qtwebengine_notifications', 'Skipped with QtWebEngine < 5.13',
         pytest.mark.skipif, config.webengine
         and not qtutils.version_check('5.13')),
        ('qtwebkit_skip', 'Skipped with QtWebKit', pytest.mark.skipif,
         not config.webengine),
        ('qtwebengine_flaky', 'Flaky with QtWebEngine', pytest.mark.skipif,
         config.webengine),
        ('qtwebengine_mac_xfail', 'Fails on macOS with QtWebEngine',
         pytest.mark.xfail, config.webengine and utils.is_mac),
    ]

    for item in items:
        for name, prefix, pytest_mark, condition in markers:
            marker = item.get_closest_marker(name)
            if marker and condition:
                if marker.args:
                    text = '{}: {}'.format(prefix, marker.args[0])
                else:
                    text = prefix
                item.add_marker(
                    pytest_mark(condition, reason=text, **marker.kwargs))
Esempio n. 6
0
    def needs_document_end_workaround(self):
        """Check whether to force @run-at document-end.

        This needs to be done on QtWebEngine with Qt 5.12 for known-broken
        scripts.

        On Qt 5.12, accessing the DOM isn't possible with "@run-at
        document-start". It was documented to be impossible before, but seems
        to work fine.

        However, some scripts do DOM access with "@run-at document-start". Fix
        those by forcing them to use document-end instead.
        """
        if objects.backend != usertypes.Backend.QtWebEngine:
            return False
        elif not qtutils.version_check('5.12', compiled=False):
            return False

        broken_scripts = [
            ('http://userstyles.org', None),
            ('https://github.com/ParticleCore', 'Iridium'),
        ]
        return any(
            self._matches_id(namespace=namespace, name=name)
            for namespace, name in broken_scripts)
def _get_suggested_filename(path):
    """Convert a path we got from chromium to a suggested filename.

    Chromium thinks we want to download stuff to ~/Download, so even if we
    don't, we get downloads with a suffix like (1) for files existing there.

    We simply strip the suffix off via regex.

    See https://bugreports.qt.io/browse/QTBUG-56978
    """
    filename = os.path.basename(path)

    suffix_re = re.compile(
        r"""
      \ ?  # Optional space between filename and suffix
      (
        # Numerical suffix
        \([0-9]+\)
      |
        # ISO-8601 suffix
        # https://cs.chromium.org/chromium/src/base/time/time_to_iso8601.cc
        \ -\ \d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{3}Z
      )
      (?=\.|$)  # Begin of extension, or filename without extension
    """, re.VERBOSE)

    filename = suffix_re.sub('', filename)
    if not qtutils.version_check('5.9', compiled=False):
        # https://bugreports.qt.io/browse/QTBUG-58155
        filename = urllib.parse.unquote(filename)
        # Doing basename a *second* time because there could be a %2F in
        # there...
        filename = os.path.basename(filename)
    return filename
Esempio n. 8
0
def _open_special_pages(args):
    """Open special notification pages which are only shown once.

    Args:
        args: The argparse namespace.
    """
    if args.basedir is not None:
        # With --basedir given, don't open anything.
        return

    general_sect = configfiles.state['general']
    tabbed_browser = objreg.get('tabbed-browser',
                                scope='window',
                                window='last-focused')

    pages = [
        # state, condition, URL
        ('quickstart-done', True,
         'https://www.glimpsebrowser.org/quickstart.html'),
        ('config-migration-shown',
         os.path.exists(
             os.path.join(standarddir.config(), 'glimpsebrowser.conf')),
         'glimpse://help/configuring.html'),
        ('webkit-warning-shown', objects.backend == usertypes.Backend.QtWebKit,
         'glimpse://warning/webkit'),
        ('old-qt-warning-shown', not qtutils.version_check('5.9'),
         'glimpse://warning/old-qt'),
    ]

    for state, condition, url in pages:
        if general_sect.get(state) != '1' and condition:
            tabbed_browser.tabopen(QUrl(url), background=False)
            general_sect[state] = '1'
def normalize_line(line):
    line = line.rstrip('\n')
    line = re.sub('boundary="-+(=_glimpse|MultipartBoundary)-[0-9a-zA-Z-]+"',
                  'boundary="---=_glimpse-UUID"', line)
    line = re.sub('^-+(=_glimpse|MultipartBoundary)-[0-9a-zA-Z-]+$',
                  '-----=_glimpse-UUID', line)
    line = re.sub(r'localhost:\d{1,5}', 'localhost:(port)', line)
    if line.startswith('Date: '):
        line = 'Date: today'
    if line.startswith('Content-ID: '):
        line = 'Content-ID: 42'

    # Depending on Python's mimetypes module/the system's mime files, .js
    # files could be either identified as x-javascript or just javascript
    line = line.replace('Content-Type: application/x-javascript',
                        'Content-Type: application/javascript')

    # With QtWebKit and newer Werkzeug versions, we also get an encoding
    # specified.
    line = line.replace('javascript; charset=utf-8', 'javascript')

    # Added with Qt 5.11
    if (line.startswith('Snapshot-Content-Location: ') and
            not qtutils.version_check('5.11', compiled=False)):
        line = None

    return line
Esempio n. 10
0
    def _on_renderer_process_terminated(self, tab, status, code):
        """Show an error when a renderer process terminated."""
        if status == browsertab.TerminationStatus.normal:
            return

        messages = {
            browsertab.TerminationStatus.abnormal:
            "Renderer process exited with status {}".format(code),
            browsertab.TerminationStatus.crashed:
            "Renderer process crashed",
            browsertab.TerminationStatus.killed:
            "Renderer process was killed",
            browsertab.TerminationStatus.unknown:
            "Renderer process did not start",
        }
        msg = messages[status]

        def show_error_page(html):
            tab.set_html(html)
            log.webview.error(msg)

        if qtutils.version_check('5.9', compiled=False):
            url_string = tab.url(requested=True).toDisplayString()
            error_page = jinja.render(
                'error.html',
                title="Error loading {}".format(url_string),
                url=url_string,
                error=msg)
            QTimer.singleShot(100, lambda: show_error_page(error_page))
        else:
            # WORKAROUND for https://bugreports.qt.io/browse/QTBUG-58698
            message.error(msg)
            self._remove_tab(tab, crashed=True)
            if self.widget.count() == 0:
                self.tabopen(QUrl('about:blank'))
Esempio n. 11
0
    def __init__(self, *, win_id, private, parent=None):
        if private:
            assert not qtutils.is_single_process()
        super().__init__(parent)
        self.widget = tabwidget.TabWidget(win_id, parent=self)
        self._win_id = win_id
        self._tab_insert_idx_left = 0
        self._tab_insert_idx_right = -1
        self.shutting_down = False
        self.widget.tabCloseRequested.connect(self.on_tab_close_requested)
        self.widget.new_tab_requested.connect(self.tabopen)
        self.widget.currentChanged.connect(self._on_current_changed)
        self.cur_fullscreen_requested.connect(self.widget.tabBar().maybe_hide)
        self.widget.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)

        # WORKAROUND for https://bugreports.qt.io/browse/QTBUG-65223
        if qtutils.version_check('5.10', compiled=False):
            self.cur_load_finished.connect(self._leave_modes_on_load)
        else:
            self.cur_load_started.connect(self._leave_modes_on_load)

        # This init is never used, it is immediately thrown away in the next
        # line.
        self._undo_stack = collections.deque()
        self._update_stack_size()
        self._filter = signalfilter.SignalFilter(win_id, self)
        self._now_focused = None
        self.search_text = None
        self.search_options = {}
        self._local_marks = {}
        self._global_marks = {}
        self.default_window_icon = self.widget.window().windowIcon()
        self.is_private = private
        config.instance.changed.connect(self._on_config_changed)
 def init_profile(self):
     """Initialize settings on the given profile."""
     self.set_http_headers()
     self.set_http_cache_size()
     self._set_hardcoded_settings()
     if qtutils.version_check('5.8'):
         self.set_dictionary_language()
Esempio n. 13
0
    def _handle_key_release(self, e):
        """Ignore repeated key release events going to the website.

        WORKAROUND for https://bugreports.qt.io/browse/QTBUG-77208
        """
        return (e.isAutoRepeat() and qtutils.version_check('5.10')
                and objects.backend == usertypes.Backend.QtWebEngine)
Esempio n. 14
0
    def eventFilter(self, obj, event):
        """Act on ChildAdded events."""
        if event.type() == QEvent.ChildAdded:
            child = event.child()
            log.misc.debug("{} got new child {}, installing filter".format(
                obj, child))
            assert obj is self._widget
            child.installEventFilter(self._filter)

            if qtutils.version_check('5.11', compiled=False, exact=True):
                # WORKAROUND for https://bugreports.qt.io/browse/QTBUG-68076
                pass_modes = [
                    usertypes.KeyMode.command, usertypes.KeyMode.prompt,
                    usertypes.KeyMode.yesno
                ]
                if modeman.instance(self._win_id).mode not in pass_modes:
                    tabbed_browser = objreg.get('tabbed-browser',
                                                scope='window',
                                                window=self._win_id)
                    current_index = tabbed_browser.widget.currentIndex()
                    try:
                        widget_index = tabbed_browser.widget.indexOf(
                            self._widget.parent())
                    except RuntimeError:
                        widget_index = -1
                    if current_index == widget_index:
                        QTimer.singleShot(0, self._widget.setFocus)

        elif event.type() == QEvent.ChildRemoved:
            child = event.child()
            log.misc.debug("{}: removed child {}".format(obj, child))

        return False
Esempio n. 15
0
 def _set_cache_size(self):
     """Set the cache size based on the config."""
     size = config.val.content.cache.size
     if size is None:
         size = 1024 * 1024 * 50  # default from QNetworkDiskCachePrivate
     # WORKAROUND for https://bugreports.qt.io/browse/QTBUG-59909
     if not qtutils.version_check('5.9', compiled=False):
         size = 0  # pragma: no cover
     self.setMaximumCacheSize(size)
Esempio n. 16
0
    def expose(self, web_tab):
        """Expose the web view if needed.

        With QtWebEngine 5.13 on macOS/Windows, searching fails (callback
        called with False) when the view isn't exposed.
        """
        if qtutils.version_check('5.13') and not utils.is_linux:
            web_tab.container.expose()
        web_tab.show()
Esempio n. 17
0
def _get_version_tag(tag):
    """Handle tags like pyqt>=5.3.1 for BDD tests.

    This transforms e.g. pyqt>=5.3.1 into an appropriate @pytest.mark.skip
    marker, and falls back to pytest-bdd's implementation for all other
    casesinto an appropriate @pytest.mark.skip marker, and falls back to
    """
    version_re = re.compile(
        r"""
        (?P<package>qt|pyqt)
        (?P<operator>==|>=|!=|<)
        (?P<version>\d+\.\d+(\.\d+)?)
    """, re.VERBOSE)

    match = version_re.fullmatch(tag)
    if not match:
        return None

    package = match.group('package')
    version = match.group('version')

    if package == 'qt':
        op = match.group('operator')
        do_skip = {
            '==':
            not qtutils.version_check(version, exact=True, compiled=False),
            '>=': not qtutils.version_check(version, compiled=False),
            '<': qtutils.version_check(version, compiled=False),
            '!=': qtutils.version_check(version, exact=True, compiled=False),
        }
        return pytest.mark.skipif(do_skip[op], reason='Needs ' + tag)
    elif package == 'pyqt':
        operators = {
            '==': operator.eq,
            '>=': operator.ge,
            '!=': operator.ne,
        }
        op = operators[match.group('operator')]
        major, minor, patch = [int(e) for e in version.split('.')]
        hex_version = (major << 16) | (minor << 8) | patch
        return pytest.mark.skipif(not op(PYQT_VERSION, hex_version),
                                  reason='Needs ' + tag)
    else:
        raise ValueError("Invalid package {!r}".format(package))
Esempio n. 18
0
    def _check_initiator(self, job):
        """Check whether the initiator of the job should be allowed.

        Only the browser itself or glimpse:// pages should access any of those
        URLs. The request interceptor further locks down glimpse://settings/set.

        Args:
            job: QWebEngineUrlRequestJob

        Return:
            True if the initiator is allowed, False if it was blocked.
        """
        try:
            initiator = job.initiator()
            request_url = job.requestUrl()
        except AttributeError:
            # Added in Qt 5.11
            return True

        # https://codereview.qt-project.org/#/c/234849/
        is_opaque = initiator == QUrl('null')
        target = request_url.scheme(), request_url.host()

        if is_opaque and not qtutils.version_check('5.12'):
            # WORKAROUND for https://bugreports.qt.io/browse/QTBUG-70421
            # When we don't register the glimpse:// scheme, all requests are
            # flagged as opaque.
            return True

        if (target == ('glimpse', 'testdata') and is_opaque
                and qtutils.version_check('5.12')):
            # Allow requests to glimpse://testdata, as this is needed in Qt 5.12
            # for all tests to work properly. No glimpse://testdata handler is
            # installed outside of tests.
            return True

        if initiator.isValid() and initiator.scheme() != 'glimpse':
            log.misc.warning("Blocking malicious request from {} to {}".format(
                initiator.toDisplayString(), request_url.toDisplayString()))
            job.fail(QWebEngineUrlRequestJob.RequestDenied)
            return False

        return True
Esempio n. 19
0
def _handle_cache_nuking():
    """Nuke the QtWebEngine cache if the Qt version changed.

    WORKAROUND for https://bugreports.qt.io/browse/QTBUG-72532
    """
    if not configfiles.state.qt_version_changed:
        return

    # Only nuke the cache in cases where we know there are problems.
    # It seems these issues started with Qt 5.12.
    # They should be fixed with Qt 5.12.5:
    # https://codereview.qt-project.org/c/qt/qtwebengine-chromium/+/265408
    affected = (qtutils.version_check('5.12', compiled=False) and not
                qtutils.version_check('5.12.5', compiled=False))
    if not affected:
        return

    log.init.info("Qt version changed, nuking QtWebEngine cache")
    cache_dir = os.path.join(standarddir.cache(), 'webengine')
    if os.path.exists(cache_dir):
        shutil.rmtree(cache_dir)
Esempio n. 20
0
 def javaScriptAlert(self, url, js_msg):
     """Override javaScriptAlert to use glimpsebrowser prompts."""
     if self._is_shutting_down:
         return
     escape_msg = qtutils.version_check('5.11', compiled=False)
     try:
         shared.javascript_alert(
             url,
             js_msg,
             abort_on=[self.loadStarted, self.shutting_down],
             escape_msg=escape_msg)
     except shared.CallSuper:
         super().javaScriptAlert(url, js_msg)
Esempio n. 21
0
def _generate_pdfjs_script(filename):
    """Generate the script that shows the pdf with pdf.js.

    Args:
        filename: The name of the file to open.
    """
    url = QUrl('glimpse://pdfjs/file')
    url_query = QUrlQuery()
    url_query.addQueryItem('filename', filename)
    url.setQuery(url_query)

    return jinja.js_environment.from_string("""
        document.addEventListener("DOMContentLoaded", function() {
          if (typeof window.PDFJS !== 'undefined') {
              // v1.x
              {% if disable_create_object_url %}
              window.PDFJS.disableCreateObjectURL = true;
              {% endif %}
              window.PDFJS.verbosity = window.PDFJS.VERBOSITY_LEVELS.info;
          } else {
              // v2.x
              const options = window.PDFViewerApplicationOptions;
              {% if disable_create_object_url %}
              options.set('disableCreateObjectURL', true);
              {% endif %}
              options.set('verbosity', pdfjsLib.VerbosityLevel.INFOS);
          }

          const viewer = window.PDFView || window.PDFViewerApplication;
          viewer.open({{ url }});
        });
    """).render(
        url=javascript.to_js(url.toString(QUrl.FullyEncoded)),
        # WORKAROUND for https://bugreports.qt.io/browse/QTBUG-70420
        disable_create_object_url=(
            not qtutils.version_check('5.12') and
            not qtutils.version_check('5.7.1', exact=True, compiled=False) and
            objects.backend == usertypes.Backend.QtWebEngine))
Esempio n. 22
0
 def javaScriptPrompt(self, url, js_msg, default):
     """Override javaScriptPrompt to use glimpsebrowser prompts."""
     escape_msg = qtutils.version_check('5.11', compiled=False)
     if self._is_shutting_down:
         return (False, "")
     try:
         return shared.javascript_prompt(
             url,
             js_msg,
             default,
             abort_on=[self.loadStarted, self.shutting_down],
             escape_msg=escape_msg)
     except shared.CallSuper:
         return super().javaScriptPrompt(url, js_msg, default)
Esempio n. 23
0
def ssl_error_page(request, glimpseproc):
    if request.config.webengine and qtutils.version_check('5.9'):
        glimpseproc.wait_for(message="Certificate error: *")
        time.sleep(0.5)  # Wait for error page to appear
        content = glimpseproc.get_content().strip()
        assert ("ERR_INSECURE_RESPONSE" in content or  # Qt <= 5.10
                "ERR_CERT_AUTHORITY_INVALID" in content)  # Qt 5.11
    else:
        if not request.config.webengine:
            line = glimpseproc.wait_for(message='Error while loading *: SSL '
                                     'handshake failed')
            line.expected = True
        glimpseproc.wait_for(message="Changing title for idx * to 'Error "
                          "loading page: *'")
        content = glimpseproc.get_content().strip()
        assert "Unable to load page" in content
Esempio n. 24
0
def _accept_cookie(request):
    """Check whether the given cookie should be accepted."""
    accept = config.val.content.cookies.accept
    if accept == 'all':
        return True
    elif accept in ['no-3rdparty', 'no-unknown-3rdparty']:
        if qtutils.version_check('5.11.3', compiled=False):
            third_party = request.thirdParty
        else:
            # WORKAROUND for https://bugreports.qt.io/browse/QTBUG-71393
            third_party = (request.thirdParty
                           and not request.firstPartyUrl.isEmpty())
        return not third_party
    elif accept == 'never':
        return False
    else:
        raise utils.Unreachable
Esempio n. 25
0
def request_blocked(request, glimpseproc, kind):
    blocking_set_msg = (
        "Blocking malicious request from glimpse://settings/set?* to "
        "glimpse://settings/set?*")
    blocking_csrf_msg = (
        "Blocking malicious request from "
        "http://localhost:*/data/misc/glimpsescheme_csrf.html to "
        "glimpse://settings/set?*")
    blocking_js_msg = (
        "[http://localhost:*/data/misc/glimpsescheme_csrf.html:0] Not allowed to "
        "load local resource: glimpse://settings/set?*")

    webkit_error_invalid = (
        "Error while loading glimpse://settings/set?*: Invalid glimpse://settings "
        "request")
    webkit_error_unsupported = (
        "Error while loading glimpse://settings/set?*: Unsupported request type"
    )

    if request.config.webengine and qtutils.version_check('5.12'):
        # On Qt 5.12, we mark glimpse:// as a local scheme, causing most requests
        # being blocked by Chromium internally (logging to the JS console).
        expected_messages = {
            'img': [blocking_js_msg],
            'link': [blocking_js_msg],
            'redirect': [blocking_set_msg],
            'form': [blocking_js_msg],
        }
    elif request.config.webengine:
        expected_messages = {
            'img': [blocking_csrf_msg],
            'link': [blocking_set_msg],
            'redirect': [blocking_set_msg],
            'form': [blocking_set_msg],
        }
    else:  # QtWebKit
        expected_messages = {
            'img': [blocking_csrf_msg],
            'link': [blocking_csrf_msg, webkit_error_invalid],
            'redirect': [blocking_csrf_msg, webkit_error_invalid],
            'form': [webkit_error_unsupported],
        }

    for pattern in expected_messages[kind]:
        msg = glimpseproc.wait_for(message=pattern)
        msg.expected = True
Esempio n. 26
0
    def wait_for_load_finished_url(self,
                                   url,
                                   *,
                                   timeout=None,
                                   load_status='success',
                                   after=None):
        """Wait until a URL has finished loading."""
        __tracebackhide__ = (
            lambda e: e.errisinstance(testprocess.WaitForTimeout))

        if timeout is None:
            if 'CI' in os.environ:
                timeout = 15000
            else:
                timeout = 5000

        qurl = QUrl(url)
        if not qurl.isValid():
            raise ValueError("Invalid URL {}: {}".format(
                url, qurl.errorString()))

        if (qurl == QUrl('about:blank')
                and not qtutils.version_check('5.10', compiled=False)):
            # For some reason, we don't get a LoadStatus.success for
            # about:blank sometimes.
            # However, if we do this for Qt 5.10, we get general testsuite
            # instability as site loads get reported with about:blank...
            pattern = "Changing title for idx * to 'about:blank'"
        else:
            # We really need the same representation that the webview uses in
            # its __repr__
            url = utils.elide(qurl.toDisplayString(QUrl.EncodeUnicode), 100)
            assert url

            pattern = re.compile(
                r"(load status for <glimpsebrowser\.browser\..* "
                r"tab_id=\d+ url='{url}/?'>: LoadStatus\.{load_status}|fetch: "
                r"PyQt5\.QtCore\.QUrl\('{url}'\) -> .*)".format(
                    load_status=re.escape(load_status), url=re.escape(url)))

        try:
            self.wait_for(message=pattern, timeout=timeout, after=after)
        except testprocess.WaitForTimeout:
            raise testprocess.WaitForTimeout("Timed out while waiting for {} "
                                             "to be loaded".format(url))
Esempio n. 27
0
    def _is_ready(self, what):
        """Called by _parse_line if loading/focusing is done.

        When both are done, emits the 'ready' signal.
        """
        if what == 'load':
            self._load_ready = True
        elif what == 'focus':
            self._focus_ready = True
        else:
            raise ValueError("Invalid value {!r} for 'what'.".format(what))

        is_qt_5_12 = qtutils.version_check('5.12', compiled=False)
        if ((self._load_ready and self._focus_ready)
                or (self._load_ready and is_qt_5_12)):
            self._load_ready = False
            self._focus_ready = False
            self.ready.emit()
Esempio n. 28
0
    def __init__(self, *, tabdata, win_id, private, parent=None):
        super().__init__(parent)
        self._win_id = win_id
        self._tabdata = tabdata

        theme_color = self.style().standardPalette().color(QPalette.Base)
        if private:
            assert webenginesettings.private_profile is not None
            profile = webenginesettings.private_profile
            assert profile.isOffTheRecord()
        else:
            profile = webenginesettings.default_profile
        page = WebEnginePage(theme_color=theme_color,
                             profile=profile,
                             parent=self)
        self.setPage(page)

        if qtutils.version_check('5.11', compiled=False):
            # Set a PseudoLayout as a WORKAROUND for
            # https://bugreports.qt.io/browse/QTBUG-68224
            # and other related issues.
            sip.delete(self.layout())
            self._layout = miscwidgets.PseudoLayout(self)
def _update_settings(option):
    """Update global settings when qwebsettings changed."""
    global_settings.update_setting(option)

    if option in [
            'content.headers.user_agent', 'content.headers.accept_language'
    ]:
        default_profile.setter.set_http_headers()
        if private_profile:
            private_profile.setter.set_http_headers()
    elif option == 'content.cache.size':
        default_profile.setter.set_http_cache_size()
        if private_profile:
            private_profile.setter.set_http_cache_size()
    elif (option == 'content.cookies.store' and
          # https://bugreports.qt.io/browse/QTBUG-58650
          qtutils.version_check('5.9', compiled=False)):
        default_profile.setter.set_persistent_cookie_policy()
        # We're not touching the private profile's cookie policy.
    elif option == 'spellcheck.languages':
        default_profile.setter.set_dictionary_language()
        if private_profile:
            private_profile.setter.set_dictionary_language(warn=False)
Esempio n. 30
0
def test_version_check(monkeypatch, qversion, compiled, pyqt, version, exact,
                       expected):
    """Test for version_check().

    Args:
        monkeypatch: The pytest monkeypatch fixture.
        qversion: The version to set as fake qVersion().
        compiled: The value for QT_VERSION_STR (set compiled=False)
        pyqt: The value for PYQT_VERSION_STR (set compiled=False)
        version: The version to compare with.
        exact: Use exact comparing (==)
        expected: The expected result.
    """
    monkeypatch.setattr(qtutils, 'qVersion', lambda: qversion)
    if compiled is not None:
        monkeypatch.setattr(qtutils, 'QT_VERSION_STR', compiled)
        monkeypatch.setattr(qtutils, 'PYQT_VERSION_STR', pyqt)
        compiled_arg = True
    else:
        compiled_arg = False

    actual = qtutils.version_check(version, exact, compiled=compiled_arg)
    assert actual == expected