tst_qrawwebview.cpp [plain text]
#include "../util.h"
#include <QImage>
#include <QMatrix4x4>
#include <QOpenGLContext>
#include <QSize>
#include <QWindow>
#include <QtTest/QtTest>
#include <WebKit2/WKContext.h>
#include <WebKit2/WKPageGroup.h>
#include <WebKit2/WKPageLoadTypes.h>
#include <WebKit2/WKPreferences.h>
#include <WebKit2/WKPreferencesPrivate.h>
#include <WebKit2/WKStringQt.h>
#include <WebKit2/WKURL.h>
#include <WebKit2/qrawwebview_p.h>
static WKContextRef webContext()
{
static WKContextRef result = WKContextCreate();
return result;
}
static WKPageGroupRef createWebPageGroup(const QString& name)
{
WKPageGroupRef pageGroup =WKPageGroupCreateWithIdentifier(WKStringCreateWithQString(name));
WKPreferencesRef preferences = WKPageGroupGetPreferences(pageGroup);
WKPreferencesSetAcceleratedCompositingEnabled(preferences, true);
WKPreferencesSetFrameFlatteningEnabled(preferences, true);
return pageGroup;
}
static WKPageGroupRef webPageGroup(const QString& name)
{
static WKPageGroupRef result = createWebPageGroup(name);
return result;
}
class WebView : public QObject, public QRawWebViewClient {
Q_OBJECT
public:
WebView(const QSize& size, bool transparent = false)
{
m_webView = new QRawWebView(webContext(), webPageGroup(QString()), this);
m_webView->setTransparentBackground(transparent);
m_webView->create();
WKPageLoaderClient loaderClient;
memset(&loaderClient, 0, sizeof(WKPageLoaderClient));
loaderClient.version = kWKPageLoaderClientCurrentVersion;
loaderClient.clientInfo = this;
loaderClient.didLayout = WebView::didLayout;
WKPageSetPageLoaderClient(m_webView->pageRef(), &loaderClient);
WKPageListenForLayoutMilestones(m_webView->pageRef(), kWKDidFirstVisuallyNonEmptyLayout);
WKPageSetUseFixedLayout(m_webView->pageRef(), true);
m_webView->setSize(size);
m_webView->setFocused(true);
m_webView->setVisible(true);
m_webView->setActive(true);
}
~WebView() { delete m_webView; }
void load(const QString& html)
{
m_frameLoaded = false;
WKPageLoadURL(m_webView->pageRef(), WKURLCreateWithUTF8CString(html.toLocal8Bit().data()));
QVERIFY(::waitForSignal(this, SIGNAL(loaded()), 5000));
}
void setDrawBackground(bool value) { m_webView->setDrawBackground(value); }
void setTransparentBackground(bool value) { m_webView->setTransparentBackground(value); }
virtual void viewNeedsDisplay(const QRect&)
{
m_webView->paint(QMatrix4x4(), 1, 0);
}
virtual void viewRequestedScroll(const QPoint&) { }
virtual void viewProcessCrashed() { }
virtual void viewProcessRelaunched() { }
virtual void viewContentSizeChanged(const QSize&) { }
virtual void viewRequestedCursorOverride(const QCursor&) { }
virtual void doneWithKeyEvent(const QKeyEvent*, bool wasHandled) { }
virtual void doneWithTouchEvent(const QTouchEvent*, bool wasHandled) { }
void frameLoaded()
{
m_frameLoaded = true;
WKPageForceRepaint(m_webView->pageRef(), this, finishForceRepaint);
}
void onRepaintDone()
{
emit loaded();
}
static void finishForceRepaint(WKErrorRef, void* context)
{
static_cast<WebView*>(context)->onRepaintDone();
}
static void didLayout(WKPageRef page, WKLayoutMilestones milestones, WKTypeRef userData, const void *clientInfo)
{
static_cast<WebView*>(const_cast<void*>(clientInfo))->frameLoaded();
}
Q_SIGNALS:
void loaded();
private:
QRawWebView* m_webView;
bool m_frameLoaded;
};
static bool compareImages(const QImage& i1, const QImage& i2, int count)
{
if (i1.size() != i2.size())
return false;
for (int x = 0; x < count; ++x) {
for (int y = 0; y < count; ++y) {
QPoint point(x * i1.width() / count, y * i1.height() / count);
if (i1.pixel(point) != i2.pixel(point))
return false;
}
}
return true;
}
class tst_qrawwebview : public QObject {
Q_OBJECT
public:
tst_qrawwebview()
: m_resourceDir(QString::fromLatin1(TESTS_SOURCE_DIR "/html/resources"))
, m_baseUrl(QUrl::fromLocalFile(TESTS_SOURCE_DIR "/html").toString())
{
addQtWebProcessToPath();
}
private Q_SLOTS:
void paint() { run(&tst_qrawwebview::doPaint, m_resourceDir + "/qwkview_paint.png"); }
void noBackground1() { run(&tst_qrawwebview::doNoBackground1, m_resourceDir + "/qwkview_noBackground1.png"); }
void noBackground2() { run(&tst_qrawwebview::doNoBackground2, m_resourceDir + "/qwkview_noBackground1.png"); }
void noBackground3() { run(&tst_qrawwebview::doNoBackground3, m_resourceDir + "/qwkview_noBackground3.png"); }
private:
const QString m_resourceDir;
const QString m_baseUrl;
void doPaint(const QSize& size);
void doNoBackground1(const QSize& size);
void doNoBackground2(const QSize& size);
void doNoBackground3(const QSize& size);
typedef void (tst_qrawwebview::*PaintMethod)(const QSize& size);
void run(PaintMethod, const QString& expectation);
};
void tst_qrawwebview::doPaint(const QSize& size)
{
WebView view(size);
view.load(m_baseUrl + "/redsquare.html");
}
void tst_qrawwebview::doNoBackground1(const QSize& size)
{
WebView view(size, true);
view.load(m_baseUrl + "/redsquare.html");
view.load(m_baseUrl + "/bluesquare.html");
}
void tst_qrawwebview::doNoBackground2(const QSize& size)
{
WebView view1(size, true);
view1.load(m_baseUrl + "/redsquare.html");
WebView view2(size, true);
view2.load(m_baseUrl + "/bluesquare.html");
}
void tst_qrawwebview::doNoBackground3(const QSize& size)
{
WebView view1(size, false);
view1.load(m_baseUrl + "/redsquare.html");
WebView view2(size, true);
view2.load(m_baseUrl + "/bluesquare.html");
}
void tst_qrawwebview::run(PaintMethod method, const QString& expectation)
{
QWindow window;
window.setSurfaceType(QSurface::OpenGLSurface);
window.setGeometry(0, 0, 200, 200);
window.create();
QOpenGLContext context;
context.create();
context.makeCurrent(&window);
glViewport(0, 0, window.size().width(), window.size().height());
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT);
(this->*method)(window.size());
QImage image(window.size(), QImage::Format_ARGB32_Premultiplied);
glReadPixels(0, 0, window.size().width(), window.size().height(), GL_RGBA, GL_UNSIGNED_BYTE, image.bits());
QVERIFY(compareImages(QImage(expectation), image.rgbSwapped(), 5));
}
QTEST_MAIN(tst_qrawwebview)
#include "tst_qrawwebview.moc"