diff options
Diffstat (limited to 'tests/webkitqml/qquickwebview/tst_qquickwebview.cpp')
| -rw-r--r-- | tests/webkitqml/qquickwebview/tst_qquickwebview.cpp | 449 |
1 files changed, 449 insertions, 0 deletions
diff --git a/tests/webkitqml/qquickwebview/tst_qquickwebview.cpp b/tests/webkitqml/qquickwebview/tst_qquickwebview.cpp new file mode 100644 index 000000000..7cf1ddb72 --- /dev/null +++ b/tests/webkitqml/qquickwebview/tst_qquickwebview.cpp @@ -0,0 +1,449 @@ +/* + Copyright (C) 2011 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 "../testwindow.h" +#include "../util.h" + +#include <QScopedPointer> +#include <QtQml/QQmlEngine> +#include <QtTest/QtTest> +#include <private/qquickwebpage_p.h> +#include <private/qquickwebview_p.h> + +class tst_QQuickWebView : public QObject { + Q_OBJECT +public: + tst_QQuickWebView(); + +private Q_SLOTS: + void init(); + void cleanup(); + + void accessPage(); + void navigationStatusAtStartup(); + void stopEnabledAfterLoadStarted(); + void baseUrl(); + void loadEmptyUrl(); + void loadEmptyPageViewVisible(); + void loadEmptyPageViewHidden(); + void loadNonexistentFileUrl(); + void backAndForward(); + void reload(); + void stop(); + void loadProgress(); + void scrollRequest(); + + void show(); + void showWebView(); + void removeFromCanvas(); + void multipleWebViewWindows(); + void multipleWebViews(); + void titleUpdate(); + void transparentWebViews(); + + void inputMethod(); + void inputMethodHints(); + void basicRenderingSanity(); + +private: + void prepareWebViewComponent(); + inline QQuickWebView* newWebView(); + inline QQuickWebView* webView() const; + void runJavaScript(const QString& script); + QScopedPointer<TestWindow> m_window; + QScopedPointer<QQmlComponent> m_component; +}; + +tst_QQuickWebView::tst_QQuickWebView() +{ + addQtWebProcessToPath(); + prepareWebViewComponent(); +} + +void tst_QQuickWebView::prepareWebViewComponent() +{ + static QQmlEngine* engine = new QQmlEngine(this); + engine->addImportPath(QString::fromUtf8(IMPORT_DIR)); + + m_component.reset(new QQmlComponent(engine, this)); + + m_component->setData(QByteArrayLiteral("import QtQuick 2.0\n" + "import QtWebKit 3.0\n" + "WebView {}") + , QUrl()); +} + +QQuickWebView* tst_QQuickWebView::newWebView() +{ + QObject* viewInstance = m_component->create(); + QQuickWebView* webView = qobject_cast<QQuickWebView*>(viewInstance); + return webView; +} + +void tst_QQuickWebView::init() +{ + m_window.reset(new TestWindow(newWebView())); +} + +void tst_QQuickWebView::cleanup() +{ + m_window.reset(); +} + +inline QQuickWebView* tst_QQuickWebView::webView() const +{ + return static_cast<QQuickWebView*>(m_window->webView.data()); +} + +void tst_QQuickWebView::runJavaScript(const QString &script) +{ + QEventLoop loop; + webView()->runJavaScriptInMainFrame(script, &loop, "quit"); + loop.exec(); +} + +void tst_QQuickWebView::accessPage() +{ + QQuickWebPage* const pageDirectAccess = webView()->page(); + + QVariant pagePropertyValue = webView()->experimental()->property("page"); + QQuickWebPage* const pagePropertyAccess = pagePropertyValue.value<QQuickWebPage*>(); + QCOMPARE(pagePropertyAccess, pageDirectAccess); +} + +void tst_QQuickWebView::navigationStatusAtStartup() +{ + QCOMPARE(webView()->canGoBack(), false); + + QCOMPARE(webView()->canGoForward(), false); + + QCOMPARE(webView()->loading(), false); +} + +void tst_QQuickWebView::stopEnabledAfterLoadStarted() +{ + QCOMPARE(webView()->loading(), false); + + LoadStartedCatcher catcher(webView()); + webView()->setUrl(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/basic_page.html"))); + waitForSignal(&catcher, SIGNAL(finished())); + + QCOMPARE(webView()->loading(), true); + + QVERIFY(waitForLoadSucceeded(webView())); +} + +void tst_QQuickWebView::baseUrl() +{ + // Test the url is in a well defined state when instanciating the view, but before loading anything. + QVERIFY(webView()->url().isEmpty()); +} + +void tst_QQuickWebView::loadEmptyUrl() +{ + webView()->setUrl(QUrl()); + webView()->setUrl(QUrl(QLatin1String(""))); +} + +void tst_QQuickWebView::loadEmptyPageViewVisible() +{ + m_window->show(); + loadEmptyPageViewHidden(); +} + +void tst_QQuickWebView::loadEmptyPageViewHidden() +{ + QSignalSpy loadSpy(webView(), SIGNAL(loadingChanged(QWebLoadRequest*))); + + webView()->setUrl(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/basic_page.html"))); + QVERIFY(waitForLoadSucceeded(webView())); + + QCOMPARE(loadSpy.size(), 2); +} + +void tst_QQuickWebView::loadNonexistentFileUrl() +{ + QSignalSpy loadSpy(webView(), SIGNAL(loadingChanged(QWebLoadRequest*))); + + webView()->setUrl(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/file_that_does_not_exist.html"))); + QVERIFY(waitForLoadFailed(webView())); + + QCOMPARE(loadSpy.size(), 2); +} + +void tst_QQuickWebView::backAndForward() +{ + webView()->setUrl(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/basic_page.html"))); + QVERIFY(waitForLoadSucceeded(webView())); + + QCOMPARE(webView()->url().path(), QLatin1String(TESTS_SOURCE_DIR "/html/basic_page.html")); + + webView()->setUrl(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/basic_page2.html"))); + QVERIFY(waitForLoadSucceeded(webView())); + + QCOMPARE(webView()->url().path(), QLatin1String(TESTS_SOURCE_DIR "/html/basic_page2.html")); + + webView()->goBack(); + QVERIFY(waitForLoadSucceeded(webView())); + + QCOMPARE(webView()->url().path(), QLatin1String(TESTS_SOURCE_DIR "/html/basic_page.html")); + + webView()->goForward(); + QVERIFY(waitForLoadSucceeded(webView())); + + QCOMPARE(webView()->url().path(), QLatin1String(TESTS_SOURCE_DIR "/html/basic_page2.html")); +} + +void tst_QQuickWebView::reload() +{ + webView()->setUrl(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/basic_page.html"))); + QVERIFY(waitForLoadSucceeded(webView())); + + QCOMPARE(webView()->url().path(), QLatin1String(TESTS_SOURCE_DIR "/html/basic_page.html")); + + webView()->reload(); + QVERIFY(waitForLoadSucceeded(webView())); + + QCOMPARE(webView()->url().path(), QLatin1String(TESTS_SOURCE_DIR "/html/basic_page.html")); +} + +void tst_QQuickWebView::stop() +{ + webView()->setUrl(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/basic_page.html"))); + QVERIFY(waitForLoadSucceeded(webView())); + + QCOMPARE(webView()->url().path(), QLatin1String(TESTS_SOURCE_DIR "/html/basic_page.html")); + + // FIXME: This test should be fleshed out. Right now it's just here to make sure we don't crash. + webView()->stop(); +} + +void tst_QQuickWebView::loadProgress() +{ + QCOMPARE(webView()->loadProgress(), 0); + + webView()->setUrl(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/basic_page.html"))); + QSignalSpy loadProgressChangedSpy(webView(), SIGNAL(loadProgressChanged())); + QVERIFY(waitForLoadSucceeded(webView())); + + QVERIFY(loadProgressChangedSpy.count() >= 1); + + QCOMPARE(webView()->loadProgress(), 100); +} + +void tst_QQuickWebView::show() +{ + // This should not crash. + m_window->show(); + QTest::qWait(200); + m_window->hide(); +} + +void tst_QQuickWebView::showWebView() +{ + webView()->setUrl(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/direct-image-compositing.html"))); + QVERIFY(waitForLoadSucceeded(webView())); + m_window->show(); + // This should not crash. + webView()->setVisible(true); + QTest::qWait(200); + webView()->setVisible(false); + QTest::qWait(200); +} + +void tst_QQuickWebView::removeFromCanvas() +{ + showWebView(); + + // This should not crash. + QQuickItem* parent = webView()->parentItem(); + QQuickItem noCanvasItem; + webView()->setParentItem(&noCanvasItem); + QTest::qWait(200); + webView()->setParentItem(parent); + webView()->setVisible(true); + QTest::qWait(200); +} + +void tst_QQuickWebView::multipleWebViewWindows() +{ + showWebView(); + + // This should not crash. + QQuickWebView* webView1 = newWebView(); + QScopedPointer<TestWindow> window1(new TestWindow(webView1)); + QQuickWebView* webView2 = newWebView(); + QScopedPointer<TestWindow> window2(new TestWindow(webView2)); + + webView1->setUrl(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/scroll.html"))); + QVERIFY(waitForLoadSucceeded(webView1)); + window1->show(); + webView1->setVisible(true); + + webView2->setUrl(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/basic_page.html"))); + QVERIFY(waitForLoadSucceeded(webView2)); + window2->show(); + webView2->setVisible(true); + QTest::qWait(200); +} + +void tst_QQuickWebView::multipleWebViews() +{ + showWebView(); + + // This should not crash. + QScopedPointer<QQuickWebView> webView1(newWebView()); + webView1->setParentItem(m_window->contentItem()); + QScopedPointer<QQuickWebView> webView2(newWebView()); + webView2->setParentItem(m_window->contentItem()); + + webView1->setSize(QSizeF(300, 400)); + webView1->setUrl(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/scroll.html"))); + QVERIFY(waitForLoadSucceeded(webView1.data())); + webView1->setVisible(true); + + webView2->setSize(QSizeF(300, 400)); + webView2->setUrl(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/basic_page.html"))); + QVERIFY(waitForLoadSucceeded(webView2.data())); + webView2->setVisible(true); + QTest::qWait(200); +} + +void tst_QQuickWebView::basicRenderingSanity() +{ + showWebView(); + + webView()->setUrl(QUrl(QString::fromUtf8("data:text/html,<html><body bgcolor=\"#00ff00\"></body></html>"))); + QVERIFY(waitForLoadSucceeded(webView())); + + // This should not crash. + webView()->setVisible(true); + QTest::qWait(200); + QImage grabbedWindow = m_window->grabWindow(); + QRgb testColor = qRgba(0, 0xff, 0, 0xff); + QVERIFY(grabbedWindow.pixel(10, 10) == testColor); + QVERIFY(grabbedWindow.pixel(100, 10) == testColor); + QVERIFY(grabbedWindow.pixel(10, 100) == testColor); + QVERIFY(grabbedWindow.pixel(100, 100) == testColor); +} + +void tst_QQuickWebView::titleUpdate() +{ + QSignalSpy titleSpy(webView(), SIGNAL(titleChanged())); + + // Load page with no title + webView()->setUrl(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/basic_page2.html"))); + QVERIFY(waitForLoadSucceeded(webView())); + QCOMPARE(titleSpy.size(), 1); + + titleSpy.clear(); + + // No titleChanged signal for failed load + webView()->setUrl(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/file_that_does_not_exist.html"))); + QVERIFY(waitForLoadFailed(webView())); + QCOMPARE(titleSpy.size(), 0); + +} + +void tst_QQuickWebView::transparentWebViews() +{ + showWebView(); + + // This should not crash. + QScopedPointer<QQuickWebView> webView1(newWebView()); + webView1->setParentItem(m_window->contentItem()); + QScopedPointer<QQuickWebView> webView2(newWebView()); + webView2->setParentItem(m_window->contentItem()); + QVERIFY(!webView1->experimental()->transparentBackground()); + webView2->experimental()->setTransparentBackground(true); + QVERIFY(webView2->experimental()->transparentBackground()); + + webView1->setSize(QSizeF(300, 400)); + webView1->loadHtml("<html><body bgcolor=\"red\"></body></html>"); + QVERIFY(waitForLoadSucceeded(webView1.data())); + webView1->setVisible(true); + + webView2->setSize(QSizeF(300, 400)); + webView2->setUrl(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/basic_page.html"))); + QVERIFY(waitForLoadSucceeded(webView2.data())); + webView2->setVisible(true); + + QTest::qWait(200); + // FIXME: test actual rendering results; https://bugs.webkit.org/show_bug.cgi?id=80609. +} + +void tst_QQuickWebView::inputMethod() +{ + QQuickWebView* view = webView(); + view->setUrl(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/inputmethod.html"))); + QVERIFY(waitForLoadSucceeded(view)); + + QVERIFY(!view->flags().testFlag(QQuickItem::ItemAcceptsInputMethod)); + runJavaScript("document.getElementById('inputField').focus();"); + QVERIFY(view->flags().testFlag(QQuickItem::ItemAcceptsInputMethod)); + runJavaScript("document.getElementById('inputField').blur();"); + QVERIFY(!view->flags().testFlag(QQuickItem::ItemAcceptsInputMethod)); +} + +void tst_QQuickWebView::inputMethodHints() +{ + QQuickWebView* view = webView(); + + view->setUrl(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/inputmethod.html"))); + QVERIFY(waitForLoadSucceeded(view)); + + // Setting focus on an input element results in an element in its shadow tree becoming the focus node. + // Input hints should not be set from this shadow tree node but from the input element itself. + runJavaScript("document.getElementById('emailInputField').focus();"); + QVERIFY(view->flags().testFlag(QQuickItem::ItemAcceptsInputMethod)); + QInputMethodQueryEvent query(Qt::ImHints); + QGuiApplication::sendEvent(view, &query); + Qt::InputMethodHints hints(query.value(Qt::ImHints).toUInt() & Qt::ImhExclusiveInputMask); + QCOMPARE(hints, Qt::ImhEmailCharactersOnly); + + // The focus of an editable DIV is given directly to it, so no shadow root element + // is necessary. This tests the WebPage::editorState() method ability to get the + // right element without breaking. + runJavaScript("document.getElementById('editableDiv').focus();"); + QVERIFY(view->flags().testFlag(QQuickItem::ItemAcceptsInputMethod)); + query = QInputMethodQueryEvent(Qt::ImHints); + QGuiApplication::sendEvent(view, &query); + hints = Qt::InputMethodHints(query.value(Qt::ImHints).toUInt()); + QCOMPARE(hints, Qt::ImhNone); +} + +void tst_QQuickWebView::scrollRequest() +{ + m_window->setGeometry(0, 0, 300, 400); + m_window->show(); + + webView()->setUrl(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/scroll.html"))); + QVERIFY(waitForViewportReady(webView())); + + // COMPARE with the position requested in the html + // Use qRound as that is also used when calculating the position + // in WebKit. + int y = qRound(50 * webView()->page()->contentsScale()); + QVERIFY(webView()->contentY() == y); +} + +QTEST_MAIN(tst_QQuickWebView) + +#include "tst_qquickwebview.moc" + |
