diff options
Diffstat (limited to 'WebKit/qt/tests')
28 files changed, 1616 insertions, 301 deletions
diff --git a/WebKit/qt/tests/benchmarks/loading/tst_loading.pro b/WebKit/qt/tests/benchmarks/loading/tst_loading.pro index af0387e..bc5e75f 100644 --- a/WebKit/qt/tests/benchmarks/loading/tst_loading.pro +++ b/WebKit/qt/tests/benchmarks/loading/tst_loading.pro @@ -4,3 +4,8 @@ include(../../../../../WebKit.pri) SOURCES += tst_loading.cpp QT += testlib network QMAKE_RPATHDIR = $$OUTPUT_DIR/lib $$QMAKE_RPATHDIR + +symbian { + TARGET.UID3 = 0xA000E541 + TARGET.CAPABILITY = ReadUserData WriteUserData NetworkServices +} diff --git a/WebKit/qt/tests/benchmarks/painting/tst_painting.pro b/WebKit/qt/tests/benchmarks/painting/tst_painting.pro index 496210e..48c7072 100644 --- a/WebKit/qt/tests/benchmarks/painting/tst_painting.pro +++ b/WebKit/qt/tests/benchmarks/painting/tst_painting.pro @@ -4,3 +4,8 @@ include(../../../../../WebKit.pri) SOURCES += tst_painting.cpp QT += testlib network QMAKE_RPATHDIR = $$OUTPUT_DIR/lib $$QMAKE_RPATHDIR + +symbian { + TARGET.UID3 = 0xA000E542 + TARGET.CAPABILITY = ReadUserData WriteUserData NetworkServices +} diff --git a/WebKit/qt/tests/qgraphicswebview/qgraphicswebview.pro b/WebKit/qt/tests/qgraphicswebview/qgraphicswebview.pro new file mode 100644 index 0000000..57b4437 --- /dev/null +++ b/WebKit/qt/tests/qgraphicswebview/qgraphicswebview.pro @@ -0,0 +1,10 @@ +TEMPLATE = app +TARGET = tst_qgraphicswebview +include(../../../../WebKit.pri) +SOURCES += tst_qgraphicswebview.cpp +QT += testlib network +QMAKE_RPATHDIR = $$OUTPUT_DIR/lib $$QMAKE_RPATHDIR + +symbian { + TARGET.CAPABILITY = ReadUserData WriteUserData NetworkServices +} diff --git a/WebKit/qt/tests/qgraphicswebview/tst_qgraphicswebview.cpp b/WebKit/qt/tests/qgraphicswebview/tst_qgraphicswebview.cpp new file mode 100644 index 0000000..657e09f --- /dev/null +++ b/WebKit/qt/tests/qgraphicswebview/tst_qgraphicswebview.cpp @@ -0,0 +1,107 @@ +/* + Copyright (C) 2009 Jakub Wieczorek <faw217@gmail.com> + + 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 "../util.h" +#include <QtTest/QtTest> +#include <QGraphicsView> +#include <qgraphicswebview.h> +#include <qwebpage.h> +#include <qwebframe.h> + +class tst_QGraphicsWebView : public QObject +{ + Q_OBJECT + +private slots: + void qgraphicswebview(); + void crashOnViewlessWebPages(); +}; + +void tst_QGraphicsWebView::qgraphicswebview() +{ + QGraphicsWebView item; + item.url(); + item.title(); + item.icon(); + item.zoomFactor(); + item.history(); + item.settings(); + item.page(); + item.setPage(0); + item.page(); + item.setUrl(QUrl()); + item.setZoomFactor(0); + item.load(QUrl()); + item.setHtml(QString()); + item.setContent(QByteArray()); + item.isModified(); +} + +class WebPage : public QWebPage +{ + Q_OBJECT + +public: + WebPage(QObject* parent = 0): QWebPage(parent) + { + } + + QGraphicsWebView* webView; + +private slots: + // Force a webview deletion during the load. + // It should not cause WebPage to crash due to + // it accessing invalid pageClient pointer. + void aborting() + { + delete webView; + } +}; + +void tst_QGraphicsWebView::crashOnViewlessWebPages() +{ + QGraphicsScene scene; + QGraphicsView view(&scene); + + QGraphicsWebView* webView = new QGraphicsWebView; + WebPage* page = new WebPage; + webView->setPage(page); + page->webView = webView; + connect(page->mainFrame(), SIGNAL(initialLayoutCompleted()), page, SLOT(aborting())); + + scene.addItem(webView); + + view.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + view.resize(600, 480); + webView->resize(view.geometry().size()); + QCoreApplication::processEvents(); + view.show(); + + page->mainFrame()->setHtml(QString("data:text/html," + "<frameset cols=\"25%,75%\">" + "<frame src=\"data:text/html,foo \">" + "<frame src=\"data:text/html,bar\">" + "</frameset>")); + + QVERIFY(waitForSignal(page, SIGNAL(loadFinished(bool)))); +} + +QTEST_MAIN(tst_QGraphicsWebView) + +#include "tst_qgraphicswebview.moc" diff --git a/WebKit/qt/tests/qwebelement/image.png b/WebKit/qt/tests/qwebelement/image.png Binary files differnew file mode 100644 index 0000000..8d70364 --- /dev/null +++ b/WebKit/qt/tests/qwebelement/image.png diff --git a/WebKit/qt/tests/qwebelement/qwebelement.pro b/WebKit/qt/tests/qwebelement/qwebelement.pro index dd0b88a..c45a9ac 100644 --- a/WebKit/qt/tests/qwebelement/qwebelement.pro +++ b/WebKit/qt/tests/qwebelement/qwebelement.pro @@ -5,3 +5,8 @@ SOURCES += tst_qwebelement.cpp RESOURCES += qwebelement.qrc QT += testlib network QMAKE_RPATHDIR = $$OUTPUT_DIR/lib $$QMAKE_RPATHDIR + +symbian { + TARGET.UID3 = 0xA000E53A + TARGET.CAPABILITY = ReadUserData WriteUserData NetworkServices +} diff --git a/WebKit/qt/tests/qwebelement/qwebelement.qrc b/WebKit/qt/tests/qwebelement/qwebelement.qrc index ed01440..28b9d7b 100644 --- a/WebKit/qt/tests/qwebelement/qwebelement.qrc +++ b/WebKit/qt/tests/qwebelement/qwebelement.qrc @@ -2,5 +2,6 @@ <qresource prefix="/"> <file>style.css</file> <file>style2.css</file> +<file>image.png</file> </qresource> </RCC> diff --git a/WebKit/qt/tests/qwebelement/tst_qwebelement.cpp b/WebKit/qt/tests/qwebelement/tst_qwebelement.cpp index 0819a3a..e9dae18 100644 --- a/WebKit/qt/tests/qwebelement/tst_qwebelement.cpp +++ b/WebKit/qt/tests/qwebelement/tst_qwebelement.cpp @@ -68,18 +68,20 @@ private slots: void simpleCollection(); void attributes(); void attributesNS(); + void listAttributes(); void classes(); void namespaceURI(); + void iteration(); + void nonConstIterator(); + void constIterator(); void foreachManipulation(); - void evaluateScript(); - void callFunction(); - void callFunctionSubmitForm(); - void functionNames(); + void emptyCollection(); + void appendCollection(); + void evaluateJavaScript(); void documentElement(); void frame(); void style(); void computedStyle(); - void properties(); void appendAndPrepend(); void insertBeforeAndAfter(); void remove(); @@ -90,6 +92,8 @@ private slots: void nullSelect(); void firstChildNextSibling(); void lastChildPreviousSibling(); + void hasSetFocus(); + void render(); private: QWebView* m_view; @@ -136,7 +140,7 @@ void tst_QWebElement::simpleCollection() m_mainFrame->setHtml(html); QWebElement body = m_mainFrame->documentElement(); - QList<QWebElement> list = body.findAll("p"); + QWebElementCollection list = body.findAll("p"); QCOMPARE(list.count(), 2); QCOMPARE(list.at(0).toPlainText(), QString("first para")); QCOMPARE(list.at(1).toPlainText(), QString("second para")); @@ -184,6 +188,29 @@ void tst_QWebElement::attributesNS() QCOMPARE(svg.attributeNS("http://www.w3.org/2000/svg", "foobar", "defaultblah"), QString("true")); } +void tst_QWebElement::listAttributes() +{ + QString content = "<html xmlns=\"http://www.w3.org/1999/xhtml\" " + "xmlns:svg=\"http://www.w3.org/2000/svg\">" + "<body><svg:svg foo=\"\" svg:bar=\"\">" + "</svg:svg></body></html>"; + + m_mainFrame->setContent(content.toUtf8(), "application/xhtml+xml"); + + QWebElement svg = m_mainFrame->findFirstElement("svg"); + QVERIFY(!svg.isNull()); + + QVERIFY(svg.attributeNames().contains("foo")); + QVERIFY(svg.attributeNames("http://www.w3.org/2000/svg").contains("bar")); + + svg.setAttributeNS("http://www.w3.org/2000/svg", "svg:foobar", "true"); + QVERIFY(svg.attributeNames().contains("foo")); + QStringList attributes = svg.attributeNames("http://www.w3.org/2000/svg"); + QCOMPARE(attributes.size(), 2); + QVERIFY(attributes.contains("bar")); + QVERIFY(attributes.contains("foobar")); +} + void tst_QWebElement::classes() { m_mainFrame->setHtml("<body><p class=\"a b c d a c\">Test"); @@ -269,6 +296,72 @@ void tst_QWebElement::namespaceURI() } +void tst_QWebElement::iteration() +{ + QString html = "<body><p>first para</p><p>second para</p></body>"; + m_mainFrame->setHtml(html); + QWebElement body = m_mainFrame->documentElement(); + + QWebElementCollection paras = body.findAll("p"); + QList<QWebElement> referenceList = paras.toList(); + + QList<QWebElement> foreachList; + foreach(QWebElement p, paras) { + foreachList.append(p); + } + QVERIFY(foreachList.count() == 2); + QCOMPARE(foreachList.count(), referenceList.count()); + QCOMPARE(foreachList.at(0), referenceList.at(0)); + QCOMPARE(foreachList.at(1), referenceList.at(1)); + + QList<QWebElement> forLoopList; + for (int i = 0; i < paras.count(); ++i) { + forLoopList.append(paras.at(i)); + } + QVERIFY(foreachList.count() == 2); + QCOMPARE(foreachList.count(), referenceList.count()); + QCOMPARE(foreachList.at(0), referenceList.at(0)); + QCOMPARE(foreachList.at(1), referenceList.at(1)); + + for (int i = 0; i < paras.count(); ++i) { + QCOMPARE(paras.at(i), paras[i]); + } + + QCOMPARE(paras.at(0), paras.first()); + QCOMPARE(paras.at(1), paras.last()); +} + +void tst_QWebElement::nonConstIterator() +{ + QString html = "<body><p>first para</p><p>second para</p></body>"; + m_mainFrame->setHtml(html); + QWebElement body = m_mainFrame->documentElement(); + QWebElementCollection paras = body.findAll("p"); + + QWebElementCollection::iterator it = paras.begin(); + QCOMPARE(*it, paras.at(0)); + ++it; + (*it).encloseWith("<div>"); + QCOMPARE(*it, paras.at(1)); + ++it; + QCOMPARE(it, paras.end()); +} + +void tst_QWebElement::constIterator() +{ + QString html = "<body><p>first para</p><p>second para</p></body>"; + m_mainFrame->setHtml(html); + QWebElement body = m_mainFrame->documentElement(); + const QWebElementCollection paras = body.findAll("p"); + + QWebElementCollection::const_iterator it = paras.begin(); + QCOMPARE(*it, paras.at(0)); + ++it; + QCOMPARE(*it, paras.at(1)); + ++it; + QCOMPARE(it, paras.end()); +} + void tst_QWebElement::foreachManipulation() { QString html = "<body><p>first para</p><p>second para</p></body>"; @@ -282,69 +375,68 @@ void tst_QWebElement::foreachManipulation() QCOMPARE(body.findAll("div").count(), 4); } -void tst_QWebElement::evaluateScript() +void tst_QWebElement::emptyCollection() +{ + QWebElementCollection emptyCollection; + QCOMPARE(emptyCollection.count(), 0); +} + +void tst_QWebElement::appendCollection() +{ + QString html = "<body><span class='a'>aaa</span><p>first para</p><div>foo</div>" + "<span class='b'>bbb</span><p>second para</p><div>bar</div></body>"; + m_mainFrame->setHtml(html); + QWebElement body = m_mainFrame->documentElement(); + + QWebElementCollection collection = body.findAll("p"); + QCOMPARE(collection.count(), 2); + + collection.append(body.findAll("div")); + QCOMPARE(collection.count(), 4); + + collection += body.findAll("span.a"); + QCOMPARE(collection.count(), 5); + + QWebElementCollection all = collection + body.findAll("span.b"); + QCOMPARE(all.count(), 6); + QCOMPARE(collection.count(), 5); + + all += collection; + QCOMPARE(all.count(), 11); + + QCOMPARE(collection.count(), 5); + QWebElementCollection test; + test.append(collection); + QCOMPARE(test.count(), 5); + test.append(QWebElementCollection()); + QCOMPARE(test.count(), 5); +} + +void tst_QWebElement::evaluateJavaScript() { QVariant result; m_mainFrame->setHtml("<body><p>test"); QWebElement para = m_mainFrame->findFirstElement("p"); - result = para.evaluateScript("this.tagName"); + result = para.evaluateJavaScript("this.tagName"); QVERIFY(result.isValid()); QVERIFY(result.type() == QVariant::String); QCOMPARE(result.toString(), QLatin1String("P")); - QVERIFY(para.functions().contains("hasAttributes")); - result = para.evaluateScript("this.hasAttributes()"); + result = para.evaluateJavaScript("this.hasAttributes()"); QVERIFY(result.isValid()); QVERIFY(result.type() == QVariant::Bool); QVERIFY(!result.toBool()); - para.evaluateScript("this.setAttribute('align', 'left');"); + para.evaluateJavaScript("this.setAttribute('align', 'left');"); QCOMPARE(para.attribute("align"), QLatin1String("left")); - result = para.evaluateScript("this.hasAttributes()"); + result = para.evaluateJavaScript("this.hasAttributes()"); QVERIFY(result.isValid()); QVERIFY(result.type() == QVariant::Bool); QVERIFY(result.toBool()); } -void tst_QWebElement::callFunction() -{ - m_mainFrame->setHtml("<body><p>test"); - QWebElement body = m_mainFrame->documentElement(); - QVERIFY(body.functions().contains("hasChildNodes")); - QVariant result = body.callFunction("hasChildNodes"); - QVERIFY(result.isValid()); - QVERIFY(result.type() == QVariant::Bool); - QVERIFY(result.toBool()); - - body.callFunction("setAttribute", QVariantList() << "foo" << "bar"); - QCOMPARE(body.attribute("foo"), QString("bar")); -} - -void tst_QWebElement::callFunctionSubmitForm() -{ - m_mainFrame->setHtml(QString("<html><body><form name='tstform' action='data:text/html,foo'method='get'>" - "<input type='text'><input type='submit'></form></body></html>"), QUrl()); - - QWebElement form = m_mainFrame->documentElement().findAll("form").at(0); - QVERIFY(form.functions().contains("submit")); - QVERIFY(!form.isNull()); - form.callFunction("submit"); - - waitForSignal(m_page, SIGNAL(loadFinished(bool))); - QCOMPARE(m_mainFrame->url().toString(), QString("data:text/html,foo?")); -} - -void tst_QWebElement::functionNames() -{ - m_mainFrame->setHtml("<body><p>Test"); - - QWebElement body = m_mainFrame->documentElement(); - - QVERIFY(body.functions().contains("setAttribute")); -} - void tst_QWebElement::documentElement() { m_mainFrame->setHtml("<body><p>Test"); @@ -398,27 +490,27 @@ void tst_QWebElement::style() m_mainFrame->setHtml(html); QWebElement p = m_mainFrame->documentElement().findAll("p").at(0); - QCOMPARE(p.styleProperty("color"), QLatin1String("blue")); - QVERIFY(p.styleProperty("cursor").isEmpty()); + QCOMPARE(p.styleProperty("color", QWebElement::InlineStyle), QLatin1String("blue")); + QVERIFY(p.styleProperty("cursor", QWebElement::InlineStyle).isEmpty()); p.setStyleProperty("color", "red"); p.setStyleProperty("cursor", "auto"); - QCOMPARE(p.styleProperty("color"), QLatin1String("red")); - QCOMPARE(p.styleProperty("color", QWebElement::RespectCascadingStyles), QLatin1String("yellow")); - QCOMPARE(p.styleProperty("cursor"), QLatin1String("auto")); + QCOMPARE(p.styleProperty("color", QWebElement::InlineStyle), QLatin1String("red")); + QCOMPARE(p.styleProperty("color", QWebElement::CascadedStyle), QLatin1String("yellow")); + QCOMPARE(p.styleProperty("cursor", QWebElement::InlineStyle), QLatin1String("auto")); p.setStyleProperty("color", "green !important"); - QCOMPARE(p.styleProperty("color"), QLatin1String("green")); - QCOMPARE(p.styleProperty("color", QWebElement::RespectCascadingStyles), QLatin1String("green")); + QCOMPARE(p.styleProperty("color", QWebElement::InlineStyle), QLatin1String("green")); + QCOMPARE(p.styleProperty("color", QWebElement::CascadedStyle), QLatin1String("green")); p.setStyleProperty("color", "blue"); - QCOMPARE(p.styleProperty("color"), QLatin1String("green")); - QCOMPARE(p.styleProperty("color", QWebElement::RespectCascadingStyles), QLatin1String("green")); + QCOMPARE(p.styleProperty("color", QWebElement::InlineStyle), QLatin1String("green")); + QCOMPARE(p.styleProperty("color", QWebElement::CascadedStyle), QLatin1String("green")); - p.setStyleProperty("color", "blue", QWebElement::ImportantStylePriority); - QCOMPARE(p.styleProperty("color"), QLatin1String("blue")); - QCOMPARE(p.styleProperty("color", QWebElement::RespectCascadingStyles), QLatin1String("blue")); + p.setStyleProperty("color", "blue !important"); + QCOMPARE(p.styleProperty("color", QWebElement::InlineStyle), QLatin1String("blue")); + QCOMPARE(p.styleProperty("color", QWebElement::CascadedStyle), QLatin1String("blue")); QString html2 = "<head>" "<style type='text/css'>" @@ -434,8 +526,8 @@ void tst_QWebElement::style() m_mainFrame->setHtml(html2); p = m_mainFrame->documentElement().findAll("p").at(0); - QCOMPARE(p.styleProperty("color"), QLatin1String("blue")); - QCOMPARE(p.styleProperty("color", QWebElement::RespectCascadingStyles), QLatin1String("blue")); + QCOMPARE(p.styleProperty("color", QWebElement::InlineStyle), QLatin1String("blue")); + QCOMPARE(p.styleProperty("color", QWebElement::CascadedStyle), QLatin1String("blue")); QString html3 = "<head>" "<style type='text/css'>" @@ -451,8 +543,8 @@ void tst_QWebElement::style() m_mainFrame->setHtml(html3); p = m_mainFrame->documentElement().findAll("p").at(0); - QCOMPARE(p.styleProperty("color"), QLatin1String("blue")); - QCOMPARE(p.styleProperty("color", QWebElement::RespectCascadingStyles), QLatin1String("blue")); + QCOMPARE(p.styleProperty("color", QWebElement::InlineStyle), QLatin1String("blue")); + QCOMPARE(p.styleProperty("color", QWebElement::CascadedStyle), QLatin1String("blue")); QString html5 = "<head>" "<style type='text/css'>" @@ -468,8 +560,8 @@ void tst_QWebElement::style() m_mainFrame->setHtml(html5); p = m_mainFrame->documentElement().findAll("p").at(0); - QCOMPARE(p.styleProperty("color"), QLatin1String("")); - QCOMPARE(p.styleProperty("color", QWebElement::RespectCascadingStyles), QLatin1String("red")); + QCOMPARE(p.styleProperty("color", QWebElement::InlineStyle), QLatin1String("")); + QCOMPARE(p.styleProperty("color", QWebElement::CascadedStyle), QLatin1String("red")); QString html6 = "<head>" "<link rel='stylesheet' href='qrc:/style.css' type='text/css' />" @@ -489,8 +581,8 @@ void tst_QWebElement::style() QTest::qWait(200); p = m_mainFrame->documentElement().findAll("p").at(0); - QCOMPARE(p.styleProperty("color"), QLatin1String("blue")); - QCOMPARE(p.styleProperty("color", QWebElement::RespectCascadingStyles), QLatin1String("black")); + QCOMPARE(p.styleProperty("color", QWebElement::InlineStyle), QLatin1String("blue")); + QCOMPARE(p.styleProperty("color", QWebElement::CascadedStyle), QLatin1String("black")); QString html7 = "<head>" "<style type='text/css'>" @@ -507,15 +599,15 @@ void tst_QWebElement::style() QTest::qWait(200); p = m_mainFrame->documentElement().findAll("p").at(0); - QCOMPARE(p.styleProperty("color", QWebElement::RespectCascadingStyles), QLatin1String("black")); + QCOMPARE(p.styleProperty("color", QWebElement::CascadedStyle), QLatin1String("black")); QString html8 = "<body><p>some text</p></body>"; m_mainFrame->setHtml(html8); p = m_mainFrame->documentElement().findAll("p").at(0); - QCOMPARE(p.styleProperty("color"), QLatin1String("")); - QCOMPARE(p.styleProperty("color", QWebElement::RespectCascadingStyles), QLatin1String("")); + QCOMPARE(p.styleProperty("color", QWebElement::InlineStyle), QLatin1String("")); + QCOMPARE(p.styleProperty("color", QWebElement::CascadedStyle), QLatin1String("")); } void tst_QWebElement::computedStyle() @@ -524,47 +616,16 @@ void tst_QWebElement::computedStyle() m_mainFrame->setHtml(html); QWebElement p = m_mainFrame->documentElement().findAll("p").at(0); - QCOMPARE(p.computedStyleProperty("cursor"), QLatin1String("auto")); - QVERIFY(!p.computedStyleProperty("cursor").isEmpty()); - QVERIFY(p.styleProperty("cursor").isEmpty()); + QCOMPARE(p.styleProperty("cursor", QWebElement::ComputedStyle), QLatin1String("auto")); + QVERIFY(!p.styleProperty("cursor", QWebElement::ComputedStyle).isEmpty()); + QVERIFY(p.styleProperty("cursor", QWebElement::InlineStyle).isEmpty()); p.setStyleProperty("cursor", "text"); p.setStyleProperty("color", "red"); - QCOMPARE(p.computedStyleProperty("cursor"), QLatin1String("text")); - QCOMPARE(p.computedStyleProperty("color"), QLatin1String("rgb(255, 0, 0)")); - QCOMPARE(p.styleProperty("color"), QLatin1String("red")); -} - -void tst_QWebElement::properties() -{ - m_mainFrame->setHtml("<body><form><input type=checkbox id=ourcheckbox checked=true>"); - - QWebElement checkBox = m_mainFrame->findFirstElement("#ourcheckbox"); - QVERIFY(!checkBox.isNull()); - - QVERIFY(checkBox.scriptableProperties().contains("checked")); - - QCOMPARE(checkBox.scriptableProperty("checked"), QVariant(true)); - checkBox.setScriptableProperty("checked", false); - QCOMPARE(checkBox.scriptableProperty("checked"), QVariant(false)); - - QVERIFY(!checkBox.scriptableProperties().contains("non_existant")); - QCOMPARE(checkBox.scriptableProperty("non_existant"), QVariant()); - - checkBox.setScriptableProperty("non_existant", "test"); - - QCOMPARE(checkBox.scriptableProperty("non_existant"), QVariant("test")); - QVERIFY(checkBox.scriptableProperties().contains("non_existant")); - - // removing scriptableProperties is currently not supported. We should look into this - // and consider the option of just allowing through the QtScript API only. -#if 0 - checkBox.setScriptableProperty("non_existant", QVariant()); - - QCOMPARE(checkBox.scriptableProperty("non_existant"), QVariant()); - QVERIFY(!checkBox.scriptableProperties().contains("non_existant")); -#endif + QCOMPARE(p.styleProperty("cursor", QWebElement::ComputedStyle), QLatin1String("text")); + QCOMPARE(p.styleProperty("color", QWebElement::ComputedStyle), QLatin1String("rgb(255, 0, 0)")); + QCOMPARE(p.styleProperty("color", QWebElement::InlineStyle), QLatin1String("red")); } void tst_QWebElement::appendAndPrepend() @@ -700,7 +761,7 @@ void tst_QWebElement::clear() QCOMPARE(body.findAll("div").count(), 1); QCOMPARE(body.findAll("p").count(), 3); - body.findFirst("div").removeChildren(); + body.findFirst("div").removeAllChildren(); QCOMPARE(body.findAll("div").count(), 1); QCOMPARE(body.findAll("p").count(), 2); } @@ -844,7 +905,7 @@ void tst_QWebElement::nullSelect() { m_mainFrame->setHtml("<body><p>Test"); - QList<QWebElement> collection = m_mainFrame->findAllElements("invalid{syn(tax;;%#$f223e>>"); + QWebElementCollection collection = m_mainFrame->findAllElements("invalid{syn(tax;;%#$f223e>>"); QVERIFY(collection.count() == 0); } @@ -878,5 +939,103 @@ void tst_QWebElement::lastChildPreviousSibling() QVERIFY(p.previousSibling().isNull()); } +void tst_QWebElement::hasSetFocus() +{ + m_mainFrame->setHtml("<html><body>" \ + "<input type='text' id='input1'/>" \ + "<br>"\ + "<input type='text' id='input2'/>" \ + "</body></html>"); + + QWebElementCollection inputs = m_mainFrame->documentElement().findAll("input"); + QWebElement input1 = inputs.at(0); + input1.setFocus(); + QVERIFY(input1.hasFocus()); + + QWebElement input2 = inputs.at(1); + input2.setFocus(); + QVERIFY(!input1.hasFocus()); + QVERIFY(input2.hasFocus()); +} + +void tst_QWebElement::render() +{ + QString html( "<html>" + "<head><style>" + "body, iframe { margin: 0px; border: none; }" + "</style></head>" + "<body><table width='300px' height='300px' border='1'>" + "<tr>" + "<td>test" + "</td>" + "<td><img src='qrc:///image.png'>" + "</td>" + "</tr>" + "</table>" + "</body>" + "</html>" + ); + + QWebPage page; + QSignalSpy loadSpy(&page, SIGNAL(loadFinished(bool))); + page.mainFrame()->setHtml(html); + + waitForSignal(&page, SIGNAL(loadFinished(bool))); + QCOMPARE(loadSpy.count(), 1); + + QSize size = page.mainFrame()->contentsSize(); + page.setViewportSize(size); + + QWebElementCollection imgs = page.mainFrame()->findAllElements("img"); + QCOMPARE(imgs.count(), 1); + + QImage resource(":/image.png"); + QRect imageRect(0, 0, resource.width(), resource.height()); + + QImage testImage(resource.width(), resource.height(), QImage::Format_ARGB32); + QPainter painter0(&testImage); + painter0.fillRect(imageRect, Qt::white); + // render() uses pixmaps internally, and pixmaps might have bit depths + // other than 32, giving different pixel values due to rounding. + QPixmap pix = QPixmap::fromImage(resource); + painter0.drawPixmap(0, 0, pix); + painter0.end(); + + QImage image1(resource.width(), resource.height(), QImage::Format_ARGB32); + QPainter painter1(&image1); + painter1.fillRect(imageRect, Qt::white); + imgs[0].render(&painter1); + painter1.end(); + + QVERIFY(image1 == testImage); + + // render image 2nd time to make sure that cached rendering works fine + QImage image2(resource.width(), resource.height(), QImage::Format_ARGB32); + QPainter painter2(&image2); + painter2.fillRect(imageRect, Qt::white); + imgs[0].render(&painter2); + painter2.end(); + + QVERIFY(image2 == testImage); + + // compare table rendered through QWebElement::render to whole page table rendering + QRect tableRect(0, 0, 300, 300); + QWebElementCollection tables = page.mainFrame()->findAllElements("table"); + QCOMPARE(tables.count(), 1); + + QImage image3(300, 300, QImage::Format_ARGB32); + QPainter painter3(&image3); + painter3.fillRect(tableRect, Qt::white); + tables[0].render(&painter3); + painter3.end(); + + QImage image4(300, 300, QImage::Format_ARGB32); + QPainter painter4(&image4); + page.mainFrame()->render(&painter4, tableRect); + painter4.end(); + + QVERIFY(image3 == image4); +} + QTEST_MAIN(tst_QWebElement) #include "tst_qwebelement.moc" diff --git a/WebKit/qt/tests/qwebframe/qwebframe.pro b/WebKit/qt/tests/qwebframe/qwebframe.pro index e45e6dc..b8734cd 100644 --- a/WebKit/qt/tests/qwebframe/qwebframe.pro +++ b/WebKit/qt/tests/qwebframe/qwebframe.pro @@ -5,3 +5,9 @@ SOURCES += tst_qwebframe.cpp RESOURCES += qwebframe.qrc QT += testlib network QMAKE_RPATHDIR = $$OUTPUT_DIR/lib $$QMAKE_RPATHDIR +!symbian:DEFINES += SRCDIR=\\\"$$PWD/resources\\\" + +symbian { + TARGET.UID3 = 0xA000E53D + TARGET.CAPABILITY = ReadUserData WriteUserData NetworkServices +} diff --git a/WebKit/qt/tests/qwebframe/resources/image2.png b/WebKit/qt/tests/qwebframe/resources/image2.png Binary files differnew file mode 100644 index 0000000..8d70364 --- /dev/null +++ b/WebKit/qt/tests/qwebframe/resources/image2.png diff --git a/WebKit/qt/tests/qwebframe/tst_qwebframe.cpp b/WebKit/qt/tests/qwebframe/tst_qwebframe.cpp index 17dea99..7c13fd0 100644 --- a/WebKit/qt/tests/qwebframe/tst_qwebframe.cpp +++ b/WebKit/qt/tests/qwebframe/tst_qwebframe.cpp @@ -33,37 +33,14 @@ #include <QRegExp> #include <QNetworkRequest> #include <QNetworkReply> +#ifndef QT_NO_OPENSSL #include <qsslerror.h> +#endif +#include "../util.h" -//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(); -} - -/* Mostly a test for the JavaScript related parts of QWebFrame */ - +#if defined(Q_OS_SYMBIAN) +# define SRCDIR "" +#endif struct CustomType { QString string; @@ -578,8 +555,12 @@ private slots: void urlChange(); void domCycles(); void requestedUrl(); + void javaScriptWindowObjectCleared_data(); + void javaScriptWindowObjectCleared(); + void javaScriptWindowObjectClearedOnEvaluate(); void setHtml(); void setHtmlWithResource(); + void setHtmlWithBaseURL(); void ipv6HostEncoding(); void metaData(); void popupFocus(); @@ -592,6 +573,8 @@ private slots: void hasSetFocus(); void render(); void scrollPosition(); + void evaluateWillCauseRepaint(); + void qObjectWrapperWithSameIdentity(); private: QString evalJS(const QString&s) { @@ -692,6 +675,7 @@ void tst_QWebFrame::init() m_page = m_view->page(); m_myObject = new MyQObject(); m_page->mainFrame()->addToJavaScriptWindowObject("myObject", m_myObject); + QDir::setCurrent(SRCDIR); } void tst_QWebFrame::cleanup() @@ -2178,8 +2162,11 @@ public: if (request.url() == QUrl("qrc:/test1.html")) { setHeader(QNetworkRequest::LocationHeader, QString("qrc:/test2.html")); setAttribute(QNetworkRequest::RedirectionTargetAttribute, QUrl("qrc:/test2.html")); - } else if (request.url() == QUrl("qrc:/fake-ssl-error.html")) + } +#ifndef QT_NO_OPENSSL + else if (request.url() == QUrl("qrc:/fake-ssl-error.html")) setError(QNetworkReply::SslHandshakeFailedError, tr("Fake error !")); // force a ssl error +#endif else if (request.url() == QUrl("http://abcdef.abcdef/")) setError(QNetworkReply::HostNotFoundError, tr("Invalid URL")); @@ -2206,8 +2193,10 @@ private slots: emit error(this->error()); else if (request().url() == QUrl("http://abcdef.abcdef/")) emit metaDataChanged(); +#ifndef QT_NO_OPENSSL else if (request().url() == QUrl("qrc:/fake-ssl-error.html")) return; +#endif emit readyRead(); emit finished(); @@ -2224,15 +2213,18 @@ protected: virtual QNetworkReply* createRequest(Operation op, const QNetworkRequest& request, QIODevice* outgoingData) { QString url = request.url().toString(); - if (op == QNetworkAccessManager::GetOperation) + if (op == QNetworkAccessManager::GetOperation) { if (url == "qrc:/test1.html" || url == "http://abcdef.abcdef/") return new FakeReply(request, this); +#ifndef QT_NO_OPENSSL else 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 + } return QNetworkAccessManager::createRequest(op, request, outgoingData); } @@ -2249,32 +2241,68 @@ void tst_QWebFrame::requestedUrl() page.setNetworkAccessManager(networkManager); frame->setUrl(QUrl("qrc:/test1.html")); - QTest::qWait(200); + 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")); - QTest::qWait(200); + 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")); - QTest::qWait(200); + 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*, const QList<QSslError>&))); + QSignalSpy spy2(page.networkAccessManager(), SIGNAL(sslErrors(QNetworkReply*,QList<QSslError>))); frame->setUrl(QUrl("qrc:/fake-ssl-error.html")); - QTest::qWait(200); + 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::javaScriptWindowObjectCleared_data() +{ + QTest::addColumn<QString>("html"); + QTest::addColumn<int>("signalCount"); + QTest::newRow("with <script>") << "<html><body><script></script><p>hello world</p></body></html>" << 1; + 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() @@ -2294,7 +2322,7 @@ void tst_QWebFrame::setHtmlWithResource() // in few seconds, the image should be completey loaded QSignalSpy spy(&page, SIGNAL(loadFinished(bool))); frame->setHtml(html); - QTest::qWait(200); + waitForSignal(frame, SIGNAL(loadFinished(bool)), 200); QCOMPARE(spy.count(), 1); QCOMPARE(frame->evaluateJavaScript("document.images.length").toInt(), 1); @@ -2313,11 +2341,33 @@ void tst_QWebFrame::setHtmlWithResource() // in few seconds, the CSS should be completey loaded frame->setHtml(html2); - QTest::qWait(200); + waitForSignal(frame, SIGNAL(loadFinished(bool)), 200); QCOMPARE(spy.size(), 2); QWebElement p = frame->documentElement().findAll("p").at(0); - QCOMPARE(p.styleProperty("color", QWebElement::RespectCascadingStyles), QLatin1String("red")); + QCOMPARE(p.styleProperty("color", QWebElement::CascadedStyle), QLatin1String("red")); +} + +void tst_QWebFrame::setHtmlWithBaseURL() +{ + QString html("<html><body><p>hello world</p><img src='resources/image2.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(QDir::currentPath())); + 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 TestNetworkManager : public QNetworkAccessManager @@ -2408,33 +2458,27 @@ void tst_QWebFrame::popupFocus() view.resize(400, 100); view.show(); view.setFocus(); - QTest::qWait(200); - QVERIFY2(view.hasFocus(), - "The WebView should be created"); + QTRY_VERIFY(view.hasFocus()); // open the popup by clicking. check if focus is on the popup QTest::mouseClick(&view, Qt::LeftButton, 0, QPoint(25, 25)); QObject* webpopup = firstChildByClassName(&view, "WebCore::QWebPopup"); QComboBox* combo = qobject_cast<QComboBox*>(webpopup); - QTest::qWait(500); - QVERIFY2(!view.hasFocus() && combo->view()->hasFocus(), - "Focus sould be on the Popup"); + 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(); - QTest::qWait(500); - QVERIFY2(view.hasFocus() && !combo->view()->hasFocus(), - "Focus sould be back on the WebView"); + QTRY_VERIFY(view.hasFocus() && !combo->view()->hasFocus()); // Focus should be back on the WebView - // triple the flashing time, should at least blink twice already - int delay = qApp->cursorFlashTime() * 3; + // double the flashing time, should at least blink once already + int delay = qApp->cursorFlashTime() * 2; // focus the lineedit and check if it blinks QTest::mouseClick(&view, Qt::LeftButton, 0, QPoint(200, 25)); m_popupTestView = &view; view.installEventFilter( this ); QTest::qWait(delay); - QVERIFY2(m_popupTestPaintCount >= 4, + QVERIFY2(m_popupTestPaintCount >= 3, "The input field should have a blinking caret"); } @@ -2578,7 +2622,7 @@ void tst_QWebFrame::hasSetFocus() QSignalSpy loadSpy(m_page, SIGNAL(loadFinished(bool))); m_page->mainFrame()->setHtml(html); - QTest::qWait(200); + waitForSignal(m_page->mainFrame(), SIGNAL(loadFinished(bool)), 200); QCOMPARE(loadSpy.size(), 1); QList<QWebFrame*> children = m_page->mainFrame()->childFrames(); @@ -2588,20 +2632,20 @@ void tst_QWebFrame::hasSetFocus() "</body></html>"); frame->setHtml(innerHtml); - QTest::qWait(200); + waitForSignal(frame, SIGNAL(loadFinished(bool)), 200); QCOMPARE(loadSpy.size(), 2); m_page->mainFrame()->setFocus(); - QVERIFY(m_page->mainFrame()->hasFocus()); + QTRY_VERIFY(m_page->mainFrame()->hasFocus()); for (int i = 0; i < children.size(); ++i) { children.at(i)->setFocus(); - QVERIFY(children.at(i)->hasFocus()); + QTRY_VERIFY(children.at(i)->hasFocus()); QVERIFY(!m_page->mainFrame()->hasFocus()); } m_page->mainFrame()->setFocus(); - QVERIFY(m_page->mainFrame()->hasFocus()); + QTRY_VERIFY(m_page->mainFrame()->hasFocus()); } void tst_QWebFrame::render() @@ -2623,26 +2667,24 @@ void tst_QWebFrame::render() QPicture picture; - // render clipping to Viewport - frame->setClipRenderToViewport(true); + 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); + frame->render(&painter1, QWebFrame::ContentsLayer); painter1.end(); - QSize size = page.mainFrame()->contentsSize(); - page.setViewportSize(size); - QCOMPARE(size.width(), picture.boundingRect().width()); // 100px - QCOMPARE(size.height(), picture.boundingRect().height()); // 100px + QCOMPARE(size.width(), picture.boundingRect().width() + frame->scrollBarGeometry(Qt::Vertical).width()); + QCOMPARE(size.height(), picture.boundingRect().height() + frame->scrollBarGeometry(Qt::Horizontal).height()); - // render without clipping to Viewport - frame->setClipRenderToViewport(false); + // render everything, should be the size of the iframe QPainter painter2(&picture); - frame->render(&painter2); + frame->render(&painter2, QWebFrame::AllLayers); painter2.end(); - QImage resource(":/image.png"); - QCOMPARE(resource.width(), picture.boundingRect().width()); // resource width: 128px - QCOMPARE(resource.height(), picture.boundingRect().height()); // resource height: 128px + QCOMPARE(size.width(), picture.boundingRect().width()); // width: 100px + QCOMPARE(size.height(), picture.boundingRect().height()); // height: 100px } void tst_QWebFrame::scrollPosition() @@ -2669,5 +2711,59 @@ void tst_QWebFrame::scrollPosition() QCOMPARE(y, 29); } +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::qWaitForWindowShown(&view); + + view.page()->mainFrame()->evaluateJavaScript( + "document.getElementById('junk').style.display = 'none';"); + + ::waitForSignal(view.page(), SIGNAL(repaintRequested(QRect))); +} + +class TestFactory : public QObject +{ + Q_OBJECT +public: + TestFactory() + : obj(0), counter(0) + {} + + Q_INVOKABLE QObject* getNewObject() + { + delete obj; + obj = new QObject(this); + obj->setObjectName(QLatin1String("test") + QString::number(++counter)); + return obj; + + } + + QObject* obj; + int counter; +}; + +void tst_QWebFrame::qObjectWrapperWithSameIdentity() +{ + m_view->setHtml("<script>function triggerBug() { document.getElementById('span1').innerText = test.getNewObject().objectName; }</script>" + "<body><span id='span1'>test</span></body>"); + + QWebFrame* mainFrame = m_view->page()->mainFrame(); + QCOMPARE(mainFrame->toPlainText(), QString("test")); + + mainFrame->addToJavaScriptWindowObject("test", new TestFactory, QScriptEngine::ScriptOwnership); + + mainFrame->evaluateJavaScript("triggerBug();"); + QCOMPARE(mainFrame->toPlainText(), QString("test1")); + + mainFrame->evaluateJavaScript("triggerBug();"); + QCOMPARE(mainFrame->toPlainText(), QString("test2")); +} + QTEST_MAIN(tst_QWebFrame) #include "tst_qwebframe.moc" diff --git a/WebKit/qt/tests/qwebhistory/qwebhistory.pro b/WebKit/qt/tests/qwebhistory/qwebhistory.pro index fd1074c..7445e3b 100644 --- a/WebKit/qt/tests/qwebhistory/qwebhistory.pro +++ b/WebKit/qt/tests/qwebhistory/qwebhistory.pro @@ -5,3 +5,8 @@ SOURCES += tst_qwebhistory.cpp RESOURCES += tst_qwebhistory.qrc QT += testlib network QMAKE_RPATHDIR = $$OUTPUT_DIR/lib $$QMAKE_RPATHDIR + +symbian { + TARGET.UID3 = 0xA000E53B + TARGET.CAPABILITY = ReadUserData WriteUserData NetworkServices +} diff --git a/WebKit/qt/tests/qwebhistory/tst_qwebhistory.cpp b/WebKit/qt/tests/qwebhistory/tst_qwebhistory.cpp index 5b55613..ec2d497 100644 --- a/WebKit/qt/tests/qwebhistory/tst_qwebhistory.cpp +++ b/WebKit/qt/tests/qwebhistory/tst_qwebhistory.cpp @@ -18,6 +18,7 @@ */ #include <QtTest/QtTest> +#include <QAction> #include "qwebpage.h" #include "qwebview.h" @@ -55,9 +56,11 @@ private slots: void serialize_1(); //QWebHistory countity void serialize_2(); //QWebHistory index void serialize_3(); //QWebHistoryItem - void saveAndRestore_1(); //simple checks saveState and restoreState - void saveAndRestore_2(); //bad parameters saveState and restoreState - void saveAndRestore_3(); //try use different version + void saveAndRestore_crash_1(); + void saveAndRestore_crash_2(); + void saveAndRestore_crash_3(); + void clear(); + private: QWebPage* page; @@ -119,6 +122,8 @@ void tst_QWebHistory::back() hist->back(); waitForLoadFinished.exec(); } + //try one more time (too many). crash test + hist->back(); } /** @@ -137,6 +142,8 @@ void tst_QWebHistory::forward() hist->forward(); waitForLoadFinished.exec(); } + //try one more time (too many). crash test + hist->forward(); } /** @@ -284,42 +291,83 @@ void tst_QWebHistory::serialize_3() QVERIFY(load.atEnd()); } -/** Simple checks should be a bit redundant to streaming operators */ -void tst_QWebHistory::saveAndRestore_1() +static void saveHistory(QWebHistory* history, QByteArray* in) { - hist->back(); - waitForLoadFinished.exec(); - QByteArray buffer(hist->saveState()); - hist->clear(); - QVERIFY(hist->count() == 1); - hist->restoreState(buffer); + in->clear(); + QDataStream save(in, QIODevice::WriteOnly); + save << *history; +} - //check only few values, do not make full test - //because most of the code is shared with streaming operators - //and these are checked before - QCOMPARE(hist->count(), histsize); - QCOMPARE(hist->currentItemIndex(), histsize - 2); - QCOMPARE(hist->itemAt(0).title(), QString("page1")); - QCOMPARE(hist->itemAt(histsize - 1).title(), QString("page") + QString::number(histsize)); +static void restoreHistory(QWebHistory* history, QByteArray* out) +{ + QDataStream load(out, QIODevice::ReadOnly); + load >> *history; } -/** Check returns value if there are bad parameters. Actually, result - * is no so importent. The test shouldn't crash :-) */ -void tst_QWebHistory::saveAndRestore_2() +/** The test shouldn't crash */ +void tst_QWebHistory::saveAndRestore_crash_1() { QByteArray buffer; - hist->restoreState(buffer); - QVERIFY(hist->count() == 1); - QVERIFY(hist->itemAt(0).isValid()); + saveHistory(hist, &buffer); + for (unsigned i = 0; i < 5; i++) { + restoreHistory(hist, &buffer); + saveHistory(hist, &buffer); + } +} + +/** The test shouldn't crash */ +void tst_QWebHistory::saveAndRestore_crash_2() +{ + QByteArray buffer; + saveHistory(hist, &buffer); + QWebPage* page2 = new QWebPage(this); + QWebHistory* hist2 = page2->history(); + for (unsigned i = 0; i < 5; i++) { + restoreHistory(hist2, &buffer); + saveHistory(hist2, &buffer); + } + delete page2; +} + +/** The test shouldn't crash */ +void tst_QWebHistory::saveAndRestore_crash_3() +{ + QByteArray buffer; + saveHistory(hist, &buffer); + QWebPage* page2 = new QWebPage(this); + QWebHistory* hist1 = hist; + QWebHistory* hist2 = page2->history(); + for (unsigned i = 0; i < 5; i++) { + restoreHistory(hist1, &buffer); + restoreHistory(hist2, &buffer); + QVERIFY(hist1->count() == hist2->count()); + QVERIFY(hist1->count() == histsize); + hist2->back(); + saveHistory(hist2, &buffer); + hist2->clear(); + } + delete page2; } -/** Try to use bad version value */ -void tst_QWebHistory::saveAndRestore_3() +/** ::clear */ +void tst_QWebHistory::clear() { - QByteArray tmp = hist->saveState((QWebHistory::HistoryStateVersion)29999); - QVERIFY(hist->saveState((QWebHistory::HistoryStateVersion)29999).isEmpty()); - QVERIFY(hist->count() == histsize); - QVERIFY(hist->itemAt(3).isValid()); + QByteArray buffer; + + QAction* actionBack = page->action(QWebPage::Back); + QVERIFY(actionBack->isEnabled()); + saveHistory(hist, &buffer); + QVERIFY(hist->count() > 1); + hist->clear(); + QVERIFY(hist->count() == 1); // Leave current item. + QVERIFY(!actionBack->isEnabled()); + + QWebPage* page2 = new QWebPage(this); + QWebHistory* hist2 = page2->history(); + QVERIFY(hist2->count() == 0); + hist2->clear(); + QVERIFY(hist2->count() == 0); // Do not change anything. + delete page2; } QTEST_MAIN(tst_QWebHistory) diff --git a/WebKit/qt/tests/qwebhistoryinterface/qwebhistoryinterface.pro b/WebKit/qt/tests/qwebhistoryinterface/qwebhistoryinterface.pro index af3b348..764f806 100644 --- a/WebKit/qt/tests/qwebhistoryinterface/qwebhistoryinterface.pro +++ b/WebKit/qt/tests/qwebhistoryinterface/qwebhistoryinterface.pro @@ -4,3 +4,8 @@ include(../../../../WebKit.pri) SOURCES += tst_qwebhistoryinterface.cpp QT += testlib network QMAKE_RPATHDIR = $$OUTPUT_DIR/lib $$QMAKE_RPATHDIR + +symbian { + TARGET.UID3 = 0xA000E53C + TARGET.CAPABILITY = ReadUserData WriteUserData NetworkServices +} diff --git a/WebKit/qt/tests/qwebinspector/qwebinspector.pro b/WebKit/qt/tests/qwebinspector/qwebinspector.pro new file mode 100644 index 0000000..520887e --- /dev/null +++ b/WebKit/qt/tests/qwebinspector/qwebinspector.pro @@ -0,0 +1,6 @@ +TEMPLATE = app +TARGET = tst_qwebinspector +include(../../../../WebKit.pri) +SOURCES += tst_qwebinspector.cpp +QT += testlib network +QMAKE_RPATHDIR = $$OUTPUT_DIR/lib $$QMAKE_RPATHDIR diff --git a/WebKit/qt/tests/qwebinspector/tst_qwebinspector.cpp b/WebKit/qt/tests/qwebinspector/tst_qwebinspector.cpp new file mode 100644 index 0000000..12cd630 --- /dev/null +++ b/WebKit/qt/tests/qwebinspector/tst_qwebinspector.cpp @@ -0,0 +1,68 @@ +/* + 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 <qdir.h> +#include <qwebinspector.h> +#include <qwebpage.h> +#include <qwebsettings.h> + +class tst_QWebInspector : public QObject { + Q_OBJECT + +private slots: + void attachAndDestroy(); +}; + +void tst_QWebInspector::attachAndDestroy() +{ + { // External inspector + manual destruction of page first + QWebPage* page = new QWebPage(); + page->settings()->setAttribute(QWebSettings::DeveloperExtrasEnabled, true); + QWebInspector* inspector = new QWebInspector(); + inspector->setPage(page); + page->updatePositionDependentActions(QPoint(0, 0)); + page->triggerAction(QWebPage::InspectElement); + + delete page; + delete inspector; + } + { // External inspector + manual destruction of inspector first + QWebPage* page = new QWebPage(); + page->settings()->setAttribute(QWebSettings::DeveloperExtrasEnabled, true); + QWebInspector* inspector = new QWebInspector(); + inspector->setPage(page); + page->updatePositionDependentActions(QPoint(0, 0)); + page->triggerAction(QWebPage::InspectElement); + + delete inspector; + delete page; + } + { // Internal inspector + QWebPage page; + page.settings()->setAttribute(QWebSettings::DeveloperExtrasEnabled, true); + page.updatePositionDependentActions(QPoint(0, 0)); + page.triggerAction(QWebPage::InspectElement); + } +} + +QTEST_MAIN(tst_QWebInspector) + +#include "tst_qwebinspector.moc" diff --git a/WebKit/qt/tests/qwebpage/qwebpage.pro b/WebKit/qt/tests/qwebpage/qwebpage.pro index 2f3a108..7853b28 100644 --- a/WebKit/qt/tests/qwebpage/qwebpage.pro +++ b/WebKit/qt/tests/qwebpage/qwebpage.pro @@ -5,3 +5,9 @@ SOURCES += tst_qwebpage.cpp RESOURCES += tst_qwebpage.qrc QT += testlib network QMAKE_RPATHDIR = $$OUTPUT_DIR/lib $$QMAKE_RPATHDIR +!symbian:DEFINES += SRCDIR=\\\"$$PWD/\\\" + +symbian { + TARGET.UID3 = 0xA000E53E + TARGET.CAPABILITY = ReadUserData WriteUserData NetworkServices +} diff --git a/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp b/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp index 966f049..2a52631 100644 --- a/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp +++ b/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp @@ -1,5 +1,6 @@ /* Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) + Copyright (C) 2009 Girish Ramakrishnan <girish@forwardbias.in> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -20,8 +21,13 @@ #include <QtTest/QtTest> +#include <qgraphicsscene.h> +#include <qgraphicsview.h> +#include <qgraphicswebview.h> +#include <qwebelement.h> #include <qwebpage.h> #include <qwidget.h> +#include <QGraphicsWidget> #include <qwebview.h> #include <qwebframe.h> #include <qwebhistory.h> @@ -32,6 +38,11 @@ #include <qwebsecurityorigin.h> #include <qwebdatabase.h> #include <QPushButton> +#include <QDir> + +#if defined(Q_OS_SYMBIAN) +# define SRCDIR "" +#endif // Will try to wait for the condition while allowing event processing #define QTRY_COMPARE(__expr, __expected) \ @@ -59,7 +70,7 @@ * \return \p true if the requested signal was received * \p false on timeout */ -static bool waitForSignal(QObject* obj, const char* signal, int timeout = 0) +static bool waitForSignal(QObject* obj, const char* signal, int timeout = 10000) { QEventLoop loop; QObject::connect(obj, signal, &loop, SLOT(quit())); @@ -74,6 +85,22 @@ static bool waitForSignal(QObject* obj, const char* signal, int timeout = 0) return timeoutSpy.isEmpty(); } +class EventSpy : public QObject, public QList<QEvent::Type> +{ + Q_OBJECT +public: + EventSpy(QObject* objectToSpy) + { + objectToSpy->installEventFilter(this); + } + + virtual bool eventFilter(QObject* receiver, QEvent* event) + { + append(event->type()); + return false; + } +}; + class tst_QWebPage : public QObject { Q_OBJECT @@ -100,7 +127,9 @@ private slots: void contextMenuCrash(); void database(); void createPlugin(); + void destroyPlugin_data(); void destroyPlugin(); + void createViewlessPlugin_data(); void createViewlessPlugin(); void multiplePageGroupsAndLocalStorage(); void cursorMovements(); @@ -110,9 +139,23 @@ private slots: void frameAt(); void requestCache(); void protectBindingsRuntimeObjectsFromCollector(); + void localURLSchemes(); + void testOptionalJSObjects(); + void testEnablePersistentStorage(); + void consoleOutput(); + void inputMethods_data(); + void inputMethods(); + void defaultTextEncoding(); + void errorPageExtension(); + void errorPageExtensionInIFrames(); + void errorPageExtensionInFrameset(); -private: + void crashTests_LazyInitializationOfMainFrame(); + + void screenshot_data(); + void screenshot(); + void originatingObjectInNetworkRequests(); private: QWebView* m_view; @@ -217,6 +260,8 @@ void tst_QWebPage::infiniteLoopJS() void tst_QWebPage::loadFinished() { + qRegisterMetaType<QWebFrame*>("QWebFrame*"); + qRegisterMetaType<QNetworkRequest*>("QNetworkRequest*"); QSignalSpy spyLoadStarted(m_view, SIGNAL(loadStarted())); QSignalSpy spyLoadFinished(m_view, SIGNAL(loadFinished(bool))); @@ -238,6 +283,31 @@ void tst_QWebPage::loadFinished() QCOMPARE(spyLoadFinished.count(), 1); } +class ConsolePage : public QWebPage +{ +public: + ConsolePage(QObject* parent = 0) : QWebPage(parent) {} + + virtual void javaScriptConsoleMessage(const QString& message, int lineNumber, const QString& sourceID) + { + messages.append(message); + lineNumbers.append(lineNumber); + sourceIDs.append(sourceID); + } + + QStringList messages; + QList<int> lineNumbers; + QStringList sourceIDs; +}; + +void tst_QWebPage::consoleOutput() +{ + ConsolePage page; + page.mainFrame()->evaluateJavaScript("this is not valid JavaScript"); + QCOMPARE(page.messages.count(), 1); + QCOMPARE(page.lineNumbers.at(0), 1); +} + class TestPage : public QWebPage { public: @@ -302,9 +372,11 @@ public: TestNetworkManager(QObject* parent) : QNetworkAccessManager(parent) {} QList<QUrl> requestedUrls; + QList<QNetworkRequest> requests; protected: virtual QNetworkReply* createRequest(Operation op, const QNetworkRequest &request, QIODevice* outgoingData) { + requests.append(request); requestedUrls.append(request.url()); return QNetworkAccessManager::createRequest(op, request, outgoingData); } @@ -316,13 +388,13 @@ void tst_QWebPage::userStyleSheet() 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_page->settings()->setUserStyleSheetUrl(QUrl("data:text/css;charset=utf-8;base64," + + QByteArray("p { background-image: url('http://does.not/exist.png');}").toBase64())); 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")); + QVERIFY(networkManager->requestedUrls.count() >= 1); + QCOMPARE(networkManager->requestedUrls.at(0), QUrl("http://does.not/exist.png")); } void tst_QWebPage::modified() @@ -378,7 +450,7 @@ void tst_QWebPage::modified() 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, SIGNAL(saveFrameStateRequested(QWebFrame*, QWebHistoryItem*)))); + QVERIFY(::waitForSignal(m_page, SIGNAL(saveFrameStateRequested(QWebFrame*,QWebHistoryItem*)))); } void tst_QWebPage::contextMenuCrash() @@ -405,13 +477,16 @@ void tst_QWebPage::database() QWebSettings::setOfflineStorageDefaultQuota(1024 * 1024); QVERIFY(QWebSettings::offlineStorageDefaultQuota() == 1024 * 1024); + m_page->settings()->setAttribute(QWebSettings::LocalStorageEnabled, true); + m_page->settings()->setAttribute(QWebSettings::OfflineStorageDatabaseEnabled, true); + QString dbFileName = path + "Databases.db"; if (QFile::exists(dbFileName)) QFile::remove(dbFileName); qRegisterMetaType<QWebFrame*>("QWebFrame*"); - QSignalSpy spy(m_page, SIGNAL(databaseQuotaExceeded(QWebFrame *, QString))); + QSignalSpy spy(m_page, SIGNAL(databaseQuotaExceeded(QWebFrame*,QString))); m_view->setHtml(QString("<html><head><script>var db; db=openDatabase('testdb', '1.0', 'test database API', 50000); </script></head><body><div></div></body></html>"), QUrl("http://www.myexample.com")); QTRY_COMPARE(spy.count(), 1); m_page->mainFrame()->evaluateJavaScript("var db2; db2=openDatabase('testdb', '1.0', 'test database API', 50000);"); @@ -432,14 +507,19 @@ void tst_QWebPage::database() m_page->mainFrame()->evaluateJavaScript("var db3; db3=openDatabase('testdb', '1.0', 'test database API', 50000);db3.transaction(function(tx) { tx.executeSql('CREATE TABLE IF NOT EXISTS Test (text TEXT)', []); }, function(tx, result) { }, function(tx, error) { });"); QTest::qWait(200); + // Remove all databases. QWebSecurityOrigin origin = m_page->mainFrame()->securityOrigin(); QList<QWebDatabase> dbs = origin.databases(); - if (dbs.count() > 0) { - QString fileName = dbs[0].fileName(); + for (int i = 0; i < dbs.count(); i++) { + QString fileName = dbs[i].fileName(); QVERIFY(QFile::exists(fileName)); - QWebDatabase::removeDatabase(dbs[0]); + QWebDatabase::removeDatabase(dbs[i]); QVERIFY(!QFile::exists(fileName)); } + QVERIFY(!origin.databases().size()); + // Remove removed test :-) + QWebDatabase::removeAllDatabases(); + QVERIFY(!origin.databases().size()); QTest::qWait(1000); } @@ -578,56 +658,121 @@ void tst_QWebPage::createPlugin() QCOMPARE(newPage->calls.count(), 0); } -class PluginTrackedPage : public QWebPage -{ + +// Standard base class for template PluginTracerPage. In tests it is used as interface. +class PluginCounterPage : public QWebPage { public: + int m_count; + QPointer<QObject> m_widget; + QObject* m_pluginParent; + PluginCounterPage(QObject* parent = 0) + : QWebPage(parent) + , m_count(0) + , m_widget(0) + , m_pluginParent(0) + { + settings()->setAttribute(QWebSettings::PluginsEnabled, true); + } + ~PluginCounterPage() + { + if (m_pluginParent) + m_pluginParent->deleteLater(); + } +}; - int count; - QPointer<QWidget> widget; +template<class T> +class PluginTracerPage : public PluginCounterPage { +public: + PluginTracerPage(QObject* parent = 0) + : PluginCounterPage(parent) + { + // this is a dummy parent object for the created plugin + m_pluginParent = new T; + } + virtual QObject* createPlugin(const QString&, const QUrl&, const QStringList&, const QStringList&) + { + m_count++; + m_widget = new T; + // need a cast to the specific type, as QObject::setParent cannot be called, + // because it is not virtual. Instead it is necesary to call QWidget::setParent, + // which also takes a QWidget* instead of a QObject*. Therefore we need to + // upcast to T*, which is a QWidget. + static_cast<T*>(m_widget.data())->setParent(static_cast<T*>(m_pluginParent)); + return m_widget; + } +}; - PluginTrackedPage(QWidget *parent = 0) : QWebPage(parent), count(0) { - settings()->setAttribute(QWebSettings::PluginsEnabled, true); +class PluginFactory { +public: + enum FactoredType {QWidgetType, QGraphicsWidgetType}; + static PluginCounterPage* create(FactoredType type, QObject* parent = 0) + { + PluginCounterPage* result = 0; + switch (type) { + case QWidgetType: + result = new PluginTracerPage<QWidget>(parent); + break; + case QGraphicsWidgetType: + result = new PluginTracerPage<QGraphicsWidget>(parent); + break; + default: {/*Oops*/}; + } + return result; } - virtual QObject* createPlugin(const QString&, const QUrl&, const QStringList&, const QStringList&) { - count++; - QWidget *w = new QWidget; - widget = w; - return w; + static void prepareTestData() + { + QTest::addColumn<int>("type"); + QTest::newRow("QWidget") << (int)PluginFactory::QWidgetType; + QTest::newRow("QGraphicsWidget") << (int)PluginFactory::QGraphicsWidgetType; } }; +void tst_QWebPage::destroyPlugin_data() +{ + PluginFactory::prepareTestData(); +} + void tst_QWebPage::destroyPlugin() { - PluginTrackedPage* page = new PluginTrackedPage(m_view); + QFETCH(int, type); + PluginCounterPage* page = PluginFactory::create((PluginFactory::FactoredType)type, m_view); m_view->setPage(page); // we create the plugin, so the widget should be constructed QString content("<html><body><object type=\"application/x-qt-plugin\" classid=\"QProgressBar\"></object></body></html>"); m_view->setHtml(content); - QVERIFY(page->widget != 0); - QCOMPARE(page->count, 1); + QVERIFY(page->m_widget); + QCOMPARE(page->m_count, 1); // navigate away, the plugin widget should be destructed m_view->setHtml("<html><body>Hi</body></html>"); QTestEventLoop::instance().enterLoop(1); - QVERIFY(page->widget == 0); + QVERIFY(!page->m_widget); +} + +void tst_QWebPage::createViewlessPlugin_data() +{ + PluginFactory::prepareTestData(); } void tst_QWebPage::createViewlessPlugin() { - PluginTrackedPage* page = new PluginTrackedPage; + QFETCH(int, type); + PluginCounterPage* page = PluginFactory::create((PluginFactory::FactoredType)type); QString content("<html><body><object type=\"application/x-qt-plugin\" classid=\"QProgressBar\"></object></body></html>"); page->mainFrame()->setHtml(content); - QCOMPARE(page->count, 1); - QVERIFY(page->widget != 0); + QCOMPARE(page->m_count, 1); + QVERIFY(page->m_widget); + QVERIFY(page->m_pluginParent); + QVERIFY(page->m_widget->parent() == page->m_pluginParent); delete page; + } // import private API void QWEBKIT_EXPORT qt_webpage_setGroupName(QWebPage* page, const QString& groupName); QString QWEBKIT_EXPORT qt_webpage_groupName(QWebPage* page); -void QWEBKIT_EXPORT qt_websettings_setLocalStorageDatabasePath(QWebSettings* settings, const QString& path); void tst_QWebPage::multiplePageGroupsAndLocalStorage() { @@ -638,9 +783,11 @@ void tst_QWebPage::multiplePageGroupsAndLocalStorage() QWebView view1; QWebView view2; - qt_websettings_setLocalStorageDatabasePath(view1.page()->settings(), QDir::toNativeSeparators(QDir::currentPath() + "/path1")); + view1.page()->settings()->setAttribute(QWebSettings::LocalStorageEnabled, true); + view1.page()->settings()->setLocalStoragePath(QDir::toNativeSeparators(QDir::currentPath() + "/path1")); qt_webpage_setGroupName(view1.page(), "group1"); - qt_websettings_setLocalStorageDatabasePath(view2.page()->settings(), QDir::toNativeSeparators(QDir::currentPath() + "/path2")); + view2.page()->settings()->setAttribute(QWebSettings::LocalStorageEnabled, true); + view2.page()->settings()->setLocalStoragePath(QDir::toNativeSeparators(QDir::currentPath() + "/path2")); qt_webpage_setGroupName(view2.page(), "group2"); QCOMPARE(qt_webpage_groupName(view1.page()), QString("group1")); QCOMPARE(qt_webpage_groupName(view2.page()), QString("group2")); @@ -1165,6 +1312,200 @@ void tst_QWebPage::frameAt() frameAtHelper(webPage, webPage->mainFrame(), webPage->mainFrame()->pos()); } +void tst_QWebPage::inputMethods_data() +{ + QTest::addColumn<QString>("viewType"); + QTest::newRow("QWebView") << "QWebView"; +#if QT_VERSION >= QT_VERSION_CHECK(4, 6, 0) + QTest::newRow("QGraphicsWebView") << "QGraphicsWebView"; +#endif +} + +#if QT_VERSION >= QT_VERSION_CHECK(4, 6, 0) +static Qt::InputMethodHints inputMethodHints(QObject* object) +{ + if (QGraphicsObject* o = qobject_cast<QGraphicsObject*>(object)) + return o->inputMethodHints(); + if (QWidget* w = qobject_cast<QWidget*>(object)) + return w->inputMethodHints(); + return Qt::InputMethodHints(); +} +#endif + +static bool inputMethodEnabled(QObject* object) +{ +#if QT_VERSION >= QT_VERSION_CHECK(4, 6, 0) + if (QGraphicsObject* o = qobject_cast<QGraphicsObject*>(object)) + return o->flags() & QGraphicsItem::ItemAcceptsInputMethod; +#endif + if (QWidget* w = qobject_cast<QWidget*>(object)) + return w->testAttribute(Qt::WA_InputMethodEnabled); + return false; +} + +void tst_QWebPage::inputMethods() +{ + QFETCH(QString, viewType); + QWebPage* page = new QWebPage; + QObject* view = 0; + QObject* container = 0; + if (viewType == "QWebView") { + QWebView* wv = new QWebView; + wv->setPage(page); + view = wv; + container = view; + } +#if QT_VERSION >= QT_VERSION_CHECK(4, 6, 0) + else if (viewType == "QGraphicsWebView") { + QGraphicsWebView* wv = new QGraphicsWebView; + wv->setPage(page); + view = wv; + + QGraphicsView* gv = new QGraphicsView; + QGraphicsScene* scene = new QGraphicsScene(gv); + gv->setScene(scene); + scene->addItem(wv); + wv->setGeometry(QRect(0, 0, 500, 500)); + + container = gv; + } +#endif + else + QVERIFY2(false, "Unknown view type"); + + page->mainFrame()->setHtml("<html><body>" \ + "<input type='text' id='input1' style='font-family: serif' value='' maxlength='20'/><br>" \ + "<input type='password'/>" \ + "</body></html>"); + page->mainFrame()->setFocus(); + + EventSpy viewEventSpy(container); + + QWebElementCollection inputs = page->mainFrame()->documentElement().findAll("input"); + + QMouseEvent evpres(QEvent::MouseButtonPress, inputs.at(0).geometry().center(), Qt::LeftButton, Qt::NoButton, Qt::NoModifier); + page->event(&evpres); + QMouseEvent evrel(QEvent::MouseButtonRelease, inputs.at(0).geometry().center(), Qt::LeftButton, Qt::NoButton, Qt::NoModifier); + page->event(&evrel); + +#if QT_VERSION >= QT_VERSION_CHECK(4, 6, 0) + QVERIFY(!viewEventSpy.contains(QEvent::RequestSoftwareInputPanel)); +#endif + viewEventSpy.clear(); + + page->event(&evpres); + page->event(&evrel); + +#if QT_VERSION >= QT_VERSION_CHECK(4, 6, 0) + QVERIFY(viewEventSpy.contains(QEvent::RequestSoftwareInputPanel)); +#endif + + //ImMicroFocus + QVariant variant = page->inputMethodQuery(Qt::ImMicroFocus); + QRect focusRect = variant.toRect(); + QVERIFY(inputs.at(0).geometry().contains(variant.toRect().topLeft())); + + //ImFont + variant = page->inputMethodQuery(Qt::ImFont); + QFont font = variant.value<QFont>(); + QCOMPARE(QString("-webkit-serif"), font.family()); + + QList<QInputMethodEvent::Attribute> inputAttributes; + + //Insert text. + { + QInputMethodEvent eventText("QtWebKit", inputAttributes); + QSignalSpy signalSpy(page, SIGNAL(microFocusChanged())); + page->event(&eventText); + QCOMPARE(signalSpy.count(), 0); + } + + { + QInputMethodEvent eventText("", inputAttributes); + eventText.setCommitString(QString("QtWebKit"), 0, 0); + page->event(&eventText); + } + +#if QT_VERSION >= 0x040600 + //ImMaximumTextLength + variant = page->inputMethodQuery(Qt::ImMaximumTextLength); + QCOMPARE(20, variant.toInt()); + + //Set selection + inputAttributes << QInputMethodEvent::Attribute(QInputMethodEvent::Selection, 3, 2, QVariant()); + QInputMethodEvent eventSelection("",inputAttributes); + page->event(&eventSelection); + + //ImAnchorPosition + variant = page->inputMethodQuery(Qt::ImAnchorPosition); + int anchorPosition = variant.toInt(); + QCOMPARE(anchorPosition, 3); + + //ImCursorPosition + variant = page->inputMethodQuery(Qt::ImCursorPosition); + int cursorPosition = variant.toInt(); + QCOMPARE(cursorPosition, 5); + + //ImCurrentSelection + variant = page->inputMethodQuery(Qt::ImCurrentSelection); + QString selectionValue = variant.value<QString>(); + QCOMPARE(selectionValue, QString("eb")); +#endif + + //ImSurroundingText + variant = page->inputMethodQuery(Qt::ImSurroundingText); + QString value = variant.value<QString>(); + QCOMPARE(value, QString("QtWebKit")); + +#if QT_VERSION >= 0x040600 + { + QList<QInputMethodEvent::Attribute> attributes; + // Clear the selection, so the next test does not clear any contents. + QInputMethodEvent::Attribute newSelection(QInputMethodEvent::Selection, 0, 0, QVariant()); + attributes.append(newSelection); + QInputMethodEvent event("composition", attributes); + page->event(&event); + } + + // A ongoing composition should not change the surrounding text before it is committed. + variant = page->inputMethodQuery(Qt::ImSurroundingText); + value = variant.value<QString>(); + QCOMPARE(value, QString("QtWebKit")); +#endif + + //ImhHiddenText + QMouseEvent evpresPassword(QEvent::MouseButtonPress, inputs.at(1).geometry().center(), Qt::LeftButton, Qt::NoButton, Qt::NoModifier); + page->event(&evpresPassword); + QMouseEvent evrelPassword(QEvent::MouseButtonRelease, inputs.at(1).geometry().center(), Qt::LeftButton, Qt::NoButton, Qt::NoModifier); + page->event(&evrelPassword); + + QVERIFY(inputMethodEnabled(view)); +#if QT_VERSION >= 0x040600 + QVERIFY(inputMethodHints(view) & Qt::ImhHiddenText); + + page->event(&evpres); + page->event(&evrel); + QVERIFY(!(inputMethodHints(view) & Qt::ImhHiddenText)); +#endif + + page->mainFrame()->setHtml("<html><body><p>nothing to input here"); + viewEventSpy.clear(); + + QWebElement para = page->mainFrame()->findFirstElement("p"); + { + QMouseEvent evpres(QEvent::MouseButtonPress, para.geometry().center(), Qt::LeftButton, Qt::NoButton, Qt::NoModifier); + page->event(&evpres); + QMouseEvent evrel(QEvent::MouseButtonRelease, para.geometry().center(), Qt::LeftButton, Qt::NoButton, Qt::NoModifier); + page->event(&evrel); + } + +#if QT_VERSION >= QT_VERSION_CHECK(4, 6, 0) + QVERIFY(!viewEventSpy.contains(QEvent::RequestSoftwareInputPanel)); +#endif + + delete container; +} + // import a little DRT helper function to trigger the garbage collector void QWEBKIT_EXPORT qt_drt_garbageCollector_collect(); @@ -1190,5 +1531,288 @@ void tst_QWebPage::protectBindingsRuntimeObjectsFromCollector() newPage->mainFrame()->evaluateJavaScript("testme('bar')"); } +void tst_QWebPage::localURLSchemes() +{ + int i = QWebSecurityOrigin::localSchemes().size(); + + QWebSecurityOrigin::removeLocalScheme("file"); + QTRY_COMPARE(QWebSecurityOrigin::localSchemes().size(), i); + QWebSecurityOrigin::addLocalScheme("file"); + QTRY_COMPARE(QWebSecurityOrigin::localSchemes().size(), i); + + QWebSecurityOrigin::removeLocalScheme("qrc"); + QTRY_COMPARE(QWebSecurityOrigin::localSchemes().size(), i - 1); + QWebSecurityOrigin::addLocalScheme("qrc"); + QTRY_COMPARE(QWebSecurityOrigin::localSchemes().size(), i); + + QString myscheme = "myscheme"; + QWebSecurityOrigin::addLocalScheme(myscheme); + QTRY_COMPARE(QWebSecurityOrigin::localSchemes().size(), i + 1); + QVERIFY(QWebSecurityOrigin::localSchemes().contains(myscheme)); + QWebSecurityOrigin::removeLocalScheme(myscheme); + QTRY_COMPARE(QWebSecurityOrigin::localSchemes().size(), i); + QWebSecurityOrigin::removeLocalScheme(myscheme); + QTRY_COMPARE(QWebSecurityOrigin::localSchemes().size(), i); +} + +static inline bool testFlag(QWebPage& webPage, QWebSettings::WebAttribute settingAttribute, const QString& jsObjectName, bool settingValue) +{ + webPage.settings()->setAttribute(settingAttribute, settingValue); + return webPage.mainFrame()->evaluateJavaScript(QString("(window.%1 != undefined)").arg(jsObjectName)).toBool(); +} + +void tst_QWebPage::testOptionalJSObjects() +{ + // Once a feature is enabled and the JS object is accessed turning off the setting will not turn off + // the visibility of the JS object any more. For this reason this test uses two QWebPage instances. + // Part of the test is to make sure that the QWebPage instances do not interfere with each other so turning on + // a feature for one instance will not turn it on for another. + + QWebPage webPage1; + QWebPage webPage2; + + webPage1.currentFrame()->setHtml(QString("<html><body>test</body></html>"), QUrl()); + webPage2.currentFrame()->setHtml(QString("<html><body>test</body></html>"), QUrl()); + + QEXPECT_FAIL("","Feature enabled/disabled checking problem. Look at bugs.webkit.org/show_bug.cgi?id=29867", Continue); + QCOMPARE(testFlag(webPage1, QWebSettings::OfflineWebApplicationCacheEnabled, "applicationCache", false), false); + QCOMPARE(testFlag(webPage2, QWebSettings::OfflineWebApplicationCacheEnabled, "applicationCache", true), true); + QEXPECT_FAIL("","Feature enabled/disabled checking problem. Look at bugs.webkit.org/show_bug.cgi?id=29867", Continue); + QCOMPARE(testFlag(webPage1, QWebSettings::OfflineWebApplicationCacheEnabled, "applicationCache", false), false); + QCOMPARE(testFlag(webPage2, QWebSettings::OfflineWebApplicationCacheEnabled, "applicationCache", false), true); + + QCOMPARE(testFlag(webPage1, QWebSettings::LocalStorageEnabled, "localStorage", false), false); + QCOMPARE(testFlag(webPage2, QWebSettings::LocalStorageEnabled, "localStorage", true), true); + QCOMPARE(testFlag(webPage1, QWebSettings::LocalStorageEnabled, "localStorage", false), false); + QCOMPARE(testFlag(webPage2, QWebSettings::LocalStorageEnabled, "localStorage", false), true); +} + +void tst_QWebPage::testEnablePersistentStorage() +{ + QWebPage webPage; + + // By default all persistent options should be disabled + QCOMPARE(webPage.settings()->testAttribute(QWebSettings::LocalStorageEnabled), false); + QCOMPARE(webPage.settings()->testAttribute(QWebSettings::OfflineStorageDatabaseEnabled), false); + QCOMPARE(webPage.settings()->testAttribute(QWebSettings::OfflineWebApplicationCacheEnabled), false); + QVERIFY(webPage.settings()->iconDatabasePath().isEmpty()); + + QWebSettings::enablePersistentStorage(); + + // Give it some time to initialize - icon database needs it + QTest::qWait(1000); + + QCOMPARE(webPage.settings()->testAttribute(QWebSettings::LocalStorageEnabled), true); + QCOMPARE(webPage.settings()->testAttribute(QWebSettings::OfflineStorageDatabaseEnabled), true); + QCOMPARE(webPage.settings()->testAttribute(QWebSettings::OfflineWebApplicationCacheEnabled), true); + + QVERIFY(!webPage.settings()->offlineStoragePath().isEmpty()); + QVERIFY(!webPage.settings()->offlineWebApplicationCachePath().isEmpty()); + QVERIFY(!webPage.settings()->iconDatabasePath().isEmpty()); +} + +void tst_QWebPage::defaultTextEncoding() +{ + QWebFrame* mainFrame = m_page->mainFrame(); + + QString defaultCharset = mainFrame->evaluateJavaScript("document.defaultCharset").toString(); + QVERIFY(!defaultCharset.isEmpty()); + QCOMPARE(QWebSettings::globalSettings()->defaultTextEncoding(), defaultCharset); + + m_page->settings()->setDefaultTextEncoding(QString("utf-8")); + QString charset = mainFrame->evaluateJavaScript("document.defaultCharset").toString(); + QCOMPARE(charset, QString("utf-8")); + QCOMPARE(m_page->settings()->defaultTextEncoding(), charset); + + m_page->settings()->setDefaultTextEncoding(QString()); + charset = mainFrame->evaluateJavaScript("document.defaultCharset").toString(); + QVERIFY(!charset.isEmpty()); + QCOMPARE(charset, defaultCharset); + + QWebSettings::globalSettings()->setDefaultTextEncoding(QString("utf-8")); + charset = mainFrame->evaluateJavaScript("document.defaultCharset").toString(); + QCOMPARE(charset, QString("utf-8")); + QCOMPARE(QWebSettings::globalSettings()->defaultTextEncoding(), charset); +} + +class ErrorPage : public QWebPage +{ +public: + + ErrorPage(QWidget* parent = 0): QWebPage(parent) + { + } + + virtual bool supportsExtension(Extension extension) const + { + return extension == ErrorPageExtension; + } + + virtual bool extension(Extension, const ExtensionOption* option, ExtensionReturn* output) + { + ErrorPageExtensionReturn* errorPage = static_cast<ErrorPageExtensionReturn*>(output); + + errorPage->content = "data:text/html,error"; + return true; + } +}; + +void tst_QWebPage::errorPageExtension() +{ + ErrorPage* page = new ErrorPage; + m_view->setPage(page); + + QSignalSpy spyLoadFinished(m_view, SIGNAL(loadFinished(bool))); + + m_view->setUrl(QUrl("data:text/html,foo")); + QTRY_COMPARE(spyLoadFinished.count(), 1); + + page->mainFrame()->setUrl(QUrl("http://non.existent/url")); + QTRY_COMPARE(spyLoadFinished.count(), 2); + QCOMPARE(page->mainFrame()->toPlainText(), QString("data:text/html,error")); + QCOMPARE(page->history()->count(), 2); + QCOMPARE(page->history()->currentItem().url(), QUrl("http://non.existent/url")); + QCOMPARE(page->history()->canGoBack(), true); + QCOMPARE(page->history()->canGoForward(), false); + + page->triggerAction(QWebPage::Back); + QTest::qWait(2000); + QCOMPARE(page->history()->canGoBack(), false); + QCOMPARE(page->history()->canGoForward(), true); + + page->triggerAction(QWebPage::Forward); + QTest::qWait(2000); + QCOMPARE(page->history()->canGoBack(), true); + QCOMPARE(page->history()->canGoForward(), false); + + page->triggerAction(QWebPage::Back); + QTest::qWait(2000); + QCOMPARE(page->history()->canGoBack(), false); + QCOMPARE(page->history()->canGoForward(), true); + QCOMPARE(page->history()->currentItem().url(), QUrl("data:text/html,foo")); + + m_view->setPage(0); +} + +void tst_QWebPage::errorPageExtensionInIFrames() +{ + ErrorPage* page = new ErrorPage; + m_view->setPage(page); + + m_view->setHtml(QString("data:text/html," + "<h1>h1</h1>" + "<iframe src='data:text/html,<p/>p'></iframe>" + "<iframe src='non-existent.html'></iframe>")); + QSignalSpy spyLoadFinished(m_view, SIGNAL(loadFinished(bool))); + QTRY_COMPARE(spyLoadFinished.count(), 1); + + QCOMPARE(page->mainFrame()->childFrames()[1]->toPlainText(), QString("data:text/html,error")); + + m_view->setPage(0); +} + +void tst_QWebPage::errorPageExtensionInFrameset() +{ + ErrorPage* page = new ErrorPage; + m_view->setPage(page); + + m_view->load(QUrl("qrc:///frametest/index.html")); + + QSignalSpy spyLoadFinished(m_view, SIGNAL(loadFinished(bool))); + QTRY_COMPARE(spyLoadFinished.count(), 1); + QCOMPARE(page->mainFrame()->childFrames()[1]->toPlainText(), QString("data:text/html,error")); + + m_view->setPage(0); +} + +void tst_QWebPage::crashTests_LazyInitializationOfMainFrame() +{ + { + QWebPage webPage; + } + { + QWebPage webPage; + webPage.selectedText(); + } + { + QWebPage webPage; + webPage.triggerAction(QWebPage::Back, true); + } + { + QWebPage webPage; + QPoint pos(10,10); + webPage.updatePositionDependentActions(pos); + } +} + +static void takeScreenshot(QWebPage* page) +{ + QWebFrame* mainFrame = page->mainFrame(); + page->setViewportSize(mainFrame->contentsSize()); + QImage image(page->viewportSize(), QImage::Format_ARGB32); + QPainter painter(&image); + mainFrame->render(&painter); + painter.end(); +} + +void tst_QWebPage::screenshot_data() +{ + QTest::addColumn<QString>("html"); + QTest::newRow("WithoutPlugin") << "<html><body id='b'>text</body></html>"; + QTest::newRow("WindowedPlugin") << QString("<html><body id='b'>text<embed src='resources/test.swf'></embed></body></html>"); + QTest::newRow("WindowlessPlugin") << QString("<html><body id='b'>text<embed src='resources/test.swf' wmode='transparent'></embed></body></html>"); +} + +void tst_QWebPage::screenshot() +{ + QDir::setCurrent(SRCDIR); + + QFETCH(QString, html); + QWebPage* page = new QWebPage; + page->settings()->setAttribute(QWebSettings::PluginsEnabled, true); + QWebFrame* mainFrame = page->mainFrame(); + mainFrame->setHtml(html, QUrl::fromLocalFile(QDir::currentPath())); + if (html.contains("</embed>")) { + // some reasonable time for the PluginStream to feed test.swf to flash and start painting + QTest::qWait(2000); + } + + // take screenshot without a view + takeScreenshot(page); + + QWebView* view = new QWebView; + view->setPage(page); + + // take screenshot when attached to a view + takeScreenshot(page); + + delete page; + delete view; + + QDir::setCurrent(QApplication::applicationDirPath()); +} + +void tst_QWebPage::originatingObjectInNetworkRequests() +{ + TestNetworkManager* networkManager = new TestNetworkManager(m_page); + m_page->setNetworkAccessManager(networkManager); + networkManager->requests.clear(); + + 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()); + QVERIFY(::waitForSignal(m_view, SIGNAL(loadFinished(bool)))); + + QCOMPARE(networkManager->requests.count(), 2); + + QList<QWebFrame*> childFrames = m_page->mainFrame()->childFrames(); + QCOMPARE(childFrames.count(), 2); + +#if QT_VERSION >= QT_VERSION_CHECK(4, 6, 0) + for (int i = 0; i < 2; ++i) + QVERIFY(qobject_cast<QWebFrame*>(networkManager->requests.at(i).originatingObject()) == childFrames.at(i)); +#endif +} + QTEST_MAIN(tst_QWebPage) #include "tst_qwebpage.moc" diff --git a/WebKit/qt/tests/qwebplugindatabase/qwebplugindatabase.pro b/WebKit/qt/tests/qwebplugindatabase/qwebplugindatabase.pro index 5d10993..569146a 100644 --- a/WebKit/qt/tests/qwebplugindatabase/qwebplugindatabase.pro +++ b/WebKit/qt/tests/qwebplugindatabase/qwebplugindatabase.pro @@ -4,3 +4,8 @@ include(../../../../WebKit.pri) SOURCES += tst_qwebplugindatabase.cpp QT += testlib network QMAKE_RPATHDIR = $$OUTPUT_DIR/lib $$QMAKE_RPATHDIR + +symbian { + TARGET.UID3 = 0xA000E540 + TARGET.CAPABILITY = ReadUserData WriteUserData NetworkServices +} diff --git a/WebKit/qt/tests/qwebplugindatabase/tst_qwebplugindatabase.cpp b/WebKit/qt/tests/qwebplugindatabase/tst_qwebplugindatabase.cpp index c0533ad..1ee6206 100644 --- a/WebKit/qt/tests/qwebplugindatabase/tst_qwebplugindatabase.cpp +++ b/WebKit/qt/tests/qwebplugindatabase/tst_qwebplugindatabase.cpp @@ -40,6 +40,8 @@ private slots: void operatorequal_data(); void operatorequal(); void preferredPlugin(); + void operatorassign_data(); + void operatorassign(); }; typedef QWebPluginInfo::MimeType MimeType; @@ -396,6 +398,40 @@ void tst_QWebPluginDatabase::preferredPlugin() } } +void tst_QWebPluginDatabase::operatorassign_data() +{ + QTest::addColumn<QWebPluginInfo>("first"); + QTest::addColumn<QWebPluginInfo>("second"); + + QWebPluginDatabase* database = QWebSettings::pluginDatabase(); + QTest::newRow("null") << QWebPluginInfo() << QWebPluginInfo(); + + QList<QWebPluginInfo> plugins = database->plugins(); + for (int i = 0; i < (plugins.count() - 1); ++i) { + QWebPluginInfo first = plugins.at(i); + QWebPluginInfo second = plugins.at(i + 1); + + QTest::newRow(QString("%1=%2").arg(first.name(), second.name()).toUtf8().constData()) << first << second; + } +} + +void tst_QWebPluginDatabase::operatorassign() +{ + QFETCH(QWebPluginInfo, first); + QFETCH(QWebPluginInfo, second); + + QWebPluginInfo info; + QCOMPARE(info.mimeTypes(), QList<MimeType>()); + QCOMPARE(info = first, first); + QCOMPARE(info, first); + QCOMPARE(info.mimeTypes(), first.mimeTypes()); + QCOMPARE(info = second, second); + QCOMPARE(info, second); + QCOMPARE(info.mimeTypes(), second.mimeTypes()); + QCOMPARE(info = QWebPluginInfo(), QWebPluginInfo()); + QCOMPARE(info.mimeTypes(), QList<MimeType>()); +} + QTEST_MAIN(tst_QWebPluginDatabase) #include "tst_qwebplugindatabase.moc" diff --git a/WebKit/qt/tests/qwebview/data/frame_a.html b/WebKit/qt/tests/qwebview/data/frame_a.html new file mode 100644 index 0000000..9ff68f1 --- /dev/null +++ b/WebKit/qt/tests/qwebview/data/frame_a.html @@ -0,0 +1,2 @@ +<a href="http://google.com" target="frame_b"><img src="" width=100 height=100 alt="Google"></a> +<a href="http://yahoo.com" target="frame_b"><img src="" width=100 height=100 alt="Yahoo"></a> diff --git a/WebKit/qt/tests/qwebview/data/index.html b/WebKit/qt/tests/qwebview/data/index.html new file mode 100644 index 0000000..c53ad09 --- /dev/null +++ b/WebKit/qt/tests/qwebview/data/index.html @@ -0,0 +1,4 @@ +<frameset cols="25%,75%"> + <frame src="frame_a.html" name="frame_a"> + <frame src="frame_b.html" name="frame_b"> +</frameset> diff --git a/WebKit/qt/tests/qwebview/qwebview.pro b/WebKit/qt/tests/qwebview/qwebview.pro index 799ccfb..735537b 100644 --- a/WebKit/qt/tests/qwebview/qwebview.pro +++ b/WebKit/qt/tests/qwebview/qwebview.pro @@ -4,3 +4,10 @@ include(../../../../WebKit.pri) SOURCES += tst_qwebview.cpp QT += testlib network QMAKE_RPATHDIR = $$OUTPUT_DIR/lib $$QMAKE_RPATHDIR +RESOURCES += tst_qwebview.qrc +DEFINES += SRCDIR=\\\"$$PWD/\\\" + +symbian { + TARGET.UID3 = 0xA000E53F + TARGET.CAPABILITY = ReadUserData WriteUserData NetworkServices +} diff --git a/WebKit/qt/tests/qwebview/tst_qwebview.cpp b/WebKit/qt/tests/qwebview/tst_qwebview.cpp index 01d0e92..bd2f185 100644 --- a/WebKit/qt/tests/qwebview/tst_qwebview.cpp +++ b/WebKit/qt/tests/qwebview/tst_qwebview.cpp @@ -1,6 +1,7 @@ /* Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies) Copyright (C) 2009 Torch Mobile Inc. + Copyright (C) 2009 Girish Ramakrishnan <girish@forwardbias.in> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -19,6 +20,7 @@ */ #include <qtest.h> +#include "../util.h" #include <qpainter.h> #include <qwebview.h> @@ -26,6 +28,7 @@ #include <qnetworkrequest.h> #include <qdiriterator.h> #include <qwebkitversion.h> +#include <qwebframe.h> class tst_QWebView : public QObject { @@ -39,9 +42,12 @@ public slots: private slots: void renderHints(); - void guessUrlFromString_data(); - void guessUrlFromString(); void getWebKitVersion(); + + void reusePage_data(); + void reusePage(); + + void crashTests(); }; // This will be called before the first test function is executed. @@ -100,73 +106,91 @@ void tst_QWebView::renderHints() QVERIFY(!(webView.renderHints() & QPainter::HighQualityAntialiasing)); } -void tst_QWebView::guessUrlFromString_data() +void tst_QWebView::getWebKitVersion() { - QTest::addColumn<QString>("string"); - QTest::addColumn<QUrl>("guessUrlFromString"); - - // Null - QTest::newRow("null") << QString() << QUrl(); - - // File - QDirIterator it(QDir::homePath()); - QString fileString; - int c = 0; - while (it.hasNext()) { - it.next(); - QTest::newRow(QString("file-%1").arg(c++).toLatin1()) << it.filePath() << QUrl::fromLocalFile(it.filePath()); - } + QVERIFY(qWebKitVersion().toDouble() > 0); +} - // basic latin1 - QTest::newRow("unicode-0") << QString::fromUtf8("å.com/") << QUrl::fromEncoded(QString::fromUtf8("http://å.com/").toUtf8(), QUrl::TolerantMode); - // unicode - QTest::newRow("unicode-1") << QString::fromUtf8("λ.com/") << QUrl::fromEncoded(QString::fromUtf8("http://λ.com/").toUtf8(), QUrl::TolerantMode); - - // no scheme - QTest::newRow("add scheme-0") << "webkit.org" << QUrl("http://webkit.org"); - QTest::newRow("add scheme-1") << "www.webkit.org" << QUrl("http://www.webkit.org"); - QTest::newRow("add scheme-2") << "ftp.webkit.org" << QUrl("ftp://ftp.webkit.org"); - QTest::newRow("add scheme-3") << "webkit" << QUrl("webkit"); - - // QUrl's tolerant parser should already handle this - QTest::newRow("not-encoded-0") << "http://webkit.org/test page.html" << QUrl("http://webkit.org/test%20page.html"); - - // Make sure the :80, i.e. port doesn't screw anything up - QUrl portUrl("http://webkit.org"); - portUrl.setPort(80); - QTest::newRow("port-0") << "webkit.org:80" << portUrl; - QTest::newRow("port-1") << "http://webkit.org:80" << portUrl; - - // mailto doesn't have a ://, but is valid - QUrl mailto("ben@meyerhome.net"); - mailto.setScheme("mailto"); - QTest::newRow("mailto") << "mailto:ben@meyerhome.net" << mailto; - - // misc - QTest::newRow("localhost-0") << "localhost" << QUrl("http://localhost"); - QTest::newRow("localhost-1") << "localhost:80" << QUrl("http://localhost:80"); - QTest::newRow("spaces-0") << " http://webkit.org/test page.html " << QUrl("http://webkit.org/test%20page.html"); - - // FYI: The scheme in the resulting url user - QUrl authUrl("user:pass@domain.com"); - QTest::newRow("misc-1") << "user:pass@domain.com" << authUrl; +void tst_QWebView::reusePage_data() +{ + QTest::addColumn<QString>("html"); + QTest::newRow("WithoutPlugin") << "<html><body id='b'>text</body></html>"; + QTest::newRow("WindowedPlugin") << QString("<html><body id='b'>text<embed src='resources/test.swf'></embed></body></html>"); + QTest::newRow("WindowlessPlugin") << QString("<html><body id='b'>text<embed src='resources/test.swf' wmode=\"transparent\"></embed></body></html>"); } -// public static QUrl guessUrlFromString(QString const& string) -void tst_QWebView::guessUrlFromString() +void tst_QWebView::reusePage() { - QFETCH(QString, string); - QFETCH(QUrl, guessUrlFromString); + QDir::setCurrent(SRCDIR); + + QFETCH(QString, html); + QWebView* view1 = new QWebView; + QPointer<QWebPage> page = new QWebPage; + view1->setPage(page); + page->settings()->setAttribute(QWebSettings::PluginsEnabled, true); + QWebFrame* mainFrame = page->mainFrame(); + mainFrame->setHtml(html, QUrl::fromLocalFile(QDir::currentPath())); + if (html.contains("</embed>")) { + // some reasonable time for the PluginStream to feed test.swf to flash and start painting + waitForSignal(view1, SIGNAL(loadFinished(bool)), 2000); + } + + view1->show(); + QTest::qWaitForWindowShown(view1); + delete view1; + QVERIFY(page != 0); // deleting view must not have deleted the page, since it's not a child of view - QUrl url = QWebView::guessUrlFromString(string); - QCOMPARE(url, guessUrlFromString); + QWebView *view2 = new QWebView; + view2->setPage(page); + view2->show(); // in Windowless mode, you should still be able to see the plugin here + QTest::qWaitForWindowShown(view2); + delete view2; + + delete page; // must not crash + + QDir::setCurrent(QApplication::applicationDirPath()); } -void tst_QWebView::getWebKitVersion() +// Class used in crashTests +class WebViewCrashTest : public QObject { + Q_OBJECT + QWebView* m_view; +public: + bool m_executed; + + + WebViewCrashTest(QWebView* view) + : m_view(view) + , m_executed(false) + { + view->connect(view, SIGNAL(loadProgress(int)), this, SLOT(loading(int))); + } + +private slots: + void loading(int progress) + { + if (progress >= 20 && progress < 90) { + QVERIFY(!m_executed); + m_view->stop(); + m_executed = true; + } + } +}; + + +// Should not crash. +void tst_QWebView::crashTests() { - QVERIFY(qWebKitVersion().toDouble() > 0); + // Test if loading can be stopped in loadProgress handler without crash. + // Test page should have frames. + QWebView view; + WebViewCrashTest tester(&view); + QUrl url("qrc:///data/index.html"); + view.load(url); + QTRY_VERIFY(tester.m_executed); // If fail it means that the test wasn't executed. } + QTEST_MAIN(tst_QWebView) #include "tst_qwebview.moc" diff --git a/WebKit/qt/tests/qwebview/tst_qwebview.qrc b/WebKit/qt/tests/qwebview/tst_qwebview.qrc new file mode 100644 index 0000000..ede34a9 --- /dev/null +++ b/WebKit/qt/tests/qwebview/tst_qwebview.qrc @@ -0,0 +1,7 @@ +<!DOCTYPE RCC><RCC version="1.0"> +<qresource> + <file>data/index.html</file> + <file>data/frame_a.html</file> +</qresource> +</RCC> + diff --git a/WebKit/qt/tests/resources/test.swf b/WebKit/qt/tests/resources/test.swf Binary files differnew file mode 100644 index 0000000..8952982 --- /dev/null +++ b/WebKit/qt/tests/resources/test.swf diff --git a/WebKit/qt/tests/tests.pro b/WebKit/qt/tests/tests.pro index b5f66ee..b967ca9 100644 --- a/WebKit/qt/tests/tests.pro +++ b/WebKit/qt/tests/tests.pro @@ -1,4 +1,4 @@ TEMPLATE = subdirs -SUBDIRS = qwebframe qwebpage qwebelement qwebhistoryinterface qwebplugindatabase qwebview qwebhistory +SUBDIRS = qwebframe qwebpage qwebelement qgraphicswebview qwebhistoryinterface qwebview qwebhistory qwebinspector greaterThan(QT_MINOR_VERSION, 4): SUBDIRS += benchmarks/painting/tst_painting.pro benchmarks/loading/tst_loading.pro diff --git a/WebKit/qt/tests/util.h b/WebKit/qt/tests/util.h new file mode 100644 index 0000000..15af262 --- /dev/null +++ b/WebKit/qt/tests/util.h @@ -0,0 +1,74 @@ +/* + Copyright (C) 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. +*/ +// Functions and macros that really need to be in QTestLib + +#include <QEventLoop> +#include <QSignalSpy> +#include <QTimer> + +/** + * 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 = 10000) +{ + 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(); +} + +// Will try to wait for the condition while allowing event processing +#define QTRY_VERIFY(__expr) \ + do { \ + const int __step = 50; \ + const int __timeout = 5000; \ + if (!(__expr)) { \ + QTest::qWait(0); \ + } \ + for (int __i = 0; __i < __timeout && !(__expr); __i+=__step) { \ + QTest::qWait(__step); \ + } \ + QVERIFY(__expr); \ + } while(0) + +// 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) |
