summaryrefslogtreecommitdiffstats
path: root/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp')
-rw-r--r--tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp837
1 files changed, 821 insertions, 16 deletions
diff --git a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
index 8d5b486b2..931dbf7f0 100644
--- a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
+++ b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
@@ -47,6 +47,7 @@
#include <qnetworkreply.h>
#include <qnetworkrequest.h>
#include <qwebenginedownloaditem.h>
+#include <qwebenginefindtextresult.h>
#include <qwebenginefullscreenrequest.h>
#include <qwebenginehistory.h>
#include <qwebenginenotification.h>
@@ -127,6 +128,8 @@ private Q_SLOTS:
void findText();
void findTextResult();
void findTextSuccessiveShouldCallAllCallbacks();
+ void findTextCalledOnMatch();
+ void findTextActiveMatchOrdinal();
void deleteQWebEngineViewTwice();
void loadSignalsOrder_data();
void loadSignalsOrder();
@@ -202,9 +205,23 @@ private Q_SLOTS:
void sendNotification();
void contentsSize();
+ void setLifecycleState();
+ void setVisible();
+ void discardPreservesProperties();
+ void discardBeforeInitialization();
+ void automaticUndiscard();
+ void setLifecycleStateWithDevTools();
+ void discardPreservesCommittedLoad();
+ void discardAbortsPendingLoad();
+ void discardAbortsPendingLoadAndPreservesCommittedLoad();
+ void recommendedState();
+ void recommendedStateAuto();
+ void setLifecycleStateAndReload();
+
void editActionsWithExplicitFocus();
void editActionsWithInitialFocus();
void editActionsWithFocusOnIframe();
+ void editActionsWithoutSelection();
void customUserAgentInNewTab();
@@ -290,9 +307,9 @@ protected:
{
Q_UNUSED(url);
Q_UNUSED(isMainFrame);
- if (type == QWebEnginePage::NavigationTypeFormSubmitted)
- return m_acceptNavigationRequest;
- return true;
+ if (type == QWebEnginePage::NavigationTypeTyped)
+ return true;
+ return m_acceptNavigationRequest;
}
};
@@ -579,7 +596,7 @@ void tst_QWebEnginePage::acceptNavigationRequestNavigationType()
<< QWebEnginePage::NavigationTypeBackForward
<< QWebEnginePage::NavigationTypeReload
<< QWebEnginePage::NavigationTypeTyped
- << QWebEnginePage::NavigationTypeOther;
+ << QWebEnginePage::NavigationTypeRedirect;
QVERIFY(expectedList.count() == page.navigations.count());
for (int i = 0; i < expectedList.count(); ++i) {
QCOMPARE(page.navigations[i].type, expectedList[i]);
@@ -927,18 +944,24 @@ void tst_QWebEnginePage::findText()
// 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());
+ CallbackSpy<bool> callbackSpy;
+ QSignalSpy signalSpy(m_view->page(), &QWebEnginePage::findTextFinished);
+ m_view->findText("", 0, callbackSpy.ref());
+ QVERIFY(callbackSpy.wasCalled());
+ QCOMPARE(signalSpy.count(), 1);
QTRY_COMPARE(m_view->selectedText(), QString("foo bar"));
}
// 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);
+ CallbackSpy<bool> callbackSpy;
+ QSignalSpy signalSpy(m_view->page(), &QWebEnginePage::findTextFinished);
+ m_view->findText("Will not be found", 0, callbackSpy.ref());
+ QCOMPARE(callbackSpy.waitForResult(), false);
+ QTRY_COMPARE(signalSpy.count(), 1);
+ auto result = signalSpy.takeFirst().value(0).value<QWebEngineFindTextResult>();
+ QCOMPARE(result.numberOfMatches(), 0);
QTRY_VERIFY(m_view->selectedText().isEmpty());
}
@@ -949,24 +972,36 @@ void tst_QWebEnginePage::findText()
// 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());
+ CallbackSpy<bool> callbackSpy;
+ QSignalSpy signalSpy(m_view->page(), &QWebEnginePage::findTextFinished);
+ m_view->findText("foo", 0, callbackSpy.ref());
+ QVERIFY(callbackSpy.waitForResult());
+ QTRY_COMPARE(signalSpy.count(), 1);
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());
+ CallbackSpy<bool> callbackSpy;
+ QSignalSpy signalSpy(m_view->page(), &QWebEnginePage::findTextFinished);
+ m_view->findText("", 0, callbackSpy.ref());
+ QTRY_VERIFY(callbackSpy.wasCalled());
+ QTRY_COMPARE(signalSpy.count(), 1);
QTRY_COMPARE(m_view->selectedText(), QString("foo"));
}
}
void tst_QWebEnginePage::findTextResult()
{
+ QSignalSpy findTextSpy(m_view->page(), &QWebEnginePage::findTextFinished);
+ auto signalResult = [&findTextSpy]() -> QVector<int> {
+ if (findTextSpy.count() != 1)
+ return QVector<int>({-1, -1});
+ auto r = findTextSpy.takeFirst().value(0).value<QWebEngineFindTextResult>();
+ return QVector<int>({ r.numberOfMatches(), r.activeMatch() });
+ };
+
// findText will abort in blink if the view has an empty size.
m_view->resize(800, 600);
m_view->show();
@@ -976,15 +1011,21 @@ void tst_QWebEnginePage::findTextResult()
QTRY_COMPARE(loadSpy.count(), 1);
QCOMPARE(findTextSync(m_page, ""), false);
+ QCOMPARE(signalResult(), QVector<int>({0, 0}));
const QStringList words = { "foo", "bar" };
for (const QString &subString : words) {
QCOMPARE(findTextSync(m_page, subString), true);
+ QCOMPARE(signalResult(), QVector<int>({1, 1}));
+
QCOMPARE(findTextSync(m_page, ""), false);
+ QCOMPARE(signalResult(), QVector<int>({0, 0}));
}
QCOMPARE(findTextSync(m_page, "blahhh"), false);
+ QCOMPARE(signalResult(), QVector<int>({0, 0}));
QCOMPARE(findTextSync(m_page, ""), false);
+ QCOMPARE(signalResult(), QVector<int>({0, 0}));
}
void tst_QWebEnginePage::findTextSuccessiveShouldCallAllCallbacks()
@@ -1010,6 +1051,91 @@ void tst_QWebEnginePage::findTextSuccessiveShouldCallAllCallbacks()
QVERIFY(spy5.wasCalled());
}
+void tst_QWebEnginePage::findTextCalledOnMatch()
+{
+ QSignalSpy loadSpy(m_view->page(), &QWebEnginePage::loadFinished);
+
+ // findText will abort in blink if the view has an empty size.
+ m_view->resize(800, 600);
+ m_view->show();
+ m_view->setHtml(QString("<html><head></head><body><div>foo bar</div></body></html>"));
+ QTRY_COMPARE(loadSpy.count(), 1);
+
+ // CALLBACK
+ bool callbackCalled = false;
+ m_view->page()->findText("foo", 0, [this, &callbackCalled](bool found) {
+ QVERIFY(found);
+
+ m_view->page()->findText("bar", 0, [&callbackCalled](bool found) {
+ QVERIFY(found);
+ callbackCalled = true;
+ });
+ });
+ QTRY_VERIFY(callbackCalled);
+
+ // SIGNAL
+ int findTextFinishedCount = 0;
+ connect(m_view->page(), &QWebEnginePage::findTextFinished, [this, &findTextFinishedCount](QWebEngineFindTextResult result) {
+ QCOMPARE(result.numberOfMatches(), 1);
+ if (findTextFinishedCount == 0)
+ m_view->page()->findText("bar");
+ findTextFinishedCount++;
+ });
+
+ m_view->page()->findText("foo");
+ QTRY_COMPARE(findTextFinishedCount, 2);
+}
+
+void tst_QWebEnginePage::findTextActiveMatchOrdinal()
+{
+ QSignalSpy loadSpy(m_view->page(), &QWebEnginePage::loadFinished);
+ QSignalSpy findTextSpy(m_view->page(), &QWebEnginePage::findTextFinished);
+ QWebEngineFindTextResult result;
+
+ // findText will abort in blink if the view has an empty size.
+ m_view->resize(800, 600);
+ m_view->show();
+ m_view->setHtml(QString("<html><head></head><body><div>foo bar foo bar foo</div></body></html>"));
+ QTRY_COMPARE(loadSpy.count(), 1);
+
+ // Iterate over all "foo" matches.
+ for (int i = 1; i <= 3; ++i) {
+ m_view->page()->findText("foo", 0);
+ QTRY_COMPARE(findTextSpy.count(), 1);
+ result = findTextSpy.takeFirst().value(0).value<QWebEngineFindTextResult>();
+ QCOMPARE(result.numberOfMatches(), 3);
+ QCOMPARE(result.activeMatch(), i);
+ }
+
+ // The last match is followed by the fist one.
+ m_view->page()->findText("foo", 0);
+ QTRY_COMPARE(findTextSpy.count(), 1);
+ result = findTextSpy.takeFirst().value(0).value<QWebEngineFindTextResult>();
+ QCOMPARE(result.numberOfMatches(), 3);
+ QCOMPARE(result.activeMatch(), 1);
+
+ // The first match is preceded by the last one.
+ m_view->page()->findText("foo", QWebEnginePage::FindBackward);
+ QTRY_COMPARE(findTextSpy.count(), 1);
+ result = findTextSpy.takeFirst().value(0).value<QWebEngineFindTextResult>();
+ QCOMPARE(result.numberOfMatches(), 3);
+ QCOMPARE(result.activeMatch(), 3);
+
+ // Finding another word resets the activeMatch.
+ m_view->page()->findText("bar", 0);
+ QTRY_COMPARE(findTextSpy.count(), 1);
+ result = findTextSpy.takeFirst().value(0).value<QWebEngineFindTextResult>();
+ QCOMPARE(result.numberOfMatches(), 2);
+ QCOMPARE(result.activeMatch(), 1);
+
+ // If no match activeMatch is 0.
+ m_view->page()->findText("bla", 0);
+ QTRY_COMPARE(findTextSpy.count(), 1);
+ result = findTextSpy.takeFirst().value(0).value<QWebEngineFindTextResult>();
+ QCOMPARE(result.numberOfMatches(), 0);
+ QCOMPARE(result.activeMatch(), 0);
+}
+
static QWindow *findNewTopLevelWindow(const QWindowList &oldTopLevelWindows)
{
const auto tlws = QGuiApplication::topLevelWindows();
@@ -1070,6 +1196,8 @@ void tst_QWebEnginePage::comboBoxPopupPositionAfterMove()
QTRY_VERIFY(QGuiApplication::topLevelWindows().contains(popup));
QTRY_VERIFY(!popup->position().isNull());
QCOMPARE(popupPos + offset, popup->position());
+ QTest::mouseClick(window, Qt::LeftButton, Qt::KeyboardModifiers(), QPoint(1, 1));
+ QTRY_VERIFY(!QGuiApplication::topLevelWindows().contains(popup));
}
void tst_QWebEnginePage::comboBoxPopupPositionAfterChildMove()
@@ -3419,6 +3547,645 @@ void tst_QWebEnginePage::contentsSize()
QCOMPARE(m_page->contentsSize().height(), 1216);
}
+void tst_QWebEnginePage::setLifecycleState()
+{
+ qRegisterMetaType<QWebEnginePage::LifecycleState>("LifecycleState");
+
+ QWebEngineProfile profile;
+ QWebEnginePage page(&profile);
+ QSignalSpy loadSpy(&page, &QWebEnginePage::loadFinished);
+ QSignalSpy lifecycleSpy(&page, &QWebEnginePage::lifecycleStateChanged);
+ QSignalSpy visibleSpy(&page, &QWebEnginePage::visibleChanged);
+
+ page.load(QStringLiteral("qrc:/resources/lifecycle.html"));
+ QTRY_COMPARE(loadSpy.count(), 1);
+ QCOMPARE(loadSpy.takeFirst().value(0), QVariant(true));
+ QCOMPARE(lifecycleSpy.count(), 0);
+ QCOMPARE(page.lifecycleState(), QWebEnginePage::LifecycleState::Active);
+ QCOMPARE(visibleSpy.count(), 0);
+ QCOMPARE(page.isVisible(), false);
+ QCOMPARE(evaluateJavaScriptSync(&page, "document.wasDiscarded"), QVariant(false));
+ QCOMPARE(evaluateJavaScriptSync(&page, "frozenness"), QVariant(0));
+
+ // Active -> Frozen
+ page.setLifecycleState(QWebEnginePage::LifecycleState::Frozen);
+ QCOMPARE(lifecycleSpy.count(), 1);
+ QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Frozen));
+ QCOMPARE(page.lifecycleState(), QWebEnginePage::LifecycleState::Frozen);
+ QCOMPARE(visibleSpy.count(), 0);
+ QCOMPARE(page.isVisible(), false);
+ QCOMPARE(evaluateJavaScriptSync(&page, "document.wasDiscarded"), QVariant(false));
+ QCOMPARE(evaluateJavaScriptSync(&page, "frozenness"), QVariant(1));
+
+ // Frozen -> Active
+ page.setLifecycleState(QWebEnginePage::LifecycleState::Active);
+ QCOMPARE(lifecycleSpy.count(), 1);
+ QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Active));
+ QCOMPARE(page.lifecycleState(), QWebEnginePage::LifecycleState::Active);
+ QCOMPARE(visibleSpy.count(), 0);
+ QCOMPARE(page.isVisible(), false);
+ QCOMPARE(evaluateJavaScriptSync(&page, "document.wasDiscarded"), QVariant(false));
+ QCOMPARE(evaluateJavaScriptSync(&page, "frozenness"), QVariant(0));
+
+ // Active -> Discarded
+ page.setLifecycleState(QWebEnginePage::LifecycleState::Discarded);
+ QCOMPARE(lifecycleSpy.count(), 1);
+ QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Discarded));
+ QCOMPARE(page.lifecycleState(), QWebEnginePage::LifecycleState::Discarded);
+ QCOMPARE(visibleSpy.count(), 0);
+ QCOMPARE(page.isVisible(), false);
+ QTest::ignoreMessage(QtWarningMsg, "runJavaScript: disabled in Discarded state");
+ QCOMPARE(evaluateJavaScriptSync(&page, "document.wasDiscarded"), QVariant());
+ QTest::ignoreMessage(QtWarningMsg, "runJavaScript: disabled in Discarded state");
+ QCOMPARE(evaluateJavaScriptSync(&page, "frozenness"), QVariant());
+ QCOMPARE(loadSpy.count(), 0);
+
+ // Discarded -> Frozen (illegal!)
+ QTest::ignoreMessage(QtWarningMsg,
+ "setLifecycleState: failed to transition from Discarded to Frozen state: "
+ "illegal transition");
+ page.setLifecycleState(QWebEnginePage::LifecycleState::Frozen);
+ QCOMPARE(lifecycleSpy.count(), 0);
+ QCOMPARE(page.lifecycleState(), QWebEnginePage::LifecycleState::Discarded);
+
+ // Discarded -> Active
+ page.setLifecycleState(QWebEnginePage::LifecycleState::Active);
+ QTRY_COMPARE(loadSpy.count(), 1);
+ QCOMPARE(loadSpy.takeFirst().value(0), QVariant(true));
+ QCOMPARE(lifecycleSpy.count(), 1);
+ QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Active));
+ QCOMPARE(page.lifecycleState(), QWebEnginePage::LifecycleState::Active);
+ QCOMPARE(visibleSpy.count(), 0);
+ QCOMPARE(page.isVisible(), false);
+ QCOMPARE(evaluateJavaScriptSync(&page, "document.wasDiscarded"), QVariant(true));
+ QCOMPARE(evaluateJavaScriptSync(&page, "frozenness"), QVariant(0));
+
+ // Active -> Frozen -> Discarded -> Active
+ page.setLifecycleState(QWebEnginePage::LifecycleState::Frozen);
+ page.setLifecycleState(QWebEnginePage::LifecycleState::Discarded);
+ page.setLifecycleState(QWebEnginePage::LifecycleState::Active);
+ QCOMPARE(lifecycleSpy.count(), 3);
+ QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Frozen));
+ QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Discarded));
+ QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Active));
+ QCOMPARE(page.lifecycleState(), QWebEnginePage::LifecycleState::Active);
+ QCOMPARE(visibleSpy.count(), 0);
+ QCOMPARE(page.isVisible(), false);
+ QTRY_COMPARE(loadSpy.count(), 1);
+ QCOMPARE(loadSpy.takeFirst().value(0), QVariant(true));
+ QCOMPARE(evaluateJavaScriptSync(&page, "document.wasDiscarded"), QVariant(true));
+ QCOMPARE(evaluateJavaScriptSync(&page, "frozenness"), QVariant(0));
+
+ // Reload clears document.wasDiscarded
+ page.triggerAction(QWebEnginePage::Reload);
+ QTRY_COMPARE(loadSpy.count(), 1);
+ QCOMPARE(loadSpy.takeFirst().value(0), QVariant(true));
+ QCOMPARE(evaluateJavaScriptSync(&page, "document.wasDiscarded"), QVariant(false));
+}
+
+void tst_QWebEnginePage::setVisible()
+{
+ qRegisterMetaType<QWebEnginePage::LifecycleState>("LifecycleState");
+
+ QWebEngineProfile profile;
+ QWebEnginePage page(&profile);
+ QSignalSpy loadSpy(&page, &QWebEnginePage::loadFinished);
+ QSignalSpy lifecycleSpy(&page, &QWebEnginePage::lifecycleStateChanged);
+ QSignalSpy visibleSpy(&page, &QWebEnginePage::visibleChanged);
+
+ page.load(QStringLiteral("about:blank"));
+ QTRY_COMPARE(loadSpy.count(), 1);
+ QCOMPARE(loadSpy.takeFirst().value(0), QVariant(true));
+ QCOMPARE(lifecycleSpy.count(), 0);
+ QCOMPARE(page.lifecycleState(), QWebEnginePage::LifecycleState::Active);
+ QCOMPARE(visibleSpy.count(), 0);
+ QCOMPARE(page.isVisible(), false);
+
+ // hidden -> visible
+ page.setVisible(true);
+ QCOMPARE(lifecycleSpy.count(), 0);
+ QCOMPARE(page.lifecycleState(), QWebEnginePage::LifecycleState::Active);
+ QCOMPARE(visibleSpy.count(), 1);
+ QCOMPARE(visibleSpy.takeFirst().value(0), QVariant(true));
+ QCOMPARE(page.isVisible(), true);
+
+ // Active -> Frozen (illegal)
+ QTest::ignoreMessage(
+ QtWarningMsg,
+ "setLifecycleState: failed to transition from Active to Frozen state: page is visible");
+ page.setLifecycleState(QWebEnginePage::LifecycleState::Frozen);
+ QCOMPARE(lifecycleSpy.count(), 0);
+
+ // visible -> hidden
+ page.setVisible(false);
+ QCOMPARE(lifecycleSpy.count(), 0);
+ QCOMPARE(page.lifecycleState(), QWebEnginePage::LifecycleState::Active);
+ QCOMPARE(visibleSpy.count(), 1);
+ QCOMPARE(visibleSpy.takeFirst().value(0), QVariant(false));
+ QCOMPARE(page.isVisible(), false);
+
+ // Active -> Frozen
+ page.setLifecycleState(QWebEnginePage::LifecycleState::Frozen);
+ QCOMPARE(lifecycleSpy.count(), 1);
+ QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Frozen));
+ QCOMPARE(page.lifecycleState(), QWebEnginePage::LifecycleState::Frozen);
+
+ // hidden -> visible (triggers Frozen -> Active)
+ page.setVisible(true);
+ QCOMPARE(lifecycleSpy.count(), 1);
+ QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Active));
+ QCOMPARE(page.lifecycleState(), QWebEnginePage::LifecycleState::Active);
+ QCOMPARE(visibleSpy.count(), 1);
+ QCOMPARE(visibleSpy.takeFirst().value(0), QVariant(true));
+ QCOMPARE(page.isVisible(), true);
+
+ // Active -> Discarded (illegal)
+ QTest::ignoreMessage(QtWarningMsg,
+ "setLifecycleState: failed to transition from Active to Discarded state: "
+ "page is visible");
+ page.setLifecycleState(QWebEnginePage::LifecycleState::Discarded);
+ QCOMPARE(lifecycleSpy.count(), 0);
+
+ // visible -> hidden
+ page.setVisible(false);
+ QCOMPARE(lifecycleSpy.count(), 0);
+ QCOMPARE(page.lifecycleState(), QWebEnginePage::LifecycleState::Active);
+ QCOMPARE(visibleSpy.count(), 1);
+ QCOMPARE(visibleSpy.takeFirst().value(0), QVariant(false));
+ QCOMPARE(page.isVisible(), false);
+
+ // Active -> Discarded
+ page.setLifecycleState(QWebEnginePage::LifecycleState::Discarded);
+ QCOMPARE(lifecycleSpy.count(), 1);
+ QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Discarded));
+ QCOMPARE(page.lifecycleState(), QWebEnginePage::LifecycleState::Discarded);
+
+ // hidden -> visible (triggers Discarded -> Active)
+ page.setVisible(true);
+ QCOMPARE(lifecycleSpy.count(), 1);
+ QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Active));
+ QCOMPARE(page.lifecycleState(), QWebEnginePage::LifecycleState::Active);
+ QCOMPARE(visibleSpy.count(), 1);
+ QCOMPARE(visibleSpy.takeFirst().value(0), QVariant(true));
+ QCOMPARE(page.isVisible(), true);
+ QTRY_COMPARE(loadSpy.count(), 1);
+ QCOMPARE(loadSpy.takeFirst().value(0), QVariant(true));
+}
+
+void tst_QWebEnginePage::discardPreservesProperties()
+{
+ QWebEngineProfile profile;
+ QWebEnginePage page(&profile);
+ QSignalSpy loadSpy(&page, &QWebEnginePage::loadFinished);
+
+ page.load(QStringLiteral("about:blank"));
+ QTRY_COMPARE(loadSpy.count(), 1);
+ QCOMPARE(loadSpy.takeFirst().value(0), QVariant(true));
+
+ // Change as many properties as possible to non-default values
+ bool audioMuted = true;
+ QVERIFY(page.isAudioMuted() != audioMuted);
+ page.setAudioMuted(audioMuted);
+ QColor backgroundColor = Qt::black;
+ QVERIFY(page.backgroundColor() != backgroundColor);
+ page.setBackgroundColor(backgroundColor);
+ qreal zoomFactor = 2;
+ QVERIFY(page.zoomFactor() != zoomFactor);
+ page.setZoomFactor(zoomFactor);
+#if QT_CONFIG(webengine_webchannel)
+ QWebChannel *webChannel = new QWebChannel(&page);
+ page.setWebChannel(webChannel);
+#endif
+
+ // Take snapshot of the rest
+ QSizeF contentsSize = page.contentsSize();
+ QIcon icon = page.icon();
+ QUrl iconUrl = page.iconUrl();
+ QUrl requestedUrl = page.requestedUrl();
+ QString title = page.title();
+ QUrl url = page.url();
+
+ // History should be preserved too
+ int historyCount = page.history()->count();
+ QCOMPARE(historyCount, 1);
+ int historyIndex = page.history()->currentItemIndex();
+ QCOMPARE(historyIndex, 0);
+ QWebEngineHistoryItem historyItem = page.history()->currentItem();
+ QVERIFY(historyItem.isValid());
+
+ // Discard + undiscard
+ page.setLifecycleState(QWebEnginePage::LifecycleState::Discarded);
+ page.setLifecycleState(QWebEnginePage::LifecycleState::Active);
+ QTRY_COMPARE(loadSpy.count(), 1);
+ QCOMPARE(loadSpy.takeFirst().value(0), QVariant(true));
+
+ // Property changes should be preserved
+ QCOMPARE(page.isAudioMuted(), audioMuted);
+ QCOMPARE(page.backgroundColor(), backgroundColor);
+ QCOMPARE(page.contentsSize(), contentsSize);
+ QCOMPARE(page.icon(), icon);
+ QCOMPARE(page.iconUrl(), iconUrl);
+ QCOMPARE(page.requestedUrl(), requestedUrl);
+ QCOMPARE(page.title(), title);
+ QCOMPARE(page.url(), url);
+ QCOMPARE(page.zoomFactor(), zoomFactor);
+#if QT_CONFIG(webengine_webchannel)
+ QCOMPARE(page.webChannel(), webChannel);
+#endif
+ QCOMPARE(page.history()->count(), historyCount);
+ QCOMPARE(page.history()->currentItemIndex(), historyIndex);
+ QCOMPARE(page.history()->currentItem().url(), historyItem.url());
+ QCOMPARE(page.history()->currentItem().originalUrl(), historyItem.originalUrl());
+ QCOMPARE(page.history()->currentItem().title(), historyItem.title());
+}
+
+void tst_QWebEnginePage::discardBeforeInitialization()
+{
+ QWebEngineProfile profile;
+ QWebEnginePage page(&profile);
+ page.setLifecycleState(QWebEnginePage::LifecycleState::Discarded);
+ // The call is ignored
+ QCOMPARE(page.lifecycleState(), QWebEnginePage::LifecycleState::Active);
+}
+
+void tst_QWebEnginePage::automaticUndiscard()
+{
+ QWebEngineProfile profile;
+ QWebEnginePage page(&profile);
+ QSignalSpy loadSpy(&page, &QWebEnginePage::loadFinished);
+
+ page.load(QStringLiteral("about:blank"));
+ QTRY_COMPARE(loadSpy.count(), 1);
+ QCOMPARE(loadSpy.takeFirst().value(0), QVariant(true));
+
+ // setUrl
+ page.setLifecycleState(QWebEnginePage::LifecycleState::Discarded);
+ page.setUrl(QStringLiteral("qrc:/resources/lifecycle.html"));
+ QCOMPARE(page.lifecycleState(), QWebEnginePage::LifecycleState::Active);
+
+ // setContent
+ page.setLifecycleState(QWebEnginePage::LifecycleState::Discarded);
+ page.setContent(QByteArrayLiteral("foo"));
+ QCOMPARE(page.lifecycleState(), QWebEnginePage::LifecycleState::Active);
+}
+
+void tst_QWebEnginePage::setLifecycleStateWithDevTools()
+{
+ QWebEngineProfile profile;
+ QWebEnginePage inspectedPage(&profile);
+ QWebEnginePage devToolsPage(&profile);
+ QSignalSpy devToolsSpy(&devToolsPage, &QWebEnginePage::loadFinished);
+ QSignalSpy inspectedSpy(&inspectedPage, &QWebEnginePage::loadFinished);
+
+ // Ensure pages are initialized
+ inspectedPage.load(QStringLiteral("about:blank"));
+ devToolsPage.load(QStringLiteral("about:blank"));
+ QTRY_COMPARE(inspectedSpy.count(), 1);
+ QCOMPARE(inspectedSpy.takeFirst().value(0), QVariant(true));
+ QTRY_COMPARE(devToolsSpy.count(), 1);
+ QCOMPARE(devToolsSpy.takeFirst().value(0), QVariant(true));
+
+ // Open DevTools with Frozen inspectedPage
+ inspectedPage.setLifecycleState(QWebEnginePage::LifecycleState::Frozen);
+ inspectedPage.setDevToolsPage(&devToolsPage);
+ QCOMPARE(inspectedPage.lifecycleState(), QWebEnginePage::LifecycleState::Active);
+ QTRY_COMPARE(devToolsSpy.count(), 1);
+ QCOMPARE(devToolsSpy.takeFirst().value(0), QVariant(true));
+ inspectedPage.setDevToolsPage(nullptr);
+
+ // Open DevTools with Discarded inspectedPage
+ inspectedPage.setLifecycleState(QWebEnginePage::LifecycleState::Discarded);
+ inspectedPage.setDevToolsPage(&devToolsPage);
+ QCOMPARE(inspectedPage.lifecycleState(), QWebEnginePage::LifecycleState::Active);
+ QTRY_COMPARE(devToolsSpy.count(), 1);
+ QCOMPARE(devToolsSpy.takeFirst().value(0), QVariant(true));
+ QTRY_COMPARE(inspectedSpy.count(), 1);
+ QCOMPARE(inspectedSpy.takeFirst().value(0), QVariant(true));
+ inspectedPage.setDevToolsPage(nullptr);
+
+ // Open DevTools with Frozen devToolsPage
+ devToolsPage.setLifecycleState(QWebEnginePage::LifecycleState::Frozen);
+ devToolsPage.setInspectedPage(&inspectedPage);
+ QCOMPARE(devToolsPage.lifecycleState(), QWebEnginePage::LifecycleState::Active);
+ QTRY_COMPARE(devToolsSpy.count(), 1);
+ QCOMPARE(devToolsSpy.takeFirst().value(0), QVariant(true));
+ devToolsPage.setInspectedPage(nullptr);
+
+ // Open DevTools with Discarded devToolsPage
+ devToolsPage.setLifecycleState(QWebEnginePage::LifecycleState::Discarded);
+ devToolsPage.setInspectedPage(&inspectedPage);
+ QCOMPARE(devToolsPage.lifecycleState(), QWebEnginePage::LifecycleState::Active);
+ QTRY_COMPARE(devToolsSpy.count(), 2);
+ QCOMPARE(devToolsSpy.takeFirst().value(0), QVariant(false));
+ QCOMPARE(devToolsSpy.takeFirst().value(0), QVariant(true));
+ // keep DevTools open
+
+ // Try to change state while DevTools are open
+ QTest::ignoreMessage(
+ QtWarningMsg,
+ "setLifecycleState: failed to transition from Active to Frozen state: DevTools open");
+ inspectedPage.setLifecycleState(QWebEnginePage::LifecycleState::Frozen);
+ QCOMPARE(inspectedPage.lifecycleState(), QWebEnginePage::LifecycleState::Active);
+ QTest::ignoreMessage(QtWarningMsg,
+ "setLifecycleState: failed to transition from Active to Discarded state: "
+ "DevTools open");
+ inspectedPage.setLifecycleState(QWebEnginePage::LifecycleState::Discarded);
+ QCOMPARE(inspectedPage.lifecycleState(), QWebEnginePage::LifecycleState::Active);
+ QTest::ignoreMessage(
+ QtWarningMsg,
+ "setLifecycleState: failed to transition from Active to Frozen state: DevTools open");
+ devToolsPage.setLifecycleState(QWebEnginePage::LifecycleState::Frozen);
+ QCOMPARE(devToolsPage.lifecycleState(), QWebEnginePage::LifecycleState::Active);
+ QTest::ignoreMessage(QtWarningMsg,
+ "setLifecycleState: failed to transition from Active to Discarded state: "
+ "DevTools open");
+ devToolsPage.setLifecycleState(QWebEnginePage::LifecycleState::Discarded);
+ QCOMPARE(devToolsPage.lifecycleState(), QWebEnginePage::LifecycleState::Active);
+}
+
+void tst_QWebEnginePage::discardPreservesCommittedLoad()
+{
+ QWebEngineProfile profile;
+ QWebEnginePage page(&profile);
+ QSignalSpy loadStartedSpy(&page, &QWebEnginePage::loadStarted);
+ QSignalSpy loadFinishedSpy(&page, &QWebEnginePage::loadFinished);
+ QSignalSpy urlChangedSpy(&page, &QWebEnginePage::urlChanged);
+ QSignalSpy titleChangedSpy(&page, &QWebEnginePage::titleChanged);
+
+ QString url = QStringLiteral("qrc:/resources/lifecycle.html");
+ page.setUrl(url);
+ QTRY_COMPARE(loadStartedSpy.count(), 1);
+ loadStartedSpy.clear();
+ QTRY_COMPARE(loadFinishedSpy.count(), 1);
+ QCOMPARE(loadFinishedSpy.takeFirst().value(0), QVariant(true));
+ QCOMPARE(urlChangedSpy.count(), 1);
+ QCOMPARE(urlChangedSpy.takeFirst().value(0), QVariant(QUrl(url)));
+ QCOMPARE(page.url(), url);
+ QCOMPARE(titleChangedSpy.count(), 2);
+ QCOMPARE(titleChangedSpy.takeFirst().value(0), QVariant(url));
+ QString title = QStringLiteral("Lifecycle");
+ QCOMPARE(titleChangedSpy.takeFirst().value(0), QVariant(title));
+ QCOMPARE(page.title(), title);
+
+ page.setLifecycleState(QWebEnginePage::LifecycleState::Discarded);
+ QCOMPARE(loadStartedSpy.count(), 0);
+ QCOMPARE(loadFinishedSpy.count(), 0);
+ QCOMPARE(urlChangedSpy.count(), 0);
+ QCOMPARE(page.url(), QUrl(url));
+ QCOMPARE(titleChangedSpy.count(), 0);
+ QCOMPARE(page.title(), title);
+
+ page.setLifecycleState(QWebEnginePage::LifecycleState::Active);
+ QTRY_COMPARE(loadStartedSpy.count(), 1);
+ loadStartedSpy.clear();
+ QTRY_COMPARE(loadFinishedSpy.count(), 1);
+ QCOMPARE(loadFinishedSpy.takeFirst().value(0), QVariant(true));
+ QCOMPARE(urlChangedSpy.count(), 0);
+ QCOMPARE(page.url(), url);
+ QCOMPARE(titleChangedSpy.count(), 0);
+ QCOMPARE(page.title(), title);
+}
+
+void tst_QWebEnginePage::discardAbortsPendingLoad()
+{
+ QWebEngineProfile profile;
+ QWebEnginePage page(&profile);
+ QSignalSpy loadStartedSpy(&page, &QWebEnginePage::loadStarted);
+ QSignalSpy loadFinishedSpy(&page, &QWebEnginePage::loadFinished);
+ QSignalSpy urlChangedSpy(&page, &QWebEnginePage::urlChanged);
+ QSignalSpy titleChangedSpy(&page, &QWebEnginePage::titleChanged);
+
+ connect(&page, &QWebEnginePage::loadStarted,
+ [&]() { page.setLifecycleState(QWebEnginePage::LifecycleState::Discarded); });
+ QUrl url = QStringLiteral("qrc:/resources/lifecycle.html");
+ page.setUrl(url);
+ QTRY_COMPARE(loadStartedSpy.count(), 1);
+ loadStartedSpy.clear();
+ QTRY_COMPARE(loadFinishedSpy.count(), 1);
+ QCOMPARE(loadFinishedSpy.takeFirst().value(0), QVariant(false));
+ QCOMPARE(urlChangedSpy.count(), 2);
+ QCOMPARE(urlChangedSpy.takeFirst().value(0), QVariant(url));
+ QCOMPARE(urlChangedSpy.takeFirst().value(0), QVariant(QUrl()));
+ QCOMPARE(titleChangedSpy.count(), 0);
+ QCOMPARE(page.url(), QUrl());
+ QCOMPARE(page.title(), QString());
+
+ page.setLifecycleState(QWebEnginePage::LifecycleState::Active);
+ QCOMPARE(loadStartedSpy.count(), 0);
+ QCOMPARE(loadFinishedSpy.count(), 0);
+ QCOMPARE(urlChangedSpy.count(), 0);
+ QCOMPARE(page.url(), QUrl());
+ QCOMPARE(page.title(), QString());
+}
+
+void tst_QWebEnginePage::discardAbortsPendingLoadAndPreservesCommittedLoad()
+{
+ QWebEngineProfile profile;
+ QWebEnginePage page(&profile);
+ QSignalSpy loadStartedSpy(&page, &QWebEnginePage::loadStarted);
+ QSignalSpy loadFinishedSpy(&page, &QWebEnginePage::loadFinished);
+ QSignalSpy urlChangedSpy(&page, &QWebEnginePage::urlChanged);
+ QSignalSpy titleChangedSpy(&page, &QWebEnginePage::titleChanged);
+
+ QString url1 = QStringLiteral("qrc:/resources/lifecycle.html");
+ page.setUrl(url1);
+ QTRY_COMPARE(loadStartedSpy.count(), 1);
+ loadStartedSpy.clear();
+ QTRY_COMPARE(loadFinishedSpy.count(), 1);
+ QCOMPARE(loadFinishedSpy.takeFirst().value(0), QVariant(true));
+ QCOMPARE(urlChangedSpy.count(), 1);
+ QCOMPARE(urlChangedSpy.takeFirst().value(0), QVariant(QUrl(url1)));
+ QCOMPARE(page.url(), url1);
+ QCOMPARE(titleChangedSpy.count(), 2);
+ QCOMPARE(titleChangedSpy.takeFirst().value(0), QVariant(url1));
+ QString title = QStringLiteral("Lifecycle");
+ QCOMPARE(titleChangedSpy.takeFirst().value(0), QVariant(title));
+ QCOMPARE(page.title(), title);
+
+ connect(&page, &QWebEnginePage::loadStarted,
+ [&]() { page.setLifecycleState(QWebEnginePage::LifecycleState::Discarded); });
+ QString url2 = QStringLiteral("about:blank");
+ page.setUrl(url2);
+ QTRY_COMPARE(loadStartedSpy.count(), 1);
+ loadStartedSpy.clear();
+ QTRY_COMPARE(loadFinishedSpy.count(), 1);
+ QCOMPARE(loadFinishedSpy.takeFirst().value(0), QVariant(false));
+ QCOMPARE(urlChangedSpy.count(), 2);
+ QCOMPARE(urlChangedSpy.takeFirst().value(0), QVariant(QUrl(url2)));
+ QCOMPARE(urlChangedSpy.takeFirst().value(0), QVariant(QUrl(url1)));
+ QCOMPARE(titleChangedSpy.count(), 0);
+ QCOMPARE(page.url(), url1);
+ QCOMPARE(page.title(), title);
+
+ page.setLifecycleState(QWebEnginePage::LifecycleState::Active);
+ QCOMPARE(loadStartedSpy.count(), 0);
+ QCOMPARE(loadFinishedSpy.count(), 0);
+ QCOMPARE(urlChangedSpy.count(), 0);
+ QCOMPARE(page.url(), url1);
+ QCOMPARE(page.title(), title);
+}
+
+void tst_QWebEnginePage::recommendedState()
+{
+ qRegisterMetaType<QWebEnginePage::LifecycleState>("LifecycleState");
+
+ QWebEngineProfile profile;
+ QWebEnginePage page(&profile);
+
+ struct Event {
+ enum { StateChange, RecommendationChange } key;
+ QWebEnginePage::LifecycleState value;
+ };
+ std::vector<Event> events;
+ connect(&page, &QWebEnginePage::lifecycleStateChanged, [&](QWebEnginePage::LifecycleState state) {
+ events.push_back(Event { Event::StateChange, state });
+ });
+ connect(&page, &QWebEnginePage::recommendedStateChanged, [&](QWebEnginePage::LifecycleState state) {
+ events.push_back(Event { Event::RecommendationChange, state });
+ });
+
+ page.load(QStringLiteral("qrc:/resources/lifecycle.html"));
+ QTRY_COMPARE(events.size(), 1u);
+ QCOMPARE(events[0].key, Event::RecommendationChange);
+ QCOMPARE(events[0].value, QWebEnginePage::LifecycleState::Frozen);
+ events.clear();
+ QCOMPARE(page.recommendedState(), QWebEnginePage::LifecycleState::Frozen);
+
+ page.setVisible(true);
+ QTRY_COMPARE(events.size(), 1u);
+ QCOMPARE(events[0].key, Event::RecommendationChange);
+ QCOMPARE(events[0].value, QWebEnginePage::LifecycleState::Active);
+ events.clear();
+ QCOMPARE(page.recommendedState(), QWebEnginePage::LifecycleState::Active);
+
+ page.setVisible(false);
+ QTRY_COMPARE(events.size(), 1u);
+ QCOMPARE(events[0].key, Event::RecommendationChange);
+ QCOMPARE(events[0].value, QWebEnginePage::LifecycleState::Frozen);
+ events.clear();
+ QCOMPARE(page.recommendedState(), QWebEnginePage::LifecycleState::Frozen);
+
+ page.triggerAction(QWebEnginePage::Reload);
+ QTRY_COMPARE(events.size(), 2u);
+ QCOMPARE(events[0].key, Event::RecommendationChange);
+ QCOMPARE(events[0].value, QWebEnginePage::LifecycleState::Active);
+ QCOMPARE(events[1].key, Event::RecommendationChange);
+ QCOMPARE(events[1].value, QWebEnginePage::LifecycleState::Frozen);
+ events.clear();
+ QCOMPARE(page.recommendedState(), QWebEnginePage::LifecycleState::Frozen);
+
+ QWebEnginePage devTools;
+ page.setDevToolsPage(&devTools);
+ QTRY_COMPARE(events.size(), 1u);
+ QCOMPARE(events[0].key, Event::RecommendationChange);
+ QCOMPARE(events[0].value, QWebEnginePage::LifecycleState::Active);
+ events.clear();
+ QCOMPARE(page.recommendedState(), QWebEnginePage::LifecycleState::Active);
+
+ page.setDevToolsPage(nullptr);
+ QTRY_COMPARE(events.size(), 1u);
+ QCOMPARE(events[0].key, Event::RecommendationChange);
+ QCOMPARE(events[0].value, QWebEnginePage::LifecycleState::Frozen);
+ events.clear();
+ QCOMPARE(page.recommendedState(), QWebEnginePage::LifecycleState::Frozen);
+
+ page.setLifecycleState(QWebEnginePage::LifecycleState::Frozen);
+ QTRY_COMPARE(events.size(), 2u);
+ QCOMPARE(events[0].key, Event::StateChange);
+ QCOMPARE(events[0].value, QWebEnginePage::LifecycleState::Frozen);
+ QCOMPARE(events[1].key, Event::RecommendationChange);
+ QCOMPARE(events[1].value, QWebEnginePage::LifecycleState::Discarded);
+ events.clear();
+ QCOMPARE(page.recommendedState(), QWebEnginePage::LifecycleState::Discarded);
+
+ page.setLifecycleState(QWebEnginePage::LifecycleState::Discarded);
+ QTRY_COMPARE(events.size(), 1u);
+ QCOMPARE(events[0].key, Event::StateChange);
+ QCOMPARE(events[0].value, QWebEnginePage::LifecycleState::Discarded);
+ events.clear();
+ QCOMPARE(page.recommendedState(), QWebEnginePage::LifecycleState::Discarded);
+}
+
+void tst_QWebEnginePage::recommendedStateAuto()
+{
+ qRegisterMetaType<QWebEnginePage::LifecycleState>("LifecycleState");
+
+ QWebEngineProfile profile;
+ QWebEnginePage page(&profile);
+ QSignalSpy lifecycleSpy(&page, &QWebEnginePage::lifecycleStateChanged);
+ connect(&page, &QWebEnginePage::recommendedStateChanged, &page, &QWebEnginePage::setLifecycleState);
+
+ page.load(QStringLiteral("qrc:/resources/lifecycle.html"));
+ QTRY_COMPARE(lifecycleSpy.count(), 2);
+ QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Frozen));
+ QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Discarded));
+
+ page.setVisible(true);
+ QTRY_COMPARE(lifecycleSpy.count(), 1);
+ QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Active));
+
+ page.setVisible(false);
+ QTRY_COMPARE(lifecycleSpy.count(), 2);
+ QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Frozen));
+ QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Discarded));
+
+ page.triggerAction(QWebEnginePage::Reload);
+ QTRY_COMPARE(lifecycleSpy.count(), 3);
+ QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Active));
+ QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Frozen));
+ QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Discarded));
+
+ QWebEnginePage devTools;
+ page.setDevToolsPage(&devTools);
+ QTRY_COMPARE(lifecycleSpy.count(), 1);
+ QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Active));
+
+ page.setDevToolsPage(nullptr);
+ QTRY_COMPARE(lifecycleSpy.count(), 2);
+ QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Frozen));
+ QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Discarded));
+}
+
+void tst_QWebEnginePage::setLifecycleStateAndReload()
+{
+ qRegisterMetaType<QWebEnginePage::LifecycleState>("LifecycleState");
+
+ QWebEngineProfile profile;
+ QWebEnginePage page(&profile);
+ QSignalSpy loadSpy(&page, &QWebEnginePage::loadFinished);
+ QSignalSpy lifecycleSpy(&page, &QWebEnginePage::lifecycleStateChanged);
+
+ page.load(QStringLiteral("qrc:/resources/lifecycle.html"));
+ QTRY_COMPARE(loadSpy.count(), 1);
+ QCOMPARE(loadSpy.takeFirst().value(0), QVariant(true));
+ QCOMPARE(lifecycleSpy.count(), 0);
+ QCOMPARE(page.lifecycleState(), QWebEnginePage::LifecycleState::Active);
+
+ page.setLifecycleState(QWebEnginePage::LifecycleState::Frozen);
+ QCOMPARE(page.lifecycleState(), QWebEnginePage::LifecycleState::Frozen);
+ QCOMPARE(lifecycleSpy.count(), 1);
+ QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Frozen));
+
+ page.triggerAction(QWebEnginePage::Reload);
+ QCOMPARE(page.lifecycleState(), QWebEnginePage::LifecycleState::Active);
+ QCOMPARE(lifecycleSpy.count(), 1);
+ QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Active));
+ QTRY_COMPARE(loadSpy.count(), 1);
+ QCOMPARE(loadSpy.takeFirst().value(0), QVariant(true));
+
+ page.setLifecycleState(QWebEnginePage::LifecycleState::Discarded);
+ QCOMPARE(page.lifecycleState(), QWebEnginePage::LifecycleState::Discarded);
+ QCOMPARE(lifecycleSpy.count(), 1);
+ QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Discarded));
+
+ page.triggerAction(QWebEnginePage::Reload);
+ QCOMPARE(page.lifecycleState(), QWebEnginePage::LifecycleState::Active);
+ QCOMPARE(lifecycleSpy.count(), 1);
+ QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Active));
+ QTRY_COMPARE(loadSpy.count(), 1);
+ QCOMPARE(loadSpy.takeFirst().value(0), QVariant(true));
+}
+
void tst_QWebEnginePage::editActionsWithExplicitFocus()
{
QWebEngineView view;
@@ -3506,6 +4273,44 @@ void tst_QWebEnginePage::editActionsWithFocusOnIframe()
QCOMPARE(page->selectedText(), QStringLiteral("inner"));
}
+void tst_QWebEnginePage::editActionsWithoutSelection()
+{
+ QWebEngineView view;
+ QWebEnginePage *page = view.page();
+ view.settings()->setAttribute(QWebEngineSettings::FocusOnNavigationEnabled, true);
+
+ QSignalSpy loadFinishedSpy(page, &QWebEnginePage::loadFinished);
+ QSignalSpy selectionChangedSpy(page, &QWebEnginePage::selectionChanged);
+ QSignalSpy actionChangedSpy(page->action(QWebEnginePage::SelectAll), &QAction::changed);
+
+ page->setHtml(QString("<html><body><div>foo bar</div></body></html>"));
+ QTRY_COMPARE(loadFinishedSpy.count(), 1);
+ QTRY_COMPARE(actionChangedSpy.count(), 1);
+
+ QVERIFY(!page->action(QWebEnginePage::Cut)->isEnabled());
+ QVERIFY(!page->action(QWebEnginePage::Copy)->isEnabled());
+ QVERIFY(page->action(QWebEnginePage::Paste)->isEnabled());
+ QVERIFY(page->action(QWebEnginePage::Undo)->isEnabled());
+ QVERIFY(page->action(QWebEnginePage::Redo)->isEnabled());
+ QVERIFY(page->action(QWebEnginePage::SelectAll)->isEnabled());
+ QVERIFY(page->action(QWebEnginePage::PasteAndMatchStyle)->isEnabled());
+ QVERIFY(!page->action(QWebEnginePage::Unselect)->isEnabled());
+
+ page->triggerAction(QWebEnginePage::SelectAll);
+ QTRY_COMPARE(selectionChangedSpy.count(), 1);
+ QCOMPARE(page->hasSelection(), true);
+ QCOMPARE(page->selectedText(), QStringLiteral("foo bar"));
+
+ QVERIFY(page->action(QWebEnginePage::Cut)->isEnabled());
+ QVERIFY(page->action(QWebEnginePage::Copy)->isEnabled());
+ QVERIFY(page->action(QWebEnginePage::Paste)->isEnabled());
+ QVERIFY(page->action(QWebEnginePage::Undo)->isEnabled());
+ QVERIFY(page->action(QWebEnginePage::Redo)->isEnabled());
+ QVERIFY(page->action(QWebEnginePage::SelectAll)->isEnabled());
+ QVERIFY(page->action(QWebEnginePage::PasteAndMatchStyle)->isEnabled());
+ QVERIFY(page->action(QWebEnginePage::Unselect)->isEnabled());
+}
+
void tst_QWebEnginePage::customUserAgentInNewTab()
{
HttpServer server;