diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2019-07-24 10:40:08 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2019-07-24 11:52:40 +0200 |
commit | ebafa45d80963fad7a8fb81e69fc7733d06b73d2 (patch) | |
tree | c9beec83e2454bc7d001bdc116620b3cc323d7a4 | |
parent | 57363264cd0ff4b2f45f5344e18436fe419e2e95 (diff) | |
parent | 5dd44f34a58b966ddc374d828b1979b9c689b1b5 (diff) |
Merge "Merge remote-tracking branch 'origin/5.13' into dev"
24 files changed, 217 insertions, 73 deletions
diff --git a/mkspecs/features/configure.prf b/mkspecs/features/configure.prf index b8d9d43ce..cc84182b7 100644 --- a/mkspecs/features/configure.prf +++ b/mkspecs/features/configure.prf @@ -94,13 +94,9 @@ defineTest(runConfigure) { } } - !qtConfig(webengine-embedded-build): qtConfig(xcb) { - for(package, $$list("libdrm xcomposite xcursor xi xtst")) { - !qtConfig(webengine-system-$$package) { - skipBuild("A suitable version of $$package could not be found.") - return(false) - } - } + !qtConfig(webengine-embedded-build): qtConfig(xcb) : !qtConfig(webengine-ozone-x11) { + skipBuild("Could not find all necessary libraries for qpa-xcb support") + return(false) } } } diff --git a/mkspecs/features/functions.prf b/mkspecs/features/functions.prf index 9efa8958f..d3eda85b2 100644 --- a/mkspecs/features/functions.prf +++ b/mkspecs/features/functions.prf @@ -121,11 +121,3 @@ defineReplace(pkgConfigHostExecutable) { return($$system_quote($$system_path($$wrapper_name))) } -defineTest(hasX11Dependencies) { - for(package, $$list("libdrm xcomposite xcursor xi xtst")) { - !qtConfig(webengine-system-$$package) { - return(false) - } - } - return(true) -} diff --git a/src/core/api/qtwebenginecoreglobal.cpp b/src/core/api/qtwebenginecoreglobal.cpp index abc2bd406..0fddacb15 100644 --- a/src/core/api/qtwebenginecoreglobal.cpp +++ b/src/core/api/qtwebenginecoreglobal.cpp @@ -80,6 +80,8 @@ static QOpenGLContext *shareContext; static void deleteShareContext() { + if (qt_gl_global_share_context() == shareContext) + qt_gl_set_global_share_context(nullptr); delete shareContext; shareContext = 0; } diff --git a/src/core/config/common.pri b/src/core/config/common.pri index dea904ef8..edebdb33c 100644 --- a/src/core/config/common.pri +++ b/src/core/config/common.pri @@ -127,3 +127,7 @@ qtConfig(webengine-kerberos) { } else { gn_args += use_kerberos=false } + +ccache { + gn_args += cc_wrapper=\"ccache\" +} diff --git a/src/core/config/linux.pri b/src/core/config/linux.pri index 40bc0b73c..998aedc40 100644 --- a/src/core/config/linux.pri +++ b/src/core/config/linux.pri @@ -180,7 +180,7 @@ host_build { } !packagesExist(libpci): gn_args += use_libpci=false - qtConfig(webengine-system-x11): hasX11Dependencies() { + qtConfig(webengine-ozone-x11) { gn_args += ozone_platform_x11=true packagesExist(xscrnsaver): gn_args += use_xscrnsaver=true } diff --git a/src/core/configure.json b/src/core/configure.json index 98eee347f..66e39ddc2 100644 --- a/src/core/configure.json +++ b/src/core/configure.json @@ -11,6 +11,7 @@ "options": { "webengine-alsa": "boolean", "webengine-embedded-build": "boolean", + "webengine-full-debug-info": "boolean", "webengine-icu": { "type": "enum", "name": "webengine-system-icu", "values": { "system": "yes", "qt": "no" } }, "webengine-ffmpeg": { "type": "enum", "name": "webengine-system-ffmpeg", "values": { "system": "yes", "qt": "no" } }, "webengine-opus": { "type": "enum", "name": "webengine-system-opus", "values": { "system": "yes", "qt": "no" } }, @@ -650,6 +651,17 @@ "condition": "config.unix && libs.webengine-x11", "output": [ "privateFeature" ] }, + "webengine-ozone-x11" : { + "label": "Support qpa-xcb", + "condition": "config.unix + && features.webengine-system-x11 + && features.webengine-system-libdrm + && features.webengine-system-xcomposite + && features.webengine-system-xcursor + && features.webengine-system-xi + && features.webengine-system-xtst", + "output": [ "privateFeature" ] + }, "webengine-sanitizer" : { "label": "Sanitizer", "autoDetect": "config.sanitizer && tests.webengine-sanitizer", @@ -685,6 +697,16 @@ "section": "WebEngine", "output": [ "privateFeature" ] }, + "webengine-full-debug-info": { + "label": "Full debug information", + "purpose": "Enables debug information for Blink and V8.", + "autoDetect": false, + "condition": "config.debug || features.debug_and_release || features.force_debug_info", + "output": [ + { "type": "privateConfig", "name": "v8base_debug" }, + { "type": "privateConfig", "name": "webcore_debug" } + ] + }, "webengine-noexecstack": { "label": "linker supports -z noexecstack", "condition": "config.unix && tests.webengine-noexecstack", @@ -742,6 +764,7 @@ "webengine-widgets", "webengine-qml", "webengine-embedded-build", + "webengine-full-debug-info", "webengine-pepper-plugins", "webengine-printing-and-pdf", "webengine-proprietary-codecs", @@ -756,6 +779,11 @@ "webengine-extensions", { "type": "feature", + "args": "webengine-ozone-x11", + "condition": "config.unix" + }, + { + "type": "feature", "args": "webengine-v8-snapshot-support", "condition": "config.unix && config.cross_compile && features.webengine-v8-snapshot" }, @@ -826,8 +854,7 @@ "webengine-system-png", "webengine-system-jpeg", "webengine-system-harfbuzz", - "webengine-system-freetype", - "webengine-system-x11" + "webengine-system-freetype" ] }, { @@ -845,6 +872,7 @@ "section": "Required system libraries for qpa-xcb", "condition": "config.unix && !config.macos", "entries": [ + "webengine-system-x11", "webengine-system-libdrm", "webengine-system-xcomposite", "webengine-system-xcursor", diff --git a/src/core/core_chromium.pri b/src/core/core_chromium.pri index f99513adf..908387788 100644 --- a/src/core/core_chromium.pri +++ b/src/core/core_chromium.pri @@ -246,7 +246,7 @@ HEADERS = \ web_engine_settings.h \ web_event_factory.h -qtConfig(webengine-system-x11): hasX11Dependencies() { +qtConfig(webengine-ozone-x11) { HEADERS += ozone/gl_ozone_glx_qt.h \ ozone/gl_surface_glx_qt.h SOURCES += ozone/gl_surface_glx_qt.cpp \ diff --git a/src/core/core_module.pro b/src/core/core_module.pro index 02aa6ac38..b220af4a5 100644 --- a/src/core/core_module.pro +++ b/src/core/core_module.pro @@ -42,11 +42,15 @@ LIBS_PRIVATE += $$NINJA_LIB_DIRS $$NINJA_LIBS unix:qtConfig(webengine-noexecstack): \ QMAKE_LFLAGS += -Wl,-z,noexecstack linux { - QMAKE_LFLAGS += -Wl,--gc-sections -Wl,-O1 -Wl,-z,now - # Embedded address sanitizer symbols are undefined and are picked up by the dynamic link loader - # at runtime. Thus we do not to pass the linker flag below, because the linker would complain - # about the undefined sanitizer symbols. - !sanitizer: QMAKE_LFLAGS += -Wl,-z,defs + # add chromium flags + for(flag, NINJA_LFLAGS) { + # filter out some flags + !contains(flag, .*noexecstack$): \ + !contains(flag, .*as-needed$): \ + !contains(flag, ^-B.*): \ + !contains(flag, ^-fuse-ld.*): \ + QMAKE_LFLAGS += $$flag + } } else { QMAKE_LFLAGS += $$NINJA_LFLAGS } diff --git a/src/core/net/qrc_url_scheme_handler.cpp b/src/core/net/qrc_url_scheme_handler.cpp index 74a77a7ec..73bf24f1d 100644 --- a/src/core/net/qrc_url_scheme_handler.cpp +++ b/src/core/net/qrc_url_scheme_handler.cpp @@ -59,6 +59,11 @@ void QrcUrlSchemeHandler::requestStarted(QWebEngineUrlRequestJob *job) QUrl requestUrl = job->requestUrl(); QString requestPath = requestUrl.path(); QScopedPointer<QFile> file(new QFile(':' + requestPath, job)); + if (!file->exists() || file->size() == 0) { + qWarning("QResource '%s' not found or is empty", qUtf8Printable(requestPath)); + job->fail(QWebEngineUrlRequestJob::UrlNotFound); + return; + } QFileInfo fileInfo(*file); QMimeDatabase mimeDatabase; QMimeType mimeType = mimeDatabase.mimeTypeForFile(fileInfo); diff --git a/src/core/render_widget_host_view_qt.cpp b/src/core/render_widget_host_view_qt.cpp index a5ae0a04a..0242506ee 100644 --- a/src/core/render_widget_host_view_qt.cpp +++ b/src/core/render_widget_host_view_qt.cpp @@ -238,7 +238,10 @@ public: float GetHistoricalTouchMajor(size_t pointer_index, size_t historical_index) const override { return 0; } float GetHistoricalX(size_t pointer_index, size_t historical_index) const override { return 0; } float GetHistoricalY(size_t pointer_index, size_t historical_index) const override { return 0; } - ToolType GetToolType(size_t pointer_index) const override { return ui::MotionEvent::ToolType::FINGER; } + ToolType GetToolType(size_t pointer_index) const override { + return (touchPoints.at(pointer_index).flags() & QTouchEvent::TouchPoint::InfoFlag::Pen) ? ui::MotionEvent::ToolType::STYLUS + : ui::MotionEvent::ToolType::FINGER; + } int GetButtonState() const override { return 0; } private: diff --git a/src/core/web_contents_adapter.cpp b/src/core/web_contents_adapter.cpp index 2295d33c0..ee0b8cc39 100644 --- a/src/core/web_contents_adapter.cpp +++ b/src/core/web_contents_adapter.cpp @@ -693,19 +693,23 @@ void WebContentsAdapter::load(const QWebEngineHttpRequest &request) } } - auto navigate = [](WebContentsAdapter *adapter, const content::NavigationController::LoadURLParams ¶ms) { + auto navigate = [](QWeakPointer<WebContentsAdapter> weakAdapter, const content::NavigationController::LoadURLParams ¶ms) { + WebContentsAdapter *adapter = weakAdapter.data(); + if (!adapter) + return; adapter->webContents()->GetController().LoadURLWithParams(params); // Follow chrome::Navigate and invalidate the URL immediately. adapter->m_webContentsDelegate->NavigationStateChanged(adapter->webContents(), content::INVALIDATE_TYPE_URL); adapter->focusIfNecessary(); }; + QWeakPointer<WebContentsAdapter> weakThis(sharedFromThis()); if (resizeNeeded) { // Schedule navigation on the event loop. base::PostTaskWithTraits(FROM_HERE, {content::BrowserThread::UI}, - base::BindOnce(navigate, this, std::move(params))); + base::BindOnce(navigate, std::move(weakThis), std::move(params))); } else { - navigate(this, params); + navigate(std::move(weakThis), params); } } @@ -1051,6 +1055,7 @@ quint64 WebContentsAdapter::findText(const QString &subString, bool caseSensitiv // waiting for it forever. // Assume that any unfinished find has been unsuccessful when a new one is started // to cover that case. + m_webContentsDelegate->setLastReceivedFindReply(m_lastFindRequestId); m_adapterClient->didFindText(m_lastFindRequestId, 0); } @@ -1071,6 +1076,7 @@ quint64 WebContentsAdapter::findText(const QString &subString, bool caseSensitiv void WebContentsAdapter::stopFinding() { CHECK_INITIALIZED(); + m_webContentsDelegate->setLastReceivedFindReply(m_lastFindRequestId); m_webContentsDelegate->setLastSearchedString(QString()); m_webContents->StopFinding(content::STOP_FIND_ACTION_KEEP_SELECTION); } diff --git a/src/core/web_contents_delegate_qt.cpp b/src/core/web_contents_delegate_qt.cpp index 93f441636..f18617f8e 100644 --- a/src/core/web_contents_delegate_qt.cpp +++ b/src/core/web_contents_delegate_qt.cpp @@ -234,6 +234,11 @@ void WebContentsDelegateQt::AddNewContents(content::WebContents* source, std::un { Q_UNUSED(source) QSharedPointer<WebContentsAdapter> newAdapter = createWindow(std::move(new_contents), disposition, initial_pos, user_gesture); + // Chromium can forget to pass user-agent override settings to new windows (see QTBUG-61774 and QTBUG-76249), + // so set it here. Note the actual value doesn't really matter here. Only the second value does, but we try + // to give the correct user-agent anyway. + if (newAdapter) + newAdapter->webContents()->SetUserAgentOverride(newAdapter->profileAdapter()->httpUserAgent().toStdString(), true); if (newAdapter && !newAdapter->isInitialized()) newAdapter->loadDefault(); if (was_blocked) @@ -575,7 +580,7 @@ void WebContentsDelegateQt::FindReply(content::WebContents *source, int request_ Q_UNUSED(source) Q_UNUSED(selection_rect) Q_UNUSED(active_match_ordinal) - if (final_update) { + if (final_update && request_id > m_lastReceivedFindReply) { m_lastReceivedFindReply = request_id; m_viewClient->didFindText(request_id, number_of_matches); } diff --git a/src/core/web_contents_delegate_qt.h b/src/core/web_contents_delegate_qt.h index 11b35c549..00b715c30 100644 --- a/src/core/web_contents_delegate_qt.h +++ b/src/core/web_contents_delegate_qt.h @@ -115,6 +115,7 @@ public: QString lastSearchedString() const { return m_lastSearchedString; } void setLastSearchedString(const QString &s) { m_lastSearchedString = s; } int lastReceivedFindReply() const { return m_lastReceivedFindReply; } + void setLastReceivedFindReply(int id) { m_lastReceivedFindReply = id; } QUrl url() const { return m_url; } QString title() const { return m_title; } diff --git a/src/webengine/doc/qtwebengine.qdocconf b/src/webengine/doc/qtwebengine.qdocconf index d84e41c5a..be5db9c19 100644 --- a/src/webengine/doc/qtwebengine.qdocconf +++ b/src/webengine/doc/qtwebengine.qdocconf @@ -61,12 +61,14 @@ depends += qtcore \ qtwidgets headerdirs += .. \ - ../../core \ - ../../webenginewidgets + ../../core/api \ + ../../webenginewidgets/api sourcedirs += .. \ - ../../core/ \ - ../../webenginewidgets \ + ../../core/api \ + ../../core/doc \ + ../../webenginewidgets/api \ + ../../webenginewidgets/doc exampledirs += . \ ../../../examples \ @@ -85,4 +87,4 @@ navigation.qmltypespage = "Qt WebEngine QML Types" # \QWE macro expands to 'Qt WebEngine' without auto-linking anywhere. macro.QWE = "Qt \\WebEngine" -Cpp.ignoretokens += Q_WEBENGINE_EXPORT QWEBENGINEWIDGETS_EXPORT +Cpp.ignoretokens += Q_WEBENGINE_EXPORT Q_WEBENGINECORE_EXPORT QWEBENGINEWIDGETS_EXPORT diff --git a/src/webengine/doc/src/qtwebengine-platform-notes.qdoc b/src/webengine/doc/src/qtwebengine-platform-notes.qdoc index fefb47795..5b7d750ff 100644 --- a/src/webengine/doc/src/qtwebengine-platform-notes.qdoc +++ b/src/webengine/doc/src/qtwebengine-platform-notes.qdoc @@ -69,7 +69,12 @@ \section2 Windows - On Windows, Visual Studio 2017 and Windows 10 SDK are required. + On Windows, the following additional tools are required: + + \list + \li Visual Studio 2017 version 15.8 or later + \li Windows 10 SDK + \endlist \QWE can only be built on 64-bit Windows, with a x64-bit toolchain. For building \QWE for x86 applications, you need to configure diff --git a/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp b/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp index 85c5c89f4..894dca4fa 100644 --- a/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp +++ b/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp @@ -77,14 +77,6 @@ protected: { m_client->forwardEvent(event); } - void keyPressEvent(QKeyEvent *event) override - { - m_client->forwardEvent(event); - } - void keyReleaseEvent(QKeyEvent *event) override - { - m_client->forwardEvent(event); - } void inputMethodEvent(QInputMethodEvent *event) override { m_client->forwardEvent(event); @@ -473,7 +465,7 @@ bool RenderWidgetHostViewQtDelegateWidget::event(QEvent *event) // where we can simply ignore the DblClick event. QMouseEvent *dblClick = static_cast<QMouseEvent *>(event); QMouseEvent press(QEvent::MouseButtonPress, dblClick->localPos(), dblClick->windowPos(), dblClick->screenPos(), - dblClick->button(), dblClick->buttons(), dblClick->modifiers()); + dblClick->button(), dblClick->buttons(), dblClick->modifiers(), dblClick->source()); press.setTimestamp(dblClick->timestamp()); handled = m_client->forwardEvent(&press); } else @@ -481,6 +473,8 @@ bool RenderWidgetHostViewQtDelegateWidget::event(QEvent *event) if (!handled) return QQuickWidget::event(event); + // Most events are accepted by default, but tablet events are not: + event->accept(); return true; } diff --git a/tests/auto/quick/dialogs/WebView.qml b/tests/auto/quick/dialogs/WebView.qml index 4f8b7a0ce..01f4ac297 100644 --- a/tests/auto/quick/dialogs/WebView.qml +++ b/tests/auto/quick/dialogs/WebView.qml @@ -56,11 +56,12 @@ Window { WebEngineView { id: view anchors.fill: parent - onLoadingChanged: function(reqeust) { - if (reqeust.status === WebEngineView.LoadSucceededStatus) { + onLoadingChanged: function(request) { + if (request.status === WebEngineView.LoadSucceededStatus) { handler.ready = true - } else { - console.log("Wooohooo loading page from qrc failed !") + } else if (request.status === WebEngineView.LoadFailedStatus) { + console.log("Page was not successfully loaded from qrc! Status: " + request.status + + ", error [code: " + request.errorCode + "]: '" + request.errorString + "'") } } diff --git a/tests/auto/quick/inspectorserver/tst_inspectorserver.cpp b/tests/auto/quick/inspectorserver/tst_inspectorserver.cpp index 8e23e86e8..922c7769e 100644 --- a/tests/auto/quick/inspectorserver/tst_inspectorserver.cpp +++ b/tests/auto/quick/inspectorserver/tst_inspectorserver.cpp @@ -167,7 +167,7 @@ void tst_InspectorServer::openRemoteDebuggingSession() // - The page list didn't return a valid inspector URL // - Or the front-end couldn't be loaded through the inspector HTTP server // - Or the web socket connection couldn't be established between the front-end and the page through the inspector server - QTRY_VERIFY(inspectorWebView->title().startsWith("DevTools -")); + QTRY_VERIFY_WITH_TIMEOUT(inspectorWebView->title().startsWith("DevTools -"), 20000); } QTEST_MAIN(tst_InspectorServer) diff --git a/tests/auto/quick/qmltests/BLACKLIST b/tests/auto/quick/qmltests/BLACKLIST index 0a71e9f27..46bc65923 100644 --- a/tests/auto/quick/qmltests/BLACKLIST +++ b/tests/auto/quick/qmltests/BLACKLIST @@ -1,7 +1,2 @@ -[WebViewFindText::test_findTextInterruptedByLoad] -linux -qemu -b2qt -windows [WebEngineViewSource::test_viewSourceURL] * diff --git a/tests/auto/quick/qmltests/data/tst_findText.qml b/tests/auto/quick/qmltests/data/tst_findText.qml index 1ec574fae..14053a675 100644 --- a/tests/auto/quick/qmltests/data/tst_findText.qml +++ b/tests/auto/quick/qmltests/data/tst_findText.qml @@ -43,13 +43,21 @@ TestWebEngineView { matchCount = -1 } + function findCallbackCalled() { return matchCount != -1 } + function findTextCallback(matchCount) { + // If this starts to fail then either clear was not called before findText + // or unexpected callback was triggered from some search. + // On c++ side callback id can be checked to verify + testcase.verify(!findCallbackCalled(), 'Unexpected callback call or uncleared state before findText call!') + webEngineView.matchCount = matchCount findFailed = matchCount == 0 } TestCase { + id: testcase name: "WebViewFindText" function getBodyInnerHTML() { @@ -207,13 +215,17 @@ TestWebEngineView { webEngineView.findText("hello", findFlags, webEngineView.findTextCallback); // This should not crash. - webEngineView.url = "https://www.qt.io"; - if (!webEngineView.waitForLoadSucceeded(12000)) - skip("Couldn't load page from network, skipping test."); + webEngineView.loadHtml("<html><body>New page with same hello text</body></html>") + verify(webEngineView.waitForLoadSucceeded()) // The callback is not supposed to be called, see QTBUG-61506. - // Check whether the callback was called (-1 = no, other values = yes). - tryVerify(function() { return webEngineView.matchCount == -1; }, 20000); + expectFailContinue('', 'No unexpected findText callback calls occurred.') + tryVerify(function() { return webEngineView.findCallbackCalled() }) + verify(!webEngineView.findCallbackCalled()) + + webEngineView.clear(); + webEngineView.findText('New page', findFlags, webEngineView.findTextCallback) + tryCompare(webEngineView, 'matchCount', 1) } } } diff --git a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp index 8fb7e05ca..713feca6d 100644 --- a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp +++ b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp @@ -220,6 +220,8 @@ private Q_SLOTS: void editActionsWithFocusOnIframe(); void editActionsWithoutSelection(); + void customUserAgentInNewTab(); + private: static QPoint elementCenter(QWebEnginePage *page, const QString &id); @@ -932,6 +934,7 @@ void tst_QWebEnginePage::findText() QTRY_COMPARE(loadSpy.count(), 1); // Select whole page contents. + QTRY_VERIFY(m_view->page()->action(QWebEnginePage::SelectAll)->isEnabled()); m_view->page()->triggerAction(QWebEnginePage::SelectAll); QTRY_COMPARE(m_view->hasSelection(), true); @@ -4183,6 +4186,69 @@ void tst_QWebEnginePage::editActionsWithoutSelection() QVERIFY(page->action(QWebEnginePage::Unselect)->isEnabled()); } +void tst_QWebEnginePage::customUserAgentInNewTab() +{ + HttpServer server; + QByteArray lastUserAgent; + connect(&server, &HttpServer::newRequest, [&](HttpReqRep *rr) { + QCOMPARE(rr->requestMethod(), "GET"); + lastUserAgent = rr->requestHeader("user-agent"); + rr->setResponseBody(QByteArrayLiteral("<html><body>Test</body></html>")); + rr->sendResponse(); + }); + QVERIFY(server.start()); + + class Page : public QWebEnginePage { + public: + QWebEngineProfile *targetProfile = nullptr; + QScopedPointer<QWebEnginePage> newPage; + Page(QWebEngineProfile *profile) : QWebEnginePage(profile) {} + private: + QWebEnginePage *createWindow(WebWindowType) override + { + newPage.reset(new QWebEnginePage(targetProfile ? targetProfile : profile(), nullptr)); + return newPage.data(); + } + }; + QWebEngineProfile profile1, profile2; + profile1.setHttpUserAgent(QStringLiteral("custom 1")); + profile2.setHttpUserAgent(QStringLiteral("custom 2")); + Page page(&profile1); + QWebEngineView view; + view.resize(500, 500); + view.setPage(&page); + view.show(); + QVERIFY(QTest::qWaitForWindowExposed(&view)); + QSignalSpy spy(&page, &QWebEnginePage::loadFinished); + + // First check we can get the user-agent passed through normally + page.setHtml(QString("<html><body><a id='link' target='_blank' href='") + + server.url("/test1").toEncoded() + + QString("'>link</a></body></html>")); + QTRY_COMPARE(spy.count(), 1); + QVERIFY(spy.takeFirst().value(0).toBool()); + QCOMPARE(evaluateJavaScriptSync(&page, QStringLiteral("navigator.userAgent")).toString(), profile1.httpUserAgent()); + QTest::mouseClick(view.focusProxy(), Qt::LeftButton, 0, elementCenter(&page, "link")); + QTRY_VERIFY(page.newPage); + QTRY_VERIFY(!lastUserAgent.isEmpty()); + QCOMPARE(lastUserAgent, profile1.httpUserAgent().toUtf8()); + + // Now check we can get the new user-agent of the profile + page.newPage.reset(); + page.targetProfile = &profile2; + spy.clear(); + lastUserAgent = { }; + page.setHtml(QString("<html><body><a id='link' target='_blank' href='") + + server.url("/test2").toEncoded() + + QString("'>link</a></body></html>")); + QTRY_COMPARE(spy.count(), 1); + QVERIFY(spy.takeFirst().value(0).toBool()); + QTest::mouseClick(view.focusProxy(), Qt::LeftButton, 0, elementCenter(&page, "link")); + QTRY_VERIFY(page.newPage); + QTRY_VERIFY(!lastUserAgent.isEmpty()); + QCOMPARE(lastUserAgent, profile2.httpUserAgent().toUtf8()); +} + static QByteArrayList params = {QByteArrayLiteral("--use-fake-device-for-media-stream")}; W_QTEST_MAIN(tst_QWebEnginePage, params) diff --git a/tests/auto/widgets/qwebengineview/BLACKLIST b/tests/auto/widgets/qwebengineview/BLACKLIST index 615400417..9087067f5 100644 --- a/tests/auto/widgets/qwebengineview/BLACKLIST +++ b/tests/auto/widgets/qwebengineview/BLACKLIST @@ -3,7 +3,3 @@ osx [textSelectionOutOfInputField] * - -[inputContextQueryInput] -osx -windows diff --git a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp index b75fc459d..fa179f2f8 100644 --- a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp +++ b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp @@ -1894,7 +1894,7 @@ void tst_QWebEngineView::inputContextQueryInput() QApplication::sendEvent(view.focusProxy(), &event); } QTRY_COMPARE(testContext.infos.count(), 2); - QCOMPARE(selectionChangedSpy.count(), 1); + QTRY_COMPARE(selectionChangedSpy.count(), 1); // As a first step, Chromium moves the cursor to the start of the selection. // We don't filter this in QtWebEngine because we don't know yet if this is part of a selection. @@ -1920,7 +1920,7 @@ void tst_QWebEngineView::inputContextQueryInput() QApplication::sendEvent(view.focusProxy(), &event); } QTRY_COMPARE(testContext.infos.count(), 1); - QCOMPARE(selectionChangedSpy.count(), 1); + QTRY_COMPARE(selectionChangedSpy.count(), 1); QCOMPARE(testContext.infos[0].cursorPosition, 0); QCOMPARE(testContext.infos[0].anchorPosition, 0); QCOMPARE(testContext.infos[0].surroundingText, QStringLiteral("QtWebEngine!")); diff --git a/tests/auto/widgets/spellchecking/tst_spellchecking.cpp b/tests/auto/widgets/spellchecking/tst_spellchecking.cpp index a9123ec15..64df05d89 100644 --- a/tests/auto/widgets/spellchecking/tst_spellchecking.cpp +++ b/tests/auto/widgets/spellchecking/tst_spellchecking.cpp @@ -187,14 +187,41 @@ void tst_Spellchecking::spellcheck() QString result = evaluateJavaScriptSync(m_view->page(), "text();").toString(); QVERIFY(result == text); - // open menu on misspelled word - m_view->activateMenu(m_view->focusWidget(), rect.center()); - QSignalSpy spyMenuReady(m_view, &WebView::menuReady); - QVERIFY(spyMenuReady.wait()); - - // check if menu is valid - QVERIFY(m_view->data().isValid()); - QVERIFY(m_view->data().isContentEditable()); + bool gotMisspelledWord = false; // clumsy QTRY_VERIFY still execs expr after first success + QString detail; + + // check that spellchecker has done text processing and filled misspelled word + QTRY_VERIFY2([&] () { + detail.clear(); + if (gotMisspelledWord) + return true; + + // open menu on misspelled word + m_view->activateMenu(m_view->focusWidget(), rect.center()); + QSignalSpy spyMenuReady(m_view, &WebView::menuReady); + if (!spyMenuReady.wait()) { + detail = "menu was not shown"; + return false; + } + + if (!m_view->data().isValid()) { + detail = "invalid data"; + return false; + } + + if (!m_view->data().isContentEditable()) { + detail = "content is not editable"; + return false; + } + + if (m_view->data().misspelledWord().isEmpty()) { + detail = "no misspelled word"; + return false; + }; + + gotMisspelledWord = true; + return true; + } (), qPrintable(QString("Context menu: %1").arg(detail))); // check misspelled word QCOMPARE(m_view->data().misspelledWord(), QStringLiteral("lowe")); |