/* 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 <qwebelement.h> #include <util.h> //TESTED_CLASS= //TESTED_FILES= class tst_QWebElement : public QObject { Q_OBJECT public: tst_QWebElement(); virtual ~tst_QWebElement(); public slots: void init(); void cleanup(); private slots: void textHtml(); void simpleCollection(); void attributes(); void attributesNS(); void listAttributes(); void classes(); void namespaceURI(); void iteration(); void nonConstIterator(); void constIterator(); void foreachManipulation(); void emptyCollection(); void appendCollection(); void evaluateJavaScript(); void documentElement(); void frame(); void style(); void computedStyle(); void appendAndPrepend(); void insertBeforeAndAfter(); void remove(); void clear(); void replaceWith(); void encloseWith(); void encloseContentsWith(); void nullSelect(); void firstChildNextSibling(); void lastChildPreviousSibling(); void hasSetFocus(); void render(); void addElementToHead(); private: QWebView* m_view; QWebPage* m_page; QWebFrame* m_mainFrame; }; tst_QWebElement::tst_QWebElement() { } tst_QWebElement::~tst_QWebElement() { } void tst_QWebElement::init() { m_view = new QWebView(); m_page = m_view->page(); m_mainFrame = m_page->mainFrame(); } void tst_QWebElement::cleanup() { delete m_view; } void tst_QWebElement::textHtml() { QString html = "<head></head><body><p>test</p></body>"; m_mainFrame->setHtml(html); QWebElement body = m_mainFrame->documentElement(); QVERIFY(!body.isNull()); QCOMPARE(body.toPlainText(), QString("test")); QCOMPARE(body.toPlainText(), m_mainFrame->toPlainText()); QCOMPARE(body.toInnerXml(), html); } void tst_QWebElement::simpleCollection() { QString html = "<body><p>first para</p><p>second para</p></body>"; m_mainFrame->setHtml(html); QWebElement body = m_mainFrame->documentElement(); 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")); } void tst_QWebElement::attributes() { m_mainFrame->setHtml("<body><p>Test"); QWebElement body = m_mainFrame->documentElement(); QVERIFY(!body.hasAttribute("title")); QVERIFY(!body.hasAttributes()); body.setAttribute("title", "test title"); QVERIFY(body.hasAttributes()); QVERIFY(body.hasAttribute("title")); QCOMPARE(body.attribute("title"), QString("test title")); body.removeAttribute("title"); QVERIFY(!body.hasAttribute("title")); QVERIFY(!body.hasAttributes()); QCOMPARE(body.attribute("does-not-exist", "testvalue"), QString("testvalue")); } void tst_QWebElement::attributesNS() { QString content = "<html xmlns=\"http://www.w3.org/1999/xhtml\" " "xmlns:svg=\"http://www.w3.org/2000/svg\">" "<body><svg:svg id=\"foobar\" width=\"400px\" height=\"300px\">" "</svg:svg></body></html>"; m_mainFrame->setContent(content.toUtf8(), "application/xhtml+xml"); QWebElement svg = m_mainFrame->findFirstElement("svg"); QVERIFY(!svg.isNull()); QVERIFY(!svg.hasAttributeNS("http://www.w3.org/2000/svg", "foobar")); QCOMPARE(svg.attributeNS("http://www.w3.org/2000/svg", "foobar", "defaultblah"), QString("defaultblah")); svg.setAttributeNS("http://www.w3.org/2000/svg", "svg:foobar", "true"); QVERIFY(svg.hasAttributeNS("http://www.w3.org/2000/svg", "foobar")); 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"); QWebElement body = m_mainFrame->documentElement(); QCOMPARE(body.classes().count(), 0); QWebElement p = m_mainFrame->documentElement().findAll("p").at(0); QStringList classes = p.classes(); QCOMPARE(classes.count(), 4); QCOMPARE(classes[0], QLatin1String("a")); QCOMPARE(classes[1], QLatin1String("b")); QCOMPARE(classes[2], QLatin1String("c")); QCOMPARE(classes[3], QLatin1String("d")); QVERIFY(p.hasClass("a")); QVERIFY(p.hasClass("b")); QVERIFY(p.hasClass("c")); QVERIFY(p.hasClass("d")); QVERIFY(!p.hasClass("e")); p.addClass("f"); QVERIFY(p.hasClass("f")); p.addClass("a"); QCOMPARE(p.classes().count(), 5); QVERIFY(p.hasClass("a")); QVERIFY(p.hasClass("b")); QVERIFY(p.hasClass("c")); QVERIFY(p.hasClass("d")); p.toggleClass("a"); QVERIFY(!p.hasClass("a")); QVERIFY(p.hasClass("b")); QVERIFY(p.hasClass("c")); QVERIFY(p.hasClass("d")); QVERIFY(p.hasClass("f")); QCOMPARE(p.classes().count(), 4); p.toggleClass("f"); QVERIFY(!p.hasClass("f")); QCOMPARE(p.classes().count(), 3); p.toggleClass("a"); p.toggleClass("f"); QVERIFY(p.hasClass("a")); QVERIFY(p.hasClass("f")); QCOMPARE(p.classes().count(), 5); p.removeClass("f"); QVERIFY(!p.hasClass("f")); QCOMPARE(p.classes().count(), 4); p.removeClass("d"); QVERIFY(!p.hasClass("d")); QCOMPARE(p.classes().count(), 3); p.removeClass("not-exist"); QCOMPARE(p.classes().count(), 3); p.removeClass("c"); QVERIFY(!p.hasClass("c")); QCOMPARE(p.classes().count(), 2); p.removeClass("b"); QVERIFY(!p.hasClass("b")); QCOMPARE(p.classes().count(), 1); p.removeClass("a"); QVERIFY(!p.hasClass("a")); QCOMPARE(p.classes().count(), 0); p.removeClass("foobar"); QCOMPARE(p.classes().count(), 0); } void tst_QWebElement::namespaceURI() { QString content = "<html xmlns=\"http://www.w3.org/1999/xhtml\" " "xmlns:svg=\"http://www.w3.org/2000/svg\">" "<body><svg:svg id=\"foobar\" width=\"400px\" height=\"300px\">" "</svg:svg></body></html>"; m_mainFrame->setContent(content.toUtf8(), "application/xhtml+xml"); QWebElement body = m_mainFrame->documentElement(); QCOMPARE(body.namespaceUri(), QLatin1String("http://www.w3.org/1999/xhtml")); QWebElement svg = body.findAll("*#foobar").at(0); QCOMPARE(svg.prefix(), QLatin1String("svg")); QCOMPARE(svg.localName(), QLatin1String("svg")); QCOMPARE(svg.tagName(), QLatin1String("svg:svg")); QCOMPARE(svg.namespaceUri(), QLatin1String("http://www.w3.org/2000/svg")); } 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>"; m_mainFrame->setHtml(html); QWebElement body = m_mainFrame->documentElement(); foreach(QWebElement p, body.findAll("p")) { p.setInnerXml("<div>foo</div><div>bar</div>"); } QCOMPARE(body.findAll("div").count(), 4); } 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.evaluateJavaScript("this.tagName"); QVERIFY(result.isValid()); QVERIFY(result.type() == QVariant::String); QCOMPARE(result.toString(), QLatin1String("P")); result = para.evaluateJavaScript("this.hasAttributes()"); QVERIFY(result.isValid()); QVERIFY(result.type() == QVariant::Bool); QVERIFY(!result.toBool()); para.evaluateJavaScript("this.setAttribute('align', 'left');"); QCOMPARE(para.attribute("align"), QLatin1String("left")); result = para.evaluateJavaScript("this.hasAttributes()"); QVERIFY(result.isValid()); QVERIFY(result.type() == QVariant::Bool); QVERIFY(result.toBool()); } void tst_QWebElement::documentElement() { m_mainFrame->setHtml("<body><p>Test"); QWebElement para = m_mainFrame->documentElement().findAll("p").at(0); QVERIFY(para.parent().parent() == m_mainFrame->documentElement()); QVERIFY(para.document() == m_mainFrame->documentElement()); } void tst_QWebElement::frame() { m_mainFrame->setHtml("<body><p>test"); QWebElement doc = m_mainFrame->documentElement(); QVERIFY(doc.webFrame() == m_mainFrame); m_mainFrame->load(QUrl("data:text/html,<frameset cols=\"25%,75%\"><frame src=\"data:text/html," "<p>frame1\">" "<frame src=\"data:text/html,<p>frame2\"></frameset>")); waitForSignal(m_page, SIGNAL(loadFinished(bool))); QCOMPARE(m_mainFrame->childFrames().count(), 2); QWebFrame* firstFrame = m_mainFrame->childFrames().at(0); QWebFrame* secondFrame = m_mainFrame->childFrames().at(1); QCOMPARE(firstFrame->toPlainText(), QString("frame1")); QCOMPARE(secondFrame->toPlainText(), QString("frame2")); QWebElement firstPara = firstFrame->documentElement().findAll("p").at(0); QWebElement secondPara = secondFrame->documentElement().findAll("p").at(0); QVERIFY(firstPara.webFrame() == firstFrame); QVERIFY(secondPara.webFrame() == secondFrame); } void tst_QWebElement::style() { QString html = "<head>" "<style type='text/css'>" "p { color: green !important }" "#idP { color: red }" ".classP { color : yellow ! important }" "</style>" "</head>" "<body>" "<p id='idP' class='classP' style='color: blue;'>some text</p>" "</body>"; m_mainFrame->setHtml(html); QWebElement p = m_mainFrame->documentElement().findAll("p").at(0); 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", 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", QWebElement::InlineStyle), QLatin1String("green")); QCOMPARE(p.styleProperty("color", QWebElement::CascadedStyle), QLatin1String("green")); p.setStyleProperty("color", "blue"); QCOMPARE(p.styleProperty("color", QWebElement::InlineStyle), QLatin1String("blue")); QCOMPARE(p.styleProperty("color", QWebElement::CascadedStyle), QLatin1String("green")); 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'>" "p { color: green }" "#idP { color: red }" ".classP { color: yellow }" "</style>" "</head>" "<body>" "<p id='idP' class='classP' style='color: blue;'>some text</p>" "</body>"; m_mainFrame->setHtml(html2); p = m_mainFrame->documentElement().findAll("p").at(0); QCOMPARE(p.styleProperty("color", QWebElement::InlineStyle), QLatin1String("blue")); QCOMPARE(p.styleProperty("color", QWebElement::CascadedStyle), QLatin1String("blue")); QString html3 = "<head>" "<style type='text/css'>" "p { color: green !important }" "#idP { color: red !important}" ".classP { color: yellow !important}" "</style>" "</head>" "<body>" "<p id='idP' class='classP' style='color: blue !important;'>some text</p>" "</body>"; m_mainFrame->setHtml(html3); p = m_mainFrame->documentElement().findAll("p").at(0); QCOMPARE(p.styleProperty("color", QWebElement::InlineStyle), QLatin1String("blue")); QCOMPARE(p.styleProperty("color", QWebElement::CascadedStyle), QLatin1String("blue")); QString html5 = "<head>" "<style type='text/css'>" "p { color: green }" "#idP { color: red }" ".classP { color: yellow }" "</style>" "</head>" "<body>" "<p id='idP' class='classP'>some text</p>" "</body>"; m_mainFrame->setHtml(html5); p = m_mainFrame->documentElement().findAll("p").at(0); 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' />" "<style type='text/css'>" "p { color: green }" "#idP { color: red }" ".classP { color: yellow ! important}" "</style>" "</head>" "<body>" "<p id='idP' class='classP' style='color: blue;'>some text</p>" "</body>"; // in few seconds, the CSS should be completey loaded m_mainFrame->setHtml(html6); waitForSignal(m_page, SIGNAL(loadFinished(bool)), 200); p = m_mainFrame->documentElement().findAll("p").at(0); QCOMPARE(p.styleProperty("color", QWebElement::InlineStyle), QLatin1String("blue")); QCOMPARE(p.styleProperty("color", QWebElement::CascadedStyle), QLatin1String("black")); QString html7 = "<head>" "<style type='text/css'>" "@import url(qrc:/style2.css);" "</style>" "<link rel='stylesheet' href='qrc:/style.css' type='text/css' />" "</head>" "<body>" "<p id='idP' style='color: blue;'>some text</p>" "</body>"; // in few seconds, the style should be completey loaded m_mainFrame->setHtml(html7); waitForSignal(m_page, SIGNAL(loadFinished(bool)), 200); p = m_mainFrame->documentElement().findAll("p").at(0); 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", QWebElement::InlineStyle), QLatin1String("")); QCOMPARE(p.styleProperty("color", QWebElement::CascadedStyle), QLatin1String("")); } void tst_QWebElement::computedStyle() { QString html = "<body><p>some text</p></body>"; m_mainFrame->setHtml(html); QWebElement p = m_mainFrame->documentElement().findAll("p").at(0); 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.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() { QString html = "<body>" "<p>" "foo" "</p>" "<p>" "bar" "</p>" "</body>"; m_mainFrame->setHtml(html); QWebElement body = m_mainFrame->documentElement().findFirst("body"); QCOMPARE(body.findAll("p").count(), 2); body.appendInside(body.findFirst("p")); QCOMPARE(body.findAll("p").count(), 2); QCOMPARE(body.findFirst("p").toPlainText(), QString("bar")); QCOMPARE(body.findAll("p").last().toPlainText(), QString("foo")); body.appendInside(body.findFirst("p").clone()); QCOMPARE(body.findAll("p").count(), 3); QCOMPARE(body.findFirst("p").toPlainText(), QString("bar")); QCOMPARE(body.findAll("p").last().toPlainText(), QString("bar")); body.prependInside(body.findAll("p").at(1).clone()); QCOMPARE(body.findAll("p").count(), 4); QCOMPARE(body.findFirst("p").toPlainText(), QString("foo")); body.findFirst("p").appendInside("<div>booyakasha</div>"); QCOMPARE(body.findAll("p div").count(), 1); QCOMPARE(body.findFirst("p div").toPlainText(), QString("booyakasha")); body.findFirst("div").prependInside("<code>yepp</code>"); QCOMPARE(body.findAll("p div code").count(), 1); QCOMPARE(body.findFirst("p div code").toPlainText(), QString("yepp")); } void tst_QWebElement::insertBeforeAndAfter() { QString html = "<body>" "<p>" "foo" "</p>" "<div>" "yeah" "</div>" "<p>" "bar" "</p>" "</body>"; m_mainFrame->setHtml(html); QWebElement body = m_mainFrame->documentElement().findFirst("body"); QWebElement div = body.findFirst("div"); QCOMPARE(body.findAll("p").count(), 2); QCOMPARE(body.findAll("div").count(), 1); div.prependOutside(body.findAll("p").last().clone()); QCOMPARE(body.findAll("p").count(), 3); QCOMPARE(body.findAll("p").at(0).toPlainText(), QString("foo")); QCOMPARE(body.findAll("p").at(1).toPlainText(), QString("bar")); QCOMPARE(body.findAll("p").at(2).toPlainText(), QString("bar")); div.appendOutside(body.findFirst("p").clone()); QCOMPARE(body.findAll("p").count(), 4); QCOMPARE(body.findAll("p").at(0).toPlainText(), QString("foo")); QCOMPARE(body.findAll("p").at(1).toPlainText(), QString("bar")); QCOMPARE(body.findAll("p").at(2).toPlainText(), QString("foo")); QCOMPARE(body.findAll("p").at(3).toPlainText(), QString("bar")); div.prependOutside("<span>hey</span>"); QCOMPARE(body.findAll("span").count(), 1); div.appendOutside("<span>there</span>"); QCOMPARE(body.findAll("span").count(), 2); QCOMPARE(body.findAll("span").at(0).toPlainText(), QString("hey")); QCOMPARE(body.findAll("span").at(1).toPlainText(), QString("there")); } void tst_QWebElement::remove() { QString html = "<body>" "<p>" "foo" "</p>" "<div>" "<p>yeah</p>" "</div>" "<p>" "bar" "</p>" "</body>"; m_mainFrame->setHtml(html); QWebElement body = m_mainFrame->documentElement().findFirst("body"); QCOMPARE(body.findAll("div").count(), 1); QCOMPARE(body.findAll("p").count(), 3); QWebElement div = body.findFirst("div"); div.takeFromDocument(); QCOMPARE(div.isNull(), false); QCOMPARE(body.findAll("div").count(), 0); QCOMPARE(body.findAll("p").count(), 2); body.appendInside(div); QCOMPARE(body.findAll("div").count(), 1); QCOMPARE(body.findAll("p").count(), 3); } void tst_QWebElement::clear() { QString html = "<body>" "<p>" "foo" "</p>" "<div>" "<p>yeah</p>" "</div>" "<p>" "bar" "</p>" "</body>"; m_mainFrame->setHtml(html); QWebElement body = m_mainFrame->documentElement().findFirst("body"); QCOMPARE(body.findAll("div").count(), 1); QCOMPARE(body.findAll("p").count(), 3); body.findFirst("div").removeAllChildren(); QCOMPARE(body.findAll("div").count(), 1); QCOMPARE(body.findAll("p").count(), 2); } void tst_QWebElement::replaceWith() { QString html = "<body>" "<p>" "foo" "</p>" "<div>" "yeah" "</div>" "<p>" "<span>haba</span>" "</p>" "</body>"; m_mainFrame->setHtml(html); QWebElement body = m_mainFrame->documentElement().findFirst("body"); QCOMPARE(body.findAll("div").count(), 1); QCOMPARE(body.findAll("span").count(), 1); body.findFirst("div").replace(body.findFirst("span").clone()); QCOMPARE(body.findAll("div").count(), 0); QCOMPARE(body.findAll("span").count(), 2); QCOMPARE(body.findAll("p").count(), 2); body.findFirst("span").replace("<p><code>wow</code></p>"); QCOMPARE(body.findAll("p").count(), 3); QCOMPARE(body.findAll("p code").count(), 1); QCOMPARE(body.findFirst("p code").toPlainText(), QString("wow")); } void tst_QWebElement::encloseContentsWith() { QString html = "<body>" "<div>" "<i>" "yeah" "</i>" "<i>" "hello" "</i>" "</div>" "<p>" "<span>foo</span>" "<span>bar</span>" "</p>" "<u></u>" "<b></b>" "<em>hey</em>" "</body>"; m_mainFrame->setHtml(html); QWebElement body = m_mainFrame->documentElement().findFirst("body"); body.findFirst("p").encloseContentsWith(body.findFirst("b")); QCOMPARE(body.findAll("p b span").count(), 2); QCOMPARE(body.findFirst("p b span").toPlainText(), QString("foo")); body.findFirst("u").encloseContentsWith("<i></i>"); QCOMPARE(body.findAll("u i").count(), 1); QCOMPARE(body.findFirst("u i").toPlainText(), QString()); body.findFirst("div").encloseContentsWith("<span></span>"); QCOMPARE(body.findAll("div span i").count(), 2); QCOMPARE(body.findFirst("div span i").toPlainText(), QString("yeah")); QString snippet = "" "<table>" "<tbody>" "<tr>" "<td></td>" "<td></td>" "</tr>" "<tr>" "<td></td>" "<td></td>" "<tr>" "</tbody>" "</table>"; body.findFirst("em").encloseContentsWith(snippet); QCOMPARE(body.findFirst("em table tbody tr td").toPlainText(), QString("hey")); } void tst_QWebElement::encloseWith() { QString html = "<body>" "<p>" "foo" "</p>" "<div>" "yeah" "</div>" "<p>" "<span>bar</span>" "</p>" "<em>hey</em>" "<h1>hello</h1>" "</body>"; m_mainFrame->setHtml(html); QWebElement body = m_mainFrame->documentElement().findFirst("body"); body.findFirst("p").encloseWith("<br>"); QCOMPARE(body.findAll("br").count(), 0); QCOMPARE(body.findAll("div").count(), 1); body.findFirst("div").encloseWith(body.findFirst("span").clone()); QCOMPARE(body.findAll("div").count(), 1); QCOMPARE(body.findAll("span").count(), 2); QCOMPARE(body.findAll("p").count(), 2); body.findFirst("div").encloseWith("<code></code>"); QCOMPARE(body.findAll("code").count(), 1); QCOMPARE(body.findAll("code div").count(), 1); QCOMPARE(body.findFirst("code div").toPlainText(), QString("yeah")); QString snippet = "" "<table>" "<tbody>" "<tr>" "<td></td>" "<td></td>" "</tr>" "<tr>" "<td></td>" "<td></td>" "<tr>" "</tbody>" "</table>"; body.findFirst("em").encloseWith(snippet); QCOMPARE(body.findFirst("table tbody tr td em").toPlainText(), QString("hey")); } void tst_QWebElement::nullSelect() { m_mainFrame->setHtml("<body><p>Test"); QWebElementCollection collection = m_mainFrame->findAllElements("invalid{syn(tax;;%#$f223e>>"); QVERIFY(collection.count() == 0); } void tst_QWebElement::firstChildNextSibling() { m_mainFrame->setHtml("<body><!--comment--><p>Test</p><!--another comment--><table>"); QWebElement body = m_mainFrame->findFirstElement("body"); QVERIFY(!body.isNull()); QWebElement p = body.firstChild(); QVERIFY(!p.isNull()); QCOMPARE(p.tagName(), QString("P")); QWebElement table = p.nextSibling(); QVERIFY(!table.isNull()); QCOMPARE(table.tagName(), QString("TABLE")); QVERIFY(table.nextSibling().isNull()); } void tst_QWebElement::lastChildPreviousSibling() { m_mainFrame->setHtml("<body><!--comment--><p>Test</p><!--another comment--><table>"); QWebElement body = m_mainFrame->findFirstElement("body"); QVERIFY(!body.isNull()); QWebElement table = body.lastChild(); QVERIFY(!table.isNull()); QCOMPARE(table.tagName(), QString("TABLE")); QWebElement p = table.previousSibling(); QVERIFY(!p.isNull()); QCOMPARE(p.tagName(), QString("P")); 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; background: white; }" "</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); // Chunked render test reuses page rendered in image4 in previous test const int chunkHeight = tableRect.height(); const int chunkWidth = tableRect.width() / 3; QImage chunk(chunkWidth, chunkHeight, QImage::Format_ARGB32); QRect chunkRect(0, 0, chunkWidth, chunkHeight); for (int x = 0; x < tableRect.width(); x += chunkWidth) { QPainter painter(&chunk); painter.fillRect(chunkRect, Qt::white); QRect chunkPaintRect(x, 0, chunkWidth, chunkHeight); tables[0].render(&painter, chunkPaintRect); painter.end(); QVERIFY(chunk == image4.copy(chunkPaintRect)); } } void tst_QWebElement::addElementToHead() { m_mainFrame->setHtml("<html><head></head><body></body></html>"); QWebElement head = m_mainFrame->findFirstElement("head"); QVERIFY(!head.isNull()); QString append = "<script type=\"text/javascript\">var t = 0;</script>"; head.appendInside(append); QCOMPARE(head.toInnerXml(), append); } QTEST_MAIN(tst_QWebElement) #include "tst_qwebelement.moc"