/*
    Copyright (C) 2016 The Qt Company Ltd.
    Copyright (C) 2009 Girish Ramakrishnan <girish@forwardbias.in>
    Copyright (C) 2010 Holger Hans Peter Freyther

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to
    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
    Boston, MA 02110-1301, USA.
*/

#include "../util.h"
#include <QtWebEngineCore/qtwebenginecore-config.h>
#include <QByteArray>
#include <QClipboard>
#include <QDir>
#include <QGraphicsWidget>
#include <QHBoxLayout>
#include <QLineEdit>
#include <QMainWindow>
#include <QMenu>
#include <QMimeDatabase>
#include <QNetworkProxy>
#include <QOpenGLWidget>
#include <QPaintEngine>
#include <QPushButton>
#include <QScreen>
#include <QStateMachine>
#include <QtGui/QClipboard>
#include <QtTest/QtTest>
#include <QTextCharFormat>
#if QT_CONFIG(webengine_webchannel)
#include <QWebChannel>
#endif
#include <httpserver.h>
#include <qnetworkcookiejar.h>
#include <qnetworkreply.h>
#include <qnetworkrequest.h>
#include <qwebenginedownloaditem.h>
#include <qwebenginefindtextresult.h>
#include <qwebenginefullscreenrequest.h>
#include <qwebenginehistory.h>
#include <qwebenginenotification.h>
#include <qwebenginepage.h>
#include <qwebengineprofile.h>
#include <qwebenginequotarequest.h>
#include <qwebengineregisterprotocolhandlerrequest.h>
#include <qwebenginescript.h>
#include <qwebenginescriptcollection.h>
#include <qwebenginesettings.h>
#include <qwebengineview.h>
#include <qimagewriter.h>

static void removeRecursive(const QString& dirname)
{
    QDir dir(dirname);
    QFileInfoList entries(dir.entryInfoList(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot));
    for (int i = 0; i < entries.count(); ++i)
        if (entries[i].isDir())
            removeRecursive(entries[i].filePath());
        else
            dir.remove(entries[i].fileName());
    QDir().rmdir(dirname);
}

class tst_QWebEnginePage : public QObject
{
    Q_OBJECT

public:
    tst_QWebEnginePage();
    virtual ~tst_QWebEnginePage();

public Q_SLOTS:
    void init();
    void cleanup();
    void cleanupFiles();

private Q_SLOTS:
    void initTestCase();
    void cleanupTestCase();
    void comboBoxPopupPositionAfterMove();
    void comboBoxPopupPositionAfterChildMove();
    void acceptNavigationRequest();
    void acceptNavigationRequestNavigationType();
    void acceptNavigationRequestRelativeToNothing();
    void geolocationRequestJS_data();
    void geolocationRequestJS();
    void loadFinished();
    void actionStates();
    void pasteImage();
    void popupFormSubmission();
    void callbackSpyDeleted();
    void multipleProfilesAndLocalStorage();
    void textSelection();
    void backActionUpdate();
    void localStorageVisibility();
    void consoleOutput();
    void userAgentNewlineStripping();
    void renderWidgetHostViewNotShowTopLevel();
    void getUserMediaRequest_data();
    void getUserMediaRequest();
    void getUserMediaRequestDesktopAudio();
    void getUserMediaRequestSettingDisabled();
    void getUserMediaRequestDesktopVideoManyPages();
    void getUserMediaRequestDesktopVideoManyRequests();
    void savePage();

    void crashTests_LazyInitializationOfMainFrame();

#if defined(ENABLE_WEBGL) && ENABLE_WEBGL
    void acceleratedWebGLScreenshotWithoutView();
    void unacceleratedWebGLScreenshotWithoutView();
#endif

    void testJSPrompt();
    void findText();
    void findTextResult();
    void findTextSuccessiveShouldCallAllCallbacks();
    void findTextCalledOnMatch();
    void findTextActiveMatchOrdinal();
    void deleteQWebEngineViewTwice();
    void loadSignalsOrder_data();
    void loadSignalsOrder();
    void openWindowDefaultSize();

#ifdef Q_OS_MAC
    void macCopyUnicodeToClipboard();
#endif

    void runJavaScript();
    void runJavaScriptDisabled();
    void runJavaScriptFromSlot();
    void fullScreenRequested();
    void quotaRequested();


    // Tests from tst_QWebEngineFrame
    void symmetricUrl();
    void progressSignal();
    void urlChange();
    void requestedUrlAfterSetAndLoadFailures();
    void asyncAndDelete();
    void earlyToHtml();
    void setHtml();
    void setHtmlWithImageResource();
    void setHtmlWithStylesheetResource();
    void setHtmlWithBaseURL();
    void setHtmlWithJSAlert();
    void setHtmlWithModuleImport();
    void baseUrl_data();
    void baseUrl();
    void scrollPosition();
    void scrollbarsOff();
    void evaluateWillCauseRepaint();
    void setContent_data();
    void setContent();
    void setUrlWithPendingLoads();
    void setUrlToEmpty();
    void setUrlToInvalid();
    void setUrlToBadDomain();
    void setUrlToBadPort();
    void setUrlHistory();
    void setUrlUsingStateObject();
    void setUrlThenLoads_data();
    void setUrlThenLoads();
    void loadFinishedAfterNotFoundError();
    void loadInSignalHandlers_data();
    void loadInSignalHandlers();
    void loadFromQrc();
#if QT_CONFIG(webengine_webchannel)
    void restoreHistory();
#endif
    void toPlainTextLoadFinishedRace_data();
    void toPlainTextLoadFinishedRace();
    void setZoomFactor();
    void mouseButtonTranslation();
    void mouseMovementProperties();

    void viewSource();
    void viewSourceURL_data();
    void viewSourceURL();
    void viewSourceCredentials();
    void proxyConfigWithUnexpectedHostPortPair();
    void registerProtocolHandler_data();
    void registerProtocolHandler();
    void dataURLFragment();
    void devTools();
    void openLinkInDifferentProfile();
    void openLinkInNewPage_data();
    void openLinkInNewPage();
    void triggerActionWithoutMenu();
    void dynamicFrame();

    void notificationPermission_data();
    void notificationPermission();
    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();
    void renderProcessCrashed();
    void renderProcessPid();
    void backgroundColor();
    void audioMuted();
    void closeContents();
    void isSafeRedirect_data();
    void isSafeRedirect();

private:
    static QPoint elementCenter(QWebEnginePage *page, const QString &id);
    static bool isFalseJavaScriptResult(QWebEnginePage *page, const QString &javaScript);
    static bool isTrueJavaScriptResult(QWebEnginePage *page, const QString &javaScript);
    static bool isEmptyListJavaScriptResult(QWebEnginePage *page, const QString &javaScript);

    QWebEngineView* m_view;
    QWebEnginePage* m_page;
    QString tmpDirPath() const
    {
        static QString tmpd = QDir::tempPath() + "/tst_qwebenginepage-"
            + QDateTime::currentDateTime().toString(QLatin1String("yyyyMMddhhmmss"));
        return tmpd;
    }
};

tst_QWebEnginePage::tst_QWebEnginePage()
{
}

tst_QWebEnginePage::~tst_QWebEnginePage()
{
}

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()
{
    delete m_view;
}

void tst_QWebEnginePage::cleanupFiles()
{
    removeRecursive(tmpDirPath());
}

void tst_QWebEnginePage::initTestCase()
{
    QLocale::setDefault(QLocale("en"));
    cleanupFiles(); // In case there are old files from previous runs

    // Set custom path since the CI doesn't install test plugins.
    // Stolen from qtlocation/tests/auto/positionplugintest.
    QString searchPath = QCoreApplication::applicationDirPath();
#ifdef Q_OS_WIN
    searchPath += QStringLiteral("/..");
#endif
    searchPath += QStringLiteral("/../../../plugins");
    QCoreApplication::addLibraryPath(searchPath);
}

void tst_QWebEnginePage::cleanupTestCase()
{
    cleanupFiles(); // Be nice
}

class NavigationRequestOverride : public QWebEnginePage
{
public:
    NavigationRequestOverride(QWebEngineProfile* profile, bool initialValue) : QWebEnginePage(profile, nullptr), m_acceptNavigationRequest(initialValue) {}

    bool m_acceptNavigationRequest;
protected:
    virtual bool acceptNavigationRequest(const QUrl &url, NavigationType type, bool isMainFrame)
    {
        Q_UNUSED(url);
        Q_UNUSED(isMainFrame);
        if (type == QWebEnginePage::NavigationTypeTyped)
            return true;
        return m_acceptNavigationRequest;
    }
};

void tst_QWebEnginePage::acceptNavigationRequest()
{
    QWebEngineProfile profile;
    NavigationRequestOverride page(&profile, false);

    QSignalSpy loadSpy(&page, SIGNAL(loadFinished(bool)));

    page.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_WITH_TIMEOUT(loadSpy.count(), 1, 20000);

    evaluateJavaScriptSync(&page, "tstform.submit();");
    QTRY_COMPARE(loadSpy.count(), 2);

    // Content hasn't changed so the form submit will still work
    page.m_acceptNavigationRequest = true;
    evaluateJavaScriptSync(&page, "tstform.submit();");
    QTRY_COMPARE(loadSpy.count(), 3);

    // Now the content has changed
    QCOMPARE(toPlainTextSync(&page), QString("foo?"));
}

class JSTestPage : public QWebEnginePage
{
Q_OBJECT
public:
    JSTestPage(QObject* parent = 0)
    : QWebEnginePage(parent) {}

    virtual bool shouldInterruptJavaScript()
    {
        return true;
    }
public Q_SLOTS:
    void requestPermission(const QUrl &origin, QWebEnginePage::Feature feature)
    {
        if (m_allowGeolocation)
            setFeaturePermission(origin, feature, PermissionGrantedByUser);
        else
            setFeaturePermission(origin, feature, PermissionDeniedByUser);
    }

public:
    void setGeolocationPermission(bool allow)
    {
        m_allowGeolocation = allow;
    }

private:
    bool m_allowGeolocation;
};

void tst_QWebEnginePage::geolocationRequestJS_data()
{
    QTest::addColumn<bool>("allowed");
    QTest::addColumn<int>("errorCode");
    QTest::newRow("allowed") << true << 0;
    QTest::newRow("not allowed") << false << 1;
}

void tst_QWebEnginePage::geolocationRequestJS()
{
    QFETCH(bool, allowed);
    QFETCH(int, errorCode);
    QWebEngineView view;
    JSTestPage *newPage = new JSTestPage(&view);
    newPage->setView(&view);
    newPage->setGeolocationPermission(allowed);

    connect(newPage, SIGNAL(featurePermissionRequested(const QUrl&, QWebEnginePage::Feature)),
            newPage, SLOT(requestPermission(const QUrl&, QWebEnginePage::Feature)));

    QSignalSpy spyLoadFinished(newPage, SIGNAL(loadFinished(bool)));
    newPage->setHtml(QString("<html><body>test</body></html>"), QUrl("qrc://secure/origin"));
    QTRY_COMPARE_WITH_TIMEOUT(spyLoadFinished.count(), 1, 20000);

    // Geolocation is only enabled for visible WebContents.
    view.show();
    QVERIFY(QTest::qWaitForWindowExposed(&view));

    if (evaluateJavaScriptSync(newPage, QLatin1String("!navigator.geolocation")).toBool())
        W_QSKIP("Geolocation is not supported.", SkipSingle);

    evaluateJavaScriptSync(newPage, "var errorCode = 0; var done = false; function error(err) { errorCode = err.code; done = true; } function success(pos) { done = true; } navigator.geolocation.getCurrentPosition(success, error)");

    QTRY_VERIFY(evaluateJavaScriptSync(newPage, "done").toBool());
    int result = evaluateJavaScriptSync(newPage, "errorCode").toInt();
    if (result == 2)
        QEXPECT_FAIL("", "No location service available.", Continue);
    QCOMPARE(result, errorCode);
}

void tst_QWebEnginePage::loadFinished()
{
    QWebEnginePage page;
    QSignalSpy spyLoadStarted(&page, SIGNAL(loadStarted()));
    QSignalSpy spyLoadFinished(&page, SIGNAL(loadFinished(bool)));

    page.load(QUrl("data:text/html,<frameset cols=\"25%,75%\"><frame src=\"data:text/html,"
                                           "<head><meta http-equiv='refresh' content='1'></head>foo \">"
                                           "<frame src=\"data:text/html,bar\"></frameset>"));
    QTRY_COMPARE_WITH_TIMEOUT(spyLoadFinished.count(), 1, 20000);

    QEXPECT_FAIL("", "Behavior change: Load signals are emitted only for the main frame in QtWebEngine.", Continue);
    QTRY_VERIFY_WITH_TIMEOUT(spyLoadStarted.count() > 1, 100);
    QEXPECT_FAIL("", "Behavior change: Load signals are emitted only for the main frame in QtWebEngine.", Continue);
    QTRY_VERIFY_WITH_TIMEOUT(spyLoadFinished.count() > 1, 100);

    spyLoadFinished.clear();

    page.load(QUrl("data:text/html,<frameset cols=\"25%,75%\"><frame src=\"data:text/html,"
                                           "foo \"><frame src=\"data:text/html,bar\"></frameset>"));
    QTRY_COMPARE(spyLoadFinished.count(), 1);
    QCOMPARE(spyLoadFinished.count(), 1);
}

void tst_QWebEnginePage::actionStates()
{
    m_page->load(QUrl("qrc:///resources/script.html"));

    QAction* reloadAction = m_page->action(QWebEnginePage::Reload);
    QAction* stopAction = m_page->action(QWebEnginePage::Stop);

    QTRY_VERIFY(reloadAction->isEnabled());
    QTRY_VERIFY(!stopAction->isEnabled());
}

static QImage imageWithoutAlpha(const QImage &image)
{
    QImage result = image;
    QPainter painter(&result);
    painter.fillRect(result.rect(), Qt::green);
    painter.drawImage(0, 0, 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
    // test -> clipboard -> webengine -> test roundtrip.
    // Clear the alpha channel to make QCOMPARE happy.
    const QImage origImage = imageWithoutAlpha(QImage(":/resources/image.png"));
    QClipboard *clipboard = QGuiApplication::clipboard();
    clipboard->setImage(origImage);
    QWebEnginePage *page = m_view->page();
    QSignalSpy spyFinished(m_view, &QWebEngineView::loadFinished);
    page->load(QUrl("qrc:///resources/pasteimage.html"));
    QTRY_VERIFY_WITH_TIMEOUT(!spyFinished.isEmpty(), 20000);
    page->triggerAction(QWebEnginePage::Paste);
    QTRY_VERIFY(evaluateJavaScriptSync(page,
            "window.myImageDataURL ? window.myImageDataURL.length : 0").toInt() > 0);
    QByteArray data = evaluateJavaScriptSync(page, "window.myImageDataURL").toByteArray();
    data.remove(0, data.indexOf(";base64,") + 8);
    QImage image = QImage::fromData(QByteArray::fromBase64(data), "PNG");
    if (image.format() == QImage::Format_RGB32)
        image.reinterpretAsFormat(QImage::Format_ARGB32);
    QCOMPARE(image, origImage);
}

class ConsolePage : public QWebEnginePage
{
public:
    ConsolePage(QObject* parent = 0) : QWebEnginePage(parent) {}

    virtual void javaScriptConsoleMessage(JavaScriptConsoleMessageLevel level, const QString& message, int lineNumber, const QString& sourceID)
    {
        levels.append(level);
        messages.append(message);
        lineNumbers.append(lineNumber);
        sourceIDs.append(sourceID);
    }

    QList<int> levels;
    QStringList messages;
    QList<int> lineNumbers;
    QStringList sourceIDs;
};

void tst_QWebEnginePage::consoleOutput()
{
    ConsolePage page;
    // We don't care about the result but want this to be synchronous
    evaluateJavaScriptSync(&page, "this is not valid JavaScript");
    QCOMPARE(page.messages.count(), 1);
    QCOMPARE(page.lineNumbers.at(0), 1);
}

class TestPage : public QWebEnginePage {
    Q_OBJECT
public:
    TestPage(QObject* parent = 0) : QWebEnginePage(parent)
    {
        connect(this, SIGNAL(geometryChangeRequested(QRect)), this, SLOT(slotGeometryChangeRequested(QRect)));
    }

    struct Navigation {
        NavigationType type;
        QUrl url;
        bool isMainFrame;
    };
    QList<Navigation> navigations;

    virtual bool acceptNavigationRequest(const QUrl &url, NavigationType type, bool isMainFrame)
    {
        Navigation n;
        n.url = url;
        n.type = type;
        n.isMainFrame = isMainFrame;
        navigations.append(n);
        return true;
    }

    QList<TestPage*> createdWindows;
    virtual QWebEnginePage* createWindow(WebWindowType) {
        TestPage* page = new TestPage(this);
        createdWindows.append(page);
        emit windowCreated();
        return page;
    }

    QRect requestedGeometry;

signals:
    void windowCreated();

private Q_SLOTS:
    void slotGeometryChangeRequested(const QRect& geom) {
        requestedGeometry = geom;
    }
};

void tst_QWebEnginePage::acceptNavigationRequestNavigationType()
{

    TestPage page;
    QSignalSpy loadSpy(&page, SIGNAL(loadFinished(bool)));

    page.load(QUrl("qrc:///resources/script.html"));
    QTRY_COMPARE_WITH_TIMEOUT(loadSpy.count(), 1, 20000);
    QTRY_COMPARE(page.navigations.count(), 1);

    page.load(QUrl("qrc:///resources/content.html"));
    QTRY_COMPARE_WITH_TIMEOUT(loadSpy.count(), 2, 20000);
    QTRY_COMPARE(page.navigations.count(), 2);

    page.triggerAction(QWebEnginePage::Stop);
    QVERIFY(page.history()->canGoBack());
    page.triggerAction(QWebEnginePage::Back);

    QTRY_COMPARE(loadSpy.count(), 3);
    QTRY_COMPARE(page.navigations.count(), 3);

    page.triggerAction(QWebEnginePage::Reload);
    QTRY_COMPARE(loadSpy.count(), 4);
    QTRY_COMPARE(page.navigations.count(), 4);

    page.load(QUrl("qrc:///resources/reload.html"));
    QTRY_COMPARE_WITH_TIMEOUT(loadSpy.count(), 6, 20000);
    QTRY_COMPARE(page.navigations.count(), 6);

    QList<QWebEnginePage::NavigationType> expectedList;
    expectedList << QWebEnginePage::NavigationTypeTyped
        << QWebEnginePage::NavigationTypeTyped
        << QWebEnginePage::NavigationTypeBackForward
        << QWebEnginePage::NavigationTypeReload
        << QWebEnginePage::NavigationTypeTyped
        << QWebEnginePage::NavigationTypeRedirect;
    QVERIFY(expectedList.count() == page.navigations.count());
    for (int i = 0; i < expectedList.count(); ++i) {
        QCOMPARE(page.navigations[i].type, expectedList[i]);
    }
}

// Relative url without base url.
//
// See also: QTBUG-48435
void tst_QWebEnginePage::acceptNavigationRequestRelativeToNothing()
{
    TestPage page;
    QSignalSpy loadSpy(&page, SIGNAL(loadFinished(bool)));

    page.setHtml(QString("<html><body><a id='link' href='S0'>limited time offer</a></body></html>"),
                 /* baseUrl: */ QUrl());
    QTRY_COMPARE_WITH_TIMEOUT(loadSpy.count(), 1, 20000);
    page.runJavaScript(QStringLiteral("document.getElementById(\"link\").click()"));
    QTRY_COMPARE_WITH_TIMEOUT(loadSpy.count(), 2, 20000);
    page.setHtml(QString("<html><body><a id='link' href='S0'>limited time offer</a></body></html>"),
                 /* baseUrl: */ QString("qrc:/"));
    QTRY_COMPARE_WITH_TIMEOUT(loadSpy.count(), 3, 20000);
    page.runJavaScript(QStringLiteral("document.getElementById(\"link\").click()"));
    QTRY_COMPARE_WITH_TIMEOUT(loadSpy.count(), 4, 20000);

    // The two setHtml and the second click are counted, while the
    // first click is ignored due to the empty base url.
    QCOMPARE(page.navigations.count(), 3);
    QCOMPARE(page.navigations[0].type, QWebEnginePage::NavigationTypeTyped);
    QCOMPARE(page.navigations[1].type, QWebEnginePage::NavigationTypeTyped);
    QCOMPARE(page.navigations[2].type, QWebEnginePage::NavigationTypeLinkClicked);
    QCOMPARE(page.navigations[2].url, QUrl(QString("qrc:/S0")));
}

void tst_QWebEnginePage::popupFormSubmission()
{
    TestPage page;
    QSignalSpy loadFinishedSpy(&page, SIGNAL(loadFinished(bool)));
    QSignalSpy windowCreatedSpy(&page, SIGNAL(windowCreated()));

    page.settings()->setAttribute(QWebEngineSettings::JavascriptCanOpenWindows, true);
    page.setHtml("<form name='form1' method=get action='' target='myNewWin'>"
                 "  <input type='hidden' name='foo' value='bar'>"
                 "</form>");
    QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.count(), 1, 20000);

    page.runJavaScript("window.open('', 'myNewWin', 'width=500,height=300,toolbar=0');");
    evaluateJavaScriptSync(&page, "document.form1.submit();");
    QTRY_COMPARE(windowCreatedSpy.count(), 1);

    // The number of popup created should be one.
    QVERIFY(page.createdWindows.size() == 1);

    QTRY_VERIFY(!page.createdWindows[0]->url().isEmpty());
    QString url = page.createdWindows[0]->url().toString();

    // Check if the form submission was OK.
    QVERIFY(url.contains("?foo=bar"));
}

class TestNetworkManager : public QNetworkAccessManager
{
public:
    TestNetworkManager(QObject* parent) : QNetworkAccessManager(parent) {}

    QList<QUrl> requestedUrls;
    QList<QNetworkRequest> requests;

protected:
    virtual QNetworkReply* createRequest(Operation op, const QNetworkRequest &request, QIODevice* outgoingData) {
        requests.append(request);
        requestedUrls.append(request.url());
        return QNetworkAccessManager::createRequest(op, request, outgoingData);
    }
};

void tst_QWebEnginePage::multipleProfilesAndLocalStorage()
{
    QDir dir(tmpDirPath());
    bool success = dir.mkpath("path1");
    success = success && dir.mkdir("path2");
    QVERIFY(success);
    {
        QWebEngineProfile profile1("test1");
        QWebEngineProfile profile2("test2");
        profile1.settings()->setAttribute(QWebEngineSettings::LocalStorageEnabled, true);
        profile2.settings()->setAttribute(QWebEngineSettings::LocalStorageEnabled, true);
        profile1.setPersistentStoragePath(QDir::toNativeSeparators(tmpDirPath() + "/path1"));
        profile2.setPersistentStoragePath(QDir::toNativeSeparators(tmpDirPath() + "/path2"));

        QWebEnginePage page1(&profile1, nullptr);
        QWebEnginePage page2(&profile2, nullptr);
        QSignalSpy loadSpy1(&page1, SIGNAL(loadFinished(bool)));
        QSignalSpy loadSpy2(&page2, SIGNAL(loadFinished(bool)));

        page1.setHtml(QString("<html><body> </body></html>"), QUrl("http://wwww.example.com"));
        page2.setHtml(QString("<html><body> </body></html>"), QUrl("http://wwww.example.com"));
        QTRY_COMPARE_WITH_TIMEOUT(loadSpy1.count(), 1, 20000);
        QTRY_COMPARE_WITH_TIMEOUT(loadSpy2.count(), 1, 20000);

        evaluateJavaScriptSync(&page1, "localStorage.setItem('test', 'value1');");
        evaluateJavaScriptSync(&page2, "localStorage.setItem('test', 'value2');");

        page1.setHtml(QString("<html><body> </body></html>"), QUrl("http://wwww.example.com"));
        page2.setHtml(QString("<html><body> </body></html>"), QUrl("http://wwww.example.com"));
        QTRY_COMPARE(loadSpy1.count(), 2);
        QTRY_COMPARE(loadSpy2.count(), 2);

        QVariant s1 = evaluateJavaScriptSync(&page1, "localStorage.getItem('test')");
        QCOMPARE(s1.toString(), QString("value1"));
        QVariant s2 = evaluateJavaScriptSync(&page2, "localStorage.getItem('test')");
        QCOMPARE(s2.toString(), QString("value2"));
    }
    // Avoid deleting on-disk dbs before the underlying browser-context has been asynchronously deleted
    QTest::qWait(1000);
    QDir(tmpDirPath() + "/path1").removeRecursively();
    QDir(tmpDirPath() + "/path2").removeRecursively();
}

class CursorTrackedPage : public QWebEnginePage
{
public:

    CursorTrackedPage(QWidget *parent = 0): QWebEnginePage(parent) {
    }

    QString jsSelectedText() {
        return evaluateJavaScriptSync(this, "window.getSelection().toString()").toString();
    }

    int selectionStartOffset() {
        return evaluateJavaScriptSync(this, "window.getSelection().getRangeAt(0).startOffset").toInt();
    }

    int selectionEndOffset() {
        return evaluateJavaScriptSync(this, "window.getSelection().getRangeAt(0).endOffset").toInt();
    }

    // true if start offset == end offset, i.e. no selected text
    int isSelectionCollapsed() {
        return evaluateJavaScriptSync(this, "window.getSelection().getRangeAt(0).collapsed").toBool();
    }
};

void tst_QWebEnginePage::textSelection()
{
    CursorTrackedPage page;

    QString textToSelect("The quick brown fox");
    QString content = QString("<html><body><p id=one>%1</p>" \
        "<p id=two>jumps over the lazy dog</p>" \
        "<p>May the source<br/>be with you!</p></body></html>").arg(textToSelect);

    QSignalSpy loadSpy(&page, SIGNAL(loadFinished(bool)));
    page.setHtml(content);
    QTRY_COMPARE_WITH_TIMEOUT(loadSpy.count(), 1, 20000);

    // these actions must exist
    QVERIFY(page.action(QWebEnginePage::SelectAll) != 0);

    // ..but SelectAll is disabled because the page has no focus due to disabled FocusOnNavigationEnabled.
    QCOMPARE(page.action(QWebEnginePage::SelectAll)->isEnabled(), false);

    // Verify hasSelection returns false since there is no selection yet...
    QVERIFY(!page.hasSelection());
    QVERIFY(page.jsSelectedText().isEmpty());

    // this will select the first paragraph
    QString selectScript = "var range = document.createRange(); " \
        "var node = document.getElementById(\"one\"); " \
        "range.selectNode(node); " \
        "getSelection().addRange(range);";
    evaluateJavaScriptSync(&page, selectScript);

    // Make sure hasSelection returns true, since there is selected text now...
    QTRY_VERIFY(page.hasSelection());
    QCOMPARE(page.selectedText().trimmed(), textToSelect);

    QCOMPARE(page.jsSelectedText().trimmed(), textToSelect);

    // navigate away and check that selection is cleared
    page.load(QUrl("about:blank"));
    QTRY_COMPARE(loadSpy.count(), 2);

    QVERIFY(!page.hasSelection());
    QVERIFY(page.selectedText().isEmpty());

    QVERIFY(page.jsSelectedText().isEmpty());
}


void tst_QWebEnginePage::backActionUpdate()
{
    QWebEngineView view;
    view.resize(640, 480);
    view.show();

    QWebEnginePage *page = view.page();
    QSignalSpy loadSpy(page, &QWebEnginePage::loadFinished);
    QAction *action = page->action(QWebEnginePage::Back);
    QVERIFY(!action->isEnabled());

    page->load(QUrl("qrc:///resources/framedindex.html"));
    QTRY_COMPARE_WITH_TIMEOUT(loadSpy.count(), 1, 20000);
    QVERIFY(!action->isEnabled());

    auto firstAnchorCenterInFrame = [](QWebEnginePage *page, const QString &frameName) {
        QVariantList rectList = evaluateJavaScriptSync(page,
            "(function(){"
            "var frame = document.getElementsByName('" + frameName + "')[0];"
            "var anchor = frame.contentDocument.getElementsByTagName('a')[0];"
            "var rect = anchor.getBoundingClientRect();"
            "return [(rect.left + rect.right) / 2, (rect.top + rect.bottom) / 2];"
        "})()").toList();

        if (rectList.count() != 2) {
            qWarning("firstAnchorCenterInFrame failed.");
            return QPoint();
        }

        return QPoint(rectList.at(0).toInt(), rectList.at(1).toInt());
    };

    QVERIFY(evaluateJavaScriptSync(page, "document.getElementsByName('frame_b')[0].contentDocument == undefined").toBool());
    QTest::mouseClick(view.focusProxy(), Qt::LeftButton, {}, firstAnchorCenterInFrame(page, "frame_c"));
    QTRY_VERIFY(evaluateJavaScriptSync(page, "document.getElementsByName('frame_b')[0].contentDocument != undefined").toBool());
    QTRY_VERIFY(action->isEnabled());
}

void tst_QWebEnginePage::localStorageVisibility()
{
    QWebEngineProfile profile;
    QWebEnginePage webPage1(&profile);
    QWebEnginePage webPage2(&profile);

    webPage1.settings()->setAttribute(QWebEngineSettings::LocalStorageEnabled, true);
    webPage2.settings()->setAttribute(QWebEngineSettings::LocalStorageEnabled, false);

    QSignalSpy loadSpy1(&webPage1, &QWebEnginePage::loadFinished);
    QSignalSpy loadSpy2(&webPage2, &QWebEnginePage::loadFinished);
    webPage1.setHtml(QString("<html><body>test</body></html>"), QUrl("http://www.example.com/"));
    webPage2.setHtml(QString("<html><body>test</body></html>"), QUrl("http://www.example.com/"));
    QTRY_COMPARE_WITH_TIMEOUT(loadSpy1.count(), 1, 20000);
    QTRY_COMPARE_WITH_TIMEOUT(loadSpy2.count(), 1, 20000);

    // The attribute determines the visibility of the window.localStorage object.
    QVERIFY(evaluateJavaScriptSync(&webPage1, QString("(window.localStorage != undefined)")).toBool());
    QVERIFY(!evaluateJavaScriptSync(&webPage2, QString("(window.localStorage != undefined)")).toBool());

    // Toggle local setting for every page and...
    webPage1.settings()->setAttribute(QWebEngineSettings::LocalStorageEnabled, false);
    webPage2.settings()->setAttribute(QWebEngineSettings::LocalStorageEnabled, true);
    // TODO: note this setting is flaky, consider settings().commit()
    // ...first check second page (for storage to appear) as applying settings is batched and done asynchronously
    QTRY_VERIFY(evaluateJavaScriptSync(&webPage2, QString("(window.localStorage != undefined)")).toBool());
    // Switching the feature off does not actively remove the object from webPage1.
    QVERIFY(evaluateJavaScriptSync(&webPage1, QString("(window.localStorage != undefined)")).toBool());

    // The object disappears only after reloading.
    webPage1.triggerAction(QWebEnginePage::Reload);
    webPage2.triggerAction(QWebEnginePage::Reload);
    QTRY_COMPARE(loadSpy1.count(), 2);
    QTRY_COMPARE(loadSpy2.count(), 2);
    QVERIFY(!evaluateJavaScriptSync(&webPage1, QString("(window.localStorage != undefined)")).toBool());
    QVERIFY(evaluateJavaScriptSync(&webPage2, QString("(window.localStorage != undefined)")).toBool());
}

void tst_QWebEnginePage::userAgentNewlineStripping()
{
    QWebEngineProfile profile;
    QWebEnginePage page(&profile);

    profile.setHttpUserAgent(QStringLiteral("My User Agent\nX-New-Http-Header: Oh Noes!"));
    // The user agent will be updated after a page load.
    page.load(QUrl("about:blank"));

    QTRY_COMPARE(evaluateJavaScriptSync(&page, "navigator.userAgent").toString(), QStringLiteral("My User Agent X-New-Http-Header: Oh Noes!"));
}

void tst_QWebEnginePage::crashTests_LazyInitializationOfMainFrame()
{
    {
        QWebEnginePage webPage;
    }
    {
        QWebEnginePage webPage;
        webPage.selectedText();
    }
    {
        QWebEnginePage webPage;
        webPage.triggerAction(QWebEnginePage::Back, true);
    }
}

#if defined(ENABLE_WEBGL) && ENABLE_WEBGL
// https://bugs.webkit.org/show_bug.cgi?id=54138
static void webGLScreenshotWithoutView(bool accelerated)
{
    QWebEnginePage page;
    page.settings()->setAttribute(QWebEngineSettings::WebGLEnabled, true);
    page.settings()->setAttribute(QWebEngineSettings::AcceleratedCompositingEnabled, accelerated);
    page.setHtml("<html><body>"
                       "<canvas id='webgl' width='300' height='300'></canvas>"
                       "<script>document.getElementById('webgl').getContext('experimental-webgl')</script>"
                       "</body></html>");

    takeScreenshot(&page);
}

void tst_QWebEnginePage::acceleratedWebGLScreenshotWithoutView()
{
    webGLScreenshotWithoutView(true);
}

void tst_QWebEnginePage::unacceleratedWebGLScreenshotWithoutView()
{
    webGLScreenshotWithoutView(false);
}
#endif

/**
 * Test fixups for https://bugs.webkit.org/show_bug.cgi?id=30914
 *
 * From JS we test the following conditions.
 *
 *   OK     + QString() => SUCCESS, empty string (but not null)
 *   OK     + "text"    => SUCCESS, "text"
 *   CANCEL + QString() => CANCEL, null string
 *   CANCEL + "text"    => CANCEL, null string
 */
class JSPromptPage : public QWebEnginePage {
    Q_OBJECT
public:
    JSPromptPage()
    {}

    bool javaScriptPrompt(const QUrl &securityOrigin, const QString& msg, const QString& defaultValue, QString* result)
    {
        if (msg == QLatin1String("test1")) {
            *result = QString();
            return true;
        } else if (msg == QLatin1String("test2")) {
            *result = QLatin1String("text");
            return true;
        } else if (msg == QLatin1String("test3")) {
            *result = QString();
            return false;
        } else if (msg == QLatin1String("test4")) {
            *result = QLatin1String("text");
            return false;
        }

        qFatal("Unknown msg.");
        return QWebEnginePage::javaScriptPrompt(securityOrigin, msg, defaultValue, result);
    }
};

void tst_QWebEnginePage::testJSPrompt()
{
    JSPromptPage page;
    bool res;
    QSignalSpy loadSpy(&page, SIGNAL(loadFinished(bool)));
    page.setHtml(QStringLiteral("<html><body></body></html>"));
    QTRY_COMPARE_WITH_TIMEOUT(loadSpy.count(), 1, 20000);

    // OK + QString()
    res = evaluateJavaScriptSync(&page,
            "var retval = prompt('test1');"
            "retval=='' && retval.length == 0;").toBool();
    QVERIFY(res);

    // OK + "text"
    res = evaluateJavaScriptSync(&page,
            "var retval = prompt('test2');"
            "retval=='text' && retval.length == 4;").toBool();
    QVERIFY(res);

    // Cancel + QString()
    res = evaluateJavaScriptSync(&page,
            "var retval = prompt('test3');"
            "retval===null;").toBool();
    QVERIFY(res);

    // Cancel + "text"
    res = evaluateJavaScriptSync(&page,
            "var retval = prompt('test4');"
            "retval===null;").toBool();
    QVERIFY(res);
}

void tst_QWebEnginePage::findText()
{
    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.
    QTRY_VERIFY(m_view->page()->action(QWebEnginePage::SelectAll)->isEnabled());
    m_view->page()->triggerAction(QWebEnginePage::SelectAll);
    QTRY_COMPARE(m_view->hasSelection(), true);

    // Invoking a stopFinding operation will not change or clear the currently selected text,
    // if nothing was found beforehand.
    {
        CallbackSpy<bool> callbackSpy;
        QSignalSpy signalSpy(m_view->page(), &QWebEnginePage::findTextFinished);
        m_view->findText("", {}, 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> callbackSpy;
        QSignalSpy signalSpy(m_view->page(), &QWebEnginePage::findTextFinished);
        m_view->findText("Will not be found", {}, 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());
    }

    // 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> callbackSpy;
        QSignalSpy signalSpy(m_view->page(), &QWebEnginePage::findTextFinished);
        m_view->findText("foo", {}, 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> callbackSpy;
        QSignalSpy signalSpy(m_view->page(), &QWebEnginePage::findTextFinished);
        m_view->findText("", {}, callbackSpy.ref());
        QTRY_VERIFY(callbackSpy.wasCalled());
        QTRY_COMPARE(signalSpy.count(), 1);
        QTRY_COMPARE(m_view->selectedText(), QString("foo"));
    }

    // Invoking startFinding operation for the same text twice. Without any wait, the second one
    // should interrupt the first one.
    {
        QSignalSpy signalSpy(m_view->page(), &QWebEnginePage::findTextFinished);
        m_view->findText("foo", {});
        m_view->findText("foo", {});
        QTRY_COMPARE(signalSpy.count(), 2);
        QTRY_VERIFY(m_view->selectedText().isEmpty());

        QCOMPARE(signalSpy.at(0).value(0).value<QWebEngineFindTextResult>().numberOfMatches(), 0);
        QCOMPARE(signalSpy.at(1).value(0).value<QWebEngineFindTextResult>().numberOfMatches(), 1);
    }
}

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();

    QSignalSpy loadSpy(m_view, SIGNAL(loadFinished(bool)));
    m_view->setHtml(QString("<html><head></head><body><div>foo bar</div></body></html>"));
    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()
{
    CallbackSpy<bool> spy1;
    CallbackSpy<bool> spy2;
    CallbackSpy<bool> spy3;
    CallbackSpy<bool> spy4;
    CallbackSpy<bool> spy5;
    QSignalSpy loadSpy(m_view, SIGNAL(loadFinished(bool)));
    m_view->setHtml(QString("<html><head></head><body><div>abcdefg abcdefg abcdefg abcdefg abcdefg</div></body></html>"));
    QTRY_COMPARE_WITH_TIMEOUT(loadSpy.count(), 1, 20000);
    m_page->findText("abcde", {}, spy1.ref());
    m_page->findText("abcd", {}, spy2.ref());
    m_page->findText("abc", {}, spy3.ref());
    m_page->findText("ab", {}, spy4.ref());
    m_page->findText("a", {}, spy5.ref());
    spy5.waitForResult();
    QVERIFY(spy1.wasCalled());
    QVERIFY(spy2.wasCalled());
    QVERIFY(spy3.wasCalled());
    QVERIFY(spy4.wasCalled());
    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", {}, [this, &callbackCalled](bool found) {
        QVERIFY(found);

        m_view->page()->findText("bar", {}, [&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", {});
        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", {});
    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", {});
    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", {});
    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();
    for (auto w : tlws) {
        if (!oldTopLevelWindows.contains(w)) {
            return w;
        }
    }
    return nullptr;
}

void tst_QWebEnginePage::comboBoxPopupPositionAfterMove()
{
    QWebEngineView view;
    view.move(QGuiApplication::primaryScreen()->availableGeometry().topLeft());
    view.resize(640, 480);
    view.show();

    QSignalSpy loadSpy(&view, SIGNAL(loadFinished(bool)));
    view.setHtml(QLatin1String("<html><head></head><body><select id='foo'>"
                               "<option>fran</option><option>troz</option>"
                               "</select></body></html>"));
    QTRY_COMPARE(loadSpy.count(), 1);
    const auto oldTlws = QGuiApplication::topLevelWindows();
    QWindow *window = view.windowHandle();
    QTest::mouseClick(window, Qt::LeftButton, Qt::KeyboardModifiers(),
                      elementCenter(view.page(), "foo"));

    QWindow *popup = nullptr;
    QTRY_VERIFY(popup = findNewTopLevelWindow(oldTlws));
    QTRY_VERIFY(QGuiApplication::topLevelWindows().contains(popup));
    QTRY_VERIFY(!popup->position().isNull());
    QPoint popupPos = popup->position();

    // Close the popup by clicking somewhere into the page.
    QTest::mouseClick(window, Qt::LeftButton, Qt::KeyboardModifiers(), QPoint(1, 1));
    QTRY_VERIFY(!QGuiApplication::topLevelWindows().contains(popup));

    auto jsViewPosition = [&view]() {
        QLatin1String script("(function() { return [window.screenX, window.screenY]; })()");
        QVariantList posList = evaluateJavaScriptSync(view.page(), script).toList();

        if (posList.count() != 2) {
            qWarning("jsViewPosition failed.");
            return QPoint();
        }

        return QPoint(posList.at(0).toInt(), posList.at(1).toInt());
    };

    // Move the top-level QWebEngineView a little and check the popup's position.
    const QPoint offset(12, 13);
    view.move(view.pos() + offset);
    QTRY_COMPARE(jsViewPosition(), view.pos());
    QTest::mouseClick(window, Qt::LeftButton, Qt::KeyboardModifiers(),
                      elementCenter(view.page(), "foo"));
    QTRY_VERIFY(popup = findNewTopLevelWindow(oldTlws));
    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()
{
    QWidget mainWidget;
    mainWidget.setLayout(new QHBoxLayout);

    QWidget spacer;
    mainWidget.layout()->addWidget(&spacer);

    QWebEngineView view;
    mainWidget.layout()->addWidget(&view);

    QScreen *screen = QGuiApplication::primaryScreen();
    mainWidget.move(screen->availableGeometry().topLeft());
    mainWidget.resize(640, 480);
    mainWidget.show();

    QSignalSpy loadSpy(&view, SIGNAL(loadFinished(bool)));
    view.setHtml(QLatin1String("<html><head></head><body><select autofocus id='foo'>"
                               "<option value=\"narf\">narf</option><option>zort</option>"
                               "</select></body></html>"));
    QTRY_COMPARE(loadSpy.count(), 1);
    const auto oldTlws = QGuiApplication::topLevelWindows();
    QWindow *window = view.window()->windowHandle();
    QTest::mouseClick(window, Qt::LeftButton, Qt::KeyboardModifiers(),
                      view.mapTo(view.window(), elementCenter(view.page(), "foo")));

    QWindow *popup = nullptr;
    QTRY_VERIFY(popup = findNewTopLevelWindow(oldTlws));
    QTRY_VERIFY(QGuiApplication::topLevelWindows().contains(popup));
    QTRY_VERIFY(!popup->position().isNull());
    QPoint popupPos = popup->position();

    // Close the popup by clicking somewhere into the page.
    QTest::mouseClick(window, Qt::LeftButton, Qt::KeyboardModifiers(),
                      view.mapTo(view.window(), QPoint(1, 1)));
    QTRY_VERIFY(!QGuiApplication::topLevelWindows().contains(popup));

    int originalViewWidth = view.size().width();
    auto jsViewWidth = [&view]() {
        QLatin1String script("(function() { return window.innerWidth; })()");
        int viewWidth = evaluateJavaScriptSync(view.page(), script).toInt();
        return viewWidth;
    };

    // Resize the "spacer" widget, and implicitly change the global position of the QWebEngineView.
    const int offset = 50;
    spacer.setMinimumWidth(spacer.size().width() + offset);
    QTRY_COMPARE(jsViewWidth(), originalViewWidth - offset);

    QTest::mouseClick(window, Qt::LeftButton, Qt::KeyboardModifiers(),
                      view.mapTo(view.window(), elementCenter(view.page(), "foo")));
    QTRY_VERIFY(popup = findNewTopLevelWindow(oldTlws));
    QTRY_VERIFY(!popup->position().isNull());
    QCOMPARE(popupPos + QPoint(50, 0), popup->position());
}

#ifdef Q_OS_MAC
void tst_QWebEnginePage::macCopyUnicodeToClipboard()
{
    QString unicodeText = QString::fromUtf8("αβγδεζηθικλμπ");
    m_page->setHtml(QString("<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" /></head><body>%1</body></html>").arg(unicodeText));
    m_page->triggerAction(QWebEnginePage::SelectAll);
    m_page->triggerAction(QWebEnginePage::Copy);

    QString clipboardData = QString::fromUtf8(QApplication::clipboard()->mimeData()->data(QLatin1String("text/html")));

    QVERIFY(clipboardData.contains(QLatin1String("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />")));
    QVERIFY(clipboardData.contains(unicodeText));
}
#endif

void tst_QWebEnginePage::deleteQWebEngineViewTwice()
{
    for (int i = 0; i < 2; ++i) {
        QMainWindow mainWindow;
        QWebEngineView* webView = new QWebEngineView(&mainWindow);
        mainWindow.setCentralWidget(webView);
        webView->load(QUrl("qrc:///resources/frame_a.html"));
        mainWindow.show();
        QSignalSpy spyFinished(webView, &QWebEngineView::loadFinished);
        QVERIFY(spyFinished.wait());
    }
}

class SpyForLoadSignalsOrder : public QStateMachine {
    Q_OBJECT
public:
    SpyForLoadSignalsOrder(QWebEnginePage* page, QObject* parent = 0)
        : QStateMachine(parent)
    {
        connect(page, SIGNAL(loadProgress(int)), SLOT(onLoadProgress(int)));

        QState* waitingForLoadStarted = new QState(this);
        QState* waitingForFirstLoadProgress = new QState(this);
        QState* waitingForLastLoadProgress = new QState(this);
        QState* waitingForLoadFinished = new QState(this);
        QFinalState* final = new QFinalState(this);

        waitingForLoadStarted->addTransition(page, SIGNAL(loadStarted()), waitingForFirstLoadProgress);
        waitingForFirstLoadProgress->addTransition(this, SIGNAL(firstLoadProgress()), waitingForLastLoadProgress);
        waitingForLastLoadProgress->addTransition(this, SIGNAL(lastLoadProgress()), waitingForLoadFinished);
        waitingForLoadFinished->addTransition(page, SIGNAL(loadFinished(bool)), final);

        setInitialState(waitingForLoadStarted);
        start();
    }
    bool isFinished() const
    {
        return !isRunning();
    }
public Q_SLOTS:
    void onLoadProgress(int progress)
    {
        if (progress == 0)
            emit firstLoadProgress();
        else if (progress == 100)
            emit lastLoadProgress();
    }
Q_SIGNALS:
    void firstLoadProgress();
    void lastLoadProgress();
};

void tst_QWebEnginePage::loadSignalsOrder_data()
{
    QTest::addColumn<QUrl>("url");
    QTest::newRow("inline data") << QUrl("data:text/html,This is first page");
    QTest::newRow("simple page") << QUrl("qrc:///resources/content.html");
    QTest::newRow("frameset page") << QUrl("qrc:///resources/index.html");
}

void tst_QWebEnginePage::loadSignalsOrder()
{
    QFETCH(QUrl, url);
    QWebEnginePage page;
    SpyForLoadSignalsOrder loadSpy(&page);
    QSignalSpy spyLoadSpy(&loadSpy, &SpyForLoadSignalsOrder::started);
    QVERIFY(spyLoadSpy.wait(500));
    page.load(url);
    QTRY_VERIFY_WITH_TIMEOUT(loadSpy.isFinished(), 20000);
}

void tst_QWebEnginePage::renderWidgetHostViewNotShowTopLevel()
{
    QWebEnginePage page;
    QSignalSpy spyLoadFinished(&page, SIGNAL(loadFinished(bool)));

    page.load(QUrl("http://qt-project.org"));
    if (!spyLoadFinished.wait(10000) || !spyLoadFinished.at(0).at(0).toBool())
        QSKIP("Couldn't load page from network, skipping test.");
    spyLoadFinished.clear();

    // Loading a different domain will force the creation of a separate render
    // process and should therefore create a new RenderWidgetHostViewQtDelegateWidget.
    page.load(QUrl("http://www.wikipedia.org/"));
    if (!spyLoadFinished.wait(10000) || !spyLoadFinished.at(0).at(0).toBool())
        QSKIP("Couldn't load page from network, skipping test.");

    // Make sure that RenderWidgetHostViewQtDelegateWidgets are not shown as top-level.
    // They should only be made visible when parented to a QWebEngineView.
    const QList<QWidget *> widgets = QApplication::topLevelWidgets();
    for (QWidget *widget : widgets)
        QCOMPARE(widget->isVisible(), false);
}

class GetUserMediaTestPage : public QWebEnginePage {
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 jsGetMedia(const QString &call)
    {
        evaluateJavaScriptSync(this,
            QStringLiteral(
                "var promiseFulfilled = false;"
                "var promiseRejected = false;"
                "navigator.mediaDevices.%1"
                ".then(stream => { promiseFulfilled = true})"
                ".catch(err => { promiseRejected = true})")
            .arg(call));
    }

    void jsGetUserMedia(const QString &constraints)
    {
        jsGetMedia(QStringLiteral("getUserMedia(%1)").arg(constraints));
    }

    bool jsPromiseFulfilled()
    {
        return evaluateJavaScriptSync(this, QStringLiteral("promiseFulfilled")).toBool();
    }

    bool jsPromiseRejected()
    {
        return evaluateJavaScriptSync(this, QStringLiteral("promiseRejected")).toBool();
    }

    void rejectPendingRequest()
    {
        setFeaturePermission(m_requestSecurityOrigin, m_requestedFeature, QWebEnginePage::PermissionDeniedByUser);
        m_gotRequest = false;
    }
    void acceptPendingRequest()
    {
        setFeaturePermission(m_requestSecurityOrigin, m_requestedFeature, QWebEnginePage::PermissionGrantedByUser);
        m_gotRequest = false;
    }

    bool gotFeatureRequest(QWebEnginePage::Feature feature)
    {
        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)
    {
        m_requestedFeature = feature;
        m_requestSecurityOrigin = securityOrigin;
        m_gotRequest = true;
    }

private:
    bool m_gotRequest;
    bool m_loadSucceeded;
    QWebEnginePage::Feature m_requestedFeature;
    QUrl m_requestSecurityOrigin;

};

void tst_QWebEnginePage::getUserMediaRequest_data()
{
    QTest::addColumn<QString>("call");
    QTest::addColumn<QWebEnginePage::Feature>("feature");

    QTest::addRow("device audio")
        << "getUserMedia({audio: true})" << QWebEnginePage::MediaAudioCapture;
    QTest::addRow("device video")
        << "getUserMedia({video: true})" << QWebEnginePage::MediaVideoCapture;
    QTest::addRow("device audio+video")
        << "getUserMedia({audio: true, video: true})" << QWebEnginePage::MediaAudioVideoCapture;
    QTest::addRow("desktop video")
        << "getUserMedia({video: { mandatory: { chromeMediaSource: 'desktop' }}})"
        << QWebEnginePage::DesktopVideoCapture;
    QTest::addRow("desktop audio+video")
        << "getUserMedia({audio: { mandatory: { chromeMediaSource: 'desktop' }}, video: { mandatory: { chromeMediaSource: 'desktop' }}})"
        << QWebEnginePage::DesktopAudioVideoCapture;
    QTest::addRow("display video")
        << "getDisplayMedia()" << QWebEnginePage::DesktopVideoCapture;
}

void tst_QWebEnginePage::getUserMediaRequest()
{
    QFETCH(QString, call);
    QFETCH(QWebEnginePage::Feature, feature);

    GetUserMediaTestPage page;
    QWebEngineView view;
    if (feature == QWebEnginePage::DesktopVideoCapture || feature == QWebEnginePage::DesktopAudioVideoCapture) {
        // Desktop capture needs to be on a desktop.
        view.setPage(&page);
        view.resize(640, 480);
        view.show();
        QVERIFY(QTest::qWaitForWindowExposed(&view));
    }

    QTRY_VERIFY_WITH_TIMEOUT(page.loadSucceeded(), 60000);
    page.settings()->setAttribute(QWebEngineSettings::ScreenCaptureEnabled, true);

    // 1. Rejecting request on C++ side should reject promise on JS side.
    page.jsGetMedia(call);
    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.jsGetMedia(call);
    QTRY_VERIFY(page.gotFeatureRequest(feature));
    page.acceptPendingRequest();
    QTRY_VERIFY(page.jsPromiseFulfilled() || page.jsPromiseRejected());

    // 3. Media feature permissions are not remembered.
    page.jsGetMedia(call);
    QTRY_VERIFY(page.gotFeatureRequest(feature));
    page.acceptPendingRequest();
    QTRY_VERIFY(page.jsPromiseFulfilled() || page.jsPromiseRejected());
}

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());
}

// Try to trigger any possible race condition between the UI thread (permission
// management) and the audio/device thread (desktop capture initialization).
void tst_QWebEnginePage::getUserMediaRequestDesktopVideoManyPages()
{
    const QString constraints = QStringLiteral("{video: { mandatory: { chromeMediaSource: 'desktop' }}}");
    const QWebEnginePage::Feature feature = QWebEnginePage::DesktopVideoCapture;
    std::vector<GetUserMediaTestPage> pages(10);

    // Desktop capture needs to be on a desktop
    std::vector<QWebEngineView> views(10);
    for (size_t i = 0; i < views.size(); ++i) {
        QWebEngineView *view = &(views[i]);
        GetUserMediaTestPage *page = &(pages[i]);
        view->setPage(page);
        view->resize(640, 480);
        view->show();
        QVERIFY(QTest::qWaitForWindowExposed(view));
    }

    for (GetUserMediaTestPage &page : pages)
        QTRY_VERIFY_WITH_TIMEOUT(page.loadSucceeded(), 20000);
    for (GetUserMediaTestPage &page : pages)
        page.settings()->setAttribute(QWebEngineSettings::ScreenCaptureEnabled, true);
    for (GetUserMediaTestPage &page : pages)
        page.jsGetUserMedia(constraints);
    for (GetUserMediaTestPage &page : pages)
        QTRY_VERIFY(page.gotFeatureRequest(feature));
    for (GetUserMediaTestPage &page : pages)
        page.acceptPendingRequest();
    for (GetUserMediaTestPage &page : pages)
        QTRY_VERIFY(page.jsPromiseFulfilled() || page.jsPromiseRejected());
}

// Try to trigger any possible race condition between the UI or audio/device
// threads and the desktop capture thread, where the capture actually happens.
void tst_QWebEnginePage::getUserMediaRequestDesktopVideoManyRequests()
{
    const QString constraints = QStringLiteral("{video: { mandatory: { chromeMediaSource: 'desktop' }}}");
    const QWebEnginePage::Feature feature = QWebEnginePage::DesktopVideoCapture;
    GetUserMediaTestPage page;

    // Desktop capture needs to be on a desktop
    QWebEngineView view;
    view.setPage(&page);
    view.resize(640, 480);
    view.show();
    QVERIFY(QTest::qWaitForWindowExposed(&view));

    QTRY_VERIFY_WITH_TIMEOUT(page.loadSucceeded(), 20000);
    page.settings()->setAttribute(QWebEngineSettings::ScreenCaptureEnabled, true);
    for (int i = 0; i != 100; ++i) {
        page.jsGetUserMedia(constraints);
        QTRY_VERIFY(page.gotFeatureRequest(feature));
        page.acceptPendingRequest();
        QTRY_VERIFY(page.jsPromiseFulfilled() || page.jsPromiseRejected());
    }
}

void tst_QWebEnginePage::savePage()
{
    QWebEngineView view;
    QWebEnginePage *page = view.page();

    connect(page->profile(), &QWebEngineProfile::downloadRequested,
            [] (QWebEngineDownloadItem *item)
    {
        connect(item, &QWebEngineDownloadItem::finished,
                &QTestEventLoop::instance(), &QTestEventLoop::exitLoop, Qt::QueuedConnection);
    });

    const QString urlPrefix = QStringLiteral("data:text/html,<h1>");
    const QString text = QStringLiteral("There is Thingumbob shouting!");
    page->load(QUrl(urlPrefix + text));
    QSignalSpy spyFinished(page, &QWebEnginePage::loadFinished);
    QVERIFY(spyFinished.wait());
    QCOMPARE(toPlainTextSync(page), text);

    // Save the loaded page as HTML.
    QTemporaryDir tempDir(QDir::tempPath() + "/tst_qwebengineview-XXXXXX");
    const QString filePath = tempDir.path() + "/thingumbob.html";
    page->save(filePath, QWebEngineDownloadItem::CompleteHtmlSaveFormat);
    QTestEventLoop::instance().enterLoop(10);

    // Load something else.
    page->load(QUrl(urlPrefix + QLatin1String("It's a Snark!")));
    QVERIFY(spyFinished.wait());
    QVERIFY(toPlainTextSync(page) != text);

    // Load the saved page and compare the contents.
    page->load(QUrl::fromLocalFile(filePath));
    QVERIFY(spyFinished.wait());
    QCOMPARE(toPlainTextSync(page), text);
}

void tst_QWebEnginePage::openWindowDefaultSize()
{
    TestPage page;
    QSignalSpy windowCreatedSpy(&page, SIGNAL(windowCreated()));
    QWebEngineView view;
    page.setView(&view);
    view.show();

    page.settings()->setAttribute(QWebEngineSettings::JavascriptCanOpenWindows, true);
    // Open a default window.
    page.runJavaScript("window.open()");
    QTRY_COMPARE(windowCreatedSpy.count(), 1);
    // Open a too small window.
    evaluateJavaScriptSync(&page, "window.open('','about:blank','width=10,height=10')");
    QTRY_COMPARE(windowCreatedSpy.count(), 2);

    // The number of popups created should be two.
    QCOMPARE(page.createdWindows.size(), 2);

    QRect requestedGeometry = page.createdWindows[0]->requestedGeometry;
    // Check default size has been requested.
    QCOMPARE(requestedGeometry.width(), 0);
    QCOMPARE(requestedGeometry.height(), 0);

    requestedGeometry = page.createdWindows[1]->requestedGeometry;
    // Check minimum size has been requested.
    QCOMPARE(requestedGeometry.width(), 100);
    QCOMPARE(requestedGeometry.height(), 100);
}

bool tst_QWebEnginePage::isFalseJavaScriptResult(QWebEnginePage *page, const QString &javaScript)
{
    QVariant result = evaluateJavaScriptSync(page, javaScript);
    return !result.isNull() && result.isValid() && result == QVariant(false);
}

bool tst_QWebEnginePage::isTrueJavaScriptResult(QWebEnginePage *page, const QString &javaScript)
{
    QVariant result = evaluateJavaScriptSync(page, javaScript);
    return !result.isNull() && result.isValid() && result == QVariant(true);
}

bool tst_QWebEnginePage::isEmptyListJavaScriptResult(QWebEnginePage *page, const QString &javaScript)
{
    QVariant result = evaluateJavaScriptSync(page, javaScript);
    return !result.isNull() && result.isValid() && result == QList<QVariant>();
}

void tst_QWebEnginePage::runJavaScript()
{
    TestPage page;
    QVariant result;
    QVariantMap map;

    QVERIFY(isFalseJavaScriptResult(&page, "false"));
    QCOMPARE(evaluateJavaScriptSync(&page, "2").toInt(), 2);
    QCOMPARE(evaluateJavaScriptSync(&page, "2.5").toDouble(), 2.5);
    QCOMPARE(evaluateJavaScriptSync(&page, "\"Test\"").toString(), "Test");
    QVERIFY(isEmptyListJavaScriptResult(&page, "[]"));

    map.insert(QStringLiteral("test"), QVariant(2));
    QCOMPARE(evaluateJavaScriptSync(&page, "var el = {\"test\": 2}; el").toMap(), map);

    QVERIFY(evaluateJavaScriptSync(&page, "null").isNull());

    result = evaluateJavaScriptSync(&page, "undefined");
    QVERIFY(result.isNull() && !result.isValid());

    QCOMPARE(evaluateJavaScriptSync(&page, "new Date(42000)").toDate(), QVariant(42.0).toDate());
    QCOMPARE(evaluateJavaScriptSync(&page, "new ArrayBuffer(8)").toByteArray(), QByteArray(8, 0));

    result = evaluateJavaScriptSync(&page, "(function(){})");
    QVERIFY(result.isNull() && !result.isValid());

    QCOMPARE(evaluateJavaScriptSync(&page, "new Promise(function(){})"), QVariant(QVariantMap{}));
}

void tst_QWebEnginePage::runJavaScriptDisabled()
{
    QWebEnginePage page;
    QSignalSpy spy(&page, &QWebEnginePage::loadFinished);
    page.settings()->setAttribute(QWebEngineSettings::JavascriptEnabled, false);
    // Settings changes take effect asynchronously. The load and wait ensure
    // that the settings are applied by the time we start to execute JavaScript.
    page.load(QStringLiteral("about:blank"));
    QTRY_COMPARE_WITH_TIMEOUT(spy.count(), 1, 20000);
    QCOMPARE(evaluateJavaScriptSyncInWorld(&page, QStringLiteral("1+1"), QWebEngineScript::MainWorld),
             QVariant());
    QCOMPARE(evaluateJavaScriptSyncInWorld(&page, QStringLiteral("1+1"), QWebEngineScript::ApplicationWorld),
             QVariant(2));
}

// Based on https://bugreports.qt.io/browse/QTBUG-73876
void tst_QWebEnginePage::runJavaScriptFromSlot()
{
    QWebEngineProfile profile;
    QWebEnginePage page(&profile);

    QSignalSpy loadFinishedSpy(&page, &QWebEnginePage::loadFinished);
    page.setHtml("<html><body>"
                 "  <input type='text' id='input1' value='QtWebEngine' size='50' />"
                 "</body></html>");
    QTRY_COMPARE(loadFinishedSpy.count(), 1);

    bool done = false;
    connect(&page, &QWebEnginePage::selectionChanged, [&]() {
        QTRY_COMPARE(evaluateJavaScriptSync(&page, QStringLiteral("2+2")), QVariant(4));
        done = true;
    });
    evaluateJavaScriptSync(&page, QStringLiteral("const input = document.getElementById('input1');"
                                                 "input.focus();"
                                                 "input.select();"));
    QTRY_VERIFY(done);
}

void tst_QWebEnginePage::fullScreenRequested()
{
    QWebEngineView view;
    QWebEnginePage* page = view.page();
    view.show();

    page->settings()->setAttribute(QWebEngineSettings::FullScreenSupportEnabled, true);

    QSignalSpy loadSpy(&view, SIGNAL(loadFinished(bool)));
    page->load(QUrl("qrc:///resources/fullscreen.html"));
    QTRY_COMPARE(loadSpy.count(), 1);

    QTRY_VERIFY(isTrueJavaScriptResult(page, "document.webkitFullscreenEnabled"));
    QVERIFY(isFalseJavaScriptResult(page, "document.webkitIsFullScreen"));

    // FullscreenRequest must be a user gesture
    bool acceptRequest = true;
    connect(page, &QWebEnginePage::fullScreenRequested,
        [&acceptRequest](QWebEngineFullScreenRequest request) {
        if (acceptRequest) request.accept(); else request.reject();
    });

    QTest::keyPress(view.focusProxy(), Qt::Key_Space);
    QTRY_VERIFY(isTrueJavaScriptResult(page, "document.webkitIsFullScreen"));
    page->runJavaScript("document.webkitExitFullscreen()");
    QTRY_VERIFY(isFalseJavaScriptResult(page, "document.webkitIsFullScreen"));

    acceptRequest = false;

    QVERIFY(isTrueJavaScriptResult(page, "document.webkitFullscreenEnabled"));
    QTest::keyPress(view.focusProxy(), Qt::Key_Space);
    QTRY_VERIFY(isFalseJavaScriptResult(page, "document.webkitIsFullScreen"));
}

void tst_QWebEnginePage::quotaRequested()
{
    ConsolePage page;
    QWebEngineView view;
    view.setPage(&page);
    QSignalSpy loadFinishedSpy(&page, SIGNAL(loadFinished(bool)));
    page.load(QUrl("qrc:///resources/content.html"));
    QVERIFY(loadFinishedSpy.wait());

    connect(&page, &QWebEnginePage::quotaRequested,
            [] (QWebEngineQuotaRequest request)
    {
        if (request.requestedSize() <= 5000)
            request.accept();
        else
            request.reject();
    });

    evaluateJavaScriptSync(&page,
        "navigator.webkitPersistentStorage.requestQuota(1024, function(grantedSize) {" \
            "console.log(grantedSize);" \
        "});");
    QTRY_COMPARE(page.messages.count(), 1);
    QTRY_COMPARE(page.messages[0], QString("1024"));

    evaluateJavaScriptSync(&page,
        "navigator.webkitPersistentStorage.requestQuota(6000, function(grantedSize) {" \
            "console.log(grantedSize);" \
        "});");
    QTRY_COMPARE(page.messages.count(), 2);
    QTRY_COMPARE(page.messages[1], QString("1024"));

    evaluateJavaScriptSync(&page,
        "navigator.webkitPersistentStorage.queryUsageAndQuota(function(usedBytes, grantedBytes) {" \
            "console.log(usedBytes + ', ' + grantedBytes);" \
        "});");
    QTRY_COMPARE(page.messages.count(), 3);
    QTRY_COMPARE(page.messages[2], QString("0, 1024"));
}

void tst_QWebEnginePage::symmetricUrl()
{
    QWebEngineView view;
    QSignalSpy loadFinishedSpy(view.page(), SIGNAL(loadFinished(bool)));

    QVERIFY(view.url().isEmpty());

    QCOMPARE(view.history()->count(), 0);

    QUrl dataUrl("data:text/html,<h1>Test");

    view.setUrl(dataUrl);
    QCOMPARE(view.url(), dataUrl);
    QCOMPARE(view.history()->count(), 0);

    // loading is _not_ immediate, so the text isn't set just yet.
    QVERIFY(toPlainTextSync(view.page()).isEmpty());

    QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.count(), 1, 20000);

    QCOMPARE(view.history()->count(), 1);
    QCOMPARE(toPlainTextSync(view.page()), QString("Test"));

    QUrl dataUrl2("data:text/html,<h1>Test2");
    QUrl dataUrl3("data:text/html,<h1>Test3");

    view.setUrl(dataUrl2);
    view.setUrl(dataUrl3);

    QCOMPARE(view.url(), dataUrl3);

    // setUrl(dataUrl3) might override the pending load for dataUrl2. Or not.
    QTRY_VERIFY(loadFinishedSpy.count() >= 2);
    QTRY_VERIFY(loadFinishedSpy.count() <= 3);

    // setUrl(dataUrl3) might stop Chromium from adding a navigation entry for dataUrl2,
    // depending on whether the load of dataUrl2 could be completed in time.
    QVERIFY(view.history()->count() >= 2);
    QVERIFY(view.history()->count() <= 3);

    QCOMPARE(toPlainTextSync(view.page()), QString("Test3"));
}

void tst_QWebEnginePage::progressSignal()
{
    QSignalSpy progressSpy(m_view, SIGNAL(loadProgress(int)));

    QUrl dataUrl("data:text/html,<h1>Test");
    m_view->setUrl(dataUrl);

    QSignalSpy spyFinished(m_view, &QWebEngineView::loadFinished);
    QVERIFY(spyFinished.wait());

    QVERIFY(progressSpy.size() >= 2);
    int previousValue = -1;
    for (QSignalSpy::ConstIterator it = progressSpy.begin(); it < progressSpy.end(); ++it) {
        int current = (*it).first().toInt();
        // verbose output for faulty condition
        if (!(current >= previousValue)) {
            qDebug() << "faulty progress values:";
            for (QSignalSpy::ConstIterator it2 = progressSpy.begin(); it2 < progressSpy.end(); ++it2)
                qDebug() << (*it2).first().toInt();
            QVERIFY(current >= previousValue);
        }
        previousValue = current;
    }

    // But we always end at 100%
    QCOMPARE(progressSpy.last().first().toInt(), 100);
}

void tst_QWebEnginePage::urlChange()
{
    QSignalSpy urlSpy(m_page, &QWebEnginePage::urlChanged);

    QUrl dataUrl("data:text/html,<h1>Test");
    m_view->setUrl(dataUrl);

    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);

    QTRY_COMPARE(urlSpy.size(), 1);
    QCOMPARE(urlSpy.takeFirst().value(0).toUrl(), dataUrl2);

    QUrl testUrl("http://test.qt.io/");
    m_view->setHtml(QStringLiteral("<h1>Test</h1"), testUrl);

    QTRY_COMPARE(urlSpy.size(), 1);
    QCOMPARE(urlSpy.takeFirst().value(0).toUrl(), testUrl);
}

class FakeReply : public QNetworkReply {
    Q_OBJECT

public:
    static const QUrl urlFor404ErrorWithoutContents;

    FakeReply(const QNetworkRequest& request, QObject* parent = 0)
        : QNetworkReply(parent)
    {
        setOperation(QNetworkAccessManager::GetOperation);
        setRequest(request);
        setUrl(request.url());
        if (request.url() == QUrl("qrc:/test1.html")) {
            setHeader(QNetworkRequest::LocationHeader, QString("qrc:/test2.html"));
            setAttribute(QNetworkRequest::RedirectionTargetAttribute, QUrl("qrc:/test2.html"));
            QTimer::singleShot(0, this, SLOT(continueRedirect()));
        }
#ifndef QT_NO_OPENSSL
        else if (request.url() == QUrl("qrc:/fake-ssl-error.html")) {
            setError(QNetworkReply::SslHandshakeFailedError, tr("Fake error!"));
            QTimer::singleShot(0, this, SLOT(continueError()));
        }
#endif
        else if (request.url().host() == QLatin1String("abcdef.abcdef")) {
            setError(QNetworkReply::HostNotFoundError, tr("Invalid URL"));
            QTimer::singleShot(0, this, SLOT(continueError()));
        } else if (request.url() == FakeReply::urlFor404ErrorWithoutContents) {
            setError(QNetworkReply::ContentNotFoundError, "Not found");
            setAttribute(QNetworkRequest::HttpStatusCodeAttribute, 404);
            QTimer::singleShot(0, this, SLOT(continueError()));
        }

        open(QIODevice::ReadOnly);
    }
    ~FakeReply()
    {
        close();
    }
    virtual void abort() {}
    virtual void close() {}

protected:
    qint64 readData(char*, qint64)
    {
        return 0;
    }

private Q_SLOTS:
    void continueRedirect()
    {
        emit metaDataChanged();
        emit finished();
    }

    void continueError()
    {
        emit error(this->error());
        emit finished();
    }
};

const QUrl FakeReply::urlFor404ErrorWithoutContents = QUrl("http://this.will/return-http-404-error-without-contents.html");

class FakeNetworkManager : public QNetworkAccessManager {
    Q_OBJECT

public:
    FakeNetworkManager(QObject* parent) : QNetworkAccessManager(parent) { }

protected:
    virtual QNetworkReply* createRequest(Operation op, const QNetworkRequest& request, QIODevice* outgoingData)
    {
        QString url = request.url().toString();
        if (op == QNetworkAccessManager::GetOperation) {
#ifndef QT_NO_OPENSSL
            if (url == "qrc:/fake-ssl-error.html") {
                FakeReply* reply = new FakeReply(request, this);
                QList<QSslError> errors;
                emit sslErrors(reply, errors << QSslError(QSslError::UnspecifiedError));
                return reply;
            }
#endif
            if (url == "qrc:/test1.html" || url == "http://abcdef.abcdef/" || request.url() == FakeReply::urlFor404ErrorWithoutContents)
                return new FakeReply(request, this);
        }

        return QNetworkAccessManager::createRequest(op, request, outgoingData);
    }
};

void tst_QWebEnginePage::requestedUrlAfterSetAndLoadFailures()
{
    QWebEnginePage page;
    page.settings()->setAttribute(QWebEngineSettings::ErrorPageEnabled, false);
    QSignalSpy spy(&page, SIGNAL(loadFinished(bool)));

    const QUrl first("http://abcdef.abcdef/");
    page.setUrl(first);
    QTRY_COMPARE_WITH_TIMEOUT(spy.count(), 1, 20000);
    QCOMPARE(page.url(), first);
    QCOMPARE(page.requestedUrl(), first);
    QVERIFY(!spy.at(0).first().toBool());

    const QUrl second("http://abcdef.abcdef/another_page.html");
    QVERIFY(first != second);

    page.load(second);
    QTRY_COMPARE_WITH_TIMEOUT(spy.count(), 2, 20000);
    QCOMPARE(page.url(), first);
    QCOMPARE(page.requestedUrl(), second);
    QVERIFY(!spy.at(1).first().toBool());
}

void tst_QWebEnginePage::asyncAndDelete()
{
    QScopedPointer<QWebEnginePage> page(new QWebEnginePage);
    CallbackSpy<QString> plainTextSpy;
    CallbackSpy<QString> htmlSpy;
    page->toPlainText(plainTextSpy.ref());
    page->toHtml(htmlSpy.ref());

    page.reset();
    // Pending callbacks should be called with an empty value in the page's destructor.
    QCOMPARE(plainTextSpy.waitForResult(), QString());
    QVERIFY(plainTextSpy.wasCalled());
    QCOMPARE(htmlSpy.waitForResult(), QString());
    QVERIFY(htmlSpy.wasCalled());
}

void tst_QWebEnginePage::earlyToHtml()
{
    QString html("<html><head></head><body></body></html>");
    QCOMPARE(toHtmlSync(m_view->page()), html);
}

void tst_QWebEnginePage::setHtml()
{
    QString html("<html><head></head><body><p>hello world</p></body></html>");
    QSignalSpy spy(m_view->page(), SIGNAL(loadFinished(bool)));
    m_view->page()->setHtml(html);
    QVERIFY(spy.wait());
    QCOMPARE(toHtmlSync(m_view->page()), html);
}

void tst_QWebEnginePage::setHtmlWithImageResource()
{
    // We allow access to qrc resources from any security origin, including local and anonymous

    QLatin1String html("<html><body><p>hello world</p><img src='qrc:/resources/image.png'/></body></html>");
    QWebEnginePage page;

    QSignalSpy spy(&page, SIGNAL(loadFinished(bool)));
    page.setHtml(html, QUrl("file:///path/to/file"));
    QTRY_COMPARE_WITH_TIMEOUT(spy.count(), 1, 12000);

    QCOMPARE(evaluateJavaScriptSync(&page, "document.images.length").toInt(), 1);
    QCOMPARE(evaluateJavaScriptSync(&page, "document.images[0].width").toInt(), 128);
    QCOMPARE(evaluateJavaScriptSync(&page, "document.images[0].height").toInt(), 128);

    // Now we test the opposite: without a baseUrl as a local file, we can still request qrc resources.

    page.setHtml(html);
    QTRY_COMPARE(spy.count(), 2);
    QCOMPARE(evaluateJavaScriptSync(&page, "document.images.length").toInt(), 1);
    QCOMPARE(evaluateJavaScriptSync(&page, "document.images[0].width").toInt(), 128);
    QCOMPARE(evaluateJavaScriptSync(&page, "document.images[0].height").toInt(), 128);
}

void tst_QWebEnginePage::setHtmlWithStylesheetResource()
{
    const char* htmlData =
        "<html>"
            "<head>"
                "<link rel='stylesheet' href='qrc:/resources/style.css' type='text/css' />"
            "</head>"
            "<body>"
                "<p id='idP'>some text</p>"
            "</body>"
        "</html>";
    QLatin1String html(htmlData);
    QWebEnginePage page;
    QSignalSpy spyFinished(&page, &QWebEnginePage::loadFinished);

    // We allow access to qrc resources from any security origin, including local and anonymous
    page.setHtml(html, QUrl("file:///path/to/file"));
    QVERIFY(spyFinished.wait());
    QCOMPARE(evaluateJavaScriptSync(&page, "window.getComputedStyle(document.getElementById('idP')).color").toString(), QString("rgb(255, 0, 0)"));

    page.setHtml(html, QUrl(QLatin1String("qrc:/")));
    QVERIFY(spyFinished.wait());
    QCOMPARE(evaluateJavaScriptSync(&page, "window.getComputedStyle(document.getElementById('idP')).color").toString(), QString("rgb(255, 0, 0)"));

    // Now we test the opposite: without a baseUrl as a local file, we can still request qrc resources.
    page.setHtml(html);
    QVERIFY(spyFinished.wait());
    QCOMPARE(evaluateJavaScriptSync(&page, "window.getComputedStyle(document.getElementById('idP')).color").toString(), QString("rgb(255, 0, 0)"));
}

void tst_QWebEnginePage::setHtmlWithBaseURL()
{
    // This tests if baseUrl is indeed affecting the relative paths from resources.
    // As we are using a local file as baseUrl, its security origin should be able to load local resources.

    if (!QDir(TESTS_SOURCE_DIR).exists())
        W_QSKIP(QString("This test requires access to resources found in '%1'").arg(TESTS_SOURCE_DIR).toLatin1().constData(), SkipAll);

    QDir::setCurrent(TESTS_SOURCE_DIR);

    QString html("<html><body><p>hello world</p><img src='resources/image2.png'/></body></html>");

    QWebEnginePage page;

    // in few seconds, the image should be completey loaded
    QSignalSpy spy(&page, SIGNAL(loadFinished(bool)));

    page.setHtml(html, QUrl::fromLocalFile(TESTS_SOURCE_DIR));
    QSignalSpy spyFinished(&page, &QWebEnginePage::loadFinished);
    QVERIFY(spyFinished.wait());
    QCOMPARE(spy.count(), 1);

    QCOMPARE(evaluateJavaScriptSync(&page, "document.images.length").toInt(), 1);
    QCOMPARE(evaluateJavaScriptSync(&page, "document.images[0].width").toInt(), 128);
    QCOMPARE(evaluateJavaScriptSync(&page, "document.images[0].height").toInt(), 128);

    // no history item has to be added.
    QCOMPARE(m_view->page()->history()->count(), 0);
}

class MyPage : public QWebEnginePage
{
public:
    MyPage() :  QWebEnginePage(), alerts(0) {}
    int alerts;

protected:
    virtual void javaScriptAlert(const QUrl &securityOrigin, const QString &msg)
    {
        alerts++;
        QCOMPARE(securityOrigin, QUrl(QStringLiteral("http://test.origin.com/")));
        QCOMPARE(msg, QString("foo"));
    }
};

void tst_QWebEnginePage::setHtmlWithJSAlert()
{
    QString html("<html><head></head><body><script>alert('foo');</script><p>hello world</p></body></html>");
    MyPage page;
    page.setHtml(html, QUrl(QStringLiteral("http://test.origin.com/path#fragment")));
    QSignalSpy spyFinished(&page, &QWebEnginePage::loadFinished);
    QVERIFY(spyFinished.wait());
    QCOMPARE(page.alerts, 1);
    QCOMPARE(toHtmlSync(&page), html);
}

void tst_QWebEnginePage::setHtmlWithModuleImport()
{
    HttpServer server;
    connect(&server, &HttpServer::newRequest, [&](HttpReqRep *rr) {
        if (rr->requestMethod() == "GET" && rr->requestPath() == "/fibonacci.mjs") {
            rr->setResponseBody("export function fib(n) {\n"
                                "    return n < 2 ? n : fib(n-1) + fib(n-2)\n"
                                "}\n");
            rr->setResponseHeader("Content-Type", "text/javascript");
            rr->sendResponse();
        } else {
            rr->setResponseStatus(404);
            rr->sendResponse();
        }
    });
    QVERIFY(server.start());

    QString html("<html>\n"
                 "  <head>\n"
                 "    <script type='module'>\n"
                 "      import {fib} from './fibonacci.mjs'\n"
                 "      window.fib7 = fib(7)\n"
                 "    </script>\n"
                 "  </head>\n"
                 "  <body></body>\n"
                 "</html>\n");

    QWebEnginePage page;
    QSignalSpy spy(&page, &QWebEnginePage::loadFinished);
    page.setHtml(html, server.url());
    QVERIFY(spy.count() || spy.wait());

    QCOMPARE(evaluateJavaScriptSync(&page, "fib7"), QVariant(13));
}

void tst_QWebEnginePage::baseUrl_data()
{
    QTest::addColumn<QString>("html");
    QTest::addColumn<QUrl>("loadUrl");
    QTest::addColumn<QUrl>("url");
    QTest::addColumn<QUrl>("baseUrl");

    QTest::newRow("null") << QString() << QUrl()
                          << QUrl("about:blank") << QUrl("about:blank");

    QTest::newRow("foo") << QString() << QUrl("http://foobar.baz/")
                         << QUrl("http://foobar.baz/") << QUrl("http://foobar.baz/");

    QString html = "<html>"
        "<head>"
            "<base href=\"http://foobaz.bar/\" />"
        "</head>"
    "</html>";
    QTest::newRow("customBaseUrl") << html << QUrl("http://foobar.baz/")
                                   << QUrl("http://foobar.baz/") << QUrl("http://foobaz.bar/");
}

void tst_QWebEnginePage::baseUrl()
{
    QFETCH(QString, html);
    QFETCH(QUrl, loadUrl);
    QFETCH(QUrl, url);
    QFETCH(QUrl, baseUrl);

    QSignalSpy loadSpy(m_page, SIGNAL(loadFinished(bool)));
    m_page->setHtml(html, loadUrl);
    QTRY_COMPARE(loadSpy.count(), 1);
    QCOMPARE(m_page->url(), url);
    QEXPECT_FAIL("null", "Slight change: We now translate QUrl() to about:blank for the virtual url, but not for the baseUrl", Continue);
    QCOMPARE(baseUrlSync(m_page), baseUrl);
}

void tst_QWebEnginePage::scrollPosition()
{
    // enlarged image in a small viewport, to provoke the scrollbars to appear
    QString html("<html><body><img src='qrc:/image.png' height=500 width=500/></body></html>");

    QWebEngineView view;
    view.setFixedSize(200,200);
    view.show();

    QVERIFY(QTest::qWaitForWindowExposed(&view));

    QSignalSpy loadSpy(view.page(), SIGNAL(loadFinished(bool)));
    view.setHtml(html);
    QTRY_COMPARE(loadSpy.count(), 1);

    // try to set the scroll offset programmatically
    view.page()->runJavaScript("window.scrollTo(23, 29);");
    QTRY_COMPARE(view.page()->scrollPosition().x(), 23 * view.windowHandle()->devicePixelRatio());
    QCOMPARE(view.page()->scrollPosition().y(), 29 * view.windowHandle()->devicePixelRatio());

    int x = evaluateJavaScriptSync(view.page(), "window.scrollX").toInt();
    int y = evaluateJavaScriptSync(view.page(), "window.scrollY").toInt();
    QCOMPARE(x, 23);
    QCOMPARE(y, 29);
}

void tst_QWebEnginePage::scrollbarsOff()
{
    QWebEngineView view;
    view.page()->settings()->setAttribute(QWebEngineSettings::ShowScrollBars, false);

    QString html("<html><body>"
                 "   <div style='margin-top:1000px ; margin-left:1000px'>"
                 "       <a id='offscreen' href='a'>End</a>"
                 "   </div>"
                 "</body></html>");

    QSignalSpy loadSpy(&view, SIGNAL(loadFinished(bool)));
    view.setHtml(html);
    QTRY_COMPARE(loadSpy.count(), 1);
    QVERIFY(evaluateJavaScriptSync(view.page(), "innerWidth == document.documentElement.offsetWidth").toBool());
}

class WebView : public QWebEngineView
{
    Q_OBJECT
signals:
    void repaintRequested();

protected:
    bool event(QEvent *event) {
        if (event->type() == QEvent::UpdateRequest)
            emit repaintRequested();

        return QWebEngineView::event(event);
    }
};

void tst_QWebEnginePage::evaluateWillCauseRepaint()
{
    WebView view;
    view.resize(640, 480);
    view.show();
    QVERIFY(QTest::qWaitForWindowExposed(&view));

    QString html("<html><body>"
                 "  top"
                 "  <div id=\"junk\" style=\"display: block;\">junk</div>"
                 "  bottom"
                 "</body></html>");

    QSignalSpy loadSpy(&view, SIGNAL(loadFinished(bool)));
    view.setHtml(html);
    QTRY_COMPARE(loadSpy.count(), 1);

    evaluateJavaScriptSync(view.page(), "document.getElementById('junk').style.display = 'none';");
    QSignalSpy repaintSpy(&view, &WebView::repaintRequested);
    QVERIFY(repaintSpy.wait());
}

void tst_QWebEnginePage::setContent_data()
{
    QTest::addColumn<QString>("mimeType");
    QTest::addColumn<QByteArray>("testContents");
    QTest::addColumn<QString>("expected");

    QString str = QString::fromUtf8("ὕαλον ϕαγεῖν δύναμαι· τοῦτο οὔ με βλάπτει");
    QTest::newRow("UTF-8 plain text") << "text/plain; charset=utf-8" << str.toUtf8() << str;

    QTextCodec *utf16 = QTextCodec::codecForName("UTF-16");
    if (utf16)
        QTest::newRow("UTF-16 plain text") << "text/plain; charset=utf-16" << utf16->fromUnicode(str) << str;

    str = QString::fromUtf8("Une chaîne de caractères à sa façon.");
    QTest::newRow("latin-1 plain text") << "text/plain; charset=iso-8859-1" << str.toLatin1() << str;


}

void tst_QWebEnginePage::setContent()
{
    QFETCH(QString, mimeType);
    QFETCH(QByteArray, testContents);
    QFETCH(QString, expected);
    QSignalSpy loadSpy(m_page, SIGNAL(loadFinished(bool)));
    m_view->setContent(testContents, mimeType);
    QVERIFY(loadSpy.wait());
    QCOMPARE(toPlainTextSync(m_view->page()), expected);
}

class CacheNetworkAccessManager : public QNetworkAccessManager {
public:
    CacheNetworkAccessManager(QObject* parent = 0)
        : QNetworkAccessManager(parent)
        , m_lastCacheLoad(QNetworkRequest::PreferNetwork)
    {
    }

    virtual QNetworkReply* createRequest(Operation, const QNetworkRequest& request, QIODevice*)
    {
        QVariant cacheLoad = request.attribute(QNetworkRequest::CacheLoadControlAttribute);
        if (cacheLoad.isValid())
            m_lastCacheLoad = static_cast<QNetworkRequest::CacheLoadControl>(cacheLoad.toUInt());
        else
            m_lastCacheLoad = QNetworkRequest::PreferNetwork; // default value
        return new FakeReply(request, this);
    }

    QNetworkRequest::CacheLoadControl lastCacheLoad() const
    {
        return m_lastCacheLoad;
    }

private:
    QNetworkRequest::CacheLoadControl m_lastCacheLoad;
};

void tst_QWebEnginePage::setUrlWithPendingLoads()
{
    QWebEnginePage page;
    page.setHtml("<img src='dummy:'/>");
    page.setUrl(QUrl("about:blank"));
}

void tst_QWebEnginePage::setUrlToEmpty()
{
    int expectedLoadFinishedCount = 0;
    const QUrl aboutBlank("about:blank");
    const QUrl url("qrc:/resources/test2.html");

    QWebEnginePage page;
    QCOMPARE(page.url(), QUrl());
    QCOMPARE(page.requestedUrl(), QUrl());
// Chromium now returns about:blank as the base url here:
//     QCOMPARE(baseUrlSync(&page), QUrl());

    QSignalSpy spy(&page, SIGNAL(loadFinished(bool)));

    // Set existing url
    page.setUrl(url);
    expectedLoadFinishedCount++;
    QVERIFY(spy.wait());

    QCOMPARE(spy.count(), expectedLoadFinishedCount);
    QCOMPARE(page.url(), url);
    QCOMPARE(page.requestedUrl(), url);
    QCOMPARE(baseUrlSync(&page), url);

    // Set empty url
    page.setUrl(QUrl());
    expectedLoadFinishedCount++;

    QTRY_COMPARE(spy.count(), expectedLoadFinishedCount);
    QCOMPARE(page.url(), aboutBlank);
    QCOMPARE(page.requestedUrl(), QUrl());
    QCOMPARE(baseUrlSync(&page), aboutBlank);

    // Set existing url
    page.setUrl(url);
    expectedLoadFinishedCount++;

    QTRY_COMPARE(spy.count(), expectedLoadFinishedCount);
    QCOMPARE(page.url(), url);
    QCOMPARE(page.requestedUrl(), url);
    QCOMPARE(baseUrlSync(&page), url);

    // Load empty url
    page.load(QUrl());
    expectedLoadFinishedCount++;

    QTRY_COMPARE(spy.count(), expectedLoadFinishedCount);
    QCOMPARE(page.url(), aboutBlank);
    QCOMPARE(page.requestedUrl(), QUrl());
    QCOMPARE(baseUrlSync(&page), aboutBlank);
}

void tst_QWebEnginePage::setUrlToInvalid()
{
    QEXPECT_FAIL("", "Unsupported: QtWebEngine doesn't adjust invalid URLs.", Abort);
    QVERIFY(false);

    QWebEnginePage page;

    const QUrl invalidUrl("http:/example.com");
    QVERIFY(!invalidUrl.isEmpty());
    QVERIFY(invalidUrl != QUrl());

    // QWebEnginePage will do its best to accept the URL, possible converting it to a valid equivalent URL.
    const QUrl validUrl("http://example.com/");
    page.setUrl(invalidUrl);
    QCOMPARE(page.url(), validUrl);
    QCOMPARE(page.requestedUrl(), validUrl);
    QCOMPARE(baseUrlSync(&page), validUrl);

    // QUrls equivalent to QUrl() will be treated as such.
    const QUrl aboutBlank("about:blank");
    const QUrl anotherInvalidUrl("1http://bugs.webkit.org");
    QVERIFY(!anotherInvalidUrl.isEmpty()); // and they are not necessarily empty.
    QVERIFY(!anotherInvalidUrl.isValid());
    QCOMPARE(anotherInvalidUrl.toEncoded(), QUrl().toEncoded());

    page.setUrl(anotherInvalidUrl);
    QCOMPARE(page.url(), aboutBlank);
    QCOMPARE(page.requestedUrl().toEncoded(), anotherInvalidUrl.toEncoded());
    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_WITH_TIMEOUT(titleSpy.count(), 1, 20000);
    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_WITH_TIMEOUT(titleSpy.count(), 1, 20000);
    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;
    const QList<QWebEngineHistoryItem> items = history->items();
    for (const QWebEngineHistoryItem &i : items)
        urls << i.url().toString();
    return urls;
}

void tst_QWebEnginePage::setUrlHistory()
{
    const QUrl aboutBlank("about:blank");
    QUrl url;
    int expectedLoadFinishedCount = 0;
    QSignalSpy spy(m_page, SIGNAL(loadFinished(bool)));

    QCOMPARE(m_page->history()->count(), 0);

    m_page->setUrl(QUrl());
    expectedLoadFinishedCount++;
    QTRY_COMPARE(spy.count(), expectedLoadFinishedCount);
    QCOMPARE(m_page->url(), aboutBlank);
    QCOMPARE(m_page->requestedUrl(), QUrl());
    // Chromium stores navigation entry for every successful loads. The load of the empty page is committed and stored as about:blank.
    QCOMPARE(collectHistoryUrls(m_page->history()), QStringList() << aboutBlank.toString());

    url = QUrl("http://url.invalid/");
    m_page->setUrl(url);
    expectedLoadFinishedCount++;
    QTRY_COMPARE_WITH_TIMEOUT(spy.count(), expectedLoadFinishedCount, 20000);
    // When error page is disabled in case of LoadFail the entry of the unavailable page is not stored.
    // We expect the url of the previously loaded page here.
    QCOMPARE(m_page->url(), aboutBlank);
    QCOMPARE(m_page->requestedUrl(), QUrl());
    // Since the entry of the unavailable page is not stored it will not available in the history.
    QCOMPARE(collectHistoryUrls(m_page->history()), QStringList() << aboutBlank.toString());

    url = QUrl("qrc:/resources/test1.html");
    m_page->setUrl(url);
    expectedLoadFinishedCount++;
    QTRY_COMPARE(spy.count(), expectedLoadFinishedCount);
    QCOMPARE(m_page->url(), url);
    QCOMPARE(m_page->requestedUrl(), url);
    QCOMPARE(collectHistoryUrls(m_page->history()), QStringList() << aboutBlank.toString() << QStringLiteral("qrc:/resources/test1.html"));

    m_page->setUrl(QUrl());
    expectedLoadFinishedCount++;
    QTRY_COMPARE(spy.count(), expectedLoadFinishedCount);
    QCOMPARE(m_page->url(), aboutBlank);
    QCOMPARE(m_page->requestedUrl(), QUrl());
    // Chromium stores navigation entry for every successful loads. The load of the empty page is committed and stored as about:blank.
    QCOMPARE(collectHistoryUrls(m_page->history()), QStringList()
                                                        << aboutBlank.toString()
                                                        << QStringLiteral("qrc:/resources/test1.html")
                                                        << aboutBlank.toString());

    url = QUrl("qrc:/resources/test1.html");
    m_page->setUrl(url);
    expectedLoadFinishedCount++;
    QTRY_COMPARE(spy.count(), expectedLoadFinishedCount);
    QCOMPARE(m_page->url(), url);
    QCOMPARE(m_page->requestedUrl(), url);
    // The history count DOES change since the about:blank is in the list.
    QCOMPARE(collectHistoryUrls(m_page->history()), QStringList()
                                                        << aboutBlank.toString()
                                                        << QStringLiteral("qrc:/resources/test1.html")
                                                        << aboutBlank.toString()
                                                        << QStringLiteral("qrc:/resources/test1.html"));

    url = QUrl("qrc:/resources/test2.html");
    m_page->setUrl(url);
    expectedLoadFinishedCount++;
    QTRY_COMPARE(spy.count(), expectedLoadFinishedCount);
    QCOMPARE(m_page->url(), url);
    QCOMPARE(m_page->requestedUrl(), url);
    QCOMPARE(collectHistoryUrls(m_page->history()), QStringList()
                                                        << aboutBlank.toString()
                                                        << QStringLiteral("qrc:/resources/test1.html")
                                                        << aboutBlank.toString()
                                                        << QStringLiteral("qrc:/resources/test1.html")
                                                        << QStringLiteral("qrc:/resources/test2.html"));
}

void tst_QWebEnginePage::setUrlUsingStateObject()
{
    QUrl url;
    QSignalSpy urlChangedSpy(m_page, SIGNAL(urlChanged(QUrl)));
    int expectedUrlChangeCount = 0;

    QCOMPARE(m_page->history()->count(), 0);

    url = QUrl("qrc:/resources/test1.html");
    m_page->setUrl(url);
    expectedUrlChangeCount++;
    QTRY_COMPARE(urlChangedSpy.count(), expectedUrlChangeCount);
    QCOMPARE(m_page->url(), url);
    QTRY_COMPARE(m_page->history()->count(), 1);

    evaluateJavaScriptSync(m_page, "window.history.pushState(null, 'push', 'navigate/to/here')");
    expectedUrlChangeCount++;
    QTRY_COMPARE(urlChangedSpy.count(), expectedUrlChangeCount);
    QCOMPARE(m_page->url(), QUrl("qrc:/resources/navigate/to/here"));
    QCOMPARE(m_page->history()->count(), 2);
    QVERIFY(m_page->history()->canGoBack());

    evaluateJavaScriptSync(m_page, "window.history.replaceState(null, 'replace', 'another/location')");
    expectedUrlChangeCount++;
    QTRY_COMPARE(urlChangedSpy.count(), expectedUrlChangeCount);
    QCOMPARE(m_page->url(), QUrl("qrc:/resources/navigate/to/another/location"));
    QCOMPARE(m_page->history()->count(), 2);
    QVERIFY(!m_page->history()->canGoForward());
    QVERIFY(m_page->history()->canGoBack());

    evaluateJavaScriptSync(m_page, "window.history.back()");
    expectedUrlChangeCount++;
    QTRY_COMPARE(urlChangedSpy.count(), expectedUrlChangeCount);
    QCOMPARE(m_page->url(), QUrl("qrc:/resources/test1.html"));
    QVERIFY(m_page->history()->canGoForward());
    QVERIFY(!m_page->history()->canGoBack());
}

static inline QUrl extractBaseUrl(const QUrl& url)
{
    return url.resolved(QUrl());
}

void tst_QWebEnginePage::setUrlThenLoads_data()
{
    QTest::addColumn<QUrl>("url");
    QTest::addColumn<QUrl>("baseUrl");

    QTest::newRow("resource file") << QUrl("qrc:/resources/test1.html") << extractBaseUrl(QUrl("qrc:/resources/test1.html"));
    QTest::newRow("base specified in HTML") << QUrl("data:text/html,<head><base href=\"http://different.base/\"></head>") << QUrl("http://different.base/");
}

void tst_QWebEnginePage::setUrlThenLoads()
{
    QFETCH(QUrl, url);
    QFETCH(QUrl, baseUrl);
    QSignalSpy urlChangedSpy(m_page, SIGNAL(urlChanged(QUrl)));
    QSignalSpy startedSpy(m_page, SIGNAL(loadStarted()));
    QSignalSpy finishedSpy(m_page, SIGNAL(loadFinished(bool)));

    m_page->setUrl(url);
    QTRY_COMPARE(startedSpy.count(), 1);
    QTRY_COMPARE(urlChangedSpy.count(), 1);
    QTRY_COMPARE(finishedSpy.count(), 1);
    QVERIFY(finishedSpy.at(0).first().toBool());
    QCOMPARE(m_page->url(), url);
    QCOMPARE(m_page->requestedUrl(), url);
    QCOMPARE(baseUrlSync(m_page), baseUrl);

    const QUrl urlToLoad1("qrc:/resources/test2.html");
    const QUrl urlToLoad2("qrc:/resources/test1.html");

    m_page->load(urlToLoad1);
    QTRY_COMPARE(m_page->url(), urlToLoad1);
    QTRY_COMPARE(m_page->requestedUrl(), urlToLoad1);
    // baseUrlSync spins an event loop and this sometimes return the next result.
    // QCOMPARE(baseUrlSync(m_page), baseUrl);
    QTRY_COMPARE(startedSpy.count(), 2);

    // After first URL changed.
    QTRY_COMPARE(urlChangedSpy.count(), 2);
    QTRY_COMPARE(finishedSpy.count(), 2);
    QVERIFY(finishedSpy.at(1).first().toBool());
    QCOMPARE(m_page->url(), urlToLoad1);
    QCOMPARE(m_page->requestedUrl(), urlToLoad1);
    QCOMPARE(baseUrlSync(m_page), extractBaseUrl(urlToLoad1));

    m_page->load(urlToLoad2);
    QCOMPARE(m_page->url(), urlToLoad1);
    QCOMPARE(m_page->requestedUrl(), urlToLoad2);
    QCOMPARE(baseUrlSync(m_page), extractBaseUrl(urlToLoad1));
    QTRY_COMPARE(startedSpy.count(), 3);

    // After second URL changed.
    QTRY_COMPARE(urlChangedSpy.count(), 3);
    QTRY_COMPARE(finishedSpy.count(), 3);
    QVERIFY(finishedSpy.at(2).first().toBool());
    QCOMPARE(m_page->url(), urlToLoad2);
    QCOMPARE(m_page->requestedUrl(), urlToLoad2);
    QCOMPARE(baseUrlSync(m_page), extractBaseUrl(urlToLoad2));
}

void tst_QWebEnginePage::loadFinishedAfterNotFoundError()
{
    QWebEnginePage page;
    QSignalSpy spy(&page, SIGNAL(loadFinished(bool)));

    page.settings()->setAttribute(QWebEngineSettings::ErrorPageEnabled, false);
    page.setUrl(QUrl("http://non.existent/url"));
    QTRY_COMPARE_WITH_TIMEOUT(spy.count(), 1, 20000);

    page.settings()->setAttribute(QWebEngineSettings::ErrorPageEnabled, true);
    page.setUrl(QUrl("http://another.non.existent/url"));
    QTRY_COMPARE_WITH_TIMEOUT(spy.count(), 2, 20000);
}

class URLSetter : public QObject {
    Q_OBJECT

public:
    enum Signal {
        LoadStarted,
        LoadFinished,
    };

    enum Type {
        UseLoad,
        UseSetUrl
    };

    URLSetter(QWebEnginePage*, Signal, Type, const QUrl&);

public Q_SLOTS:
    void execute();

Q_SIGNALS:
    void finished();

private:
    QWebEnginePage* m_page;
    QUrl m_url;
    Type m_type;
};

Q_DECLARE_METATYPE(URLSetter::Signal)
Q_DECLARE_METATYPE(URLSetter::Type)

URLSetter::URLSetter(QWebEnginePage* page, Signal signal, URLSetter::Type type, const QUrl& url)
    : m_page(page), m_url(url), m_type(type)
{
    if (signal == LoadStarted)
        connect(m_page, SIGNAL(loadStarted()), SLOT(execute()));
    else if (signal == LoadFinished)
        connect(m_page, SIGNAL(loadFinished(bool)), SLOT(execute()));
}

void URLSetter::execute()
{
    // We track only the first emission.
    m_page->disconnect(this);
    connect(m_page, SIGNAL(loadFinished(bool)), SIGNAL(finished()));
    if (m_type == URLSetter::UseLoad)
        m_page->load(m_url);
    else
        m_page->setUrl(m_url);
}

void tst_QWebEnginePage::loadInSignalHandlers_data()
{
    QTest::addColumn<URLSetter::Type>("type");
    QTest::addColumn<URLSetter::Signal>("signal");
    QTest::addColumn<QUrl>("url");

    const QUrl validUrl("qrc:/resources/test2.html");
    const QUrl invalidUrl("qrc:/invalid");

    QTest::newRow("call load() in loadStarted() after valid url") << URLSetter::UseLoad << URLSetter::LoadStarted << validUrl;
    QTest::newRow("call load() in loadStarted() after invalid url") << URLSetter::UseLoad << URLSetter::LoadStarted << invalidUrl;
    QTest::newRow("call load() in loadFinished() after valid url") << URLSetter::UseLoad << URLSetter::LoadFinished << validUrl;
    QTest::newRow("call load() in loadFinished() after invalid url") << URLSetter::UseLoad << URLSetter::LoadFinished << invalidUrl;

    QTest::newRow("call setUrl() in loadStarted() after valid url") << URLSetter::UseSetUrl << URLSetter::LoadStarted << validUrl;
    QTest::newRow("call setUrl() in loadStarted() after invalid url") << URLSetter::UseSetUrl << URLSetter::LoadStarted << invalidUrl;
    QTest::newRow("call setUrl() in loadFinished() after valid url") << URLSetter::UseSetUrl << URLSetter::LoadFinished << validUrl;
    QTest::newRow("call setUrl() in loadFinished() after invalid url") << URLSetter::UseSetUrl << URLSetter::LoadFinished << invalidUrl;
}

void tst_QWebEnginePage::loadInSignalHandlers()
{
    QFETCH(URLSetter::Type, type);
    QFETCH(URLSetter::Signal, signal);
    QFETCH(QUrl, url);

    const QUrl urlForSetter("qrc:/resources/test1.html");
    URLSetter setter(m_page, signal, type, urlForSetter);
    QSignalSpy spy(&setter, &URLSetter::finished);
    m_page->load(url);
    // every loadStarted() call should have also loadFinished()
    if (signal == URLSetter::LoadStarted)
        QTRY_COMPARE(spy.count(), 2);
    else
        QTRY_COMPARE(spy.count(), 1);
    QCOMPARE(m_page->url(), urlForSetter);
}

void tst_QWebEnginePage::loadFromQrc()
{
    QWebEnginePage page;
    QSignalSpy spy(&page, &QWebEnginePage::loadFinished);

    // Standard case.
    page.load(QStringLiteral("qrc:///resources/foo.txt"));
    QTRY_COMPARE(spy.count(), 1);
    QCOMPARE(spy.takeFirst().value(0).toBool(), true);
    QCOMPARE(toPlainTextSync(&page), QStringLiteral("foo\n"));

    // Query and fragment parts are ignored.
    page.load(QStringLiteral("qrc:///resources/bar.txt?foo=1#bar"));
    QTRY_COMPARE(spy.count(), 1);
    QCOMPARE(spy.takeFirst().value(0).toBool(), true);
    QCOMPARE(toPlainTextSync(&page), QStringLiteral("bar\n"));

    // Literal spaces are OK.
    page.load(QStringLiteral("qrc:///resources/path with spaces.txt"));
    QTRY_COMPARE(spy.count(), 1);
    QCOMPARE(spy.takeFirst().value(0).toBool(), true);
    QCOMPARE(toPlainTextSync(&page), QStringLiteral("contents with spaces\n"));

    // Escaped spaces are OK too.
    page.load(QStringLiteral("qrc:///resources/path%20with%20spaces.txt"));
    QTRY_COMPARE(spy.count(), 1);
    QCOMPARE(spy.takeFirst().value(0).toBool(), true);
    QCOMPARE(toPlainTextSync(&page), QStringLiteral("contents with spaces\n"));

    // Resource not found, loading fails.
    page.load(QStringLiteral("qrc:///nope"));
    QTRY_COMPARE(spy.count(), 1);
    QCOMPARE(spy.takeFirst().value(0).toBool(), false);
}

#if QT_CONFIG(webengine_webchannel)
void tst_QWebEnginePage::restoreHistory()
{
    QWebChannel channel;
    QWebEnginePage page;
    page.setWebChannel(&channel);

    QWebEngineScript script;
    script.setName(QStringLiteral("script"));
    page.scripts().insert(script);

    QSignalSpy spy(&page, SIGNAL(loadFinished(bool)));
    page.load(QUrl(QStringLiteral("qrc:/resources/test1.html")));
    QTRY_COMPARE(spy.count(), 1);

    QCOMPARE(page.webChannel(), &channel);
    QVERIFY(page.scripts().contains(script));

    QByteArray data;
    QDataStream out(&data, QIODevice::ReadWrite);
    out << *page.history();
    QDataStream in(&data, QIODevice::ReadOnly);
    in >> *page.history();
    QTRY_COMPARE(spy.count(), 2);

    QCOMPARE(page.webChannel(), &channel);
    QVERIFY(page.scripts().contains(script));
}
#endif

void tst_QWebEnginePage::toPlainTextLoadFinishedRace_data()
{
    QTest::addColumn<bool>("enableErrorPage");
    QTest::newRow("disableErrorPage") << false;
    QTest::newRow("enableErrorPage") << true;
}

void tst_QWebEnginePage::toPlainTextLoadFinishedRace()
{
    QFETCH(bool, enableErrorPage);

    QScopedPointer<QWebEnginePage> page(new QWebEnginePage);
    page->settings()->setAttribute(QWebEngineSettings::ErrorPageEnabled, enableErrorPage);
    QSignalSpy spy(page.data(), SIGNAL(loadFinished(bool)));

    page->load(QUrl("data:text/plain,foobarbaz"));
    QTRY_VERIFY(spy.count() == 1);
    QCOMPARE(toPlainTextSync(page.data()), QString("foobarbaz"));

    page->load(QUrl("http://fail.invalid/"));
    QTRY_COMPARE_WITH_TIMEOUT(spy.count(), 2, 20000);
    QString s = toPlainTextSync(page.data());
    QVERIFY(s.contains("foobarbaz") == !enableErrorPage);

    page->load(QUrl("data:text/plain,lalala"));
    QTRY_COMPARE(spy.count(), 3);
    QTRY_COMPARE(toPlainTextSync(page.data()), QString("lalala"));
    page.reset();
    QCOMPARE(spy.count(), 3);
}

void tst_QWebEnginePage::setZoomFactor()
{
    QWebEnginePage page;

    QVERIFY(qFuzzyCompare(page.zoomFactor(), 1.0));
    page.setZoomFactor(2.5);
    QVERIFY(qFuzzyCompare(page.zoomFactor(), 2.5));

    const QUrl urlToLoad("qrc:/resources/test1.html");

    QSignalSpy finishedSpy(&page, SIGNAL(loadFinished(bool)));
    page.load(urlToLoad);
    QTRY_COMPARE(finishedSpy.count(), 1);
    QVERIFY(finishedSpy.at(0).first().toBool());
    QVERIFY(qFuzzyCompare(page.zoomFactor(), 2.5));

    page.setZoomFactor(5.5);
    QVERIFY(qFuzzyCompare(page.zoomFactor(), 2.5));

    page.setZoomFactor(0.1);
    QVERIFY(qFuzzyCompare(page.zoomFactor(), 2.5));
}

void tst_QWebEnginePage::mouseButtonTranslation()
{
    QWebEngineView view;

    QSignalSpy spy(&view, SIGNAL(loadFinished(bool)));
    view.setHtml(QStringLiteral(
                      "<html><head><script>\
                           var lastEvent = { 'button' : -1 }; \
                           function saveLastEvent(event) { console.log(event); lastEvent = event; }; \
                      </script></head>\
                      <body>\
                      <div style=\"height:600px;\" onmousedown=\"saveLastEvent(event)\">\
                      </div>\
                      </body></html>"));
    view.resize(640, 480);
    view.show();
    QVERIFY(QTest::qWaitForWindowExposed(&view));
    QTRY_VERIFY(spy.count() == 1);

    QVERIFY(view.focusProxy() != nullptr);

    QMouseEvent evpres(QEvent::MouseButtonPress, view.rect().center(), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
    QGuiApplication::sendEvent(view.focusProxy(), &evpres);

    QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "lastEvent.button").toInt(), 0);
    QCOMPARE(evaluateJavaScriptSync(view.page(), "lastEvent.buttons").toInt(), 1);

    QMouseEvent evpres2(QEvent::MouseButtonPress, view.rect().center(), Qt::RightButton, Qt::LeftButton | Qt::RightButton, Qt::NoModifier);
    QGuiApplication::sendEvent(view.focusProxy(), &evpres2);

    QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "lastEvent.button").toInt(), 2);
    QCOMPARE(evaluateJavaScriptSync(view.page(), "lastEvent.buttons").toInt(), 3);
}

void tst_QWebEnginePage::mouseMovementProperties()
{
    QWebEngineView view;
    ConsolePage page;
    view.setPage(&page);
    view.resize(640, 480);
    QTest::mouseMove(&view, QPoint(10, 10));
    view.show();
    QVERIFY(QTest::qWaitForWindowExposed(&view));

    QSignalSpy loadFinishedSpy(&page, SIGNAL(loadFinished(bool)));
    page.setHtml(QStringLiteral(
                        "<html><head><script>\
                            function onMouseMove(event) { console.log(event.movementX + \", \" + event.movementY); }; \
                        </script></head>\
                        <body>\
                            <div style=\"height:600px;\" onmousemove=\"onMouseMove(event)\">\
                        </div>\
                        </body></html>"));
    loadFinishedSpy.wait();

    QTest::mouseMove(&view, QPoint(20, 20));
    QTRY_COMPARE(page.messages.count(), 1);

    QTest::mouseMove(&view, QPoint(30, 30));
    QTRY_COMPARE(page.messages.count(), 2);
    QTRY_COMPARE(page.messages[1], QString("10, 10"));

    QTest::mouseMove(&view, QPoint(20, 20));
    QTRY_COMPARE(page.messages.count(), 3);
    QTRY_COMPARE(page.messages[2], QString("-10, -10"));
}

QPoint tst_QWebEnginePage::elementCenter(QWebEnginePage *page, const QString &id)
{
    QVariantList rectList = evaluateJavaScriptSync(page,
            "(function(){"
            "var elem = document.getElementById('" + id + "');"
            "var rect = elem.getBoundingClientRect();"
            "return [(rect.left + rect.right) / 2, (rect.top + rect.bottom) / 2];"
            "})()").toList();

    if (rectList.count() != 2) {
        qWarning("elementCenter failed.");
        return QPoint();
    }

    return QPoint(rectList.at(0).toInt(), rectList.at(1).toInt());
}

void tst_QWebEnginePage::viewSource()
{
    TestPage page;
    QSignalSpy loadFinishedSpy(&page, SIGNAL(loadFinished(bool)));
    QSignalSpy windowCreatedSpy(&page, SIGNAL(windowCreated()));
    const QUrl url("qrc:/resources/test1.html");

    page.load(url);
    QTRY_COMPARE(loadFinishedSpy.count(), 1);
    QCOMPARE(page.title(), QStringLiteral("Test page 1"));
    QVERIFY(page.action(QWebEnginePage::ViewSource)->isEnabled());

    page.triggerAction(QWebEnginePage::ViewSource);
    QTRY_COMPARE(windowCreatedSpy.count(), 1);
    QCOMPARE(page.createdWindows.size(), 1);

    QTRY_COMPARE(page.createdWindows[0]->url().toString(), QStringLiteral("view-source:%1").arg(url.toString()));
    // The requested URL should not be about:blank if the qrc scheme is supported
    QTRY_COMPARE(page.createdWindows[0]->requestedUrl(), url);
    QTRY_COMPARE(page.createdWindows[0]->title(), QStringLiteral("view-source:%1").arg(url.toString()));
    QVERIFY(!page.createdWindows[0]->action(QWebEnginePage::ViewSource)->isEnabled());
}

void tst_QWebEnginePage::viewSourceURL_data()
{
    QTest::addColumn<QUrl>("userInputUrl");
    QTest::addColumn<bool>("loadSucceed");
    QTest::addColumn<QUrl>("url");
    QTest::addColumn<QUrl>("requestedUrl");
    QTest::addColumn<QString>("title");

    QTest::newRow("view-source:") << QUrl("view-source:") << true << QUrl("view-source:") << QUrl("about:blank") << QString("view-source:");
    QTest::newRow("view-source:about:blank") << QUrl("view-source:about:blank") << true << QUrl("view-source:about:blank") << QUrl("about:blank") << QString("view-source:about:blank");

    QString localFilePath = QString("%1qwebenginepage/resources/test1.html").arg(TESTS_SOURCE_DIR);
    QUrl testLocalUrl = QUrl(QString("view-source:%1").arg(QUrl::fromLocalFile(localFilePath).toString()));
    QUrl testLocalUrlWithoutScheme = QUrl(QString("view-source:%1").arg(localFilePath));
    QTest::newRow(testLocalUrl.toString().toStdString().c_str()) << testLocalUrl << true << testLocalUrl << QUrl::fromLocalFile(localFilePath) << QString("test1.html");
    QTest::newRow(testLocalUrlWithoutScheme.toString().toStdString().c_str()) << testLocalUrlWithoutScheme << true << testLocalUrl << QUrl::fromLocalFile(localFilePath) << QString("test1.html");

    QString resourcePath = QLatin1String("qrc:/resources/test1.html");
    QUrl testResourceUrl = QUrl(QString("view-source:%1").arg(resourcePath));
    QTest::newRow(testResourceUrl.toString().toStdString().c_str()) << testResourceUrl << true << testResourceUrl << QUrl(resourcePath) << testResourceUrl.toString();

    QTest::newRow("view-source:http://non.existent") << QUrl("view-source:non.existent") << false << QUrl("view-source:http://non.existent/") << QUrl("http://non.existent/") << QString("non.existent");
    QTest::newRow("view-source:non.existent") << QUrl("view-source:non.existent") << false << QUrl("view-source:http://non.existent/") << QUrl("http://non.existent/") << QString("non.existent");
}

void tst_QWebEnginePage::viewSourceURL()
{
    if (!QDir(TESTS_SOURCE_DIR).exists())
        W_QSKIP(QString("This test requires access to resources found in '%1'").arg(TESTS_SOURCE_DIR).toLatin1().constData(), SkipAll);

    QFETCH(QUrl, userInputUrl);
    QFETCH(bool, loadSucceed);
    QFETCH(QUrl, url);
    QFETCH(QUrl, requestedUrl);
    QFETCH(QString, title);

    QWebEnginePage page;
    QSignalSpy loadFinishedSpy(&page, SIGNAL(loadFinished(bool)));

    page.load(userInputUrl);
    QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.count(), 1, 12000);
    QList<QVariant> arguments = loadFinishedSpy.takeFirst();

    QCOMPARE(arguments.at(0).toBool(), loadSucceed);
    QCOMPARE(page.url(), url);
    QCOMPARE(page.requestedUrl(), requestedUrl);
    QCOMPARE(page.title(), title);
    QVERIFY(!page.action(QWebEnginePage::ViewSource)->isEnabled());
}

void tst_QWebEnginePage::viewSourceCredentials()
{
    TestPage page;
    QSignalSpy loadFinishedSpy(&page, SIGNAL(loadFinished(bool)));
    QSignalSpy windowCreatedSpy(&page, SIGNAL(windowCreated()));
    QUrl url("http://user:passwd@httpbin.org/basic-auth/user/passwd");

    // Test explicit view-source URL with credentials
    page.load(QUrl(QString("view-source:" + url.toString())));
    if (!loadFinishedSpy.wait(10000) || !loadFinishedSpy.at(0).at(0).toBool())
        QSKIP("Couldn't load page from network, skipping test.");

    QCOMPARE(page.url().toString(), QString("view-source:" + url.toDisplayString(QUrl::RemoveUserInfo)));
    QCOMPARE(page.requestedUrl(), url);
    QCOMPARE(page.title(), QString("view-source:" + url.toDisplayString(QUrl::RemoveScheme | QUrl::RemoveUserInfo).remove(0, 2)));
    loadFinishedSpy.clear();
    windowCreatedSpy.clear();

    // Test ViewSource web action on URL with credentials
    page.load(url);
    if (!loadFinishedSpy.wait(10000) || !loadFinishedSpy.at(0).at(0).toBool())
        QSKIP("Couldn't load page from network, skipping test.");
    QVERIFY(page.action(QWebEnginePage::ViewSource)->isEnabled());

    page.triggerAction(QWebEnginePage::ViewSource);
    QTRY_COMPARE(windowCreatedSpy.count(), 1);
    QCOMPARE(page.createdWindows.size(), 1);

    QTRY_COMPARE(page.createdWindows[0]->url().toString(), QString("view-source:" + url.toDisplayString(QUrl::RemoveUserInfo)));
    QTRY_COMPARE(page.createdWindows[0]->requestedUrl(), url);
    QTRY_COMPARE(page.createdWindows[0]->title(), QString("view-source:" + url.toDisplayString(QUrl::RemoveScheme | QUrl::RemoveUserInfo).remove(0, 2)));
}

Q_DECLARE_METATYPE(QNetworkProxy::ProxyType);

void tst_QWebEnginePage::proxyConfigWithUnexpectedHostPortPair()
{
    // Chromium expects a proxy of type NoProxy to not have a host or port set.

    QNetworkProxy proxy;
    proxy.setType(QNetworkProxy::NoProxy);
    proxy.setHostName(QStringLiteral("127.0.0.1"));
    proxy.setPort(244);
    QNetworkProxy::setApplicationProxy(proxy);

    QSignalSpy loadFinishedSpy(m_page, SIGNAL(loadFinished(bool)));
    m_page->load(QStringLiteral("http://127.0.0.1:245/"));
    QTRY_COMPARE(loadFinishedSpy.count(), 1);
}

void tst_QWebEnginePage::registerProtocolHandler_data()
{
    QTest::addColumn<bool>("permission");
    QTest::newRow("accept") << true;
    QTest::newRow("reject") << false;
}

void tst_QWebEnginePage::registerProtocolHandler()
{
    QFETCH(bool, permission);

    HttpServer server;
    int mailRequestCount = 0;
    connect(&server, &HttpServer::newRequest, [&](HttpReqRep *rr) {
        if (rr->requestMethod() == "GET" && rr->requestPath() == "/") {
            rr->setResponseBody(QByteArrayLiteral("<html><body><a id=\"link\" href=\"mailto:foo@bar.com\">some text here</a></body></html>"));
            rr->sendResponse();
        } else if (rr->requestMethod() == "GET" && rr->requestPath() == "/mail?uri=mailto%3Afoo%40bar.com") {
            mailRequestCount++;
            rr->sendResponse();
        } else {
            rr->setResponseStatus(404);
            rr->sendResponse();
        }
    });
    QVERIFY(server.start());

    QWebEnginePage page;
    QSignalSpy loadSpy(&page, &QWebEnginePage::loadFinished);
    QSignalSpy permissionSpy(&page, &QWebEnginePage::registerProtocolHandlerRequested);

    page.setUrl(server.url("/"));
    QTRY_COMPARE(loadSpy.count(), 1);
    QCOMPARE(loadSpy.takeFirst().value(0).toBool(), true);

    QString callFormat = QStringLiteral("window.navigator.registerProtocolHandler(\"%1\", \"%2\", \"%3\")");
    QString scheme = QStringLiteral("mailto");
    QString url = server.url("/mail").toString() + QStringLiteral("?uri=%s");
    QString title;
    QString call = callFormat.arg(scheme).arg(url).arg(title);
    page.runJavaScript(call);

    QTRY_COMPARE(permissionSpy.count(), 1);
    auto request = permissionSpy.takeFirst().value(0).value<QWebEngineRegisterProtocolHandlerRequest>();
    QCOMPARE(request.origin(), QUrl(url));
    QCOMPARE(request.scheme(), scheme);
    if (permission)
        request.accept();
    else
        request.reject();

    page.runJavaScript(QStringLiteral("document.getElementById(\"link\").click()"));

    QTRY_COMPARE(loadSpy.count(), 1);
    QCOMPARE(loadSpy.takeFirst().value(0).toBool(), permission);
    QCOMPARE(mailRequestCount, permission ? 1 : 0);
    QVERIFY(server.stop());
}

void tst_QWebEnginePage::dataURLFragment()
{
    m_view->resize(800, 600);
    m_view->show();
    QSignalSpy loadFinishedSpy(m_page, SIGNAL(loadFinished(bool)));

    m_page->setHtml("<html><body>"
                    "<a id='link' href='#anchor'>anchor</a>"
                    "</body></html>");
    QTRY_COMPARE(loadFinishedSpy.count(), 1);

    QSignalSpy urlChangedSpy(m_page, SIGNAL(urlChanged(QUrl)));
    QTest::mouseClick(m_view->focusProxy(), Qt::LeftButton, {}, elementCenter(m_page, "link"));
    QVERIFY(urlChangedSpy.wait());
    QCOMPARE(m_page->url().fragment(), QStringLiteral("anchor"));


    m_page->setHtml("<html><body>"
                    "<a id='link' href='#anchor'>anchor</a>"
                    "</body></html>", QUrl("http://test.qt.io/mytest.html"));
    QTRY_COMPARE(loadFinishedSpy.count(), 2);

    QTest::mouseClick(m_view->focusProxy(), Qt::LeftButton, {}, elementCenter(m_page, "link"));
    QVERIFY(urlChangedSpy.wait());
    QCOMPARE(m_page->url(), QUrl("http://test.qt.io/mytest.html#anchor"));
}

void tst_QWebEnginePage::devTools()
{
    QWebEngineProfile profile;
    QWebEnginePage inspectedPage1(&profile);
    QWebEnginePage inspectedPage2(&profile);
    QWebEnginePage devToolsPage(&profile);
    QSignalSpy spy(&devToolsPage, &QWebEnginePage::loadFinished);

    inspectedPage1.setDevToolsPage(&devToolsPage);

    QCOMPARE(inspectedPage1.devToolsPage(), &devToolsPage);
    QCOMPARE(inspectedPage1.inspectedPage(), nullptr);
    QCOMPARE(inspectedPage2.devToolsPage(), nullptr);
    QCOMPARE(inspectedPage2.inspectedPage(), nullptr);
    QCOMPARE(devToolsPage.devToolsPage(), nullptr);
    QCOMPARE(devToolsPage.inspectedPage(), &inspectedPage1);

    QTRY_COMPARE_WITH_TIMEOUT(spy.count(), 1, 30000);
    QVERIFY(spy.takeFirst().value(0).toBool());

    devToolsPage.setInspectedPage(&inspectedPage2);

    QCOMPARE(inspectedPage1.devToolsPage(), nullptr);
    QCOMPARE(inspectedPage1.inspectedPage(), nullptr);
    QCOMPARE(inspectedPage2.devToolsPage(), &devToolsPage);
    QCOMPARE(inspectedPage2.inspectedPage(), nullptr);
    QCOMPARE(devToolsPage.devToolsPage(), nullptr);
    QCOMPARE(devToolsPage.inspectedPage(), &inspectedPage2);

    QTRY_COMPARE_WITH_TIMEOUT(spy.count(), 1, 30000);
    QVERIFY(spy.takeFirst().value(0).toBool());

    devToolsPage.setInspectedPage(nullptr);

    QCOMPARE(inspectedPage1.devToolsPage(), nullptr);
    QCOMPARE(inspectedPage1.inspectedPage(), nullptr);
    QCOMPARE(inspectedPage2.devToolsPage(), nullptr);
    QCOMPARE(inspectedPage2.inspectedPage(), nullptr);
    QCOMPARE(devToolsPage.devToolsPage(), nullptr);
    QCOMPARE(devToolsPage.inspectedPage(), nullptr);
}

void tst_QWebEnginePage::openLinkInDifferentProfile()
{
    class Page : public QWebEnginePage {
    public:
        QWebEnginePage *targetPage = nullptr;
        Page(QWebEngineProfile *profile) : QWebEnginePage(profile) {}
    private:
        QWebEnginePage *createWindow(WebWindowType) override { return targetPage; }
    };
    QWebEngineProfile profile1, profile2;
    Page page1(&profile1), page2(&profile2);
    QWebEngineView view;
    view.resize(500, 500);
    view.setPage(&page1);
    view.show();
    QVERIFY(QTest::qWaitForWindowExposed(&view));
    QSignalSpy spy1(&page1, &QWebEnginePage::loadFinished), spy2(&page2, &QWebEnginePage::loadFinished);
    page1.setHtml("<html><body>"
                  "<a id='link' href='data:,hello'>link</a>"
                  "</body></html>");
    QTRY_COMPARE(spy1.count(), 1);
    QVERIFY(spy1.takeFirst().value(0).toBool());
    page1.targetPage = &page2;
    QTest::mouseClick(view.focusProxy(), Qt::MiddleButton, {}, elementCenter(&page1, "link"));
    QTRY_COMPARE(spy2.count(), 1);
    QVERIFY(spy2.takeFirst().value(0).toBool());
}

// What does createWindow do?
enum class OpenLinkInNewPageDecision {
    // Returns nullptr,
    ReturnNull,
    // Returns this,
    ReturnSelf,
    // Returns page != this
    ReturnOther,
};

// What causes createWindow to be called?
enum class OpenLinkInNewPageCause {
    // User clicks on a link with target=_blank.
    TargetBlank,
    // User clicks with MiddleButton.
    MiddleClick,
};

// What happens after createWindow?
enum class OpenLinkInNewPageEffect {
    // The navigation request disappears into the ether.
    Blocked,
    // The navigation request becomes a navigation in the original page.
    LoadInSelf,
    // The navigation request becomes a navigation in a different page.
    LoadInOther,
};

Q_DECLARE_METATYPE(OpenLinkInNewPageCause)
Q_DECLARE_METATYPE(OpenLinkInNewPageDecision)
Q_DECLARE_METATYPE(OpenLinkInNewPageEffect)

void tst_QWebEnginePage::openLinkInNewPage_data()
{
    using Decision = OpenLinkInNewPageDecision;
    using Cause = OpenLinkInNewPageCause;
    using Effect = OpenLinkInNewPageEffect;

    QTest::addColumn<Decision>("decision");
    QTest::addColumn<Cause>("cause");
    QTest::addColumn<Effect>("effect");

    // Note that the meaning of returning nullptr from createWindow is not
    // consistent between the TargetBlank and MiddleClick scenarios.
    //
    // With TargetBlank, the open-in-new-page disposition comes from the HTML
    // target attribute; something the user is probably not aware of. Returning
    // nullptr is interpreted as a decision by the app to block an unwanted
    // popup.
    //
    // With MiddleClick, the open-in-new-page disposition comes from the user's
    // explicit intent. Returning nullptr is then interpreted as a failure by
    // the app to fulfill this intent, which we try to compensate by ignoring
    // the disposition and performing the navigation request normally.

    QTest::newRow("BlockPopup")     << Decision::ReturnNull  << Cause::TargetBlank << Effect::Blocked;
    QTest::newRow("IgnoreIntent")   << Decision::ReturnNull  << Cause::MiddleClick << Effect::LoadInSelf;
    QTest::newRow("OverridePopup")  << Decision::ReturnSelf  << Cause::TargetBlank << Effect::LoadInSelf;
    QTest::newRow("OverrideIntent") << Decision::ReturnSelf  << Cause::MiddleClick << Effect::LoadInSelf;
    QTest::newRow("AcceptPopup")    << Decision::ReturnOther << Cause::TargetBlank << Effect::LoadInOther;
    QTest::newRow("AcceptIntent")   << Decision::ReturnOther << Cause::MiddleClick << Effect::LoadInOther;
}

void tst_QWebEnginePage::openLinkInNewPage()
{
    using Decision = OpenLinkInNewPageDecision;
    using Cause = OpenLinkInNewPageCause;
    using Effect = OpenLinkInNewPageEffect;

    class Page : public QWebEnginePage
    {
    public:
        Page *targetPage = nullptr;
        QSignalSpy spy{this, &QWebEnginePage::loadFinished};
        Page(QWebEngineProfile *profile) : QWebEnginePage(profile) {}
    private:
        QWebEnginePage *createWindow(WebWindowType) override { return targetPage; }
    };

    class View : public QWebEngineView
    {
    public:
        View(Page *page)
        {
            resize(500, 500);
            setPage(page);
        }
    };

    QFETCH(Decision, decision);
    QFETCH(Cause, cause);
    QFETCH(Effect, effect);

    QWebEngineProfile profile;
    Page page1(&profile);
    Page page2(&profile);
    View view1(&page1);
    View view2(&page2);

    view1.show();
    QVERIFY(QTest::qWaitForWindowExposed(&view1));

    page1.setHtml("<html><body>"
                  "<a id='link' href='data:,hello' target='_blank'>link</a>"
                  "</body></html>");
    QTRY_COMPARE(page1.spy.count(), 1);
    QVERIFY(page1.spy.takeFirst().value(0).toBool());

    switch (decision) {
    case Decision::ReturnNull:
        page1.targetPage = nullptr;
        break;
    case Decision::ReturnSelf:
        page1.targetPage = &page1;
        break;
    case Decision::ReturnOther:
        page1.targetPage = &page2;
        break;
    }

    Qt::MouseButton button;
    switch (cause) {
    case Cause::TargetBlank:
        button = Qt::LeftButton;
        break;
    case Cause::MiddleClick:
        button = Qt::MiddleButton;
        break;
    }
    QTest::mouseClick(view1.focusProxy(), button, {}, elementCenter(&page1, "link"));

    switch (effect) {
    case Effect::Blocked:
        // Nothing to test
        break;
    case Effect::LoadInSelf:
        QTRY_COMPARE(page1.spy.count(), 1);
        QVERIFY(page1.spy.takeFirst().value(0).toBool());
        QCOMPARE(page2.spy.count(), 0);
        if (decision == Decision::ReturnSelf && cause == Cause::TargetBlank)
            // History was discarded due to AddNewContents
            QCOMPARE(page1.history()->count(), 1);
        else
            QCOMPARE(page1.history()->count(), 2);
        QCOMPARE(page2.history()->count(), 0);
        break;
    case Effect::LoadInOther:
        QTRY_COMPARE(page2.spy.count(), 1);
        QVERIFY(page2.spy.takeFirst().value(0).toBool());
        QCOMPARE(page1.spy.count(), 0);
        QCOMPARE(page1.history()->count(), 1);
        QCOMPARE(page2.history()->count(), 1);
        break;
    }
}

void tst_QWebEnginePage::triggerActionWithoutMenu()
{
    // Calling triggerAction should not crash even when for
    // context-menu-specific actions without a context menu.
    QWebEngineProfile profile;
    QWebEnginePage page(&profile);
    page.triggerAction(QWebEnginePage::DownloadLinkToDisk);
}

void tst_QWebEnginePage::dynamicFrame()
{
    QWebEnginePage page;
    page.settings()->setAttribute(QWebEngineSettings::ErrorPageEnabled, false);
    QSignalSpy spy(&page, &QWebEnginePage::loadFinished);
    page.load(QStringLiteral("qrc:/resources/dynamicFrame.html"));
    QTRY_COMPARE(spy.count(), 1);
    QCOMPARE(toPlainTextSync(&page).trimmed(), QStringLiteral("foo"));
}

struct NotificationPage : ConsolePage {
    Q_OBJECT
    const QWebEnginePage::PermissionPolicy policy;

public:
    NotificationPage(QWebEnginePage::PermissionPolicy ppolicy) : policy(ppolicy) {
        connect(this, &QWebEnginePage::loadFinished, [load = spyLoad.ref()] (bool result) mutable { load(result); });

        connect(this, &QWebEnginePage::featurePermissionRequested,
                [this] (const QUrl &origin, QWebEnginePage::Feature feature) {
            if (feature != QWebEnginePage::Notifications)
                return;
            if (spyRequest.wasCalled())
                QFAIL("request executed twise!");
            setFeaturePermission(origin, feature, policy);
            spyRequest.ref()(origin);
        });

        load(QStringLiteral("qrc:///shared/notification.html"));
    }

    CallbackSpy<bool> spyLoad;
    CallbackSpy<QUrl> spyRequest;

    QString getPermission() { return evaluateJavaScriptSync(this, "getPermission()").toString(); }
    void requestPermission() { runJavaScript("requestPermission()"); }
    void resetPermission() { runJavaScript("resetPermission()"); }
    void sendNotification(const QString &title, const QString &body) {
        runJavaScript("sendNotification('" + title + "', '" + body + "')");
    }
};

void tst_QWebEnginePage::notificationPermission_data()
{
    QTest::addColumn<bool>("setOnInit");
    QTest::addColumn<QWebEnginePage::PermissionPolicy>("policy");
    QTest::addColumn<QString>("permission");
    QTest::newRow("denyOnInit")  << true  << QWebEnginePage::PermissionDeniedByUser << "denied";
    QTest::newRow("deny")        << false << QWebEnginePage::PermissionDeniedByUser << "denied";
    QTest::newRow("grant")       << false << QWebEnginePage::PermissionGrantedByUser << "granted";
    QTest::newRow("grantOnInit") << true  << QWebEnginePage::PermissionGrantedByUser << "granted";
}

void tst_QWebEnginePage::notificationPermission()
{
    QFETCH(bool, setOnInit);
    QFETCH(QWebEnginePage::PermissionPolicy, policy);
    QFETCH(QString, permission);

    QWebEngineProfile otr;
    QWebEnginePage page(&otr, nullptr);

    QUrl baseUrl("https://www.example.com/somepage.html");

    bool permissionRequested = false, errorState = false;
    connect(&page, &QWebEnginePage::featurePermissionRequested, &page, [&] (const QUrl &o, QWebEnginePage::Feature f) {
        if (f != QWebEnginePage::Notifications)
            return;
        if (permissionRequested || o != baseUrl.url(QUrl::RemoveFilename)) {
            qWarning() << "Unexpected case. Can't proceed." << setOnInit << permissionRequested << o;
            errorState = true;
            return;
        }
        permissionRequested = true;
        page.setFeaturePermission(o, f, policy);
    });

    if (setOnInit)
        page.setFeaturePermission(baseUrl, QWebEnginePage::Notifications, policy);

    QSignalSpy spy(&page, &QWebEnginePage::loadFinished);
    page.setHtml(QString("<html><body>Test</body></html>"), baseUrl);
    QTRY_COMPARE(spy.count(), 1);

    QCOMPARE(evaluateJavaScriptSync(&page, QStringLiteral("Notification.permission")), setOnInit ? permission : QLatin1String("default"));

    if (!setOnInit) {
        page.setFeaturePermission(baseUrl, QWebEnginePage::Notifications, policy);
        QTRY_COMPARE(evaluateJavaScriptSync(&page, QStringLiteral("Notification.permission")), permission);
    }

    auto js = QStringLiteral("var permission; Notification.requestPermission().then(p => { permission = p })");
    evaluateJavaScriptSync(&page, js);
    QTRY_COMPARE(evaluateJavaScriptSync(&page, "permission").toString(), permission);
    // permission is not 'remembered' from api standpoint, hence is not suppressed on explicit call from JS
    QVERIFY(permissionRequested);
    QVERIFY(!errorState);
}

void tst_QWebEnginePage::sendNotification()
{
    NotificationPage page(QWebEnginePage::PermissionGrantedByUser);
    QVERIFY(page.spyLoad.waitForResult());

    page.resetPermission();
    page.requestPermission();
    auto origin = page.spyRequest.waitForResult();
    QVERIFY(page.spyRequest.wasCalled());
    QCOMPARE(page.getPermission(), "granted");

    std::unique_ptr<QWebEngineNotification> activeNotification;
    CallbackSpy<bool> presenter;
    page.profile()->setNotificationPresenter(
                [&] (std::unique_ptr<QWebEngineNotification> notification)
                {
                    activeNotification = std::move(notification);
                    presenter(true);
                });

    QString title("Title"), message("Message");
    page.sendNotification(title, message);

    presenter.waitForResult();
    QVERIFY(presenter.wasCalled());
    QVERIFY(activeNotification);
    QCOMPARE(activeNotification->title(), title);
    QCOMPARE(activeNotification->message(), message);
    QCOMPARE(activeNotification->origin(), origin);
    QCOMPARE(activeNotification->direction(), Qt::RightToLeft);
    QCOMPARE(activeNotification->language(), "de");
    QCOMPARE(activeNotification->tag(), "tst");

    activeNotification->show();
    QTRY_VERIFY2(page.messages.contains("onshow"), page.messages.join("\n").toLatin1().constData());
    activeNotification->click();
    QTRY_VERIFY2(page.messages.contains("onclick"), page.messages.join("\n").toLatin1().constData());
    activeNotification->close();
    QTRY_VERIFY2(page.messages.contains("onclose"), page.messages.join("\n").toLatin1().constData());
}

void tst_QWebEnginePage::contentsSize()
{
    m_view->resize(800, 600);
    m_view->show();

    QSignalSpy loadSpy(m_page, &QWebEnginePage::loadFinished);
    QSignalSpy contentsSizeChangedSpy(m_page, &QWebEnginePage::contentsSizeChanged);

    m_view->setHtml(QString("<html><body style=\"width: 1600px; height: 1200px;\"><p>hi</p></body></html>"));

    QTRY_COMPARE(loadSpy.count(), 1);
    QTRY_COMPARE(contentsSizeChangedSpy.count(), 1);

    // Verify the page's contents size is not limited by the view's size.
    QCOMPARE(m_page->contentsSize().width(), 1608);
    QCOMPARE(m_page->contentsSize().height(), 1216);

    // Verify resizing the view does not affect the contents size.
    m_view->resize(2400, 1800);
    QCOMPARE(m_page->contentsSize().width(), 1608);
    QCOMPARE(m_page->contentsSize().height(), 1216);

    // Verify resizing the view does not affect the contents size.
    m_view->resize(1600, 1200);
    QCOMPARE(m_page->contentsSize().width(), 1608);
    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_WITH_TIMEOUT(inspectedSpy.count(), 1, 30000);
    QCOMPARE(inspectedSpy.takeFirst().value(0), QVariant(true));
    QTRY_COMPARE_WITH_TIMEOUT(devToolsSpy.count(), 1, 30000);
    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;
    QWebEnginePage *page = view.page();
    view.settings()->setAttribute(QWebEngineSettings::FocusOnNavigationEnabled, false);

    QSignalSpy loadFinishedSpy(page, &QWebEnginePage::loadFinished);
    QSignalSpy selectionChangedSpy(page, &QWebEnginePage::selectionChanged);
    QSignalSpy actionChangedSpy(page->action(QWebEnginePage::SelectAll), &QAction::changed);

    // The view is hidden and no focus on the page. Edit actions should be disabled.
    QVERIFY(!view.isVisible());
    QVERIFY(!page->action(QWebEnginePage::SelectAll)->isEnabled());

    page->setHtml(QString("<html><body><div>foo bar</div></body></html>"));
    QTRY_COMPARE(loadFinishedSpy.count(), 1);

    // Still no focus because focus on navigation is disabled. Edit actions don't do anything (should not crash).
    QVERIFY(!page->action(QWebEnginePage::SelectAll)->isEnabled());
    view.page()->triggerAction(QWebEnginePage::SelectAll);
    QCOMPARE(selectionChangedSpy.count(), 0);
    QCOMPARE(page->hasSelection(), false);

    // Focus content by focusing window from JavaScript. Edit actions should be enabled and functional.
    evaluateJavaScriptSync(page, "window.focus();");
    QTRY_COMPARE(actionChangedSpy.count(), 1);
    QVERIFY(page->action(QWebEnginePage::SelectAll)->isEnabled());
    view.page()->triggerAction(QWebEnginePage::SelectAll);
    QTRY_COMPARE(selectionChangedSpy.count(), 1);
    QCOMPARE(page->hasSelection(), true);
    QCOMPARE(page->selectedText(), QStringLiteral("foo bar"));
}

void tst_QWebEnginePage::editActionsWithInitialFocus()
{
    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);

    // The view is hidden and no focus on the page. Edit actions should be disabled.
    QVERIFY(!view.isVisible());
    QVERIFY(!page->action(QWebEnginePage::SelectAll)->isEnabled());

    page->setHtml(QString("<html><body><div>foo bar</div></body></html>"));
    QTRY_COMPARE(loadFinishedSpy.count(), 1);

    // Content gets initial focus.
    QTRY_COMPARE(actionChangedSpy.count(), 1);
    QVERIFY(page->action(QWebEnginePage::SelectAll)->isEnabled());
    view.page()->triggerAction(QWebEnginePage::SelectAll);
    QTRY_COMPARE(selectionChangedSpy.count(), 1);
    QCOMPARE(page->hasSelection(), true);
    QCOMPARE(page->selectedText(), QStringLiteral("foo bar"));
}

void tst_QWebEnginePage::editActionsWithFocusOnIframe()
{
    QWebEngineView view;
    QWebEnginePage *page = view.page();
    view.settings()->setAttribute(QWebEngineSettings::FocusOnNavigationEnabled, false);

    QSignalSpy loadFinishedSpy(page, &QWebEnginePage::loadFinished);
    QSignalSpy selectionChangedSpy(page, &QWebEnginePage::selectionChanged);
    QSignalSpy actionChangedSpy(page->action(QWebEnginePage::SelectAll), &QAction::changed);

    // The view is hidden and no focus on the page. Edit actions should be disabled.
    QVERIFY(!view.isVisible());
    QVERIFY(!page->action(QWebEnginePage::SelectAll)->isEnabled());

    page->load(QUrl("qrc:///resources/iframe2.html"));
    QTRY_COMPARE(loadFinishedSpy.count(), 1);
    QVERIFY(!page->action(QWebEnginePage::SelectAll)->isEnabled());

    // Focusing an iframe.
    evaluateJavaScriptSync(page, "document.getElementsByTagName('iframe')[0].contentWindow.focus()");
    QTRY_COMPARE(actionChangedSpy.count(), 1);
    QVERIFY(page->action(QWebEnginePage::SelectAll)->isEnabled());
    view.page()->triggerAction(QWebEnginePage::SelectAll);
    QTRY_COMPARE(selectionChangedSpy.count(), 1);
    QCOMPARE(page->hasSelection(), true);
    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;
    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, {}, 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, {}, elementCenter(&page, "link"));
    QTRY_VERIFY(page.newPage);
    QTRY_VERIFY(!lastUserAgent.isEmpty());
    QCOMPARE(lastUserAgent, profile2.httpUserAgent().toUtf8());
}

void tst_QWebEnginePage::renderProcessCrashed()
{
    using Status = QWebEnginePage::RenderProcessTerminationStatus;
    QWebEngineProfile profile;
    QWebEnginePage page(&profile);
    bool done = false;
    Status status;
    connect(&page, &QWebEnginePage::renderProcessTerminated, [&](Status newStatus) {
        status = newStatus;
        done = true;
    });
    page.load(QUrl("chrome://crash"));
    QTRY_VERIFY_WITH_TIMEOUT(done, 20000);
    // The status depends on whether stack traces are enabled. With
    // --disable-in-process-stack-traces we get an AbnormalTerminationStatus,
    // otherwise a CrashedTerminationStatus.
    QVERIFY(status == QWebEnginePage::CrashedTerminationStatus ||
            status == QWebEnginePage::AbnormalTerminationStatus);
}

void tst_QWebEnginePage::renderProcessPid()
{
    QCOMPARE(m_page->renderProcessPid(), 0);

    m_page->load(QUrl("about:blank"));
    QSignalSpy spyFinished(m_page, &QWebEnginePage::loadFinished);
    QVERIFY(spyFinished.wait());

    QVERIFY(m_page->renderProcessPid() > 1);

    bool crashed = false;
    connect(m_page, &QWebEnginePage::renderProcessTerminated, [&]() { crashed = true; });
    m_page->load(QUrl("chrome://crash"));
    QTRY_VERIFY_WITH_TIMEOUT(crashed, 20000);

    QCOMPARE(m_page->renderProcessPid(), 0);
}

void tst_QWebEnginePage::backgroundColor()
{
    QWebEngineProfile profile;
    QWebEngineView view;
    QWebEnginePage *page = new QWebEnginePage(&profile, &view);

    view.resize(640, 480);
    view.setStyleSheet("background: yellow");
    view.show();
    QPoint center(view.size().width() / 2, view.size().height() / 2);

    QCOMPARE(page->backgroundColor(), Qt::white);
    QTRY_COMPARE(view.grab().toImage().pixelColor(center), Qt::white);

    page->setBackgroundColor(Qt::red);
    view.setPage(page);

    QCOMPARE(page->backgroundColor(), Qt::red);
    QTRY_COMPARE(view.grab().toImage().pixelColor(center), Qt::red);

    page->setHtml(QString("<html>"
                          "<head><style>html, body { margin:0; padding:0; }</style></head>"
                          "<body><div style=\"width:100%; height:10px; background-color:black\"/></body>"
                          "</html>"));
    QSignalSpy spyFinished(page, &QWebEnginePage::loadFinished);
    QVERIFY(spyFinished.wait());
    // Make sure the page is rendered and the test is not grabbing the color of the RenderWidgetHostViewQtDelegateWidget.
    QTRY_COMPARE(view.grab().toImage().pixelColor(QPoint(5, 5)), Qt::black);

    QCOMPARE(page->backgroundColor(), Qt::red);
    QCOMPARE(view.grab().toImage().pixelColor(center), Qt::red);

    page->setBackgroundColor(Qt::transparent);

    QCOMPARE(page->backgroundColor(), Qt::transparent);
    QTRY_COMPARE(view.grab().toImage().pixelColor(center), Qt::yellow);

    page->setBackgroundColor(Qt::green);

    QCOMPARE(page->backgroundColor(), Qt::green);
    QTRY_COMPARE(view.grab().toImage().pixelColor(center), Qt::green);
}

void tst_QWebEnginePage::audioMuted()
{
    QWebEngineProfile profile;
    QWebEnginePage page(&profile);
    QSignalSpy spy(&page, &QWebEnginePage::audioMutedChanged);

    QCOMPARE(page.isAudioMuted(), false);
    page.setAudioMuted(true);
    loadSync(&page, QUrl("about:blank"));
    QCOMPARE(page.isAudioMuted(), true);
    QCOMPARE(spy.count(), 1);
    QCOMPARE(spy[0][0], QVariant(true));
    page.setAudioMuted(false);
    QCOMPARE(page.isAudioMuted(), false);
    QCOMPARE(spy.count(), 2);
    QCOMPARE(spy[1][0], QVariant(false));
}

void tst_QWebEnginePage::closeContents()
{
    TestPage page;
    QSignalSpy windowCreatedSpy(&page, &TestPage::windowCreated);
    page.runJavaScript("var dialog = window.open('', '', 'width=100, height=100');");
    QTRY_COMPARE(windowCreatedSpy.count(), 1);

    QWebEngineView *dialogView = new QWebEngineView;
    QWebEnginePage *dialogPage = page.createdWindows[0];
    dialogPage->setView(dialogView);
    QCOMPARE(dialogPage->lifecycleState(), QWebEnginePage::LifecycleState::Active);

    // This should not crash.
    connect(dialogPage, &QWebEnginePage::windowCloseRequested, dialogView, &QWebEngineView::close);
    page.runJavaScript("dialog.close();");

    // QWebEngineView::closeEvent() sets the life cycle state to discarded.
    QTRY_COMPARE(dialogPage->lifecycleState(), QWebEnginePage::LifecycleState::Discarded);
    delete dialogView;
}

// Based on QTBUG-84011
void tst_QWebEnginePage::isSafeRedirect_data()
{
    QTest::addColumn<QUrl>("requestedUrl");
    QTest::addColumn<QUrl>("expectedUrl");
    QString fileScheme = "file://";

#ifdef Q_OS_WIN
    fileScheme += "/";
#endif

    QString tempDir(fileScheme + QDir::tempPath());
    QTest::newRow(qPrintable(tempDir)) << QUrl(tempDir) << QUrl(tempDir + "/");
    QTest::newRow(qPrintable(tempDir + QString("/foo/bar"))) << QUrl(tempDir + "/foo/bar") << QUrl(tempDir + "/foo/bar");
    QTest::newRow("filesystem:http://foo.com/bar") << QUrl("filesystem:http://foo.com/bar") << QUrl("filesystem:http://foo.com/bar/");
}

void tst_QWebEnginePage::isSafeRedirect()
{
    QFETCH(QUrl, requestedUrl);
    QFETCH(QUrl, expectedUrl);

    TestPage page;
    QSignalSpy spy(&page, SIGNAL(loadFinished(bool)));
    page.setUrl(requestedUrl);
    QTRY_COMPARE_WITH_TIMEOUT(spy.count(), 1, 20000);
    QCOMPARE(page.url(), expectedUrl);
    spy.clear();
}

static QByteArrayList params = {QByteArrayLiteral("--use-fake-device-for-media-stream")};
W_QTEST_MAIN(tst_QWebEnginePage, params)

#include "tst_qwebenginepage.moc"
