summaryrefslogtreecommitdiffstats
path: root/tests/auto/widgets/qwebenginepage
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/widgets/qwebenginepage')
-rw-r--r--tests/auto/widgets/qwebenginepage/BLACKLIST2
-rw-r--r--tests/auto/widgets/qwebenginepage/qwebenginepage.pro2
-rw-r--r--tests/auto/widgets/qwebenginepage/resources/basic_printing_page.html8
-rw-r--r--tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp419
-rw-r--r--tests/auto/widgets/qwebenginepage/tst_qwebenginepage.qrc1
5 files changed, 308 insertions, 124 deletions
diff --git a/tests/auto/widgets/qwebenginepage/BLACKLIST b/tests/auto/widgets/qwebenginepage/BLACKLIST
index b376cd375..7470a1523 100644
--- a/tests/auto/widgets/qwebenginepage/BLACKLIST
+++ b/tests/auto/widgets/qwebenginepage/BLACKLIST
@@ -7,8 +7,6 @@
[macCopyUnicodeToClipboard]
osx
-[getUserMediaRequest]
-*
[mouseMovementProperties]
osx-10.11
osx-10.12
diff --git a/tests/auto/widgets/qwebenginepage/qwebenginepage.pro b/tests/auto/widgets/qwebenginepage/qwebenginepage.pro
index e0765736e..47c09e1ce 100644
--- a/tests/auto/widgets/qwebenginepage/qwebenginepage.pro
+++ b/tests/auto/widgets/qwebenginepage/qwebenginepage.pro
@@ -1,4 +1,4 @@
include(../tests.pri)
QT *= core-private
-contains(WEBENGINE_CONFIG, use_pdf): DEFINES+=QWEBENGINEPAGE_PDFPRINTINGENABLED
+qtConfig(webengine-printing-and-pdf): DEFINES+=QWEBENGINEPAGE_PDFPRINTINGENABLED
diff --git a/tests/auto/widgets/qwebenginepage/resources/basic_printing_page.html b/tests/auto/widgets/qwebenginepage/resources/basic_printing_page.html
new file mode 100644
index 000000000..0c6ff379f
--- /dev/null
+++ b/tests/auto/widgets/qwebenginepage/resources/basic_printing_page.html
@@ -0,0 +1,8 @@
+<html>
+<head>
+<title> Basic Printing Page </title>
+</head>
+<body>
+<h1>Hello Paper World</h1>
+</body>
+</html>
diff --git a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
index 182094a11..54cf27066 100644
--- a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
+++ b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
@@ -106,6 +106,7 @@ private Q_SLOTS:
void updatePositionDependentActionsCrash();
void createPluginWithPluginsEnabled();
void createPluginWithPluginsDisabled();
+ void callbackSpyDeleted();
void destroyPlugin_data();
void destroyPlugin();
void createViewlessPlugin_data();
@@ -126,7 +127,10 @@ private Q_SLOTS:
void userAgentNewlineStripping();
void undoActionHaveCustomText();
void renderWidgetHostViewNotShowTopLevel();
+ void getUserMediaRequest_data();
void getUserMediaRequest();
+ void getUserMediaRequestDesktopAudio();
+ void getUserMediaRequestSettingDisabled();
void savePage();
void crashTests_LazyInitializationOfMainFrame();
@@ -182,7 +186,6 @@ private Q_SLOTS:
void baseUrl_data();
void baseUrl();
void scrollPosition();
- void scrollToAnchor();
void scrollbarsOff();
void evaluateWillCauseRepaint();
void setContent_data();
@@ -191,6 +194,8 @@ private Q_SLOTS:
void setUrlWithPendingLoads();
void setUrlToEmpty();
void setUrlToInvalid();
+ void setUrlToBadDomain();
+ void setUrlToBadPort();
void setUrlHistory();
void setUrlUsingStateObject();
void setUrlThenLoads_data();
@@ -251,6 +256,7 @@ void tst_QWebEnginePage::init()
m_view = new QWebEngineView();
m_page = m_view->page();
m_page->settings()->setAttribute(QWebEngineSettings::ErrorPageEnabled, false);
+ m_view->settings()->setAttribute(QWebEngineSettings::FocusOnNavigationEnabled, true);
}
void tst_QWebEnginePage::cleanup()
@@ -308,6 +314,10 @@ void tst_QWebEnginePage::acceptNavigationRequest()
NavigationRequestOverride* newPage = new NavigationRequestOverride(&view, false);
view.setPage(newPage);
+ // acceptNavigationRequest and QWebEngineUrlRequestInterceptor::interceptRequest are not called
+ // for data: urls, which means the test is broken, aka setting
+ // newPage->m_acceptNavigationRequest to false does nothing to stop the page from loading.
+ // See QTBUG-50922 comments.
view.setHtml(QString("<html><body><form name='tstform' action='data:text/html,foo'method='get'>"
"<input type='text'><input type='submit'></form></body></html>"), QUrl());
QTRY_COMPARE(loadSpy.count(), 1);
@@ -442,6 +452,22 @@ static QImage imageWithoutAlpha(const QImage &image)
return result;
}
+void tst_QWebEnginePage::callbackSpyDeleted()
+{
+ QWebEnginePage *page = m_view->page();
+ CallbackSpy<QVariant> spy;
+ QString poorManSleep("function wait(ms){"
+ " var start = new Date().getTime();"
+ " var end = start;"
+ " while (start + ms > end) {"
+ "end = new Date().getTime();"
+ " }"
+ "}"
+ "wait(1000);");
+ page->runJavaScript(poorManSleep, spy.ref());
+ //spy deleted before callback
+}
+
void tst_QWebEnginePage::pasteImage()
{
// Pixels with an alpha value of 0 will have different RGB values after the
@@ -459,7 +485,9 @@ void tst_QWebEnginePage::pasteImage()
"window.myImageDataURL ? window.myImageDataURL.length : 0").toInt() > 0);
QByteArray data = evaluateJavaScriptSync(page, "window.myImageDataURL").toByteArray();
data.remove(0, data.indexOf(";base64,") + 8);
- const QImage image = QImage::fromData(QByteArray::fromBase64(data), "PNG");
+ QImage image = QImage::fromData(QByteArray::fromBase64(data), "PNG");
+ if (image.format() == QImage::Format_RGB32)
+ image.reinterpretAsFormat(QImage::Format_ARGB32);
QCOMPARE(image, origImage);
}
@@ -2114,29 +2142,55 @@ void tst_QWebEnginePage::testStopScheduledPageRefresh()
void tst_QWebEnginePage::findText()
{
- QSignalSpy loadSpy(m_page, SIGNAL(loadFinished(bool)));
- m_page->setHtml(QString("<html><head></head><body><div>foo bar</div></body></html>"));
+ QSignalSpy loadSpy(m_view, SIGNAL(loadFinished(bool)));
+ m_view->setHtml(QString("<html><head></head><body><div>foo bar</div></body></html>"));
+
+ // Showing is required, otherwise all find operations fail.
+ m_view->show();
QTRY_COMPARE(loadSpy.count(), 1);
// Select whole page contents.
- m_page->triggerAction(QWebEnginePage::SelectAll);
- QTRY_COMPARE(m_page->hasSelection(), true);
+ m_view->page()->triggerAction(QWebEnginePage::SelectAll);
+ QTRY_COMPARE(m_view->hasSelection(), true);
- // Invoke a stopFinding() operation, which should clear the currently selected text.
- m_page->findText("");
- QTRY_VERIFY(m_page->selectedText().isEmpty());
+ // Invoking a stopFinding operation will not change or clear the currently selected text,
+ // if nothing was found beforehand.
+ {
+ CallbackSpy<bool> spy;
+ m_view->findText("", 0, spy.ref());
+ QVERIFY(spy.wasCalled());
+ QTRY_COMPARE(m_view->selectedText(), QString("foo bar"));
+ }
- QStringList words = (QStringList() << "foo" << "bar");
- foreach (QString subString, words) {
- // Invoke a find operation, which should clear the currently selected text, should
- // highlight all the found ocurrences, but should not update the selected text to the
- // searched for string.
- m_page->findText(subString);
- QTRY_VERIFY(m_page->selectedText().isEmpty());
-
- // Search highlights should be cleared, selected text should still be empty.
- m_page->findText("");
- QTRY_VERIFY(m_page->selectedText().isEmpty());
+ // Invoking a startFinding operation with text that won't be found, will clear the current
+ // selection.
+ {
+ CallbackSpy<bool> spy;
+ m_view->findText("Will not be found", 0, spy.ref());
+ QCOMPARE(spy.waitForResult(), false);
+ QTRY_VERIFY(m_view->selectedText().isEmpty());
+ }
+
+ // Select whole page contents again.
+ m_view->page()->triggerAction(QWebEnginePage::SelectAll);
+ QTRY_COMPARE(m_view->hasSelection(), true);
+
+ // Invoking a startFinding operation with text that will be found, will clear the current
+ // selection as well.
+ {
+ CallbackSpy<bool> spy;
+ m_view->findText("foo", 0, spy.ref());
+ QVERIFY(spy.waitForResult());
+ QTRY_VERIFY(m_view->selectedText().isEmpty());
+ }
+
+ // Invoking a stopFinding operation after text was found, will set the selected text to the
+ // found text.
+ {
+ CallbackSpy<bool> spy;
+ m_view->findText("", 0, spy.ref());
+ QTRY_VERIFY(spy.wasCalled());
+ QTRY_COMPARE(m_view->selectedText(), QString("foo"));
}
}
@@ -2606,8 +2660,36 @@ Q_OBJECT
public:
GetUserMediaTestPage()
: m_gotRequest(false)
+ , m_loadSucceeded(false)
{
connect(this, &QWebEnginePage::featurePermissionRequested, this, &GetUserMediaTestPage::onFeaturePermissionRequested);
+ connect(this, &QWebEnginePage::loadFinished, [this](bool success){
+ m_loadSucceeded = success;
+ });
+ // We need to load content from a resource in order for the securityOrigin to be valid.
+ load(QUrl("qrc:///resources/content.html"));
+ }
+
+ void jsGetUserMedia(const QString & constraints)
+ {
+ evaluateJavaScriptSync(this,
+ QStringLiteral(
+ "var promiseFulfilled = false;"
+ "var promiseRejected = false;"
+ "navigator.mediaDevices.getUserMedia(%1)"
+ ".then(stream => { promiseFulfilled = true})"
+ ".catch(err => { promiseRejected = true})")
+ .arg(constraints));
+ }
+
+ bool jsPromiseFulfilled()
+ {
+ return evaluateJavaScriptSync(this, QStringLiteral("promiseFulfilled")).toBool();
+ }
+
+ bool jsPromiseRejected()
+ {
+ return evaluateJavaScriptSync(this, QStringLiteral("promiseRejected")).toBool();
}
void rejectPendingRequest()
@@ -2626,6 +2708,16 @@ public:
return m_gotRequest && m_requestedFeature == feature;
}
+ bool gotFeatureRequest() const
+ {
+ return m_gotRequest;
+ }
+
+ bool loadSucceeded() const
+ {
+ return m_loadSucceeded;
+ }
+
private Q_SLOTS:
void onFeaturePermissionRequested(const QUrl &securityOrigin, QWebEnginePage::Feature feature)
{
@@ -2636,33 +2728,92 @@ private Q_SLOTS:
private:
bool m_gotRequest;
+ bool m_loadSucceeded;
QWebEnginePage::Feature m_requestedFeature;
QUrl m_requestSecurityOrigin;
};
+void tst_QWebEnginePage::getUserMediaRequest_data()
+{
+ QTest::addColumn<QString>("constraints");
+ QTest::addColumn<QWebEnginePage::Feature>("feature");
+
+ QTest::addRow("device audio")
+ << "{audio: true}" << QWebEnginePage::MediaAudioCapture;
+ QTest::addRow("device video")
+ << "{video: true}" << QWebEnginePage::MediaVideoCapture;
+ QTest::addRow("device audio+video")
+ << "{audio: true, video: true}" << QWebEnginePage::MediaAudioVideoCapture;
+ QTest::addRow("desktop video")
+ << "{video: { mandatory: { chromeMediaSource: 'desktop' }}}"
+ << QWebEnginePage::DesktopVideoCapture;
+ QTest::addRow("desktop audio+video")
+ << "{audio: { mandatory: { chromeMediaSource: 'desktop' }}, video: { mandatory: { chromeMediaSource: 'desktop' }}}"
+ << QWebEnginePage::DesktopAudioVideoCapture;
+}
void tst_QWebEnginePage::getUserMediaRequest()
{
- GetUserMediaTestPage page;
+ QFETCH(QString, constraints);
+ QFETCH(QWebEnginePage::Feature, feature);
- // We need to load content from a resource in order for the securityOrigin to be valid.
- QSignalSpy loadSpy(&page, SIGNAL(loadFinished(bool)));
- page.load(QUrl("qrc:///resources/content.html"));
- QTRY_COMPARE(loadSpy.count(), 1);
+ GetUserMediaTestPage page;
+ QTRY_VERIFY_WITH_TIMEOUT(page.loadSucceeded(), 20000);
+ page.settings()->setAttribute(QWebEngineSettings::ScreenCaptureEnabled, true);
+
+ // 1. Rejecting request on C++ side should reject promise on JS side.
+ page.jsGetUserMedia(constraints);
+ QTRY_VERIFY(page.gotFeatureRequest(feature));
+ page.rejectPendingRequest();
+ QTRY_VERIFY(!page.jsPromiseFulfilled() && page.jsPromiseRejected());
+
+ // 2. Accepting request on C++ side should either fulfill or reject the
+ // Promise on JS side. Due to the potential lack of physical media devices
+ // deeper in the content layer we cannot guarantee that the promise will
+ // always be fulfilled, however in this case an error should be returned to
+ // JS instead of leaving the Promise in limbo.
+ page.jsGetUserMedia(constraints);
+ QTRY_VERIFY(page.gotFeatureRequest(feature));
+ page.acceptPendingRequest();
+ QTRY_VERIFY(page.jsPromiseFulfilled() || page.jsPromiseRejected());
- QVERIFY(evaluateJavaScriptSync(&page, QStringLiteral("!!navigator.webkitGetUserMedia")).toBool());
- evaluateJavaScriptSync(&page, QStringLiteral("navigator.webkitGetUserMedia({audio: true}, function() {}, function(){})"));
- QTRY_VERIFY(page.gotFeatureRequest(QWebEnginePage::MediaAudioCapture));
- // Might end up failing due to the lack of physical media devices deeper in the content layer, so the JS callback is not guaranteed to be called,
- // but at least we go through that code path, potentially uncovering failing assertions.
+ // 3. Media feature permissions are not remembered.
+ page.jsGetUserMedia(constraints);
+ QTRY_VERIFY(page.gotFeatureRequest(feature));
page.acceptPendingRequest();
+ QTRY_VERIFY(page.jsPromiseFulfilled() || page.jsPromiseRejected());
+}
- page.runJavaScript(QStringLiteral("errorCallbackCalled = false;"));
- evaluateJavaScriptSync(&page, QStringLiteral("navigator.webkitGetUserMedia({audio: true, video: true}, function() {}, function(){errorCallbackCalled = true;})"));
- QTRY_VERIFY(page.gotFeatureRequest(QWebEnginePage::MediaAudioVideoCapture));
- page.rejectPendingRequest(); // Should always end up calling the error callback in JS.
- QTRY_VERIFY(evaluateJavaScriptSync(&page, QStringLiteral("errorCallbackCalled;")).toBool());
+void tst_QWebEnginePage::getUserMediaRequestDesktopAudio()
+{
+ GetUserMediaTestPage page;
+ QTRY_VERIFY_WITH_TIMEOUT(page.loadSucceeded(), 20000);
+ page.settings()->setAttribute(QWebEngineSettings::ScreenCaptureEnabled, true);
+
+ // Audio-only desktop capture is not supported. JS Promise should be
+ // rejected immediately.
+
+ page.jsGetUserMedia(
+ QStringLiteral("{audio: { mandatory: { chromeMediaSource: 'desktop' }}}"));
+ QTRY_VERIFY(!page.jsPromiseFulfilled() && page.jsPromiseRejected());
+
+ page.jsGetUserMedia(
+ QStringLiteral("{audio: { mandatory: { chromeMediaSource: 'desktop' }}, video: true}"));
+ QTRY_VERIFY(!page.jsPromiseFulfilled() && page.jsPromiseRejected());
+}
+
+void tst_QWebEnginePage::getUserMediaRequestSettingDisabled()
+{
+ GetUserMediaTestPage page;
+ QTRY_VERIFY_WITH_TIMEOUT(page.loadSucceeded(), 20000);
+ page.settings()->setAttribute(QWebEngineSettings::ScreenCaptureEnabled, false);
+
+ // With the setting disabled, the JS Promise should be rejected without
+ // asking for permission first.
+
+ page.jsGetUserMedia(QStringLiteral("{video: { mandatory: { chromeMediaSource: 'desktop' }}}"));
+ QTRY_VERIFY(!page.jsPromiseFulfilled() && page.jsPromiseRejected());
}
void tst_QWebEnginePage::savePage()
@@ -3044,21 +3195,19 @@ void tst_QWebEnginePage::progressSignal()
void tst_QWebEnginePage::urlChange()
{
- QSignalSpy urlSpy(m_page, SIGNAL(urlChanged(QUrl)));
+ QSignalSpy urlSpy(m_page, &QWebEnginePage::urlChanged);
QUrl dataUrl("data:text/html,<h1>Test");
m_view->setUrl(dataUrl);
- QVERIFY(urlSpy.wait());
-
- QCOMPARE(urlSpy.size(), 1);
+ QTRY_COMPARE(urlSpy.size(), 1);
+ QCOMPARE(urlSpy.takeFirst().value(0).toUrl(), dataUrl);
QUrl dataUrl2("data:text/html,<html><head><title>title</title></head><body><h1>Test</body></html>");
m_view->setUrl(dataUrl2);
- QVERIFY(urlSpy.wait());
-
- QCOMPARE(urlSpy.size(), 2);
+ QTRY_COMPARE(urlSpy.size(), 1);
+ QCOMPARE(urlSpy.takeFirst().value(0).toUrl(), dataUrl2);
}
class FakeReply : public QNetworkReply {
@@ -3169,7 +3318,7 @@ void tst_QWebEnginePage::requestedUrlAfterSetAndLoadFailures()
page.load(second);
QTRY_COMPARE_WITH_TIMEOUT(spy.count(), 2, 12000);
- QCOMPARE(page.url(), first);
+ QCOMPARE(page.url(), second);
QCOMPARE(page.requestedUrl(), second);
QVERIFY(!spy.at(1).first().toBool());
}
@@ -3410,7 +3559,7 @@ void tst_QWebEnginePage::scrollPosition()
view.setFixedSize(200,200);
view.show();
- QTest::qWaitForWindowExposed(&view);
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
QSignalSpy loadSpy(view.page(), SIGNAL(loadFinished(bool)));
view.setHtml(html);
@@ -3427,77 +3576,21 @@ void tst_QWebEnginePage::scrollPosition()
QCOMPARE(y, 29);
}
-void tst_QWebEnginePage::scrollToAnchor()
+void tst_QWebEnginePage::scrollbarsOff()
{
-#if !defined(QWEBENGINEELEMENT)
- QSKIP("QWEBENGINEELEMENT");
-#else
- QWebEnginePage page;
- page.setViewportSize(QSize(480, 800));
+ QWebEngineView view;
+ view.page()->settings()->setAttribute(QWebEngineSettings::ShowScrollBars, false);
- QString html("<html><body><p style=\"margin-bottom: 1500px;\">Hello.</p>"
- "<p><a id=\"foo\">This</a> is an anchor</p>"
- "<p style=\"margin-bottom: 1500px;\"><a id=\"bar\">This</a> is another anchor</p>"
+ QString html("<html><body>"
+ " <div style='margin-top:1000px ; margin-left:1000px'>"
+ " <a id='offscreen' href='a'>End</a>"
+ " </div>"
"</body></html>");
- page.setHtml(html);
- page.setScrollPosition(QPoint(0, 0));
- QCOMPARE(page.scrollPosition().x(), 0);
- QCOMPARE(page.scrollPosition().y(), 0);
-
- QWebEngineElement fooAnchor = page.findFirstElement("a[id=foo]");
- page.scrollToAnchor("foo");
- QCOMPARE(page.scrollPosition().y(), fooAnchor.geometry().top());
-
- page.scrollToAnchor("bar");
- page.scrollToAnchor("foo");
- QCOMPARE(page.scrollPosition().y(), fooAnchor.geometry().top());
-
- page.scrollToAnchor("top");
- QCOMPARE(page.scrollPosition().y(), 0);
-
- page.scrollToAnchor("bar");
- page.scrollToAnchor("notexist");
- QVERIFY(page.scrollPosition().y() != 0);
-#endif
-}
-
-
-void tst_QWebEnginePage::scrollbarsOff()
-{
-#if !defined(QWEBENGINEPAGE_EVALUATEJAVASCRIPT)
- QSKIP("QWEBENGINEPAGE_EVALUATEJAVASCRIPT");
-#else
- QWebEngineView view;
- QWebEngineFrame* mainFrame = view.page();
-
- mainFrame->setScrollBarPolicy(Qt::Vertical, Qt::ScrollBarAlwaysOff);
- mainFrame->setScrollBarPolicy(Qt::Horizontal, Qt::ScrollBarAlwaysOff);
-
- QString html("<script>" \
- " function checkScrollbar() {" \
- " if (innerWidth === document.documentElement.offsetWidth)" \
- " document.getElementById('span1').innerText = 'SUCCESS';" \
- " else" \
- " document.getElementById('span1').innerText = 'FAIL';" \
- " }" \
- "</script>" \
- "<body>" \
- " <div style='margin-top:1000px ; margin-left:1000px'>" \
- " <a id='offscreen' href='a'>End</a>" \
- " </div>" \
- "<span id='span1'></span>" \
- "</body>");
-
-
- QSignalSpy loadSpy(&view, &QWebEngineView::loadFinished);
+ QSignalSpy loadSpy(&view, SIGNAL(loadFinished(bool)));
view.setHtml(html);
- QVERIFY(loadSpy.wait(200);
- QCOMPARE(loadSpy.count(), 1);
-
- mainFrame->evaluateJavaScript("checkScrollbar();");
- QCOMPARE(mainFrame->documentElement().findAll("span").at(0).toPlainText(), QString("SUCCESS"));
-#endif
+ QTRY_COMPARE(loadSpy.count(), 1);
+ QVERIFY(evaluateJavaScriptSync(view.page(), "innerWidth == document.documentElement.offsetWidth").toBool());
}
void tst_QWebEnginePage::horizontalScrollAfterBack()
@@ -3545,7 +3638,7 @@ void tst_QWebEnginePage::evaluateWillCauseRepaint()
{
WebView view;
view.show();
- QTest::qWaitForWindowExposed(&view);
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
QString html("<html><body>"
" top"
@@ -3739,6 +3832,90 @@ void tst_QWebEnginePage::setUrlToInvalid()
QCOMPARE(baseUrlSync(&page), aboutBlank);
}
+void tst_QWebEnginePage::setUrlToBadDomain()
+{
+ // Failing to load a URL should still emit a urlChanged signal.
+ //
+ // This test is based on the scenario in QTBUG-48995 where the second setUrl
+ // call first triggers an unexpected additional urlChanged signal with the
+ // original url before the expected signal with the new url.
+
+ // RFC 2606 says the .invalid TLD should be invalid.
+ const QUrl url1 = QStringLiteral("http://this.is.definitely.invalid/");
+ const QUrl url2 = QStringLiteral("http://this.is.also.invalid/");
+ QWebEnginePage page;
+ QSignalSpy urlSpy(&page, &QWebEnginePage::urlChanged);
+ QSignalSpy titleSpy(&page, &QWebEnginePage::titleChanged);
+ QSignalSpy loadSpy(&page, &QWebEnginePage::loadFinished);
+
+ page.setUrl(url1);
+
+ QTRY_COMPARE(urlSpy.count(), 1);
+ QTRY_COMPARE(titleSpy.count(), 1);
+ QTRY_COMPARE(loadSpy.count(), 1);
+
+ QCOMPARE(urlSpy.takeFirst().value(0).toUrl(), url1);
+ QCOMPARE(titleSpy.takeFirst().value(0).toString(), url1.host());
+ QCOMPARE(loadSpy.takeFirst().value(0).toBool(), false);
+
+ QCOMPARE(page.url(), url1);
+ QCOMPARE(page.title(), url1.host());
+
+ page.setUrl(url2);
+
+ QTRY_COMPARE(urlSpy.count(), 1);
+ QTRY_COMPARE(titleSpy.count(), 1);
+ QTRY_COMPARE(loadSpy.count(), 1);
+
+ QCOMPARE(urlSpy.takeFirst().value(0).toUrl(), url2);
+ QCOMPARE(titleSpy.takeFirst().value(0).toString(), url2.host());
+ QCOMPARE(loadSpy.takeFirst().value(0).toBool(), false);
+
+ QCOMPARE(page.url(), url2);
+ QCOMPARE(page.title(), url2.host());
+}
+
+void tst_QWebEnginePage::setUrlToBadPort()
+{
+ // Failing to load a URL should still emit a urlChanged signal.
+
+ // Ports 244-245 are hopefully unbound (marked unassigned in RFC1700).
+ const QUrl url1 = QStringLiteral("http://127.0.0.1:244/");
+ const QUrl url2 = QStringLiteral("http://127.0.0.1:245/");
+ QWebEnginePage page;
+ QSignalSpy urlSpy(&page, &QWebEnginePage::urlChanged);
+ QSignalSpy titleSpy(&page, &QWebEnginePage::titleChanged);
+ QSignalSpy loadSpy(&page, &QWebEnginePage::loadFinished);
+
+ page.setUrl(url1);
+
+ QTRY_COMPARE(urlSpy.count(), 1);
+ QTRY_COMPARE(titleSpy.count(), 2);
+ QTRY_COMPARE(loadSpy.count(), 1);
+
+ QCOMPARE(urlSpy.takeFirst().value(0).toUrl(), url1);
+ QCOMPARE(titleSpy.takeFirst().value(0).toString(), url1.authority());
+ QCOMPARE(titleSpy.takeFirst().value(0).toString(), url1.host());
+ QCOMPARE(loadSpy.takeFirst().value(0).toBool(), false);
+
+ QCOMPARE(page.url(), url1);
+ QCOMPARE(page.title(), url1.host());
+
+ page.setUrl(url2);
+
+ QTRY_COMPARE(urlSpy.count(), 1);
+ QTRY_COMPARE(titleSpy.count(), 2);
+ QTRY_COMPARE(loadSpy.count(), 1);
+
+ QCOMPARE(urlSpy.takeFirst().value(0).toUrl(), url2);
+ QCOMPARE(titleSpy.takeFirst().value(0).toString(), url2.authority());
+ QCOMPARE(titleSpy.takeFirst().value(0).toString(), url2.host());
+ QCOMPARE(loadSpy.takeFirst().value(0).toBool(), false);
+
+ QCOMPARE(page.url(), url2);
+ QCOMPARE(page.title(), url2.host());
+}
+
static QStringList collectHistoryUrls(QWebEngineHistory *history)
{
QStringList urls;
@@ -3899,9 +4076,8 @@ void tst_QWebEnginePage::setUrlThenLoads()
const QUrl urlToLoad1("qrc:/resources/test2.html");
const QUrl urlToLoad2("qrc:/resources/test1.html");
- // Just after first load. URL didn't changed yet.
m_page->load(urlToLoad1);
- QCOMPARE(m_page->url(), url);
+ QCOMPARE(m_page->url(), urlToLoad1);
QCOMPARE(m_page->requestedUrl(), urlToLoad1);
// baseUrlSync spins an event loop and this sometimes return the next result.
// QCOMPARE(baseUrlSync(m_page), baseUrl);
@@ -3915,9 +4091,8 @@ void tst_QWebEnginePage::setUrlThenLoads()
QCOMPARE(m_page->requestedUrl(), urlToLoad1);
QCOMPARE(baseUrlSync(m_page), extractBaseUrl(urlToLoad1));
- // Just after second load. URL didn't changed yet.
m_page->load(urlToLoad2);
- QCOMPARE(m_page->url(), urlToLoad1);
+ QCOMPARE(m_page->url(), urlToLoad2);
QCOMPARE(m_page->requestedUrl(), urlToLoad2);
QCOMPARE(baseUrlSync(m_page), extractBaseUrl(urlToLoad1));
QTRY_COMPARE(startedSpy.count(), 3);
@@ -4128,10 +4303,10 @@ void tst_QWebEnginePage::toPlainTextLoadFinishedRace()
QVERIFY(s.contains("foobarbaz") == !enableErrorPage);
page->load(QUrl("data:text/plain,lalala"));
- QTRY_VERIFY(spy.count() == 3);
- QCOMPARE(toPlainTextSync(page.data()), QString("lalala"));
+ QTRY_COMPARE(spy.count(), 3);
+ QTRY_COMPARE(toPlainTextSync(page.data()), QString("lalala"));
page.reset();
- QVERIFY(spy.count() == 3);
+ QCOMPARE(spy.count(), 3);
}
void tst_QWebEnginePage::setZoomFactor()
@@ -4216,7 +4391,7 @@ void tst_QWebEnginePage::mouseButtonTranslation()
</div>\
</body></html>"));
view.show();
- QTest::qWaitForWindowExposed(&view);
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
QTRY_VERIFY(spy.count() == 1);
QVERIFY(view.focusProxy() != nullptr);
@@ -4240,7 +4415,7 @@ void tst_QWebEnginePage::mouseMovementProperties()
ConsolePage page;
view.setPage(&page);
view.show();
- QTest::qWaitForWindowExposed(&view);
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
QSignalSpy loadFinishedSpy(&page, SIGNAL(loadFinished(bool)));
page.setHtml(QStringLiteral(
@@ -4372,5 +4547,7 @@ void tst_QWebEnginePage::proxyConfigWithUnexpectedHostPortPair()
QTRY_COMPARE(loadFinishedSpy.count(), 1);
}
-QTEST_MAIN(tst_QWebEnginePage)
+static QByteArrayList params = {QByteArrayLiteral("--use-fake-device-for-media-stream")};
+W_QTEST_MAIN(tst_QWebEnginePage, params)
+
#include "tst_qwebenginepage.moc"
diff --git a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.qrc b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.qrc
index 1226e367d..fc83aefa5 100644
--- a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.qrc
+++ b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.qrc
@@ -1,5 +1,6 @@
<!DOCTYPE RCC><RCC version="1.0">
<qresource>
+ <file>resources/basic_printing_page.html</file>
<file>resources/content.html</file>
<file>resources/index.html</file>
<file>resources/frame_a.html</file>