diff options
| author | Simon Hausmann <simon.hausmann@nokia.com> | 2012-01-06 14:44:00 +0100 |
|---|---|---|
| committer | Simon Hausmann <simon.hausmann@nokia.com> | 2012-01-06 14:44:00 +0100 |
| commit | 40736c5763bf61337c8c14e16d8587db021a87d4 (patch) | |
| tree | b17a9c00042ad89cb1308e2484491799aa14e9f8 /Tools/WebKitTestRunner/TestInvocation.cpp | |
| download | qtwebkit-40736c5763bf61337c8c14e16d8587db021a87d4.tar.gz | |
Imported WebKit commit 2ea9d364d0f6efa8fa64acf19f451504c59be0e4 (http://svn.webkit.org/repository/webkit/trunk@104285)
Diffstat (limited to 'Tools/WebKitTestRunner/TestInvocation.cpp')
| -rw-r--r-- | Tools/WebKitTestRunner/TestInvocation.cpp | 299 |
1 files changed, 299 insertions, 0 deletions
diff --git a/Tools/WebKitTestRunner/TestInvocation.cpp b/Tools/WebKitTestRunner/TestInvocation.cpp new file mode 100644 index 000000000..451d66661 --- /dev/null +++ b/Tools/WebKitTestRunner/TestInvocation.cpp @@ -0,0 +1,299 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "TestInvocation.h" + +#include "PlatformWebView.h" +#include "StringFunctions.h" +#include "TestController.h" +#include <climits> +#include <cstdio> +#include <WebKit2/WKDictionary.h> +#include <WebKit2/WKContextPrivate.h> +#include <WebKit2/WKInspector.h> +#include <WebKit2/WKRetainPtr.h> +#include <wtf/OwnArrayPtr.h> +#include <wtf/PassOwnArrayPtr.h> + +#if OS(WINDOWS) +#include <direct.h> // For _getcwd. +#define getcwd _getcwd // MSDN says getcwd is deprecated. +#define PATH_MAX _MAX_PATH +#endif + +using namespace WebKit; +using namespace std; + +namespace WTR { + +static WKURLRef createWKURL(const char* pathOrURL) +{ + if (strstr(pathOrURL, "http://") || strstr(pathOrURL, "https://") || strstr(pathOrURL, "file://")) + return WKURLCreateWithUTF8CString(pathOrURL); + + // Creating from filesytem path. + size_t length = strlen(pathOrURL); + if (!length) + return 0; + + // FIXME: Remove the "localhost/" suffix once <http://webkit.org/b/55683> is fixed. + const char* filePrefix = "file://localhost/"; + static const size_t prefixLength = strlen(filePrefix); +#if OS(WINDOWS) + const char separator = '\\'; + bool isAbsolutePath = length >= 3 && pathOrURL[1] == ':' && pathOrURL[2] == separator; +#else + const char separator = '/'; + bool isAbsolutePath = pathOrURL[0] == separator; +#endif + + OwnArrayPtr<char> buffer; + if (isAbsolutePath) { + buffer = adoptArrayPtr(new char[prefixLength + length + 1]); + strcpy(buffer.get(), filePrefix); + strcpy(buffer.get() + prefixLength, pathOrURL); + } else { + buffer = adoptArrayPtr(new char[prefixLength + PATH_MAX + length + 2]); // 1 for the separator + strcpy(buffer.get(), filePrefix); + if (!getcwd(buffer.get() + prefixLength, PATH_MAX)) + return 0; + size_t numCharacters = strlen(buffer.get()); + buffer[numCharacters] = separator; + strcpy(buffer.get() + numCharacters + 1, pathOrURL); + } + + return WKURLCreateWithUTF8CString(buffer.get()); +} + +TestInvocation::TestInvocation(const std::string& pathOrURL) + : m_url(AdoptWK, createWKURL(pathOrURL.c_str())) + , m_pathOrURL(pathOrURL) + , m_dumpPixels(false) + , m_gotInitialResponse(false) + , m_gotFinalMessage(false) + , m_gotRepaint(false) + , m_error(false) +{ +} + +TestInvocation::~TestInvocation() +{ +} + +void TestInvocation::setIsPixelTest(const std::string& expectedPixelHash) +{ + m_dumpPixels = true; + m_expectedPixelHash = expectedPixelHash; +} + +static const unsigned w3cSVGWidth = 480; +static const unsigned w3cSVGHeight = 360; +static const unsigned normalWidth = 800; +static const unsigned normalHeight = 600; + +static void sizeWebViewForCurrentTest(const char* pathOrURL) +{ + bool isSVGW3CTest = strstr(pathOrURL, "svg/W3C-SVG-1.1") || strstr(pathOrURL, "svg\\W3C-SVG-1.1"); + + if (isSVGW3CTest) + TestController::shared().mainWebView()->resizeTo(w3cSVGWidth, w3cSVGHeight); + else + TestController::shared().mainWebView()->resizeTo(normalWidth, normalHeight); +} + +static bool shouldOpenWebInspector(const char* pathOrURL) +{ + return strstr(pathOrURL, "inspector/") || strstr(pathOrURL, "inspector\\"); +} + +void TestInvocation::invoke() +{ + sizeWebViewForCurrentTest(m_pathOrURL.c_str()); + + WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("BeginTest")); + WKRetainPtr<WKBooleanRef> dumpPixels = adoptWK(WKBooleanCreate(m_dumpPixels)); + WKContextPostMessageToInjectedBundle(TestController::shared().context(), messageName.get(), dumpPixels.get()); + + TestController::shared().runUntil(m_gotInitialResponse, TestController::ShortTimeout); + if (!m_gotInitialResponse) { + dump("Timed out waiting for initial response from web process\n"); + return; + } + if (m_error) { + dump("FAIL\n"); + return; + } + + if (shouldOpenWebInspector(m_pathOrURL.c_str())) + WKInspectorShow(WKPageGetInspector(TestController::shared().mainWebView()->page())); + + WKPageLoadURL(TestController::shared().mainWebView()->page(), m_url.get()); + + TestController::shared().runUntil(m_gotFinalMessage, TestController::LongTimeout); + if (!m_gotFinalMessage) + dump("Timed out waiting for final message from web process\n"); + else if (m_error) + dump("FAIL\n"); + + WKInspectorClose(WKPageGetInspector(TestController::shared().mainWebView()->page())); +} + +void TestInvocation::dump(const char* stringToDump, bool singleEOF) +{ + printf("Content-Type: text/plain\n"); + printf("%s", stringToDump); + + fputs("#EOF\n", stdout); + fputs("#EOF\n", stderr); + if (!singleEOF) + fputs("#EOF\n", stdout); + fflush(stdout); + fflush(stderr); +} + +bool TestInvocation::compareActualHashToExpectedAndDumpResults(const char actualHash[33]) +{ + // Compute the hash of the bitmap context pixels + fprintf(stdout, "\nActualHash: %s\n", actualHash); + + if (!m_expectedPixelHash.length()) + return false; + + ASSERT(m_expectedPixelHash.length() == 32); + fprintf(stdout, "\nExpectedHash: %s\n", m_expectedPixelHash.c_str()); + + // FIXME: Do case insensitive compare. + return m_expectedPixelHash == actualHash; +} + +void TestInvocation::didReceiveMessageFromInjectedBundle(WKStringRef messageName, WKTypeRef messageBody) +{ + if (WKStringIsEqualToUTF8CString(messageName, "Error")) { + // Set all states to true to stop spinning the runloop. + m_gotInitialResponse = true; + m_gotFinalMessage = true; + m_error = true; + TestController::shared().notifyDone(); + return; + } + + if (WKStringIsEqualToUTF8CString(messageName, "Ack")) { + ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID()); + WKStringRef messageBodyString = static_cast<WKStringRef>(messageBody); + if (WKStringIsEqualToUTF8CString(messageBodyString, "BeginTest")) { + m_gotInitialResponse = true; + TestController::shared().notifyDone(); + return; + } + + ASSERT_NOT_REACHED(); + } + + if (WKStringIsEqualToUTF8CString(messageName, "Done")) { + ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID()); + WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody); + + WKRetainPtr<WKStringRef> textOutputKey(AdoptWK, WKStringCreateWithUTF8CString("TextOutput")); + WKStringRef textOutput = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, textOutputKey.get())); + + WKRetainPtr<WKStringRef> pixelResultKey = adoptWK(WKStringCreateWithUTF8CString("PixelResult")); + WKImageRef pixelResult = static_cast<WKImageRef>(WKDictionaryGetItemForKey(messageBodyDictionary, pixelResultKey.get())); + ASSERT(!pixelResult || m_dumpPixels); + + WKRetainPtr<WKStringRef> repaintRectsKey = adoptWK(WKStringCreateWithUTF8CString("RepaintRects")); + WKArrayRef repaintRects = static_cast<WKArrayRef>(WKDictionaryGetItemForKey(messageBodyDictionary, repaintRectsKey.get())); + + // Dump text. + dump(toSTD(textOutput).c_str(), true); + + // Dump pixels (if necessary). + if (m_dumpPixels && pixelResult) + dumpPixelsAndCompareWithExpected(pixelResult, repaintRects); + + fputs("#EOF\n", stdout); + fflush(stdout); + fflush(stderr); + + m_gotFinalMessage = true; + TestController::shared().notifyDone(); + return; + } + + if (WKStringIsEqualToUTF8CString(messageName, "BeforeUnloadReturnValue")) { + ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID()); + WKBooleanRef beforeUnloadReturnValue = static_cast<WKBooleanRef>(messageBody); + TestController::shared().setBeforeUnloadReturnValue(WKBooleanGetValue(beforeUnloadReturnValue)); + return; + } + + if (WKStringIsEqualToUTF8CString(messageName, "AddChromeInputField")) { + TestController::shared().mainWebView()->addChromeInputField(); + WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CallAddChromeInputFieldCallback")); + WKContextPostMessageToInjectedBundle(TestController::shared().context(), messageName.get(), 0); + return; + } + + if (WKStringIsEqualToUTF8CString(messageName, "RemoveChromeInputField")) { + TestController::shared().mainWebView()->removeChromeInputField(); + WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CallRemoveChromeInputFieldCallback")); + WKContextPostMessageToInjectedBundle(TestController::shared().context(), messageName.get(), 0); + return; + } + + if (WKStringIsEqualToUTF8CString(messageName, "FocusWebView")) { + TestController::shared().mainWebView()->makeWebViewFirstResponder(); + WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CallFocusWebViewCallback")); + WKContextPostMessageToInjectedBundle(TestController::shared().context(), messageName.get(), 0); + return; + } + + if (WKStringIsEqualToUTF8CString(messageName, "SetBackingScaleFactor")) { + ASSERT(WKGetTypeID(messageBody) == WKDoubleGetTypeID()); + double backingScaleFactor = WKDoubleGetValue(static_cast<WKDoubleRef>(messageBody)); + WKPageSetCustomBackingScaleFactor(TestController::shared().mainWebView()->page(), backingScaleFactor); + + WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CallSetBackingScaleFactorCallback")); + WKContextPostMessageToInjectedBundle(TestController::shared().context(), messageName.get(), 0); + return; + } + + ASSERT_NOT_REACHED(); +} + +WKRetainPtr<WKTypeRef> TestInvocation::didReceiveSynchronousMessageFromInjectedBundle(WKStringRef messageName, WKTypeRef messageBody) +{ + if (WKStringIsEqualToUTF8CString(messageName, "SetWindowIsKey")) { + ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID()); + WKBooleanRef isKeyValue = static_cast<WKBooleanRef>(messageBody); + TestController::shared().mainWebView()->setWindowIsKey(WKBooleanGetValue(isKeyValue)); + return 0; + } + + ASSERT_NOT_REACHED(); + return 0; +} + +} // namespace WTR |
