summaryrefslogtreecommitdiffstats
path: root/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'WebKit/qt/tests/qwebpage/tst_qwebpage.cpp')
-rw-r--r--WebKit/qt/tests/qwebpage/tst_qwebpage.cpp342
1 files changed, 342 insertions, 0 deletions
diff --git a/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp b/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp
new file mode 100644
index 0000000..13b9bd2
--- /dev/null
+++ b/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp
@@ -0,0 +1,342 @@
+/*
+ Copyright (C) 2008 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 <qwidget.h>
+#include <qwebview.h>
+#include <qwebframe.h>
+#include <qwebhistory.h>
+#include <qnetworkrequest.h>
+#include <QDebug>
+#include <QMenu>
+
+// Will try to wait for the condition while allowing event processing
+#define QTRY_COMPARE(__expr, __expected) \
+ do { \
+ const int __step = 50; \
+ const int __timeout = 5000; \
+ if ((__expr) != (__expected)) { \
+ QTest::qWait(0); \
+ } \
+ for (int __i = 0; __i < __timeout && ((__expr) != (__expected)); __i+=__step) { \
+ QTest::qWait(__step); \
+ } \
+ QCOMPARE(__expr, __expected); \
+ } while(0)
+
+//TESTED_CLASS=
+//TESTED_FILES=
+
+// Task 160192
+/**
+ * Starts an event loop that runs until the given signal is received.
+ Optionally the event loop
+ * can return earlier on a timeout.
+ *
+ * \return \p true if the requested signal was received
+ * \p false on timeout
+ */
+static bool waitForSignal(QObject* obj, const char* signal, int timeout = 0)
+{
+ QEventLoop loop;
+ QObject::connect(obj, signal, &loop, SLOT(quit()));
+ QTimer timer;
+ QSignalSpy timeoutSpy(&timer, SIGNAL(timeout()));
+ if (timeout > 0) {
+ QObject::connect(&timer, SIGNAL(timeout()), &loop, SLOT(quit()));
+ timer.setSingleShot(true);
+ timer.start(timeout);
+ }
+ loop.exec();
+ return timeoutSpy.isEmpty();
+}
+
+class tst_QWebPage : public QObject
+{
+ Q_OBJECT
+
+public:
+ tst_QWebPage();
+ virtual ~tst_QWebPage();
+
+public slots:
+ void init();
+ void cleanup();
+
+private slots:
+ void acceptNavigationRequest();
+ void loadFinished();
+ void acceptNavigationRequestWithNewWindow();
+ void userStyleSheet();
+ void modified();
+ void contextMenuCrash();
+
+private:
+
+
+private:
+ QWebView* m_view;
+ QWebPage* m_page;
+};
+
+tst_QWebPage::tst_QWebPage()
+{
+}
+
+tst_QWebPage::~tst_QWebPage()
+{
+}
+
+void tst_QWebPage::init()
+{
+ m_view = new QWebView();
+ m_page = m_view->page();
+}
+
+void tst_QWebPage::cleanup()
+{
+ delete m_view;
+}
+
+class NavigationRequestOverride : public QWebPage
+{
+public:
+ NavigationRequestOverride(QWebView* parent, bool initialValue) : QWebPage(parent), m_acceptNavigationRequest(initialValue) {}
+
+ bool m_acceptNavigationRequest;
+protected:
+ virtual bool acceptNavigationRequest(QWebFrame* frame, const QNetworkRequest &request, QWebPage::NavigationType type) {
+ Q_UNUSED(frame);
+ Q_UNUSED(request);
+ Q_UNUSED(type);
+
+ return m_acceptNavigationRequest;
+ }
+};
+
+void tst_QWebPage::acceptNavigationRequest()
+{
+ QSignalSpy loadSpy(m_view, SIGNAL(loadFinished(bool)));
+
+ NavigationRequestOverride* newPage = new NavigationRequestOverride(m_view, false);
+ m_view->setPage(newPage);
+
+ m_view->setHtml(QString("<html><body><form name='tstform' action='data:text/html,foo'method='get'>"
+ "<input type='text'><input type='submit'></form></body></html>"), QUrl());
+ QTRY_COMPARE(loadSpy.count(), 1);
+
+ m_view->page()->mainFrame()->evaluateJavaScript("tstform.submit();");
+
+ newPage->m_acceptNavigationRequest = true;
+ m_view->page()->mainFrame()->evaluateJavaScript("tstform.submit();");
+ QTRY_COMPARE(loadSpy.count(), 2);
+
+ QCOMPARE(m_view->page()->mainFrame()->toPlainText(), QString("foo?"));
+
+ // Restore default page
+ m_view->setPage(0);
+}
+
+
+void tst_QWebPage::loadFinished()
+{
+ QSignalSpy spyLoadStarted(m_view, SIGNAL(loadStarted()));
+ QSignalSpy spyLoadFinished(m_view, SIGNAL(loadFinished(bool)));
+
+ m_view->setHtml(QString("data:text/html,<frameset cols=\"25%,75%\"><frame src=\"data:text/html,"
+ "<head><meta http-equiv='refresh' content='1'></head>foo \">"
+ "<frame src=\"data:text/html,bar\"></frameset>"), QUrl());
+ QTRY_COMPARE(spyLoadFinished.count(), 1);
+
+ QTest::qWait(3000);
+
+ QVERIFY(spyLoadStarted.count() > 1);
+ QVERIFY(spyLoadFinished.count() > 1);
+
+ spyLoadFinished.clear();
+
+ m_view->setHtml(QString("data:text/html,<frameset cols=\"25%,75%\"><frame src=\"data:text/html,"
+ "foo \"><frame src=\"data:text/html,bar\"></frameset>"), QUrl());
+ QTRY_COMPARE(spyLoadFinished.count(), 1);
+ QCOMPARE(spyLoadFinished.count(), 1);
+}
+
+class TestPage : public QWebPage
+{
+public:
+ TestPage(QObject* parent = 0) : QWebPage(parent) {}
+
+ struct Navigation {
+ QPointer<QWebFrame> frame;
+ QNetworkRequest request;
+ NavigationType type;
+ };
+
+ QList<Navigation> navigations;
+ QList<QWebPage*> createdWindows;
+
+ virtual bool acceptNavigationRequest(QWebFrame* frame, const QNetworkRequest &request, NavigationType type) {
+ Navigation n;
+ n.frame = frame;
+ n.request = request;
+ n.type = type;
+ navigations.append(n);
+ return true;
+ }
+
+ virtual QWebPage* createWindow(WebWindowType type) {
+ QWebPage* page = new TestPage(this);
+ createdWindows.append(page);
+ return page;
+ }
+};
+
+void tst_QWebPage::acceptNavigationRequestWithNewWindow()
+{
+ TestPage* page = new TestPage(m_view);
+ page->settings()->setAttribute(QWebSettings::LinksIncludedInFocusChain, true);
+ m_page = page;
+ m_view->setPage(m_page);
+
+ m_view->setUrl(QString("data:text/html,<a href=\"data:text/html,Reached\" target=\"_blank\">Click me</a>"));
+ QVERIFY(::waitForSignal(m_view, SIGNAL(loadFinished(bool))));
+
+ QFocusEvent fe(QEvent::FocusIn);
+ m_page->event(&fe);
+
+ QVERIFY(m_page->focusNextPrevChild(/*next*/ true));
+
+ QKeyEvent keyEnter(QEvent::KeyPress, Qt::Key_Enter, Qt::NoModifier);
+ m_page->event(&keyEnter);
+
+ QCOMPARE(page->navigations.count(), 2);
+
+ TestPage::Navigation n = page->navigations.at(1);
+ QVERIFY(n.frame.isNull());
+ QCOMPARE(n.request.url().toString(), QString("data:text/html,Reached"));
+ QVERIFY(n.type == QWebPage::NavigationTypeLinkClicked);
+
+ QCOMPARE(page->createdWindows.count(), 1);
+}
+
+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());
+ return QNetworkAccessManager::createRequest(op, request, outgoingData);
+ }
+};
+
+void tst_QWebPage::userStyleSheet()
+{
+ TestNetworkManager* networkManager = new TestNetworkManager(m_page);
+ m_page->setNetworkAccessManager(networkManager);
+ networkManager->requestedUrls.clear();
+
+ m_page->settings()->setUserStyleSheetUrl(QUrl("data:text/css,p { background-image: url('http://does.not/exist.png');}"));
+ m_view->setHtml("<p>hello world</p>");
+ QVERIFY(::waitForSignal(m_view, SIGNAL(loadFinished(bool))));
+
+ QVERIFY(networkManager->requestedUrls.count() >= 2);
+ QCOMPARE(networkManager->requestedUrls.at(0), QUrl("data:text/css,p { background-image: url('http://does.not/exist.png');}"));
+ QCOMPARE(networkManager->requestedUrls.at(1), QUrl("http://does.not/exist.png"));
+}
+
+void tst_QWebPage::modified()
+{
+ m_page->mainFrame()->setUrl(QUrl("data:text/html,<body>blub"));
+ QVERIFY(::waitForSignal(m_view, SIGNAL(loadFinished(bool))));
+
+ m_page->mainFrame()->setUrl(QUrl("data:text/html,<body id=foo contenteditable>blah"));
+ QVERIFY(::waitForSignal(m_view, SIGNAL(loadFinished(bool))));
+
+ QVERIFY(!m_page->isModified());
+
+// m_page->mainFrame()->evaluateJavaScript("alert(document.getElementById('foo'))");
+ m_page->mainFrame()->evaluateJavaScript("document.getElementById('foo').focus()");
+ m_page->mainFrame()->evaluateJavaScript("document.execCommand('InsertText', true, 'Test');");
+
+ QVERIFY(m_page->isModified());
+
+ m_page->mainFrame()->evaluateJavaScript("document.execCommand('Undo', true);");
+
+ QVERIFY(!m_page->isModified());
+
+ m_page->mainFrame()->evaluateJavaScript("document.execCommand('Redo', true);");
+
+ QVERIFY(m_page->isModified());
+
+ QVERIFY(m_page->history()->canGoBack());
+ QVERIFY(!m_page->history()->canGoForward());
+ QCOMPARE(m_page->history()->count(), 2);
+ QVERIFY(m_page->history()->backItem().isValid());
+ QVERIFY(!m_page->history()->forwardItem().isValid());
+
+ m_page->history()->back();
+ QVERIFY(::waitForSignal(m_view, SIGNAL(loadFinished(bool))));
+
+ QVERIFY(!m_page->history()->canGoBack());
+ QVERIFY(m_page->history()->canGoForward());
+
+ QVERIFY(!m_page->isModified());
+
+ QVERIFY(m_page->history()->currentItemIndex() == 0);
+
+ m_page->history()->setMaximumItemCount(3);
+ QVERIFY(m_page->history()->maximumItemCount() == 3);
+
+ QVariant variant("string test");
+ m_page->history()->currentItem().setUserData(variant);
+ QVERIFY(m_page->history()->currentItem().userData().toString() == "string test");
+
+ m_page->mainFrame()->setUrl(QUrl("data:text/html,<body>This is second page"));
+ m_page->mainFrame()->setUrl(QUrl("data:text/html,<body>This is third page"));
+ QVERIFY(m_page->history()->count() == 2);
+ m_page->mainFrame()->setUrl(QUrl("data:text/html,<body>This is fourth page"));
+ QVERIFY(m_page->history()->count() == 2);
+ m_page->mainFrame()->setUrl(QUrl("data:text/html,<body>This is fifth page"));
+ QVERIFY(::waitForSignal(m_page->mainFrame(), SIGNAL(aboutToUpdateHistory(QWebHistoryItem*))));
+}
+
+void tst_QWebPage::contextMenuCrash()
+{
+ QWebView view;
+ view.setHtml("<p>test");
+ view.page()->updatePositionDependentActions(QPoint(0, 0));
+ QMenu* contextMenu = 0;
+ foreach (QObject* child, view.children()) {
+ contextMenu = qobject_cast<QMenu*>(child);
+ if (contextMenu)
+ break;
+ }
+ QVERIFY(contextMenu);
+ delete contextMenu;
+}
+
+QTEST_MAIN(tst_QWebPage)
+#include "tst_qwebpage.moc"