diff options
Diffstat (limited to 'WebKit/qt/tests/qwebpage/tst_qwebpage.cpp')
-rw-r--r-- | WebKit/qt/tests/qwebpage/tst_qwebpage.cpp | 342 |
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" |