Friday, March 4, 2011

Test WebKit Rendering with Qt

Using the QtWebKit module provided by Qt, developers can test WebKit rendering without visual inspection. The QWebView class from QtWebKit, along with a few classes from QtGui, can be used to verify rendering in relatively few lines of code.

The basic approach creates a QImage by rendering a QWebView's frame to a QPainter, whose paint device is a QImage instance. Once QWebView has rendered to the QImage, this object can be simply compared with another QImage.

This is creating a screenshot of a web page and comparing it to another screenshot to confirm or refute that the images are the same. The images can be optionally saved to a file if visual proof is desired.

For example, given two QWebView objects, a screenshot for each can be generated and then compared:


QWebView viewA, viewB;
QImage screenShotA, screenShotB;
WebKitRenderTest renderTest;

screenShotA = renderTest.initWebView(QColor(Qt::red), viewA, html, QString("viewA"));

screenShotB = renderTest.initWebView(QColor(Qt::blue), viewB, html, QString("viewB"));

QString result = (screenShotA == screenShotB) ? "images are same" : "images are different";


Note that the comparison is done with the overloaded equality operator in QImage.

The WebKitRenderTest is just a helper class with little more than a function for initializing a QWebVIew, setting the HTML content, applying a background color via QWebView's QPalette, and returning a QImage--the screenshot. Here is the body of such a function:


QImage WebKitRenderTest::initWebView(QColor bgColor, QWebView& view, QString& content, QString imgName){
QPalette pal;
QBrush brush(bgColor);
brush.setStyle(Qt::SolidPattern);
pal.setBrush(QPalette::Base, brush);

view.setPalette(pal);
view.setHtml(content);
view.page()->setViewportSize(view.page()->currentFrame()->contentsSize());

QImage img(view.page()->viewportSize(), QImage::Format_ARGB32);
QPainter paintView(&img);
view.page()->currentFrame()->render(&paintView);
paintView.end();

QString imgFileName = imgName + ".png";
img.save(imgFileName); // not necessary, just for visual inspection
view.close();

return img;
}




By using the QPalette::Base color role on the brush, the entire page background can be colored as desired by the application.

The technique is straightforward and easily adapted for automated tests. It is especially suited for use with the QTestLib framework provided by Qt.

A compilable, buildable project based on this example can be found here in zipped form:
https://docs.google.com/uc?id=0B7qXaguuORTFNWM4MjE1MGMtMTg4Yi00YzQ4LTk2ZjYtYzczZjQ1NzFiOTMw&export=download&authkey=COfEpIoB&hl=en

To see how this approach is already being used in WebKit, see this Changeset:
http://trac.webkit.org/changeset/79409

No comments: