/*
    Copyright (C) 2015 The Qt Company Ltd.

    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 <QtTest/QtTest>
#include <QtWebEngineCore/qtwebenginecore-config.h>
#include <qwebenginepage.h>
#include <qwebengineprofile.h>
#include <qwebenginescript.h>
#include <qwebenginescriptcollection.h>
#include <qwebenginesettings.h>
#include <qwebengineview.h>
#include "../util.h"
#if QT_CONFIG(webengine_webchannel)
#include <QWebChannel>
#endif

static bool verifyOrder(QStringList orderList)
{
    QStringList expected = {
        "DocumentCreation",
        "DOMContentLoaded",
        "DocumentReady",
        "load",
        "Deferred"
    };

    if (orderList.at(4) == "load (timeout)") {
        if (orderList.at(3) != "Deferred")
            return false;
        expected[3] = "Deferred";
        expected[4] = "load (timeout)";
    }

    return orderList == expected;
}

class tst_QWebEngineScript: public QObject {
    Q_OBJECT

private Q_SLOTS:
    void domEditing();
    void loadEvents();
    void scriptWorld_data();
    void scriptWorld();
    void scriptDisabled();
    void viewSource();
    void scriptModifications();
#if QT_CONFIG(webengine_webchannel)
    void webChannel_data();
    void webChannel();
    void webChannelResettingAndUnsetting();
    void webChannelWithExistingQtObject();
    void navigation();
    void webChannelWithBadString();
#endif
    void noTransportWithoutWebChannel();
    void scriptsInNestedIframes();
    void matchQrcUrl();
};

void tst_QWebEngineScript::domEditing()
{
    QWebEnginePage page;
    QWebEngineView view;
    view.setPage(&page);
    QWebEngineScript s;
    s.setInjectionPoint(QWebEngineScript::DocumentReady);
    s.setWorldId(QWebEngineScript::ApplicationWorld + 1);
    s.setSourceCode("el = document.createElement(\"div\");\
                el.id = \"banner\";\
                el.style.position = \"absolute\";\
                el.style.width = \"100%\";\
                el.style.padding = \"1em\";\
                el.style.textAlign = \"center\";\
                el.style.top = \"0\";\
                el.style.left = \"0\";\
                el.style.backgroundColor = \"#80C342\";\
                el.innerText = \"Injected banner\";\
                document.body.appendChild(el);");
    page.scripts().insert(s);
    page.load(QUrl("about:blank"));
    view.show();
    QSignalSpy spyFinished(&page, &QWebEnginePage::loadFinished);
    QVERIFY(spyFinished.wait());
    QCOMPARE(evaluateJavaScriptSync(&page, "document.getElementById(\"banner\").innerText"), QVariant(QStringLiteral("Injected banner")));
    // elementFromPoint only works for exposed elements
    QVERIFY(QTest::qWaitForWindowExposed(&view));
    QCOMPARE(evaluateJavaScriptSync(&page, "document.elementFromPoint(2, 2).id"), QVariant::fromValue(QStringLiteral("banner")));
}

void tst_QWebEngineScript::loadEvents()
{
    // Test relative order of injection and loading.
    //
    // - install event listeners for "DOMContentLoaded" and "load" events
    // - install user scripts for every injection point
    // - check that event listeners and user scripts execute in the expected order

    class Page;
    class Profile : public QWebEngineProfile {
        QWebEngineScript scriptFor(QWebEngineScript::ScriptWorldId worldId,
                                   QWebEngineScript::InjectionPoint injectionPoint) {
            QWebEngineScript script;
            script.setWorldId(worldId);
            script.setInjectionPoint(injectionPoint);
            script.setRunsOnSubFrames(true);
            if (injectionPoint == QWebEngineScript::DocumentCreation) {
                script.setSourceCode(QStringLiteral(R"(
                var log = ['DocumentCreation'];
                var timestamps = {'DocumentCreation': Date.now()};
                for (let type of ['DOMContentLoaded', 'load']) {
                    window.addEventListener(type, () => {
                                                    timestamps[type] = Date.now();
                                                    if (type === 'load' && log.includes('Deferred') && timestamps['Deferred'] - timestamps['DOMContentLoaded'] > 500)
                                                        log.push(type + ' (timeout)');
                                                    else
                                                        log.push(type);
                                                    });
                }
                )"));
            } else if (injectionPoint == QWebEngineScript::DocumentReady) {
                script.setSourceCode(QStringLiteral(R"(
                                                    timestamps['DocumentReady'] = Date.now();
                                                    log.push('DocumentReady');
                                                    )"));
            } else {
                script.setSourceCode(QStringLiteral(R"(
                                                    timestamps['Deferred'] = Date.now();
                                                    log.push('Deferred');
                                                    )"));
            }
            return script;
        }
    public:
        Profile() {
            scripts()->insert(scriptFor(QWebEngineScript::MainWorld, QWebEngineScript::DocumentCreation));
            scripts()->insert(scriptFor(QWebEngineScript::MainWorld, QWebEngineScript::DocumentReady));
            scripts()->insert(scriptFor(QWebEngineScript::MainWorld, QWebEngineScript::Deferred));
            scripts()->insert(scriptFor(QWebEngineScript::ApplicationWorld, QWebEngineScript::DocumentCreation));
            scripts()->insert(scriptFor(QWebEngineScript::ApplicationWorld, QWebEngineScript::DocumentReady));
            scripts()->insert(scriptFor(QWebEngineScript::ApplicationWorld, QWebEngineScript::Deferred));
        }
        std::list<Page> pages;
    };

    class Page : public QWebEnginePage {
        QWebEnginePage *createWindow(WebWindowType) override {
            profile.pages.emplace_back(profile);
            return &profile.pages.back();
        };
    public:
        Page(Profile &profile) : QWebEnginePage(&profile), profile(profile) {}
        QVariant eval(const QString &code, QWebEngineScript::ScriptWorldId worldId)
        {
            return evaluateJavaScriptSyncInWorld(this, code, worldId);
        }
        Profile &profile;
        QSignalSpy spy{this, &QWebEnginePage::loadFinished};
    };

    Profile profile;
    profile.pages.emplace_back(profile);
    Page &page = profile.pages.back();

    // Single frame / setHtml
    page.setHtml(QStringLiteral("<!DOCTYPE html><html><head><title>mr</title></head><body></body></html>"));
    QTRY_COMPARE_WITH_TIMEOUT(page.spy.count(), 1, 20000);
    QVERIFY(page.spy.takeFirst().value(0).toBool());
    QVERIFY(verifyOrder(page.eval("window.log", QWebEngineScript::MainWorld).toStringList()));
    QVERIFY(verifyOrder(page.eval("window.log", QWebEngineScript::ApplicationWorld).toStringList()));

    // After discard
    page.setLifecycleState(QWebEnginePage::LifecycleState::Discarded);
    page.setLifecycleState(QWebEnginePage::LifecycleState::Active);
    QTRY_COMPARE_WITH_TIMEOUT(page.spy.count(), 1, 20000);
    QVERIFY(page.spy.takeFirst().value(0).toBool());
    QVERIFY(verifyOrder(page.eval("window.log", QWebEngineScript::MainWorld).toStringList()));
    QVERIFY(verifyOrder(page.eval("window.log", QWebEngineScript::ApplicationWorld).toStringList()));

    // Multiple frames
    page.load(QUrl("qrc:/resources/test_iframe_main.html"));
    QTRY_COMPARE_WITH_TIMEOUT(page.spy.count(), 1, 20000);
    QVERIFY(page.spy.takeFirst().value(0).toBool());
    QVERIFY(verifyOrder(page.eval("window.log", QWebEngineScript::MainWorld).toStringList()));
    QVERIFY(verifyOrder(page.eval("window.log", QWebEngineScript::ApplicationWorld).toStringList()));
    QVERIFY(verifyOrder(page.eval("window[0].log", QWebEngineScript::MainWorld).toStringList()));
    QVERIFY(verifyOrder(page.eval("window[0].log", QWebEngineScript::ApplicationWorld).toStringList()));
    QVERIFY(verifyOrder(page.eval("window[0][0].log", QWebEngineScript::MainWorld).toStringList()));
    QVERIFY(verifyOrder(page.eval("window[0][0].log", QWebEngineScript::ApplicationWorld).toStringList()));

    // Cross-process navigation
    page.load(QUrl("chrome://gpu"));
    QTRY_COMPARE_WITH_TIMEOUT(page.spy.count(), 1, 20000);
    QVERIFY(page.spy.takeFirst().value(0).toBool());
    QVERIFY(verifyOrder(page.eval("window.log", QWebEngineScript::MainWorld).toStringList()));
    QVERIFY(verifyOrder(page.eval("window.log", QWebEngineScript::ApplicationWorld).toStringList()));

    // Using window.open from JS
    QVERIFY(profile.pages.size() == 1);
    page.load(QUrl("qrc:/resources/test_window_open.html"));
    QTRY_COMPARE(profile.pages.size(), 2);
    QTRY_COMPARE(profile.pages.front().spy.count(), 1);
    QTRY_COMPARE(profile.pages.back().spy.count(), 1);
    QVERIFY(verifyOrder(profile.pages.front().eval("window.log", QWebEngineScript::MainWorld).toStringList()));
    QVERIFY(verifyOrder(profile.pages.front().eval("window.log", QWebEngineScript::ApplicationWorld).toStringList()));
    QVERIFY(verifyOrder(profile.pages.back().eval("window.log", QWebEngineScript::MainWorld).toStringList()));
    QVERIFY(verifyOrder(profile.pages.back().eval("window.log", QWebEngineScript::ApplicationWorld).toStringList()));
}

void tst_QWebEngineScript::scriptWorld_data()
{
    QTest::addColumn<int>("worldId");

    QTest::newRow("ApplicationWorld") << static_cast<int>(QWebEngineScript::ApplicationWorld);
    QTest::newRow("UserWorld") << static_cast<int>(QWebEngineScript::UserWorld);
    QTest::newRow("150") << 150;
}

void tst_QWebEngineScript::scriptWorld()
{
    QFETCH(int, worldId);
    QWebEnginePage page;
    QWebEngineScript script;
    script.setInjectionPoint(QWebEngineScript::DocumentCreation);
    script.setWorldId(QWebEngineScript::MainWorld);
    script.setSourceCode(QStringLiteral("var userScriptTest = 1;"));
    page.scripts().insert(script);
    page.load(QUrl("about:blank"));
    QSignalSpy spyFinished(&page, &QWebEnginePage::loadFinished);
    QVERIFY(spyFinished.wait());
    QCOMPARE(evaluateJavaScriptSync(&page, "typeof(userScriptTest) != \"undefined\" && userScriptTest == 1;"), QVariant::fromValue(true));
    QCOMPARE(evaluateJavaScriptSyncInWorld(&page, "typeof(userScriptTest) == \"undefined\"", worldId), QVariant::fromValue(true));
    script.setWorldId(worldId);
    page.scripts().clear();
    page.scripts().insert(script);
    page.load(QUrl("about:blank"));
    QVERIFY(spyFinished.wait());
    QCOMPARE(evaluateJavaScriptSync(&page, "typeof(userScriptTest) == \"undefined\""), QVariant::fromValue(true));
    QCOMPARE(evaluateJavaScriptSyncInWorld(&page, "typeof(userScriptTest) != \"undefined\" && userScriptTest == 1;", worldId), QVariant::fromValue(true));
}

// Based on QTBUG-74304
void tst_QWebEngineScript::scriptDisabled()
{
    QWebEnginePage page;
    page.settings()->setAttribute(QWebEngineSettings::JavascriptEnabled, false);
    QWebEngineScript script;
    script.setInjectionPoint(QWebEngineScript::DocumentCreation);
    script.setWorldId(QWebEngineScript::MainWorld);
    script.setSourceCode("var foo = 42");
    page.scripts().insert(script);
    page.load(QUrl("about:blank"));
    QSignalSpy spy(&page, &QWebEnginePage::loadFinished);
    QTRY_COMPARE(spy.count(), 1);
    QCOMPARE(spy.takeFirst().value(0).toBool(), true);
    // MainWorld scripts are disabled by the setting...
    QCOMPARE(evaluateJavaScriptSyncInWorld(&page, "foo", QWebEngineScript::MainWorld), QVariant());
    QCOMPARE(evaluateJavaScriptSyncInWorld(&page, "foo", QWebEngineScript::ApplicationWorld), QVariant());
    script.setWorldId(QWebEngineScript::ApplicationWorld);
    page.scripts().clear();
    page.scripts().insert(script);
    page.load(QUrl("about:blank"));
    QTRY_COMPARE(spy.count(), 1);
    QCOMPARE(spy.takeFirst().value(0).toBool(), true);
    // ...but ApplicationWorld scripts should still work
    QCOMPARE(evaluateJavaScriptSyncInWorld(&page, "foo", QWebEngineScript::MainWorld), QVariant());
    QCOMPARE(evaluateJavaScriptSyncInWorld(&page, "foo", QWebEngineScript::ApplicationWorld), QVariant(42));
}

// Based on QTBUG-66011
void tst_QWebEngineScript::viewSource()
{
    QWebEnginePage page;
    QWebEngineScript script;
    script.setInjectionPoint(QWebEngineScript::DocumentCreation);
    script.setWorldId(QWebEngineScript::MainWorld);
    script.setSourceCode("var foo = 42");
    page.scripts().insert(script);
    page.load(QUrl("view-source:about:blank"));
    QSignalSpy spy(&page, &QWebEnginePage::loadFinished);
    QTRY_COMPARE(spy.count(), 1);
    QCOMPARE(spy.takeFirst().value(0).toBool(), true);
    QCOMPARE(evaluateJavaScriptSync(&page, "foo"), QVariant(42));
}

void tst_QWebEngineScript::scriptModifications()
{
    QWebEnginePage page;
    QWebEngineScript script;
    script.setName(QStringLiteral("String1"));
    script.setInjectionPoint(QWebEngineScript::DocumentCreation);
    script.setWorldId(QWebEngineScript::MainWorld);
    script.setSourceCode("var foo = \"SUCCESS\";");
    page.scripts().insert(script);
    page.setHtml(QStringLiteral("<html><head><script>document.addEventListener(\"DOMContentLoaded\", function() {\
                                 document.body.innerText = foo;});\
                                 </script></head><body></body></html>"));
    QVERIFY(page.scripts().count() == 1);
    QSignalSpy spyFinished(&page, &QWebEnginePage::loadFinished);
    QVERIFY(spyFinished.wait());
    QCOMPARE(evaluateJavaScriptSync(&page, "document.body.innerText"), QVariant::fromValue(QStringLiteral("SUCCESS")));
    script.setSourceCode("var foo = \"FAILURE\"");
    page.triggerAction(QWebEnginePage::ReloadAndBypassCache);
    QVERIFY(spyFinished.wait());
    QCOMPARE(evaluateJavaScriptSync(&page, "document.body.innerText"), QVariant::fromValue(QStringLiteral("SUCCESS")));
    QVERIFY(page.scripts().count() == 1);
    QWebEngineScript s = page.scripts().findScript(QStringLiteral("String1"));
    QVERIFY(page.scripts().remove(s));
    QVERIFY(page.scripts().count() == 0);
}

class TestObject : public QObject
{
    Q_OBJECT
    Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged)
public:
    TestObject(QObject *parent = 0) : QObject(parent) { }

    void setText(const QString &text)
    {
        if (text == m_text)
            return;
        m_text = text;
        emit textChanged(text);
    }

    QString text() const { return m_text; }

signals:
    void textChanged(const QString &text);

private:
    QString m_text;
};

#if QT_CONFIG(webengine_webchannel)
static QString readFile(const QString &path)
{
    QFile file(path);
    file.open(QFile::ReadOnly);
    QByteArray contents = file.readAll();
    file.close();
    return contents;
}

static QWebEngineScript webChannelScript()
{
    QString sourceCode = readFile(QStringLiteral(":/qtwebchannel/qwebchannel.js"));
    Q_ASSERT(!sourceCode.isEmpty());

    QWebEngineScript script;
    script.setSourceCode(sourceCode);
    script.setInjectionPoint(QWebEngineScript::DocumentCreation);
    script.setWorldId(QWebEngineScript::MainWorld);
    return script;
}

void tst_QWebEngineScript::webChannel_data()
{
    QTest::addColumn<int>("worldId");
    QTest::addColumn<bool>("reloadFirst");
    QTest::newRow("MainWorld") << static_cast<int>(QWebEngineScript::MainWorld) << false;
    QTest::newRow("ApplicationWorld") << static_cast<int>(QWebEngineScript::ApplicationWorld) << false;
    QTest::newRow("MainWorldWithReload") << static_cast<int>(QWebEngineScript::MainWorld) << true;
    QTest::newRow("ApplicationWorldWithReload") << static_cast<int>(QWebEngineScript::ApplicationWorld) << true;
}

void tst_QWebEngineScript::webChannel()
{
    QFETCH(int, worldId);
    QFETCH(bool, reloadFirst);
    QWebEnginePage page;
    TestObject testObject;
    QScopedPointer<QWebChannel> channel(new QWebChannel(this));
    channel->registerObject(QStringLiteral("object"), &testObject);
    page.setWebChannel(channel.data(), worldId);

    QWebEngineScript script = webChannelScript();
    script.setWorldId(worldId);
    page.scripts().insert(script);
    page.setHtml(QStringLiteral("<html><body></body></html>"));
    QSignalSpy spyFinished(&page, &QWebEnginePage::loadFinished);
    QVERIFY(spyFinished.wait());
    if (reloadFirst) {
        // Check that the transport is also reinstalled on navigation
        page.triggerAction(QWebEnginePage::Reload);
        QVERIFY(spyFinished.wait());
    }
    page.runJavaScript(QLatin1String(
                                "new QWebChannel(qt.webChannelTransport,"
                                "  function(channel) {"
                                "    channel.objects.object.text = 'test';"
                                "  }"
                                ");"), worldId);
    QSignalSpy spyTextChanged(&testObject, &TestObject::textChanged);
    QVERIFY(spyTextChanged.wait());
    QCOMPARE(testObject.text(), QStringLiteral("test"));

    if (worldId != QWebEngineScript::MainWorld)
        QCOMPARE(evaluateJavaScriptSync(&page, "qt.webChannelTransport"), QVariant(QVariant::Invalid));
}
#endif
void tst_QWebEngineScript::noTransportWithoutWebChannel()
{
    QWebEnginePage page;
    page.setHtml(QStringLiteral("<html><body></body></html>"));

    QCOMPARE(evaluateJavaScriptSync(&page, "qt.webChannelTransport"), QVariant(QVariant::Invalid));
    page.triggerAction(QWebEnginePage::Reload);
    QSignalSpy spyFinished(&page, &QWebEnginePage::loadFinished);
    QVERIFY(spyFinished.wait());
    QCOMPARE(evaluateJavaScriptSync(&page, "qt.webChannelTransport"), QVariant(QVariant::Invalid));
}

void tst_QWebEngineScript::scriptsInNestedIframes()
{
    QWebEnginePage page;
    QWebEngineView view;
    view.setPage(&page);
    QWebEngineScript s;
    s.setInjectionPoint(QWebEngineScript::DocumentReady);
    s.setWorldId(QWebEngineScript::ApplicationWorld);

    // Prepend a "Modified prefix" to every frame's div content.
    s.setSourceCode("var elements = document.getElementsByTagName(\"div\");\
                    var i;\
                    for (i = 0; i < elements.length; i++) {\
                        var content = elements[i].innerHTML;\
                        elements[i].innerHTML = \"Modified \" + content;\
                    }\
                    ");

    // Make sure the script runs on all frames.
    s.setRunsOnSubFrames(true);
    page.scripts().insert(s);

    QSignalSpy spyFinished(&page, &QWebEnginePage::loadFinished);
    page.load(QUrl("qrc:/resources/test_iframe_main.html"));
    view.show();
    QVERIFY(spyFinished.wait());

    // Check that main frame has modified content.
    QCOMPARE(
        evaluateJavaScriptSyncInWorld(&page, "document.getElementsByTagName(\"div\")[0].innerHTML",
                                      QWebEngineScript::ApplicationWorld),
                QVariant::fromValue(QStringLiteral("Modified Main text")));

    // Check that outer frame has modified content.
    QCOMPARE(
        evaluateJavaScriptSyncInWorld(&page,
                                      "var i = document.getElementById(\"outer\").contentDocument;\
                                       i.getElementsByTagName(\"div\")[0].innerHTML",
                                      QWebEngineScript::ApplicationWorld),
                QVariant::fromValue(QStringLiteral("Modified Outer text")));


    // Check that inner frame has modified content.
    QCOMPARE(
        evaluateJavaScriptSyncInWorld(&page,
                                      "var i = document.getElementById(\"outer\").contentDocument;\
                                       var i2 = i.getElementById(\"inner\").contentDocument;\
                                       i2.getElementsByTagName(\"div\")[0].innerHTML",
                                      QWebEngineScript::ApplicationWorld),
                QVariant::fromValue(QStringLiteral("Modified Inner text")));
}
#if QT_CONFIG(webengine_webchannel)
void tst_QWebEngineScript::webChannelResettingAndUnsetting()
{
    QWebEnginePage page;

    // There should be no webChannelTransport yet.
    QCOMPARE(evaluateJavaScriptSyncInWorld(&page, "qt.webChannelTransport", QWebEngineScript::MainWorld),
             QVariant(QVariant::Invalid));
    QCOMPARE(evaluateJavaScriptSyncInWorld(&page, "qt.webChannelTransport", QWebEngineScript::ApplicationWorld),
             QVariant(QVariant::Invalid));

    QWebChannel channel;
    page.setWebChannel(&channel, QWebEngineScript::MainWorld);

    // There should be one in MainWorld now.
    QCOMPARE(evaluateJavaScriptSyncInWorld(&page, "qt.webChannelTransport", QWebEngineScript::MainWorld),
             QVariant(QVariantMap()));
    QCOMPARE(evaluateJavaScriptSyncInWorld(&page, "qt.webChannelTransport", QWebEngineScript::ApplicationWorld),
             QVariant(QVariant::Invalid));

    page.setWebChannel(&channel, QWebEngineScript::ApplicationWorld);

    // Now it should have moved to ApplicationWorld.
    QCOMPARE(evaluateJavaScriptSyncInWorld(&page, "qt.webChannelTransport", QWebEngineScript::MainWorld),
             QVariant(QVariant::Invalid));
    QCOMPARE(evaluateJavaScriptSyncInWorld(&page, "qt.webChannelTransport", QWebEngineScript::ApplicationWorld),
             QVariant(QVariantMap()));

    page.setWebChannel(nullptr);

    // And now it should be gone again.
    QCOMPARE(evaluateJavaScriptSyncInWorld(&page, "qt.webChannelTransport", QWebEngineScript::MainWorld),
             QVariant(QVariant::Invalid));
    QCOMPARE(evaluateJavaScriptSyncInWorld(&page, "qt.webChannelTransport", QWebEngineScript::ApplicationWorld),
             QVariant(QVariant::Invalid));
}

void tst_QWebEngineScript::webChannelWithExistingQtObject()
{
    QWebEnginePage page;

    evaluateJavaScriptSync(&page, "qt = 42");
    QCOMPARE(evaluateJavaScriptSync(&page, "qt.webChannelTransport"), QVariant(QVariant::Invalid));

    QWebChannel channel;
    page.setWebChannel(&channel);

    // setWebChannel should have overwritten the qt variable
    QCOMPARE(evaluateJavaScriptSync(&page, "qt.webChannelTransport"), QVariant(QVariantMap()));
}

static QWebEngineScript locationMonitorScript()
{
    QWebEngineScript script = webChannelScript();
    script.setSourceCode(script.sourceCode() + QStringLiteral(R"(
        new QWebChannel(qt.webChannelTransport, channel => {
            channel.objects.object.text = window.location.href;
        })
    )"));
    return script;
}

void tst_QWebEngineScript::navigation()
{
    QWebEnginePage page;
    TestObject testObject;
    QSignalSpy spyTextChanged(&testObject, &TestObject::textChanged);
    QWebChannel channel;
    channel.registerObject(QStringLiteral("object"), &testObject);
    page.setWebChannel(&channel);
    page.scripts().insert(locationMonitorScript());

    QString url1 = QStringLiteral("about:blank");
    page.setUrl(url1);
    QTRY_COMPARE(spyTextChanged.count(), 1);
    QCOMPARE(testObject.text(), url1);

    QString url2 = QStringLiteral("chrome://gpu/");
    page.setUrl(url2);
    QTRY_COMPARE(spyTextChanged.count(), 2);
    QCOMPARE(testObject.text(), url2);

    QString url3 = QStringLiteral("qrc:/resources/test_iframe_main.html");
    page.setUrl(url3);
    QTRY_COMPARE(spyTextChanged.count(), 3);
    QCOMPARE(testObject.text(), url3);

    page.setLifecycleState(QWebEnginePage::LifecycleState::Discarded);
    page.setUrl(url1);
    QTRY_COMPARE(spyTextChanged.count(), 4);
    QCOMPARE(testObject.text(), url1);
}

// Try to set TestObject::text to an invalid UTF-16 string.
//
// See QTBUG-61969.
void tst_QWebEngineScript::webChannelWithBadString()
{
    QWebEnginePage page;
    TestObject host;
    QSignalSpy hostSpy(&host, &TestObject::textChanged);
    QWebChannel channel;
    channel.registerObject(QStringLiteral("host"), &host);
    page.setWebChannel(&channel);
    page.setUrl(QStringLiteral("qrc:/resources/webChannelWithBadString.html"));
    QVERIFY(hostSpy.wait(20000));
    // expect 0xD800 see https://chromium-review.googlesource.com/c/1282993
    QChar data(0xd800);
    QCOMPARE(host.text(), data);
}
#endif

void tst_QWebEngineScript::matchQrcUrl()
{
    QWebEnginePage page;
    QWebEngineView view;
    view.setPage(&page);
    QWebEngineScript s;
    s.setInjectionPoint(QWebEngineScript::DocumentReady);
    s.setWorldId(QWebEngineScript::MainWorld);


    s.setSourceCode(QStringLiteral(R"(
// ==UserScript==
// @match qrc:/*main.html
// ==/UserScript==

document.title = 'New title';
    )"));

    page.scripts().insert(s);
    page.load(QUrl("qrc:/resources/test_iframe_main.html"));
    view.show();
    QSignalSpy spyFinished(&page, &QWebEnginePage::loadFinished);
    QVERIFY(spyFinished.wait());
    QCOMPARE(page.title(), "New title");
}

QTEST_MAIN(tst_QWebEngineScript)

#include "tst_qwebenginescript.moc"
