diff options
Diffstat (limited to 'Source/WebKit/qt/tests/qwebframe/tst_qwebframe.cpp')
-rw-r--r-- | Source/WebKit/qt/tests/qwebframe/tst_qwebframe.cpp | 1599 |
1 files changed, 0 insertions, 1599 deletions
diff --git a/Source/WebKit/qt/tests/qwebframe/tst_qwebframe.cpp b/Source/WebKit/qt/tests/qwebframe/tst_qwebframe.cpp deleted file mode 100644 index 2068eec3f..000000000 --- a/Source/WebKit/qt/tests/qwebframe/tst_qwebframe.cpp +++ /dev/null @@ -1,1599 +0,0 @@ -/* - Copyright (C) 2008,2009 Nokia Corporation and/or its subsidiary(-ies) - - 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 <qwebpage.h> -#include <qwebelement.h> -#include <qwebview.h> -#include <qwebframe.h> -#include <qwebhistory.h> -#include <QAbstractItemView> -#include <QApplication> -#include <QComboBox> -#include <QPaintEngine> -#include <QPicture> -#include <QNetworkRequest> -#include <QNetworkReply> -#include <QTextCodec> -#ifndef QT_NO_OPENSSL -#include <qsslerror.h> -#endif -#include "../util.h" - -class tst_QWebFrame : public QObject -{ - Q_OBJECT - -public: - bool eventFilter(QObject* watched, QEvent* event); - -public Q_SLOTS: - void init(); - void cleanup(); - -private Q_SLOTS: - void horizontalScrollAfterBack(); - void symmetricUrl(); - void progressSignal(); - void urlChange(); - void requestedUrl(); - void requestedUrlAfterSetAndLoadFailures(); - void javaScriptWindowObjectCleared_data(); - void javaScriptWindowObjectCleared(); - void javaScriptWindowObjectClearedOnEvaluate(); - void setHtml(); - void setHtmlWithImageResource(); - void setHtmlWithStylesheetResource(); - void setHtmlWithBaseURL(); - void setHtmlWithJSAlert(); - void ipv6HostEncoding(); - void metaData(); -#if !defined(QT_NO_COMBOBOX) - void popupFocus(); -#endif - void inputFieldFocus(); - void hitTestContent(); - void baseUrl_data(); - void baseUrl(); - void hasSetFocus(); - void renderGeometry(); - void renderHints(); - void scrollPosition(); - void scrollToAnchor(); - void scrollbarsOff(); - void evaluateWillCauseRepaint(); - void setContent_data(); - void setContent(); - void setCacheLoadControlAttribute(); - void setUrlWithPendingLoads(); - void setUrlWithFragment_data(); - void setUrlWithFragment(); - void setUrlToEmpty(); - void setUrlToInvalid(); - void setUrlHistory(); - void setUrlUsingStateObject(); - void setUrlSameUrl(); - void setUrlThenLoads_data(); - void setUrlThenLoads(); - void loadFinishedAfterNotFoundError(); - void signalsDuringErrorHandling(); - void loadInSignalHandlers_data(); - void loadInSignalHandlers(); - -private: - QWebView* m_view { nullptr }; - QWebPage* m_page { nullptr }; - QWebView* m_inputFieldsTestView { nullptr }; - int m_inputFieldTestPaintCount { 0 }; -}; - -bool tst_QWebFrame::eventFilter(QObject* watched, QEvent* event) -{ - // used on the inputFieldFocus test - if (watched == m_inputFieldsTestView) { - if (event->type() == QEvent::Paint) - m_inputFieldTestPaintCount++; - } - return QObject::eventFilter(watched, event); -} - -void tst_QWebFrame::init() -{ - m_view = new QWebView(); - m_page = m_view->page(); -} - -void tst_QWebFrame::cleanup() -{ - delete m_view; -} - -void tst_QWebFrame::symmetricUrl() -{ - QVERIFY(m_view->url().isEmpty()); - - QCOMPARE(m_view->history()->count(), 0); - - QUrl dataUrl("data:text/html,<h1>Test"); - - m_view->setUrl(dataUrl); - QCOMPARE(m_view->url(), dataUrl); - QCOMPARE(m_view->history()->count(), 0); - - // loading is _not_ immediate, so the text isn't set just yet. - QVERIFY(m_view->page()->mainFrame()->toPlainText().isEmpty()); - - ::waitForSignal(m_view, SIGNAL(loadFinished(bool))); - - QCOMPARE(m_view->history()->count(), 1); - QCOMPARE(m_view->page()->mainFrame()->toPlainText(), QString("Test")); - - QUrl dataUrl2("data:text/html,<h1>Test2"); - QUrl dataUrl3("data:text/html,<h1>Test3"); - - m_view->setUrl(dataUrl2); - m_view->setUrl(dataUrl3); - - QCOMPARE(m_view->url(), dataUrl3); - - ::waitForSignal(m_view, SIGNAL(loadFinished(bool))); - - QCOMPARE(m_view->history()->count(), 2); - - QCOMPARE(m_view->page()->mainFrame()->toPlainText(), QString("Test3")); -} - -void tst_QWebFrame::progressSignal() -{ - QSignalSpy progressSpy(m_view, SIGNAL(loadProgress(int))); - - QUrl dataUrl("data:text/html,<h1>Test"); - m_view->setUrl(dataUrl); - - ::waitForSignal(m_view, SIGNAL(loadFinished(bool))); - - QVERIFY(progressSpy.size() >= 1); - QCOMPARE(progressSpy.last().first().toInt(), 100); -} - -void tst_QWebFrame::urlChange() -{ - QSignalSpy urlSpy(m_page->mainFrame(), SIGNAL(urlChanged(QUrl))); - - QUrl dataUrl("data:text/html,<h1>Test"); - m_view->setUrl(dataUrl); - - ::waitForSignal(m_page->mainFrame(), SIGNAL(urlChanged(QUrl))); - - QCOMPARE(urlSpy.size(), 1); - - QUrl dataUrl2("data:text/html,<html><head><title>title</title></head><body><h1>Test</body></html>"); - m_view->setUrl(dataUrl2); - - ::waitForSignal(m_page->mainFrame(), SIGNAL(urlChanged(QUrl))); - - QCOMPARE(urlSpy.size(), 2); -} - -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_QWebFrame::requestedUrl() -{ - QWebPage page; - QWebFrame* frame = page.mainFrame(); - - // in few seconds, the image should be completely loaded - QSignalSpy spy(&page, SIGNAL(loadFinished(bool))); - FakeNetworkManager* networkManager = new FakeNetworkManager(&page); - page.setNetworkAccessManager(networkManager); - - frame->setUrl(QUrl("qrc:/test1.html")); - waitForSignal(frame, SIGNAL(loadFinished(bool)), 200); - QCOMPARE(spy.count(), 1); - QCOMPARE(frame->requestedUrl(), QUrl("qrc:/test1.html")); - QCOMPARE(frame->url(), QUrl("qrc:/test2.html")); - - frame->setUrl(QUrl("qrc:/non-existent.html")); - waitForSignal(frame, SIGNAL(loadFinished(bool)), 200); - QCOMPARE(spy.count(), 2); - QCOMPARE(frame->requestedUrl(), QUrl("qrc:/non-existent.html")); - QCOMPARE(frame->url(), QUrl("qrc:/non-existent.html")); - - frame->setUrl(QUrl("http://abcdef.abcdef")); - waitForSignal(frame, SIGNAL(loadFinished(bool)), 200); - QCOMPARE(spy.count(), 3); - QCOMPARE(frame->requestedUrl(), QUrl("http://abcdef.abcdef/")); - QCOMPARE(frame->url(), QUrl("http://abcdef.abcdef/")); - -#ifndef QT_NO_OPENSSL - qRegisterMetaType<QList<QSslError> >("QList<QSslError>"); - qRegisterMetaType<QNetworkReply* >("QNetworkReply*"); - - QSignalSpy spy2(page.networkAccessManager(), SIGNAL(sslErrors(QNetworkReply*,QList<QSslError>))); - frame->setUrl(QUrl("qrc:/fake-ssl-error.html")); - waitForSignal(frame, SIGNAL(loadFinished(bool)), 200); - QCOMPARE(spy2.count(), 1); - QCOMPARE(frame->requestedUrl(), QUrl("qrc:/fake-ssl-error.html")); - QCOMPARE(frame->url(), QUrl("qrc:/fake-ssl-error.html")); -#endif -} - -void tst_QWebFrame::requestedUrlAfterSetAndLoadFailures() -{ - QWebPage page; - QWebFrame* frame = page.mainFrame(); - - QSignalSpy spy(frame, SIGNAL(loadFinished(bool))); - - const QUrl first("http://abcdef.abcdef/"); - frame->setUrl(first); - ::waitForSignal(frame, SIGNAL(loadFinished(bool))); - QCOMPARE(frame->url(), first); - QCOMPARE(frame->requestedUrl(), first); - QVERIFY(!spy.at(0).first().toBool()); - - const QUrl second("http://abcdef.abcdef/another_page.html"); - QVERIFY(first != second); - - page.settings()->setAttribute(QWebSettings::ErrorPageEnabled, false); - - frame->load(second); - ::waitForSignal(frame, SIGNAL(loadFinished(bool))); - QCOMPARE(frame->url(), first); - QCOMPARE(frame->requestedUrl(), second); - QVERIFY(!spy.at(1).first().toBool()); - - page.settings()->setAttribute(QWebSettings::ErrorPageEnabled, true); - - frame->load(second); - ::waitForSignal(frame, SIGNAL(loadFinished(bool))); - QCOMPARE(frame->url(), second); - QCOMPARE(frame->requestedUrl(), second); - QVERIFY(!spy.at(2).first().toBool()); -} - -void tst_QWebFrame::javaScriptWindowObjectCleared_data() -{ - QTest::addColumn<QString>("html"); - QTest::addColumn<int>("signalCount"); - QTest::newRow("with <script>") << "<html><body><script>i=0</script><p>hello world</p></body></html>" << 1; - // NOTE: Empty scripts no longer cause this signal to be emitted. - QTest::newRow("with empty <script>") << "<html><body><script></script><p>hello world</p></body></html>" << 0; - QTest::newRow("without <script>") << "<html><body><p>hello world</p></body></html>" << 0; -} - -void tst_QWebFrame::javaScriptWindowObjectCleared() -{ - QWebPage page; - QWebFrame* frame = page.mainFrame(); - QSignalSpy spy(frame, SIGNAL(javaScriptWindowObjectCleared())); - QFETCH(QString, html); - frame->setHtml(html); - - QFETCH(int, signalCount); - QCOMPARE(spy.count(), signalCount); -} - -void tst_QWebFrame::javaScriptWindowObjectClearedOnEvaluate() -{ - QWebPage page; - QWebFrame* frame = page.mainFrame(); - QSignalSpy spy(frame, SIGNAL(javaScriptWindowObjectCleared())); - frame->setHtml("<html></html>"); - QCOMPARE(spy.count(), 0); - frame->evaluateJavaScript("var a = 'a';"); - QCOMPARE(spy.count(), 1); - // no new clear for a new script: - frame->evaluateJavaScript("var a = 1;"); - QCOMPARE(spy.count(), 1); -} - -void tst_QWebFrame::setHtml() -{ - QString html("<html><head></head><body><p>hello world</p></body></html>"); - QSignalSpy spy(m_view->page(), SIGNAL(loadFinished(bool))); - m_view->page()->mainFrame()->setHtml(html); - QCOMPARE(m_view->page()->mainFrame()->toHtml(), html); - QCOMPARE(spy.count(), 1); -} - -void tst_QWebFrame::setHtmlWithImageResource() -{ - // By default, only security origins of local files can load local resources. - // So we should specify baseUrl to be a local file in order to get a proper origin and load the local image. - - QLatin1String html("<html><body><p>hello world</p><img src='qrc:/image.png'/></body></html>"); - QWebPage page; - QWebFrame* frame = page.mainFrame(); - - frame->setHtml(html, QUrl(QLatin1String("file:///path/to/file"))); - waitForSignal(frame, SIGNAL(loadFinished(bool)), 200); - - QCOMPARE(frame->evaluateJavaScript("document.images.length").toInt(), 1); - QCOMPARE(frame->evaluateJavaScript("document.images[0].width").toInt(), 128); - QCOMPARE(frame->evaluateJavaScript("document.images[0].height").toInt(), 128); - - // Now we test the opposite: without a baseUrl as a local file, we cannot request local resources. - - frame->setHtml(html); - waitForSignal(frame, SIGNAL(loadFinished(bool)), 200); - QCOMPARE(frame->evaluateJavaScript("document.images.length").toInt(), 1); - QEXPECT_FAIL("", "https://bugs.webkit.org/show_bug.cgi?id=118659", Continue); - QCOMPARE(frame->evaluateJavaScript("document.images[0].width").toInt(), 0); - QEXPECT_FAIL("", "https://bugs.webkit.org/show_bug.cgi?id=118659", Continue); - QCOMPARE(frame->evaluateJavaScript("document.images[0].height").toInt(), 0); -} - -void tst_QWebFrame::setHtmlWithStylesheetResource() -{ - // By default, only security origins of local files can load local resources. - // So we should specify baseUrl to be a local file in order to be able to download the local stylesheet. - - const char* htmlData = - "<html>" - "<head>" - "<link rel='stylesheet' href='qrc:/style.css' type='text/css' />" - "</head>" - "<body>" - "<p id='idP'>some text</p>" - "</body>" - "</html>"; - QLatin1String html(htmlData); - QWebPage page; - QWebFrame* frame = page.mainFrame(); - QWebElement webElement; - - frame->setHtml(html, QUrl(QLatin1String("qrc:///file"))); - waitForSignal(frame, SIGNAL(loadFinished(bool)), 200); - webElement = frame->documentElement().findFirst("p"); - QCOMPARE(webElement.styleProperty("color", QWebElement::CascadedStyle), QLatin1String("red")); - - // Now we test the opposite: without a baseUrl as a local file, we cannot request local resources. - - frame->setHtml(html, QUrl(QLatin1String("http://www.example.com/"))); - waitForSignal(frame, SIGNAL(loadFinished(bool)), 200); - webElement = frame->documentElement().findFirst("p"); - QEXPECT_FAIL("", "https://bugs.webkit.org/show_bug.cgi?id=118659", Continue); - QCOMPARE(webElement.styleProperty("color", QWebElement::CascadedStyle), QString()); -} - -void tst_QWebFrame::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='qwebframe/resources/image.png'/></body></html>"); - - QWebPage page; - QWebFrame* frame = page.mainFrame(); - - // in few seconds, the image should be completey loaded - QSignalSpy spy(&page, SIGNAL(loadFinished(bool))); - - frame->setHtml(html, QUrl::fromLocalFile(TESTS_SOURCE_DIR)); - waitForSignal(frame, SIGNAL(loadFinished(bool)), 200); - QCOMPARE(spy.count(), 1); - - QCOMPARE(frame->evaluateJavaScript("document.images.length").toInt(), 1); - QCOMPARE(frame->evaluateJavaScript("document.images[0].width").toInt(), 128); - QCOMPARE(frame->evaluateJavaScript("document.images[0].height").toInt(), 128); - - // no history item has to be added. - QCOMPARE(m_view->page()->history()->count(), 0); -} - -class MyPage : public QWebPage -{ -public: - MyPage() : QWebPage(), alerts(0) {} - int alerts; - -protected: - virtual void javaScriptAlert(QWebFrame*, const QString& msg) - { - alerts++; - QCOMPARE(msg, QString("foo")); - // Should not be enough to trigger deferred loading, since we've upped the HTML - // tokenizer delay in the Qt frameloader. See HTMLTokenizer::continueProcessing() - QTest::qWait(1000); - } -}; - -void tst_QWebFrame::setHtmlWithJSAlert() -{ - QString html("<html><head></head><body><script>alert('foo');</script><p>hello world</p></body></html>"); - MyPage page; - m_view->setPage(&page); - page.mainFrame()->setHtml(html); - QCOMPARE(page.alerts, 1); - QEXPECT_FAIL("", "https://bugs.webkit.org/show_bug.cgi?id=118663", Continue); - QCOMPARE(m_view->page()->mainFrame()->toHtml(), html); -} - -class TestNetworkManager : public QNetworkAccessManager -{ -public: - TestNetworkManager(QObject* parent) : QNetworkAccessManager(parent) {} - - QList<QUrl> requestedUrls; - -protected: - virtual QNetworkReply* createRequest(Operation op, const QNetworkRequest &request, QIODevice* outgoingData) { - requestedUrls.append(request.url()); - QNetworkRequest redirectedRequest = request; - redirectedRequest.setUrl(QUrl("data:text/html,<p>hello")); - return QNetworkAccessManager::createRequest(op, redirectedRequest, outgoingData); - } -}; - -void tst_QWebFrame::ipv6HostEncoding() -{ - TestNetworkManager* networkManager = new TestNetworkManager(m_page); - m_page->setNetworkAccessManager(networkManager); - networkManager->requestedUrls.clear(); - - QUrl baseUrl = QUrl::fromEncoded("http://[::1]/index.html"); - m_view->setHtml("<p>Hi", baseUrl); - m_view->page()->mainFrame()->evaluateJavaScript("var r = new XMLHttpRequest();" - "r.open('GET', 'http://[::1]/test.xml', false);" - "r.send(null);" - ); - QCOMPARE(networkManager->requestedUrls.count(), 1); - QCOMPARE(networkManager->requestedUrls.at(0), QUrl::fromEncoded("http://[::1]/test.xml")); -} - -void tst_QWebFrame::metaData() -{ - m_view->setHtml("<html>" - " <head>" - " <meta name=\"description\" content=\"Test description\">" - " <meta name=\"keywords\" content=\"HTML, JavaScript, Css\">" - " </head>" - "</html>"); - - QMultiMap<QString, QString> metaData = m_view->page()->mainFrame()->metaData(); - - QCOMPARE(metaData.count(), 2); - - QCOMPARE(metaData.value("description"), QString("Test description")); - QCOMPARE(metaData.value("keywords"), QString("HTML, JavaScript, Css")); - QCOMPARE(metaData.value("nonexistant"), QString()); - - m_view->setHtml("<html>" - " <head>" - " <meta name=\"samekey\" content=\"FirstValue\">" - " <meta name=\"samekey\" content=\"SecondValue\">" - " </head>" - "</html>"); - - metaData = m_view->page()->mainFrame()->metaData(); - - QCOMPARE(metaData.count(), 2); - - QStringList values = metaData.values("samekey"); - QCOMPARE(values.count(), 2); - - QVERIFY(values.contains("FirstValue")); - QVERIFY(values.contains("SecondValue")); - - QCOMPARE(metaData.value("nonexistant"), QString()); -} - -#if !defined(QT_NO_COMBOBOX) -void tst_QWebFrame::popupFocus() -{ - QWebView view; - view.setHtml("<html>" - " <body>" - " <select name=\"select\">" - " <option>1</option>" - " <option>2</option>" - " </select>" - " <input type=\"text\"> </input>" - " <textarea name=\"text_area\" rows=\"3\" cols=\"40\">" - "This test checks whether showing and hiding a popup" - "takes the focus away from the webpage." - " </textarea>" - " </body>" - "</html>"); - view.resize(400, 100); - // Call setFocus before show to work around http://bugreports.qt.nokia.com/browse/QTBUG-14762 - view.setFocus(); - view.show(); - QTest::qWaitForWindowExposed(&view); - view.activateWindow(); - QTRY_VERIFY(view.hasFocus()); - - // open the popup by clicking. check if focus is on the popup - const QWebElement webCombo = view.page()->mainFrame()->documentElement().findFirst(QLatin1String("select[name=select]")); - QTest::mouseClick(&view, Qt::LeftButton, 0, webCombo.geometry().center()); - - QComboBox* combo = view.findChild<QComboBox*>(); - QVERIFY(combo != 0); - QTRY_VERIFY(!view.hasFocus() && combo->view()->hasFocus()); // Focus should be on the popup - - // hide the popup and check if focus is on the page - combo->hidePopup(); - QTRY_VERIFY(view.hasFocus()); // Focus should be back on the WebView -} -#endif - -void tst_QWebFrame::inputFieldFocus() -{ - QWebView view; - view.setHtml("<html><body><input type=\"text\"></input></body></html>"); - view.resize(400, 100); - view.show(); - QTest::qWaitForWindowExposed(&view); - view.activateWindow(); - view.setFocus(); - QTRY_VERIFY(view.hasFocus()); - - // double the flashing time, should at least blink once already - int delay = qApp->cursorFlashTime() * 2; - - // focus the lineedit and check if it blinks - bool autoSipEnabled = qApp->autoSipEnabled(); - qApp->setAutoSipEnabled(false); - const QWebElement inputElement = view.page()->mainFrame()->documentElement().findFirst(QLatin1String("input[type=text]")); - QTest::mouseClick(&view, Qt::LeftButton, 0, inputElement.geometry().center()); - m_inputFieldsTestView = &view; - view.installEventFilter( this ); - QTest::qWait(delay); - QVERIFY2(m_inputFieldTestPaintCount >= 3, - "The input field should have a blinking caret"); - qApp->setAutoSipEnabled(autoSipEnabled); -} - -void tst_QWebFrame::hitTestContent() -{ - QString html("<html><body><p>A paragraph</p><br/><br/><br/><a href=\"about:blank\" target=\"_foo\" id=\"link\">link text</a></body></html>"); - - QWebPage page; - QWebFrame* frame = page.mainFrame(); - frame->setHtml(html); - page.setViewportSize(QSize(200, 0)); //no height so link is not visible - const QWebElement linkElement = frame->documentElement().findFirst(QLatin1String("a#link")); - QWebHitTestResult result = frame->hitTestContent(linkElement.geometry().center()); - QCOMPARE(result.linkText(), QString("link text")); - QWebElement link = result.linkElement(); - QCOMPARE(link.attribute("target"), QString("_foo")); - QCOMPARE(result.element().tagName(), QString("A")); -} - -void tst_QWebFrame::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_QWebFrame::baseUrl() -{ - QFETCH(QString, html); - QFETCH(QUrl, loadUrl); - QFETCH(QUrl, url); - QFETCH(QUrl, baseUrl); - - m_page->mainFrame()->setHtml(html, loadUrl); - QCOMPARE(m_page->mainFrame()->url(), url); - QCOMPARE(m_page->mainFrame()->baseUrl(), baseUrl); -} - -void tst_QWebFrame::hasSetFocus() -{ - QString html("<html><body><p>top</p>" \ - "<iframe width='80%' height='30%'/>" \ - "</body></html>"); - - QSignalSpy loadSpy(m_page, SIGNAL(loadFinished(bool))); - m_page->mainFrame()->setHtml(html); - - waitForSignal(m_page->mainFrame(), SIGNAL(loadFinished(bool)), 200); - QCOMPARE(loadSpy.size(), 1); - - QList<QWebFrame*> children = m_page->mainFrame()->childFrames(); - QWebFrame* frame = children.at(0); - QString innerHtml("<html><body><p>another iframe</p>" \ - "<iframe width='80%' height='30%'/>" \ - "</body></html>"); - frame->setHtml(innerHtml); - - waitForSignal(frame, SIGNAL(loadFinished(bool)), 200); - QCOMPARE(loadSpy.size(), 2); - - m_page->mainFrame()->setFocus(); - QTRY_VERIFY(m_page->mainFrame()->hasFocus()); - - for (int i = 0; i < children.size(); ++i) { - children.at(i)->setFocus(); - QTRY_VERIFY(children.at(i)->hasFocus()); - QVERIFY(!m_page->mainFrame()->hasFocus()); - } - - m_page->mainFrame()->setFocus(); - QTRY_VERIFY(m_page->mainFrame()->hasFocus()); -} - -void tst_QWebFrame::renderGeometry() -{ - QString html("<html>" \ - "<head><style>" \ - "body, iframe { margin: 0px; border: none; }" \ - "</style></head>" \ - "<body><iframe width='100px' height='100px'/></body>" \ - "</html>"); - - QWebPage page; - page.mainFrame()->setHtml(html); - - QList<QWebFrame*> frames = page.mainFrame()->childFrames(); - QWebFrame *frame = frames.at(0); - QString innerHtml("<body style='margin: 0px;'><img src='qrc:/image.png'/></body>"); - - // By default, only security origins of local files can load local resources. - // So we should specify baseUrl to be a local file in order to get a proper origin. - frame->setHtml(innerHtml, QUrl("file:///path/to/file")); - waitForSignal(frame, SIGNAL(loadFinished(bool)), 200); - - QPicture picture; - - QSize size = page.mainFrame()->contentsSize(); - page.setViewportSize(size); - - // render contents layer only (the iframe is smaller than the image, so it will have scrollbars) - QPainter painter1(&picture); - frame->render(&painter1, QWebFrame::ContentsLayer); - painter1.end(); - - QCOMPARE(size.width(), picture.boundingRect().width() + frame->scrollBarGeometry(Qt::Vertical).width()); - QCOMPARE(size.height(), picture.boundingRect().height() + frame->scrollBarGeometry(Qt::Horizontal).height()); - - // render everything, should be the size of the iframe - QPainter painter2(&picture); - frame->render(&painter2, QWebFrame::AllLayers); - painter2.end(); - - QCOMPARE(size.width(), picture.boundingRect().width()); // width: 100px - QCOMPARE(size.height(), picture.boundingRect().height()); // height: 100px -} - - -class DummyPaintEngine: public QPaintEngine { -public: - - DummyPaintEngine() - : QPaintEngine(QPaintEngine::AllFeatures) - , renderHints(0) - { - } - - bool begin(QPaintDevice*) - { - setActive(true); - return true; - } - - bool end() - { - setActive(false); - return false; - } - - void updateState(const QPaintEngineState& state) - { - renderHints = state.renderHints(); - } - - void drawPath(const QPainterPath&) { } - void drawPixmap(const QRectF&, const QPixmap&, const QRectF&) { } - - QPaintEngine::Type type() const - { - return static_cast<QPaintEngine::Type>(QPaintEngine::User + 2); - } - - QPainter::RenderHints renderHints; -}; - -class DummyPaintDevice: public QPaintDevice { -public: - DummyPaintDevice() - : QPaintDevice() - , m_engine(new DummyPaintEngine) - { - } - - ~DummyPaintDevice() - { - delete m_engine; - } - - QPaintEngine* paintEngine() const - { - return m_engine; - } - - QPainter::RenderHints renderHints() const - { - return m_engine->renderHints; - } - -protected: - int metric(PaintDeviceMetric metric) const; - -private: - DummyPaintEngine* m_engine; - friend class DummyPaintEngine; -}; - - -int DummyPaintDevice::metric(PaintDeviceMetric metric) const -{ - switch (metric) { - case PdmWidth: - return 400; - break; - - case PdmHeight: - return 200; - break; - - case PdmNumColors: - return INT_MAX; - break; - - case PdmDepth: - return 32; - break; - - default: - break; - } - return 0; -} - -void tst_QWebFrame::renderHints() -{ - QString html("<html><body><p>Hello, world!</p></body></html>"); - - QWebPage page; - page.mainFrame()->setHtml(html); - page.setViewportSize(page.mainFrame()->contentsSize()); - - // We will call frame->render and trap the paint engine state changes - // to ensure that GraphicsContext does not clobber the render hints. - DummyPaintDevice buffer; - QPainter painter(&buffer); - - painter.setRenderHint(QPainter::TextAntialiasing, false); - page.mainFrame()->render(&painter); - QVERIFY(!(buffer.renderHints() & QPainter::TextAntialiasing)); - QVERIFY(!(buffer.renderHints() & QPainter::SmoothPixmapTransform)); - QVERIFY(!(buffer.renderHints() & QPainter::HighQualityAntialiasing)); - - painter.setRenderHint(QPainter::TextAntialiasing, true); - page.mainFrame()->render(&painter); - QVERIFY(buffer.renderHints() & QPainter::TextAntialiasing); - QVERIFY(!(buffer.renderHints() & QPainter::SmoothPixmapTransform)); - QVERIFY(!(buffer.renderHints() & QPainter::HighQualityAntialiasing)); - - painter.setRenderHint(QPainter::SmoothPixmapTransform, true); - page.mainFrame()->render(&painter); - QVERIFY(buffer.renderHints() & QPainter::TextAntialiasing); - QVERIFY(buffer.renderHints() & QPainter::SmoothPixmapTransform); - QVERIFY(!(buffer.renderHints() & QPainter::HighQualityAntialiasing)); - - painter.setRenderHint(QPainter::HighQualityAntialiasing, true); - page.mainFrame()->render(&painter); - QVERIFY(buffer.renderHints() & QPainter::TextAntialiasing); - QVERIFY(buffer.renderHints() & QPainter::SmoothPixmapTransform); - QVERIFY(buffer.renderHints() & QPainter::HighQualityAntialiasing); -} - -void tst_QWebFrame::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>"); - - QWebPage page; - page.setViewportSize(QSize(200, 200)); - - QWebFrame* frame = page.mainFrame(); - frame->setHtml(html); - frame->setScrollBarPolicy(Qt::Vertical, Qt::ScrollBarAlwaysOff); - frame->setScrollBarPolicy(Qt::Horizontal, Qt::ScrollBarAlwaysOff); - - // try to set the scroll offset programmatically - frame->setScrollPosition(QPoint(23, 29)); - QCOMPARE(frame->scrollPosition().x(), 23); - QCOMPARE(frame->scrollPosition().y(), 29); - - int x = frame->evaluateJavaScript("window.scrollX").toInt(); - int y = frame->evaluateJavaScript("window.scrollY").toInt(); - QCOMPARE(x, 23); - QCOMPARE(y, 29); -} - -void tst_QWebFrame::scrollToAnchor() -{ - QWebPage page; - page.setViewportSize(QSize(480, 800)); - QWebFrame* frame = page.mainFrame(); - - QString html("<html><body><p style=\"margin-bottom: 1500px;\">Hello.</p>" - "<p><a id=\"foo\">This</a> is an anchor</p>" - "<p style=\"margin-bottom: 1500px;\"><a id=\"bar\">This</a> is another anchor</p>" - "</body></html>"); - frame->setHtml(html); - frame->setScrollPosition(QPoint(0, 0)); - QCOMPARE(frame->scrollPosition().x(), 0); - QCOMPARE(frame->scrollPosition().y(), 0); - - QWebElement fooAnchor = frame->findFirstElement("a[id=foo]"); - - frame->scrollToAnchor("foo"); - QCOMPARE(frame->scrollPosition().y(), fooAnchor.geometry().top()); - - frame->scrollToAnchor("bar"); - frame->scrollToAnchor("foo"); - QCOMPARE(frame->scrollPosition().y(), fooAnchor.geometry().top()); - - frame->scrollToAnchor("top"); - QCOMPARE(frame->scrollPosition().y(), 0); - - frame->scrollToAnchor("bar"); - frame->scrollToAnchor("notexist"); - QVERIFY(frame->scrollPosition().y() != 0); -} - - -void tst_QWebFrame::scrollbarsOff() -{ - QWebView view; - QWebFrame* mainFrame = view.page()->mainFrame(); - - mainFrame->setScrollBarPolicy(Qt::Vertical, Qt::ScrollBarAlwaysOff); - mainFrame->setScrollBarPolicy(Qt::Horizontal, Qt::ScrollBarAlwaysOff); - - QString html("<script>" \ - " function checkScrollbar() {" \ - " if (innerWidth === document.documentElement.offsetWidth)" \ - " document.getElementById('span1').innerText = 'SUCCESS';" \ - " else" \ - " document.getElementById('span1').innerText = 'FAIL';" \ - " }" \ - "</script>" \ - "<body>" \ - " <div style='margin-top:1000px ; margin-left:1000px'>" \ - " <a id='offscreen' href='a'>End</a>" \ - " </div>" \ - "<span id='span1'></span>" \ - "</body>"); - - - QSignalSpy loadSpy(&view, SIGNAL(loadFinished(bool))); - view.setHtml(html); - ::waitForSignal(&view, SIGNAL(loadFinished(bool)), 200); - QCOMPARE(loadSpy.count(), 1); - - mainFrame->evaluateJavaScript("checkScrollbar();"); - QCOMPARE(mainFrame->documentElement().findAll("span").at(0).toPlainText(), QString("SUCCESS")); -} - -void tst_QWebFrame::horizontalScrollAfterBack() -{ - QWebView view; - QWebFrame* frame = view.page()->mainFrame(); - QSignalSpy loadSpy(view.page(), SIGNAL(loadFinished(bool))); - - view.page()->settings()->setMaximumPagesInCache(2); - frame->setScrollBarPolicy(Qt::Vertical, Qt::ScrollBarAsNeeded); - frame->setScrollBarPolicy(Qt::Horizontal, Qt::ScrollBarAsNeeded); - - view.load(QUrl("qrc:/testiframe2.html")); - view.resize(200, 200); - QTRY_COMPARE(loadSpy.count(), 1); - QTRY_VERIFY((frame->scrollBarGeometry(Qt::Horizontal)).height()); - - view.load(QUrl("qrc:/testiframe.html")); - QTRY_COMPARE(loadSpy.count(), 2); - - view.page()->triggerAction(QWebPage::Back); - QTRY_COMPARE(loadSpy.count(), 3); - QTRY_VERIFY((frame->scrollBarGeometry(Qt::Horizontal)).height()); -} - -void tst_QWebFrame::evaluateWillCauseRepaint() -{ - QWebView view; - QString html("<html><body>top<div id=\"junk\" style=\"display: block;\">" - "junk</div>bottom</body></html>"); - view.setHtml(html); - view.show(); - - QTest::qWaitForWindowExposed(&view); - view.page()->mainFrame()->evaluateJavaScript( - "document.getElementById('junk').style.display = 'none';"); - - ::waitForSignal(view.page(), SIGNAL(repaintRequested(QRect))); -} - -void tst_QWebFrame::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_QWebFrame::setContent() -{ - QFETCH(QString, mimeType); - QFETCH(QByteArray, testContents); - QFETCH(QString, expected); - m_view->setContent(testContents, mimeType); - QWebFrame* mainFrame = m_view->page()->mainFrame(); - QCOMPARE(expected , mainFrame->toPlainText()); -} - -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_QWebFrame::setCacheLoadControlAttribute() -{ - QWebPage page; - CacheNetworkAccessManager* manager = new CacheNetworkAccessManager(&page); - page.setNetworkAccessManager(manager); - QWebFrame* frame = page.mainFrame(); - - QNetworkRequest request(QUrl("http://abcdef.abcdef/")); - - request.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::AlwaysCache); - frame->load(request); - QCOMPARE(manager->lastCacheLoad(), QNetworkRequest::AlwaysCache); - - request.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache); - frame->load(request); - QCOMPARE(manager->lastCacheLoad(), QNetworkRequest::PreferCache); - - request.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::AlwaysNetwork); - frame->load(request); - QCOMPARE(manager->lastCacheLoad(), QNetworkRequest::AlwaysNetwork); - - request.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferNetwork); - frame->load(request); - QCOMPARE(manager->lastCacheLoad(), QNetworkRequest::PreferNetwork); -} - -void tst_QWebFrame::setUrlWithPendingLoads() -{ - QWebPage page; - page.mainFrame()->setHtml("<img src='dummy:'/>"); - page.mainFrame()->setUrl(QUrl("about:blank")); -} - -void tst_QWebFrame::setUrlWithFragment_data() -{ - QTest::addColumn<QUrl>("previousUrl"); - QTest::newRow("empty") << QUrl(); - QTest::newRow("same URL no fragment") << QUrl("qrc:/test1.html"); - // See comments in setUrlSameUrl about using setUrl() with the same url(). - QTest::newRow("same URL with same fragment") << QUrl("qrc:/test1.html#"); - QTest::newRow("same URL with different fragment") << QUrl("qrc:/test1.html#anotherFragment"); - QTest::newRow("another URL") << QUrl("qrc:/test2.html"); -} - -// Based on bug report https://bugs.webkit.org/show_bug.cgi?id=32723 -void tst_QWebFrame::setUrlWithFragment() -{ - QFETCH(QUrl, previousUrl); - - QWebPage page; - QWebFrame* frame = page.mainFrame(); - - if (!previousUrl.isEmpty()) { - frame->load(previousUrl); - ::waitForSignal(frame, SIGNAL(loadFinished(bool))); - QCOMPARE(frame->url(), previousUrl); - } - - QSignalSpy spy(frame, SIGNAL(loadFinished(bool))); - const QUrl url("qrc:/test1.html#"); - QVERIFY(!url.fragment().isNull()); - - frame->setUrl(url); - ::waitForSignal(frame, SIGNAL(loadFinished(bool))); - - QCOMPARE(spy.count(), 1); - QVERIFY(!frame->toPlainText().isEmpty()); - QCOMPARE(frame->requestedUrl(), url); - QCOMPARE(frame->url(), url); -} - -void tst_QWebFrame::setUrlToEmpty() -{ - int expectedLoadFinishedCount = 0; - const QUrl aboutBlank("about:blank"); - const QUrl url("qrc:/test2.html"); - - QWebPage page; - QWebFrame* frame = page.mainFrame(); - QCOMPARE(frame->url(), QUrl()); - QCOMPARE(frame->requestedUrl(), QUrl()); - QCOMPARE(frame->baseUrl(), QUrl()); - - QSignalSpy spy(frame, SIGNAL(loadFinished(bool))); - - // Set existing url - frame->setUrl(url); - expectedLoadFinishedCount++; - ::waitForSignal(frame, SIGNAL(loadFinished(bool))); - - QCOMPARE(spy.count(), expectedLoadFinishedCount); - QCOMPARE(frame->url(), url); - QCOMPARE(frame->requestedUrl(), url); - QCOMPARE(frame->baseUrl(), url); - - // Set empty url - frame->setUrl(QUrl()); - expectedLoadFinishedCount++; - - QCOMPARE(spy.count(), expectedLoadFinishedCount); - QCOMPARE(frame->url(), aboutBlank); - QCOMPARE(frame->requestedUrl(), QUrl()); - QCOMPARE(frame->baseUrl(), aboutBlank); - - // Set existing url - frame->setUrl(url); - expectedLoadFinishedCount++; - ::waitForSignal(frame, SIGNAL(loadFinished(bool))); - - QCOMPARE(spy.count(), expectedLoadFinishedCount); - QCOMPARE(frame->url(), url); - QCOMPARE(frame->requestedUrl(), url); - QCOMPARE(frame->baseUrl(), url); - - // Load empty url - frame->load(QUrl()); - expectedLoadFinishedCount++; - - QCOMPARE(spy.count(), expectedLoadFinishedCount); - QCOMPARE(frame->url(), aboutBlank); - QCOMPARE(frame->requestedUrl(), QUrl()); - QCOMPARE(frame->baseUrl(), aboutBlank); -} - -void tst_QWebFrame::setUrlToInvalid() -{ - QWebPage page; - QWebFrame* frame = page.mainFrame(); - - const QUrl invalidUrl("http:/example.com"); - QVERIFY(!invalidUrl.isEmpty()); - QVERIFY(invalidUrl != QUrl()); - - // QWebFrame will do its best to accept the URL, possible converting it to a valid equivalent URL. - const QUrl validUrl("http://example.com/"); - frame->setUrl(invalidUrl); - QCOMPARE(frame->url(), validUrl); - QCOMPARE(frame->requestedUrl(), validUrl); - QCOMPARE(frame->baseUrl(), 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()); - - frame->setUrl(anotherInvalidUrl); - QCOMPARE(frame->url(), aboutBlank); - QCOMPARE(frame->requestedUrl().toEncoded(), anotherInvalidUrl.toEncoded()); - QCOMPARE(frame->baseUrl(), aboutBlank); -} - -void tst_QWebFrame::setUrlHistory() -{ - const QUrl aboutBlank("about:blank"); - QUrl url; - int expectedLoadFinishedCount = 0; - QWebFrame* frame = m_page->mainFrame(); - QSignalSpy spy(frame, SIGNAL(loadFinished(bool))); - - QCOMPARE(m_page->history()->count(), 0); - - frame->setUrl(QUrl()); - expectedLoadFinishedCount++; - QCOMPARE(spy.count(), expectedLoadFinishedCount); - QCOMPARE(frame->url(), aboutBlank); - QCOMPARE(frame->requestedUrl(), QUrl()); - QCOMPARE(m_page->history()->count(), 0); - - url = QUrl("http://non.existant/"); - frame->setUrl(url); - ::waitForSignal(m_page, SIGNAL(loadFinished(bool))); - expectedLoadFinishedCount++; - QCOMPARE(spy.count(), expectedLoadFinishedCount); - QCOMPARE(frame->url(), url); - QCOMPARE(frame->requestedUrl(), url); - QCOMPARE(m_page->history()->count(), 1); - - url = QUrl("qrc:/test1.html"); - frame->setUrl(url); - ::waitForSignal(m_page, SIGNAL(loadFinished(bool))); - expectedLoadFinishedCount++; - QCOMPARE(spy.count(), expectedLoadFinishedCount); - QCOMPARE(frame->url(), url); - QCOMPARE(frame->requestedUrl(), url); - QCOMPARE(m_page->history()->count(), 2); - - frame->setUrl(QUrl()); - expectedLoadFinishedCount++; - QCOMPARE(spy.count(), expectedLoadFinishedCount); - QCOMPARE(frame->url(), aboutBlank); - QCOMPARE(frame->requestedUrl(), QUrl()); - QCOMPARE(m_page->history()->count(), 2); - - // Loading same page as current in history, so history count doesn't change. - url = QUrl("qrc:/test1.html"); - frame->setUrl(url); - ::waitForSignal(m_page, SIGNAL(loadFinished(bool))); - expectedLoadFinishedCount++; - QCOMPARE(spy.count(), expectedLoadFinishedCount); - QCOMPARE(frame->url(), url); - QCOMPARE(frame->requestedUrl(), url); - QCOMPARE(m_page->history()->count(), 2); - - url = QUrl("qrc:/test2.html"); - frame->setUrl(url); - ::waitForSignal(m_page, SIGNAL(loadFinished(bool))); - expectedLoadFinishedCount++; - QCOMPARE(spy.count(), expectedLoadFinishedCount); - QCOMPARE(frame->url(), url); - QCOMPARE(frame->requestedUrl(), url); - QCOMPARE(m_page->history()->count(), 3); -} - -void tst_QWebFrame::setUrlUsingStateObject() -{ - const QUrl aboutBlank("about:blank"); - QUrl url; - QWebFrame* frame = m_page->mainFrame(); - QSignalSpy urlChangedSpy(frame, SIGNAL(urlChanged(QUrl))); - int expectedUrlChangeCount = 0; - - QCOMPARE(m_page->history()->count(), 0); - - url = QUrl("qrc:/test1.html"); - frame->setUrl(url); - waitForSignal(m_page, SIGNAL(loadFinished(bool))); - expectedUrlChangeCount++; - QCOMPARE(urlChangedSpy.count(), expectedUrlChangeCount); - QCOMPARE(frame->url(), url); - QCOMPARE(m_page->history()->count(), 1); - - frame->evaluateJavaScript("window.history.pushState(null,'push', 'navigate/to/here')"); - expectedUrlChangeCount++; - QCOMPARE(urlChangedSpy.count(), expectedUrlChangeCount); - QCOMPARE(frame->url(), QUrl("qrc:/navigate/to/here")); - QCOMPARE(m_page->history()->count(), 2); - QVERIFY(m_page->history()->canGoBack()); - - frame->evaluateJavaScript("window.history.replaceState(null,'replace', 'another/location')"); - expectedUrlChangeCount++; - QCOMPARE(urlChangedSpy.count(), expectedUrlChangeCount); - QCOMPARE(frame->url(), QUrl("qrc:/navigate/to/another/location")); - QCOMPARE(m_page->history()->count(), 2); - QVERIFY(!m_page->history()->canGoForward()); - QVERIFY(m_page->history()->canGoBack()); - - frame->evaluateJavaScript("window.history.back()"); - QTest::qWait(100); - expectedUrlChangeCount++; - QCOMPARE(urlChangedSpy.count(), expectedUrlChangeCount); - QCOMPARE(frame->url(), QUrl("qrc:/test1.html")); - QVERIFY(m_page->history()->canGoForward()); - QVERIFY(!m_page->history()->canGoBack()); -} - -void tst_QWebFrame::setUrlSameUrl() -{ - const QUrl url1("qrc:/test1.html"); - const QUrl url2("qrc:/test2.html"); - - QWebPage page; - QWebFrame* frame = page.mainFrame(); - FakeNetworkManager* networkManager = new FakeNetworkManager(&page); - page.setNetworkAccessManager(networkManager); - - QSignalSpy spy(frame, SIGNAL(loadFinished(bool))); - - frame->setUrl(url1); - waitForSignal(frame, SIGNAL(loadFinished(bool))); - QVERIFY(frame->url() != url1); // Nota bene: our QNAM redirects url1 to url2 - QCOMPARE(frame->url(), url2); - QCOMPARE(spy.count(), 1); - - frame->setUrl(url1); - waitForSignal(frame, SIGNAL(loadFinished(bool))); - QVERIFY(frame->url() != url1); - QCOMPARE(frame->url(), url2); - QCOMPARE(spy.count(), 2); - - // Now a case without redirect. The existing behavior we have for setUrl() - // is more like a "clear(); load()", so the page will be loaded again, even - // if urlToBeLoaded == url(). This test should be changed if we want to - // make setUrl() early return in this case. - frame->setUrl(url2); - waitForSignal(frame, SIGNAL(loadFinished(bool))); - QCOMPARE(frame->url(), url2); - QCOMPARE(spy.count(), 3); - - frame->setUrl(url1); - waitForSignal(frame, SIGNAL(loadFinished(bool))); - QCOMPARE(frame->url(), url2); - QCOMPARE(spy.count(), 4); -} - -static inline QUrl extractBaseUrl(const QUrl& url) -{ - return url.resolved(QUrl()); -} - -void tst_QWebFrame::setUrlThenLoads_data() -{ - QTest::addColumn<QUrl>("url"); - QTest::addColumn<QUrl>("baseUrl"); - - QTest::newRow("resource file") << QUrl("qrc:/test1.html") << extractBaseUrl(QUrl("qrc:/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_QWebFrame::setUrlThenLoads() -{ - QFETCH(QUrl, url); - QFETCH(QUrl, baseUrl); - QWebFrame* frame = m_page->mainFrame(); - QSignalSpy urlChangedSpy(frame, SIGNAL(urlChanged(QUrl))); - QSignalSpy startedSpy(frame, SIGNAL(loadStarted())); - QSignalSpy finishedSpy(frame, SIGNAL(loadFinished(bool))); - - frame->setUrl(url); - QCOMPARE(startedSpy.count(), 1); - ::waitForSignal(frame, SIGNAL(urlChanged(QUrl))); - QCOMPARE(urlChangedSpy.count(), 1); - QVERIFY(finishedSpy.at(0).first().toBool()); - QCOMPARE(frame->url(), url); - QCOMPARE(frame->requestedUrl(), url); - QCOMPARE(frame->baseUrl(), baseUrl); - - const QUrl urlToLoad1("qrc:/test2.html"); - const QUrl urlToLoad2("qrc:/test1.html"); - - // Just after first load. URL didn't changed yet. - frame->load(urlToLoad1); - QCOMPARE(startedSpy.count(), 2); - QCOMPARE(frame->url(), url); - QCOMPARE(frame->requestedUrl(), urlToLoad1); - QCOMPARE(frame->baseUrl(), baseUrl); - - // After first URL changed. - ::waitForSignal(frame, SIGNAL(urlChanged(QUrl))); - QCOMPARE(urlChangedSpy.count(), 2); - QVERIFY(finishedSpy.at(1).first().toBool()); - QCOMPARE(frame->url(), urlToLoad1); - QCOMPARE(frame->requestedUrl(), urlToLoad1); - QCOMPARE(frame->baseUrl(), extractBaseUrl(urlToLoad1)); - - // Just after second load. URL didn't changed yet. - frame->load(urlToLoad2); - QCOMPARE(startedSpy.count(), 3); - QCOMPARE(frame->url(), urlToLoad1); - QCOMPARE(frame->requestedUrl(), urlToLoad2); - QCOMPARE(frame->baseUrl(), extractBaseUrl(urlToLoad1)); - - // After second URL changed. - ::waitForSignal(frame, SIGNAL(urlChanged(QUrl))); - QCOMPARE(urlChangedSpy.count(), 3); - QVERIFY(finishedSpy.at(2).first().toBool()); - QCOMPARE(frame->url(), urlToLoad2); - QCOMPARE(frame->requestedUrl(), urlToLoad2); - QCOMPARE(frame->baseUrl(), extractBaseUrl(urlToLoad2)); -} - -void tst_QWebFrame::loadFinishedAfterNotFoundError() -{ - QWebPage page; - QWebFrame* frame = page.mainFrame(); - - QSignalSpy spy(&page, SIGNAL(loadFinished(bool))); - FakeNetworkManager* networkManager = new FakeNetworkManager(&page); - page.setNetworkAccessManager(networkManager); - - frame->setUrl(FakeReply::urlFor404ErrorWithoutContents); - QTRY_COMPARE(spy.count(), 1); - const bool wasLoadOk = spy.at(0).at(0).toBool(); - QVERIFY(!wasLoadOk); -} - -void tst_QWebFrame::signalsDuringErrorHandling() -{ - QWebPage page; - QWebFrame* frame = page.mainFrame(); - - QSignalSpy loadStartedSpy(frame, &QWebFrame::loadStarted); - QSignalSpy loadFinishedSpy(frame, &QWebFrame::loadFinished); - FakeNetworkManager* networkManager = new FakeNetworkManager(&page); - page.setNetworkAccessManager(networkManager); - - frame->setUrl(FakeReply::urlFor404ErrorWithoutContents); - QTRY_COMPARE(loadStartedSpy.count(), 1); - QTRY_COMPARE(loadFinishedSpy.count(), 1); - bool wasLoadOk = loadFinishedSpy.at(0).at(0).toBool(); - QVERIFY(!wasLoadOk); - - frame->load(QUrl("http://example.com")); - waitForSignal(frame, SIGNAL(loadFinished(bool))); - QCOMPARE(loadStartedSpy.count(), 2); - QCOMPARE(loadFinishedSpy.count(), 2); - wasLoadOk = loadFinishedSpy.at(1).at(0).toBool(); - QVERIFY(wasLoadOk); -} - -class URLSetter : public QObject { - Q_OBJECT - -public: - enum Signal { - LoadStarted, - LoadFinished, - ProvisionalLoad - }; - - enum Type { - UseLoad, - UseSetUrl - }; - - URLSetter(QWebFrame*, Signal, Type, const QUrl&); - -public Q_SLOTS: - void execute(); - -Q_SIGNALS: - void finished(); - -private: - QWebFrame* m_frame; - QUrl m_url; - Type m_type; -}; - -Q_DECLARE_METATYPE(URLSetter::Signal) -Q_DECLARE_METATYPE(URLSetter::Type) - -URLSetter::URLSetter(QWebFrame* frame, Signal signal, URLSetter::Type type, const QUrl& url) - : m_frame(frame), m_url(url), m_type(type) -{ - if (signal == LoadStarted) - connect(m_frame, SIGNAL(loadStarted()), SLOT(execute())); - else if (signal == LoadFinished) - connect(m_frame, SIGNAL(loadFinished(bool)), SLOT(execute())); - else - connect(m_frame, SIGNAL(provisionalLoad()), SLOT(execute())); -} - -void URLSetter::execute() -{ - // We track only the first emission. - m_frame->disconnect(this); - if (m_type == URLSetter::UseLoad) - m_frame->load(m_url); - else - m_frame->setUrl(m_url); - connect(m_frame, SIGNAL(loadFinished(bool)), SIGNAL(finished())); -} - -void tst_QWebFrame::loadInSignalHandlers_data() -{ - QTest::addColumn<URLSetter::Type>("type"); - QTest::addColumn<URLSetter::Signal>("signal"); - QTest::addColumn<QUrl>("url"); - - const QUrl validUrl("qrc:/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 load() in provisionalLoad() after valid url") << URLSetter::UseLoad << URLSetter::ProvisionalLoad << validUrl; - QTest::newRow("call load() in provisionalLoad() after invalid url") << URLSetter::UseLoad << URLSetter::ProvisionalLoad << 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; - QTest::newRow("call setUrl() in provisionalLoad() after valid url") << URLSetter::UseSetUrl << URLSetter::ProvisionalLoad << validUrl; - QTest::newRow("call setUrl() in provisionalLoad() after invalid url") << URLSetter::UseSetUrl << URLSetter::ProvisionalLoad << invalidUrl; -} - -void tst_QWebFrame::loadInSignalHandlers() -{ - QFETCH(URLSetter::Type, type); - QFETCH(URLSetter::Signal, signal); - QFETCH(QUrl, url); - - QWebFrame* frame = m_page->mainFrame(); - const QUrl urlForSetter("qrc:/test1.html"); - URLSetter setter(frame, signal, type, urlForSetter); - - frame->load(url); - waitForSignal(&setter, SIGNAL(finished()), 200); - QCOMPARE(frame->url(), urlForSetter); -} - -QTEST_MAIN(tst_QWebFrame) -#include "tst_qwebframe.moc" |