diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
commit | 1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch) | |
tree | 46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Tools/WebKitTestRunner/TestInvocation.cpp | |
parent | 32761a6cee1d0dee366b885b7b9c777e67885688 (diff) | |
download | WebKitGtk-tarball-master.tar.gz |
webkitgtk-2.16.5HEADwebkitgtk-2.16.5master
Diffstat (limited to 'Tools/WebKitTestRunner/TestInvocation.cpp')
-rw-r--r-- | Tools/WebKitTestRunner/TestInvocation.cpp | 772 |
1 files changed, 561 insertions, 211 deletions
diff --git a/Tools/WebKitTestRunner/TestInvocation.cpp b/Tools/WebKitTestRunner/TestInvocation.cpp index cac2ba8b8..b0a0442cc 100644 --- a/Tools/WebKitTestRunner/TestInvocation.cpp +++ b/Tools/WebKitTestRunner/TestInvocation.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010, 2011, 2012 Apple Inc. All rights reserved. + * Copyright (C) 2010-2017 Apple Inc. All rights reserved. * Copyright (C) 2012 Intel Corporation. All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -30,196 +30,144 @@ #include "PlatformWebView.h" #include "StringFunctions.h" #include "TestController.h" +#include "UIScriptController.h" +#include "WebCoreTestSupport.h" +#include <WebKit/WKContextPrivate.h> +#include <WebKit/WKCookieManager.h> +#include <WebKit/WKData.h> +#include <WebKit/WKDictionary.h> +#include <WebKit/WKInspector.h> +#include <WebKit/WKPagePrivate.h> +#include <WebKit/WKRetainPtr.h> +#include <WebKit/WKWebsiteDataStoreRef.h> #include <climits> #include <cstdio> -#include <WebKit2/WKContextPrivate.h> -#include <WebKit2/WKData.h> -#include <WebKit2/WKDictionary.h> -#include <WebKit2/WKInspector.h> -#include <WebKit2/WKRetainPtr.h> -#include <wtf/PassOwnPtr.h> +#include <unistd.h> #include <wtf/StdLibExtras.h> #include <wtf/text/CString.h> -#if PLATFORM(MAC) -#if !PLATFORM(IOS) +#if PLATFORM(MAC) && !PLATFORM(IOS) #include <Carbon/Carbon.h> #endif -#include <WebKit2/WKPagePrivateMac.h> -#endif -#include <unistd.h> // For getcwd. +#if PLATFORM(COCOA) +#include <WebKit/WKPagePrivateMac.h> +#endif +using namespace JSC; using namespace WebKit; using namespace std; namespace WTR { -static WKURLRef createWKURL(const char* pathOrURL) +TestInvocation::TestInvocation(WKURLRef url, const TestOptions& options) + : m_options(options) + , m_url(url) { - if (strstr(pathOrURL, "http://") || strstr(pathOrURL, "https://") || strstr(pathOrURL, "file://")) - return WKURLCreateWithUTF8CString(pathOrURL); + WKRetainPtr<WKStringRef> urlString = adoptWK(WKURLCopyString(m_url.get())); - // Creating from filesytem path. - size_t length = strlen(pathOrURL); - if (!length) - return 0; - - const char separator = '/'; - bool isAbsolutePath = pathOrURL[0] == separator; - const char* filePrefix = "file://"; - static const size_t prefixLength = strlen(filePrefix); - - std::unique_ptr<char[]> buffer; - if (isAbsolutePath) { - buffer = std::make_unique<char[]>(prefixLength + length + 1); - strcpy(buffer.get(), filePrefix); - strcpy(buffer.get() + prefixLength, pathOrURL); - } else { - buffer = std::make_unique<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()); -} + size_t stringLength = WKStringGetLength(urlString.get()); -TestInvocation::TestInvocation(const std::string& pathOrURL) - : m_url(AdoptWK, createWKURL(pathOrURL.c_str())) - , m_pathOrURL(pathOrURL) - , m_dumpPixels(false) - , m_timeout(0) - , m_gotInitialResponse(false) - , m_gotFinalMessage(false) - , m_gotRepaint(false) - , m_error(false) - , m_webProcessIsUnresponsive(false) -{ + Vector<char> urlVector; + urlVector.resize(stringLength + 1); + + WKStringGetUTF8CString(urlString.get(), urlVector.data(), stringLength + 1); + + m_urlString = String(urlVector.data(), stringLength); } TestInvocation::~TestInvocation() { + if (m_pendingUIScriptInvocationData) + m_pendingUIScriptInvocationData->testInvocation = nullptr; } -void TestInvocation::setIsPixelTest(const std::string& expectedPixelHash) +WKURLRef TestInvocation::url() const { - m_dumpPixels = true; - m_expectedPixelHash = expectedPixelHash; + return m_url.get(); } -void TestInvocation::setCustomTimeout(int timeout) +bool TestInvocation::urlContains(const char* searchString) const { - m_timeout = timeout; + return m_urlString.contains(searchString, false); } -static void sizeWebViewForCurrentTest(const char* pathOrURL) +void TestInvocation::setIsPixelTest(const std::string& expectedPixelHash) { - bool isSVGW3CTest = strstr(pathOrURL, "svg/W3C-SVG-1.1") || strstr(pathOrURL, "svg\\W3C-SVG-1.1"); - - if (isSVGW3CTest) - TestController::shared().mainWebView()->resizeTo(TestController::w3cSVGViewWidth, TestController::w3cSVGViewHeight); - else - TestController::shared().mainWebView()->resizeTo(TestController::viewWidth, TestController::viewHeight); + m_dumpPixels = true; + m_expectedPixelHash = expectedPixelHash; } -static bool shouldLogFrameLoadDelegates(const char* pathOrURL) +double TestInvocation::shortTimeout() const { - return strstr(pathOrURL, "loading/"); -} + if (!m_timeout) { + // Running WKTR directly, without webkitpy. + return TestController::defaultShortTimeout; + } -#if ENABLE(INSPECTOR) && !PLATFORM(IOS) -static bool shouldOpenWebInspector(const char* pathOrURL) -{ - return strstr(pathOrURL, "inspector/") || strstr(pathOrURL, "inspector\\"); + // This is not exactly correct for the way short timeout is used - it should not depend on whether a test is "slow", + // but it currently does. There is no way to know what a normal test's timeout is, as webkitpy only passes timeouts + // for each test individually. + // But there shouldn't be any observable negative consequences from this. + return m_timeout / 1000. / 2; } -#endif -#if PLATFORM(MAC) -static bool shouldUseThreadedScrolling(const char* pathOrURL) +bool TestInvocation::shouldLogFrameLoadDelegates() const { - return strstr(pathOrURL, "tiled-drawing/") || strstr(pathOrURL, "tiled-drawing\\"); + return urlContains("loading/"); } -#endif -static void updateThreadedScrollingForCurrentTest(const char* pathOrURL) +bool TestInvocation::shouldLogHistoryClientCallbacks() const { -#if PLATFORM(MAC) - WKRetainPtr<WKMutableDictionaryRef> viewOptions = adoptWK(WKMutableDictionaryCreate()); - WKRetainPtr<WKStringRef> useThreadedScrollingKey = adoptWK(WKStringCreateWithUTF8CString("ThreadedScrolling")); - WKRetainPtr<WKBooleanRef> useThreadedScrollingValue = adoptWK(WKBooleanCreate(shouldUseThreadedScrolling(pathOrURL))); - WKDictionarySetItem(viewOptions.get(), useThreadedScrollingKey.get(), useThreadedScrollingValue.get()); - - WKRetainPtr<WKStringRef> useRemoteLayerTreeKey = adoptWK(WKStringCreateWithUTF8CString("RemoteLayerTree")); - WKRetainPtr<WKBooleanRef> useRemoteLayerTreeValue = adoptWK(WKBooleanCreate(TestController::shared().shouldUseRemoteLayerTree())); - WKDictionarySetItem(viewOptions.get(), useRemoteLayerTreeKey.get(), useRemoteLayerTreeValue.get()); - - TestController::shared().ensureViewSupportsOptions(viewOptions.get()); -#else - UNUSED_PARAM(pathOrURL); -#endif + return urlContains("globalhistory/"); } -static bool shouldUseFixedLayout(const char* pathOrURL) +void TestInvocation::invoke() { -#if ENABLE(CSS_DEVICE_ADAPTATION) - if (strstr(pathOrURL, "device-adapt/") || strstr(pathOrURL, "device-adapt\\")) - return true; -#endif + TestController::singleton().configureViewForTest(*this); -#if USE(TILED_BACKING_STORE) && PLATFORM(EFL) - if (strstr(pathOrURL, "sticky/") || strstr(pathOrURL, "sticky\\")) - return true; -#endif - return false; + WKPageSetAddsVisitedLinks(TestController::singleton().mainWebView()->page(), false); - UNUSED_PARAM(pathOrURL); -} - -static void updateLayoutType(const char* pathOrURL) -{ - WKRetainPtr<WKMutableDictionaryRef> viewOptions = adoptWK(WKMutableDictionaryCreate()); - WKRetainPtr<WKStringRef> useFixedLayoutKey = adoptWK(WKStringCreateWithUTF8CString("UseFixedLayout")); - WKRetainPtr<WKBooleanRef> useFixedLayoutValue = adoptWK(WKBooleanCreate(shouldUseFixedLayout(pathOrURL))); - WKDictionarySetItem(viewOptions.get(), useFixedLayoutKey.get(), useFixedLayoutValue.get()); + m_textOutput.clear(); - TestController::shared().ensureViewSupportsOptions(viewOptions.get()); -} + TestController::singleton().setShouldLogHistoryClientCallbacks(shouldLogHistoryClientCallbacks()); -void TestInvocation::invoke() -{ - TestController::TimeoutDuration timeoutToUse = TestController::LongTimeout; - sizeWebViewForCurrentTest(m_pathOrURL.c_str()); - updateLayoutType(m_pathOrURL.c_str()); - updateThreadedScrollingForCurrentTest(m_pathOrURL.c_str()); + WKCookieManagerSetHTTPCookieAcceptPolicy(WKContextGetCookieManager(TestController::singleton().context()), kWKHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain); - m_textOutput.clear(); + // FIXME: We should clear out visited links here. WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("BeginTest")); WKRetainPtr<WKMutableDictionaryRef> beginTestMessageBody = adoptWK(WKMutableDictionaryCreate()); WKRetainPtr<WKStringRef> dumpFrameLoadDelegatesKey = adoptWK(WKStringCreateWithUTF8CString("DumpFrameLoadDelegates")); - WKRetainPtr<WKBooleanRef> dumpFrameLoadDelegatesValue = adoptWK(WKBooleanCreate(shouldLogFrameLoadDelegates(m_pathOrURL.c_str()))); + WKRetainPtr<WKBooleanRef> dumpFrameLoadDelegatesValue = adoptWK(WKBooleanCreate(shouldLogFrameLoadDelegates())); WKDictionarySetItem(beginTestMessageBody.get(), dumpFrameLoadDelegatesKey.get(), dumpFrameLoadDelegatesValue.get()); + WKRetainPtr<WKStringRef> useFlexibleViewportKey = adoptWK(WKStringCreateWithUTF8CString("UseFlexibleViewport")); + WKRetainPtr<WKBooleanRef> useFlexibleViewportValue = adoptWK(WKBooleanCreate(options().useFlexibleViewport)); + WKDictionarySetItem(beginTestMessageBody.get(), useFlexibleViewportKey.get(), useFlexibleViewportValue.get()); + WKRetainPtr<WKStringRef> dumpPixelsKey = adoptWK(WKStringCreateWithUTF8CString("DumpPixels")); WKRetainPtr<WKBooleanRef> dumpPixelsValue = adoptWK(WKBooleanCreate(m_dumpPixels)); WKDictionarySetItem(beginTestMessageBody.get(), dumpPixelsKey.get(), dumpPixelsValue.get()); WKRetainPtr<WKStringRef> useWaitToDumpWatchdogTimerKey = adoptWK(WKStringCreateWithUTF8CString("UseWaitToDumpWatchdogTimer")); - WKRetainPtr<WKBooleanRef> useWaitToDumpWatchdogTimerValue = adoptWK(WKBooleanCreate(TestController::shared().useWaitToDumpWatchdogTimer())); + WKRetainPtr<WKBooleanRef> useWaitToDumpWatchdogTimerValue = adoptWK(WKBooleanCreate(TestController::singleton().useWaitToDumpWatchdogTimer())); WKDictionarySetItem(beginTestMessageBody.get(), useWaitToDumpWatchdogTimerKey.get(), useWaitToDumpWatchdogTimerValue.get()); WKRetainPtr<WKStringRef> timeoutKey = adoptWK(WKStringCreateWithUTF8CString("Timeout")); WKRetainPtr<WKUInt64Ref> timeoutValue = adoptWK(WKUInt64Create(m_timeout)); WKDictionarySetItem(beginTestMessageBody.get(), timeoutKey.get(), timeoutValue.get()); - WKContextPostMessageToInjectedBundle(TestController::shared().context(), messageName.get(), beginTestMessageBody.get()); + WKRetainPtr<WKStringRef> dumpJSConsoleLogInStdErrKey = adoptWK(WKStringCreateWithUTF8CString("DumpJSConsoleLogInStdErr")); + WKRetainPtr<WKBooleanRef> dumpJSConsoleLogInStdErrValue = adoptWK(WKBooleanCreate(m_dumpJSConsoleLogInStdErr)); + WKDictionarySetItem(beginTestMessageBody.get(), dumpJSConsoleLogInStdErrKey.get(), dumpJSConsoleLogInStdErrValue.get()); - TestController::shared().runUntil(m_gotInitialResponse, TestController::ShortTimeout); + WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), beginTestMessageBody.get()); + + bool shouldOpenExternalURLs = false; + + TestController::singleton().runUntil(m_gotInitialResponse, shortTimeout()); if (!m_gotInitialResponse) { m_errorMessage = "Timed out waiting for initial response from web process\n"; m_webProcessIsUnresponsive = true; @@ -228,42 +176,29 @@ void TestInvocation::invoke() if (m_error) goto end; -#if ENABLE(INSPECTOR) && !PLATFORM(IOS) - if (shouldOpenWebInspector(m_pathOrURL.c_str())) - WKInspectorShow(WKPageGetInspector(TestController::shared().mainWebView()->page())); -#endif // ENABLE(INSPECTOR) - - WKPageLoadURL(TestController::shared().mainWebView()->page(), m_url.get()); - - if (TestController::shared().useWaitToDumpWatchdogTimer()) { - if (m_timeout > 0) - timeoutToUse = TestController::CustomTimeout; - } else - timeoutToUse = TestController::NoTimeout; - TestController::shared().runUntil(m_gotFinalMessage, timeoutToUse); + WKPageLoadURLWithShouldOpenExternalURLsPolicy(TestController::singleton().mainWebView()->page(), m_url.get(), shouldOpenExternalURLs); - if (!m_gotFinalMessage) { - m_errorMessage = "Timed out waiting for final message from web process\n"; - m_webProcessIsUnresponsive = true; - goto end; - } + TestController::singleton().runUntil(m_gotFinalMessage, TestController::noTimeout); if (m_error) goto end; dumpResults(); end: -#if ENABLE(INSPECTOR) && !PLATFORM(IOS) +#if !PLATFORM(IOS) if (m_gotInitialResponse) - WKInspectorClose(WKPageGetInspector(TestController::shared().mainWebView()->page())); -#endif // ENABLE(INSPECTOR) + WKInspectorClose(WKPageGetInspector(TestController::singleton().mainWebView()->page())); +#endif // !PLATFORM(IOS) if (m_webProcessIsUnresponsive) dumpWebProcessUnresponsiveness(); - else if (!TestController::shared().resetStateToConsistentValues()) { - m_errorMessage = "Timed out loading about:blank before the next test"; - dumpWebProcessUnresponsiveness(); - } + else if (TestController::singleton().resetStateToConsistentValues(m_options)) + return; + + // The process is unresponsive, so let's start a new one. + TestController::singleton().terminateWebContentProcess(); + // Make sure that we have a process, as invoke() will need one to send bundle messages for the next test. + TestController::singleton().reattachPageToWebProcess(); } void TestInvocation::dumpWebProcessUnresponsiveness() @@ -273,17 +208,25 @@ void TestInvocation::dumpWebProcessUnresponsiveness() void TestInvocation::dumpWebProcessUnresponsiveness(const char* errorMessage) { - const char* errorMessageToStderr = 0; -#if PLATFORM(MAC) - char buffer[64]; - pid_t pid = WKPageGetProcessIdentifier(TestController::shared().mainWebView()->page()); - sprintf(buffer, "#PROCESS UNRESPONSIVE - WebProcess (pid %ld)\n", static_cast<long>(pid)); - errorMessageToStderr = buffer; + fprintf(stderr, "%s", errorMessage); + char buffer[1024] = { }; +#if PLATFORM(COCOA) + pid_t pid = WKPageGetProcessIdentifier(TestController::singleton().mainWebView()->page()); + snprintf(buffer, sizeof(buffer), "#PROCESS UNRESPONSIVE - %s (pid %ld)\n", TestController::webProcessName(), static_cast<long>(pid)); #else - errorMessageToStderr = "#PROCESS UNRESPONSIVE - WebProcess"; + snprintf(buffer, sizeof(buffer), "#PROCESS UNRESPONSIVE - %s\n", TestController::webProcessName()); #endif - dump(errorMessage, errorMessageToStderr, true); + dump(errorMessage, buffer, true); + + if (!TestController::singleton().usingServerMode()) + return; + + if (isatty(fileno(stdin)) || isatty(fileno(stderr))) + fputs("Grab an image of the stack, then hit enter...\n", stderr); + + if (!fgets(buffer, sizeof(buffer), stdin) || strcmp(buffer, "#SAMPLE FINISHED\n")) + fprintf(stderr, "Failed receive expected sample response, got:\n\t\"%s\"\nContinuing...\n", buffer); } void TestInvocation::dump(const char* textToStdout, const char* textToStderr, bool seenError) @@ -302,11 +245,17 @@ void TestInvocation::dump(const char* textToStdout, const char* textToStderr, bo fflush(stderr); } -void TestInvocation::forceRepaintDoneCallback(WKErrorRef, void* context) +void TestInvocation::forceRepaintDoneCallback(WKErrorRef error, void* context) { + // The context may not be valid any more, e.g. if WebKit is invalidating callbacks at process exit. + if (error) + return; + TestInvocation* testInvocation = static_cast<TestInvocation*>(context); + RELEASE_ASSERT(TestController::singleton().isCurrentInvocation(testInvocation)); + testInvocation->m_gotRepaint = true; - TestController::shared().notifyDone(); + TestController::singleton().notifyDone(); } void TestInvocation::dumpResults() @@ -316,18 +265,22 @@ void TestInvocation::dumpResults() else dumpAudio(m_audioResult.get()); - if (m_dumpPixels && m_pixelResult) { - if (PlatformWebView::windowSnapshotEnabled()) { + if (m_dumpPixels) { + if (m_pixelResult) + dumpPixelsAndCompareWithExpected(m_pixelResult.get(), m_repaintRects.get(), TestInvocation::SnapshotResultType::WebContents); + else if (m_pixelResultIsPending) { m_gotRepaint = false; - WKPageForceRepaint(TestController::shared().mainWebView()->page(), this, TestInvocation::forceRepaintDoneCallback); - TestController::shared().runUntil(m_gotRepaint, TestController::ShortTimeout); + WKPageForceRepaint(TestController::singleton().mainWebView()->page(), this, TestInvocation::forceRepaintDoneCallback); + TestController::singleton().runUntil(m_gotRepaint, shortTimeout()); if (!m_gotRepaint) { m_errorMessage = "Timed out waiting for pre-pixel dump repaint\n"; m_webProcessIsUnresponsive = true; return; } + + WKRetainPtr<WKImageRef> windowSnapshot = TestController::singleton().mainWebView()->windowSnapshotImage(); + dumpPixelsAndCompareWithExpected(windowSnapshot.get(), m_repaintRects.get(), TestInvocation::SnapshotResultType::WebView); } - dumpPixelsAndCompareWithExpected(m_pixelResult.get(), m_repaintRects.get()); } fputs("#EOF\n", stdout); @@ -374,7 +327,7 @@ void TestInvocation::didReceiveMessageFromInjectedBundle(WKStringRef messageName m_gotFinalMessage = true; m_error = true; m_errorMessage = "FAIL\n"; - TestController::shared().notifyDone(); + TestController::singleton().notifyDone(); return; } @@ -383,7 +336,7 @@ void TestInvocation::didReceiveMessageFromInjectedBundle(WKStringRef messageName WKStringRef messageBodyString = static_cast<WKStringRef>(messageBody); if (WKStringIsEqualToUTF8CString(messageBodyString, "BeginTest")) { m_gotInitialResponse = true; - TestController::shared().notifyDone(); + TestController::singleton().notifyDone(); return; } @@ -394,9 +347,15 @@ void TestInvocation::didReceiveMessageFromInjectedBundle(WKStringRef messageName ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID()); WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody); - WKRetainPtr<WKStringRef> pixelResultKey = adoptWK(WKStringCreateWithUTF8CString("PixelResult")); - m_pixelResult = static_cast<WKImageRef>(WKDictionaryGetItemForKey(messageBodyDictionary, pixelResultKey.get())); - ASSERT(!m_pixelResult || m_dumpPixels); + WKRetainPtr<WKStringRef> pixelResultIsPendingKey = adoptWK(WKStringCreateWithUTF8CString("PixelResultIsPending")); + WKBooleanRef pixelResultIsPending = static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(messageBodyDictionary, pixelResultIsPendingKey.get())); + m_pixelResultIsPending = WKBooleanGetValue(pixelResultIsPending); + + if (!m_pixelResultIsPending) { + WKRetainPtr<WKStringRef> pixelResultKey = adoptWK(WKStringCreateWithUTF8CString("PixelResult")); + m_pixelResult = static_cast<WKImageRef>(WKDictionaryGetItemForKey(messageBodyDictionary, pixelResultKey.get())); + ASSERT(!m_pixelResult || m_dumpPixels); + } WKRetainPtr<WKStringRef> repaintRectsKey = adoptWK(WKStringCreateWithUTF8CString("RepaintRects")); m_repaintRects = static_cast<WKArrayRef>(WKDictionaryGetItemForKey(messageBodyDictionary, repaintRectsKey.get())); @@ -405,7 +364,7 @@ void TestInvocation::didReceiveMessageFromInjectedBundle(WKStringRef messageName m_audioResult = static_cast<WKDataRef>(WKDictionaryGetItemForKey(messageBodyDictionary, audioResultKey.get())); m_gotFinalMessage = true; - TestController::shared().notifyDone(); + TestController::singleton().notifyDone(); return; } @@ -416,55 +375,69 @@ void TestInvocation::didReceiveMessageFromInjectedBundle(WKStringRef messageName return; } + if (WKStringIsEqualToUTF8CString(messageName, "DumpToStdErr")) { + ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID()); + WKStringRef textOutput = static_cast<WKStringRef>(messageBody); + fprintf(stderr, "%s", toWTFString(textOutput).utf8().data()); + return; + } + if (WKStringIsEqualToUTF8CString(messageName, "BeforeUnloadReturnValue")) { ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID()); WKBooleanRef beforeUnloadReturnValue = static_cast<WKBooleanRef>(messageBody); - TestController::shared().setBeforeUnloadReturnValue(WKBooleanGetValue(beforeUnloadReturnValue)); + TestController::singleton().setBeforeUnloadReturnValue(WKBooleanGetValue(beforeUnloadReturnValue)); return; } if (WKStringIsEqualToUTF8CString(messageName, "AddChromeInputField")) { - TestController::shared().mainWebView()->addChromeInputField(); + TestController::singleton().mainWebView()->addChromeInputField(); WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CallAddChromeInputFieldCallback")); - WKContextPostMessageToInjectedBundle(TestController::shared().context(), messageName.get(), 0); + WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0); return; } if (WKStringIsEqualToUTF8CString(messageName, "RemoveChromeInputField")) { - TestController::shared().mainWebView()->removeChromeInputField(); + TestController::singleton().mainWebView()->removeChromeInputField(); WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CallRemoveChromeInputFieldCallback")); - WKContextPostMessageToInjectedBundle(TestController::shared().context(), messageName.get(), 0); + WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0); return; } if (WKStringIsEqualToUTF8CString(messageName, "FocusWebView")) { - TestController::shared().mainWebView()->makeWebViewFirstResponder(); + TestController::singleton().mainWebView()->makeWebViewFirstResponder(); WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CallFocusWebViewCallback")); - WKContextPostMessageToInjectedBundle(TestController::shared().context(), messageName.get(), 0); + WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), 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); + WKPageSetCustomBackingScaleFactor(TestController::singleton().mainWebView()->page(), backingScaleFactor); WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CallSetBackingScaleFactorCallback")); - WKContextPostMessageToInjectedBundle(TestController::shared().context(), messageName.get(), 0); + WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0); return; } if (WKStringIsEqualToUTF8CString(messageName, "SimulateWebNotificationClick")) { ASSERT(WKGetTypeID(messageBody) == WKUInt64GetTypeID()); uint64_t notificationID = WKUInt64GetValue(static_cast<WKUInt64Ref>(messageBody)); - TestController::shared().simulateWebNotificationClick(notificationID); + TestController::singleton().simulateWebNotificationClick(notificationID); + return; + } + + if (WKStringIsEqualToUTF8CString(messageName, "SetAddsVisitedLinks")) { + ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID()); + WKBooleanRef enabledWK = static_cast<WKBooleanRef>(messageBody); + WKPageSetAddsVisitedLinks(TestController::singleton().mainWebView()->page(), WKBooleanGetValue(enabledWK)); return; } if (WKStringIsEqualToUTF8CString(messageName, "SetGeolocationPermission")) { ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID()); WKBooleanRef enabledWK = static_cast<WKBooleanRef>(messageBody); - TestController::shared().setGeolocationPermission(WKBooleanGetValue(enabledWK)); + TestController::singleton().setGeolocationPermission(WKBooleanGetValue(enabledWK)); return; } @@ -516,14 +489,60 @@ void TestInvocation::didReceiveMessageFromInjectedBundle(WKStringRef messageName WKDoubleRef speedWK = static_cast<WKDoubleRef>(WKDictionaryGetItemForKey(messageBodyDictionary, speedKeyWK.get())); double speed = WKDoubleGetValue(speedWK); - TestController::shared().setMockGeolocationPosition(latitude, longitude, accuracy, providesAltitude, altitude, providesAltitudeAccuracy, altitudeAccuracy, providesHeading, heading, providesSpeed, speed); + TestController::singleton().setMockGeolocationPosition(latitude, longitude, accuracy, providesAltitude, altitude, providesAltitudeAccuracy, altitudeAccuracy, providesHeading, heading, providesSpeed, speed); return; } if (WKStringIsEqualToUTF8CString(messageName, "SetMockGeolocationPositionUnavailableError")) { ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID()); WKStringRef errorMessage = static_cast<WKStringRef>(messageBody); - TestController::shared().setMockGeolocationPositionUnavailableError(errorMessage); + TestController::singleton().setMockGeolocationPositionUnavailableError(errorMessage); + return; + } + + if (WKStringIsEqualToUTF8CString(messageName, "SetUserMediaPermission")) { + ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID()); + WKBooleanRef enabledWK = static_cast<WKBooleanRef>(messageBody); + TestController::singleton().setUserMediaPermission(WKBooleanGetValue(enabledWK)); + return; + } + + if (WKStringIsEqualToUTF8CString(messageName, "SetUserMediaPersistentPermissionForOrigin")) { + ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID()); + WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody); + + WKRetainPtr<WKStringRef> permissionKeyWK(AdoptWK, WKStringCreateWithUTF8CString("permission")); + WKBooleanRef permissionWK = static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(messageBodyDictionary, permissionKeyWK.get())); + bool permission = WKBooleanGetValue(permissionWK); + + WKRetainPtr<WKStringRef> originKey(AdoptWK, WKStringCreateWithUTF8CString("origin")); + WKStringRef originWK = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, originKey.get())); + + WKRetainPtr<WKStringRef> parentOriginKey(AdoptWK, WKStringCreateWithUTF8CString("parentOrigin")); + WKStringRef parentOriginWK = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, parentOriginKey.get())); + + TestController::singleton().setUserMediaPersistentPermissionForOrigin(permission, originWK, parentOriginWK); + return; + } + + if (WKStringIsEqualToUTF8CString(messageName, "ResetUserMediaPermissionRequestCountForOrigin")) { + ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID()); + WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody); + + WKRetainPtr<WKStringRef> originKey(AdoptWK, WKStringCreateWithUTF8CString("origin")); + WKStringRef originWK = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, originKey.get())); + + WKRetainPtr<WKStringRef> parentOriginKey(AdoptWK, WKStringCreateWithUTF8CString("parentOrigin")); + WKStringRef parentOriginWK = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, parentOriginKey.get())); + + TestController::singleton().resetUserMediaPermissionRequestCountForOrigin(originWK, parentOriginWK); + return; + } + + if (WKStringIsEqualToUTF8CString(messageName, "SetCacheModel")) { + ASSERT(WKGetTypeID(messageBody) == WKUInt64GetTypeID()); + uint64_t model = WKUInt64GetValue(static_cast<WKUInt64Ref>(messageBody)); + WKContextSetCacheModel(TestController::singleton().context(), model); return; } @@ -539,30 +558,26 @@ void TestInvocation::didReceiveMessageFromInjectedBundle(WKStringRef messageName WKBooleanRef permissiveWK = static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(messageBodyDictionary, permissiveKeyWK.get())); bool permissive = WKBooleanGetValue(permissiveWK); - TestController::shared().setCustomPolicyDelegate(enabled, permissive); + TestController::singleton().setCustomPolicyDelegate(enabled, permissive); return; } - if (WKStringIsEqualToUTF8CString(messageName, "SetVisibilityState")) { + if (WKStringIsEqualToUTF8CString(messageName, "SetHidden")) { ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID()); WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody); - WKRetainPtr<WKStringRef> visibilityStateKeyWK(AdoptWK, WKStringCreateWithUTF8CString("visibilityState")); - WKUInt64Ref visibilityStateWK = static_cast<WKUInt64Ref>(WKDictionaryGetItemForKey(messageBodyDictionary, visibilityStateKeyWK.get())); - WKPageVisibilityState visibilityState = static_cast<WKPageVisibilityState>(WKUInt64GetValue(visibilityStateWK)); - - WKRetainPtr<WKStringRef> isInitialKeyWK(AdoptWK, WKStringCreateWithUTF8CString("isInitialState")); - WKBooleanRef isInitialWK = static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(messageBodyDictionary, isInitialKeyWK.get())); - bool isInitialState = WKBooleanGetValue(isInitialWK); + WKRetainPtr<WKStringRef> isInitialKeyWK(AdoptWK, WKStringCreateWithUTF8CString("hidden")); + WKBooleanRef hiddenWK = static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(messageBodyDictionary, isInitialKeyWK.get())); + bool hidden = WKBooleanGetValue(hiddenWK); - TestController::shared().setVisibilityState(visibilityState, isInitialState); + TestController::singleton().setHidden(hidden); return; } if (WKStringIsEqualToUTF8CString(messageName, "ProcessWorkQueue")) { - if (TestController::shared().workQueueManager().processWorkQueue()) { + if (TestController::singleton().workQueueManager().processWorkQueue()) { WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("WorkQueueProcessedCallback")); - WKContextPostMessageToInjectedBundle(TestController::shared().context(), messageName.get(), 0); + WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0); } return; } @@ -570,14 +585,14 @@ void TestInvocation::didReceiveMessageFromInjectedBundle(WKStringRef messageName if (WKStringIsEqualToUTF8CString(messageName, "QueueBackNavigation")) { ASSERT(WKGetTypeID(messageBody) == WKUInt64GetTypeID()); uint64_t stepCount = WKUInt64GetValue(static_cast<WKUInt64Ref>(messageBody)); - TestController::shared().workQueueManager().queueBackNavigation(stepCount); + TestController::singleton().workQueueManager().queueBackNavigation(stepCount); return; } if (WKStringIsEqualToUTF8CString(messageName, "QueueForwardNavigation")) { ASSERT(WKGetTypeID(messageBody) == WKUInt64GetTypeID()); uint64_t stepCount = WKUInt64GetValue(static_cast<WKUInt64Ref>(messageBody)); - TestController::shared().workQueueManager().queueForwardNavigation(stepCount); + TestController::singleton().workQueueManager().queueForwardNavigation(stepCount); return; } @@ -591,7 +606,10 @@ void TestInvocation::didReceiveMessageFromInjectedBundle(WKStringRef messageName WKRetainPtr<WKStringRef> targetKey(AdoptWK, WKStringCreateWithUTF8CString("target")); WKStringRef targetWK = static_cast<WKStringRef>(WKDictionaryGetItemForKey(loadDataDictionary, targetKey.get())); - TestController::shared().workQueueManager().queueLoad(toWTFString(urlWK), toWTFString(targetWK)); + WKRetainPtr<WKStringRef> shouldOpenExternalURLsKey(AdoptWK, WKStringCreateWithUTF8CString("shouldOpenExternalURLs")); + WKBooleanRef shouldOpenExternalURLsValueWK = static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(loadDataDictionary, shouldOpenExternalURLsKey.get())); + + TestController::singleton().workQueueManager().queueLoad(toWTFString(urlWK), toWTFString(targetWK), WKBooleanGetValue(shouldOpenExternalURLsValueWK)); return; } @@ -608,54 +626,110 @@ void TestInvocation::didReceiveMessageFromInjectedBundle(WKStringRef messageName WKRetainPtr<WKStringRef> unreachableURLKey(AdoptWK, WKStringCreateWithUTF8CString("unreachableURL")); WKStringRef unreachableURLWK = static_cast<WKStringRef>(WKDictionaryGetItemForKey(loadDataDictionary, unreachableURLKey.get())); - TestController::shared().workQueueManager().queueLoadHTMLString(toWTFString(contentWK), baseURLWK ? toWTFString(baseURLWK) : String(), unreachableURLWK ? toWTFString(unreachableURLWK) : String()); + TestController::singleton().workQueueManager().queueLoadHTMLString(toWTFString(contentWK), baseURLWK ? toWTFString(baseURLWK) : String(), unreachableURLWK ? toWTFString(unreachableURLWK) : String()); return; } if (WKStringIsEqualToUTF8CString(messageName, "QueueReload")) { - TestController::shared().workQueueManager().queueReload(); + TestController::singleton().workQueueManager().queueReload(); return; } if (WKStringIsEqualToUTF8CString(messageName, "QueueLoadingScript")) { ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID()); WKStringRef script = static_cast<WKStringRef>(messageBody); - TestController::shared().workQueueManager().queueLoadingScript(toWTFString(script)); + TestController::singleton().workQueueManager().queueLoadingScript(toWTFString(script)); return; } if (WKStringIsEqualToUTF8CString(messageName, "QueueNonLoadingScript")) { ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID()); WKStringRef script = static_cast<WKStringRef>(messageBody); - TestController::shared().workQueueManager().queueNonLoadingScript(toWTFString(script)); + TestController::singleton().workQueueManager().queueNonLoadingScript(toWTFString(script)); + return; + } + + if (WKStringIsEqualToUTF8CString(messageName, "SetRejectsProtectionSpaceAndContinueForAuthenticationChallenges")) { + ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID()); + WKBooleanRef value = static_cast<WKBooleanRef>(messageBody); + TestController::singleton().setRejectsProtectionSpaceAndContinueForAuthenticationChallenges(WKBooleanGetValue(value)); return; } - if (WKStringIsEqualToUTF8CString(messageName, "SetHandlesAuthenticationChallenge")) { + if (WKStringIsEqualToUTF8CString(messageName, "SetHandlesAuthenticationChallenges")) { ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID()); WKBooleanRef value = static_cast<WKBooleanRef>(messageBody); - TestController::shared().setHandlesAuthenticationChallenges(WKBooleanGetValue(value)); + TestController::singleton().setHandlesAuthenticationChallenges(WKBooleanGetValue(value)); + return; + } + + if (WKStringIsEqualToUTF8CString(messageName, "SetShouldLogCanAuthenticateAgainstProtectionSpace")) { + ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID()); + WKBooleanRef value = static_cast<WKBooleanRef>(messageBody); + TestController::singleton().setShouldLogCanAuthenticateAgainstProtectionSpace(WKBooleanGetValue(value)); return; } if (WKStringIsEqualToUTF8CString(messageName, "SetAuthenticationUsername")) { ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID()); WKStringRef username = static_cast<WKStringRef>(messageBody); - TestController::shared().setAuthenticationUsername(toWTFString(username)); + TestController::singleton().setAuthenticationUsername(toWTFString(username)); return; } if (WKStringIsEqualToUTF8CString(messageName, "SetAuthenticationPassword")) { ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID()); WKStringRef password = static_cast<WKStringRef>(messageBody); - TestController::shared().setAuthenticationPassword(toWTFString(password)); + TestController::singleton().setAuthenticationPassword(toWTFString(password)); return; } if (WKStringIsEqualToUTF8CString(messageName, "SetBlockAllPlugins")) { ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID()); WKBooleanRef shouldBlock = static_cast<WKBooleanRef>(messageBody); - TestController::shared().setBlockAllPlugins(WKBooleanGetValue(shouldBlock)); + TestController::singleton().setBlockAllPlugins(WKBooleanGetValue(shouldBlock)); + return; + } + + if (WKStringIsEqualToUTF8CString(messageName, "SetShouldDecideNavigationPolicyAfterDelay")) { + ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID()); + WKBooleanRef value = static_cast<WKBooleanRef>(messageBody); + TestController::singleton().setShouldDecideNavigationPolicyAfterDelay(WKBooleanGetValue(value)); + return; + } + + if (WKStringIsEqualToUTF8CString(messageName, "SetNavigationGesturesEnabled")) { + ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID()); + WKBooleanRef value = static_cast<WKBooleanRef>(messageBody); + TestController::singleton().setNavigationGesturesEnabled(WKBooleanGetValue(value)); + return; + } + + if (WKStringIsEqualToUTF8CString(messageName, "SetIgnoresViewportScaleLimits")) { + ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID()); + WKBooleanRef value = static_cast<WKBooleanRef>(messageBody); + TestController::singleton().setIgnoresViewportScaleLimits(WKBooleanGetValue(value)); + return; + } + + if (WKStringIsEqualToUTF8CString(messageName, "SetShouldDownloadUndisplayableMIMETypes")) { + ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID()); + WKBooleanRef value = static_cast<WKBooleanRef>(messageBody); + TestController::singleton().setShouldDownloadUndisplayableMIMETypes(WKBooleanGetValue(value)); + return; + } + + if (WKStringIsEqualToUTF8CString(messageName, "RunUIProcessScript")) { + WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody); + WKRetainPtr<WKStringRef> scriptKey(AdoptWK, WKStringCreateWithUTF8CString("Script")); + WKRetainPtr<WKStringRef> callbackIDKey(AdoptWK, WKStringCreateWithUTF8CString("CallbackID")); + + UIScriptInvocationData* invocationData = new UIScriptInvocationData(); + invocationData->testInvocation = this; + invocationData->callbackID = (unsigned)WKUInt64GetValue(static_cast<WKUInt64Ref>(WKDictionaryGetItemForKey(messageBodyDictionary, callbackIDKey.get()))); + invocationData->scriptString = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, scriptKey.get())); + m_pendingUIScriptInvocationData = invocationData; + WKPageCallAfterNextPresentationUpdate(TestController::singleton().mainWebView()->page(), invocationData, runUISideScriptAfterUpdateCallback); return; } @@ -667,12 +741,32 @@ WKRetainPtr<WKTypeRef> TestInvocation::didReceiveSynchronousMessageFromInjectedB if (WKStringIsEqualToUTF8CString(messageName, "SetWindowIsKey")) { ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID()); WKBooleanRef isKeyValue = static_cast<WKBooleanRef>(messageBody); - TestController::shared().mainWebView()->setWindowIsKey(WKBooleanGetValue(isKeyValue)); - return 0; + TestController::singleton().mainWebView()->setWindowIsKey(WKBooleanGetValue(isKeyValue)); + return nullptr; + } + + if (WKStringIsEqualToUTF8CString(messageName, "SetViewSize")) { + ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID()); + + WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody); + WKRetainPtr<WKStringRef> widthKey(AdoptWK, WKStringCreateWithUTF8CString("width")); + WKRetainPtr<WKStringRef> heightKey(AdoptWK, WKStringCreateWithUTF8CString("height")); + + WKDoubleRef widthWK = static_cast<WKDoubleRef>(WKDictionaryGetItemForKey(messageBodyDictionary, widthKey.get())); + WKDoubleRef heightWK = static_cast<WKDoubleRef>(WKDictionaryGetItemForKey(messageBodyDictionary, heightKey.get())); + + TestController::singleton().mainWebView()->resizeTo(WKDoubleGetValue(widthWK), WKDoubleGetValue(heightWK)); + return nullptr; + } + + if (WKStringIsEqualToUTF8CString(messageName, "IsGeolocationClientActive")) { + bool isActive = TestController::singleton().isGeolocationProviderActive(); + WKRetainPtr<WKTypeRef> result(AdoptWK, WKBooleanCreate(isActive)); + return result; } if (WKStringIsEqualToUTF8CString(messageName, "IsWorkQueueEmpty")) { - bool isEmpty = TestController::shared().workQueueManager().isWorkQueueEmpty(); + bool isEmpty = TestController::singleton().workQueueManager().isWorkQueueEmpty(); WKRetainPtr<WKTypeRef> result(AdoptWK, WKBooleanCreate(isEmpty)); return result; } @@ -685,8 +779,234 @@ WKRetainPtr<WKTypeRef> TestInvocation::didReceiveSynchronousMessageFromInjectedB #endif return result; } + + if (WKStringIsEqualToUTF8CString(messageName, "SetAlwaysAcceptCookies")) { + WKBooleanRef accept = static_cast<WKBooleanRef>(messageBody); + WKHTTPCookieAcceptPolicy policy = WKBooleanGetValue(accept) ? kWKHTTPCookieAcceptPolicyAlways : kWKHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain; + // FIXME: This updates the policy in WebProcess and in NetworkProcess asynchronously, which might break some tests' expectations. + WKCookieManagerSetHTTPCookieAcceptPolicy(WKContextGetCookieManager(TestController::singleton().context()), policy); + return nullptr; + } + + if (WKStringIsEqualToUTF8CString(messageName, "ImageCountInGeneralPasteboard")) { + unsigned count = TestController::singleton().imageCountInGeneralPasteboard(); + WKRetainPtr<WKUInt64Ref> result(AdoptWK, WKUInt64Create(count)); + return result; + } + + if (WKStringIsEqualToUTF8CString(messageName, "DeleteAllIndexedDatabases")) { + WKWebsiteDataStoreRemoveAllIndexedDatabases(WKContextGetWebsiteDataStore(TestController::singleton().context())); + return nullptr; + } + +#if PLATFORM(MAC) + if (WKStringIsEqualToUTF8CString(messageName, "ConnectMockGamepad")) { + ASSERT(WKGetTypeID(messageBody) == WKUInt64GetTypeID()); + + uint64_t index = WKUInt64GetValue(static_cast<WKUInt64Ref>(messageBody)); + WebCoreTestSupport::connectMockGamepad(index); + + return nullptr; + } + + if (WKStringIsEqualToUTF8CString(messageName, "DisconnectMockGamepad")) { + ASSERT(WKGetTypeID(messageBody) == WKUInt64GetTypeID()); + + uint64_t index = WKUInt64GetValue(static_cast<WKUInt64Ref>(messageBody)); + WebCoreTestSupport::disconnectMockGamepad(index); + + return nullptr; + } + + if (WKStringIsEqualToUTF8CString(messageName, "SetMockGamepadDetails")) { + ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID()); + + WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody); + WKRetainPtr<WKStringRef> gamepadIndexKey(AdoptWK, WKStringCreateWithUTF8CString("GamepadIndex")); + WKRetainPtr<WKStringRef> gamepadIDKey(AdoptWK, WKStringCreateWithUTF8CString("GamepadID")); + WKRetainPtr<WKStringRef> axisCountKey(AdoptWK, WKStringCreateWithUTF8CString("AxisCount")); + WKRetainPtr<WKStringRef> buttonCountKey(AdoptWK, WKStringCreateWithUTF8CString("ButtonCount")); + + WKUInt64Ref gamepadIndex = static_cast<WKUInt64Ref>(WKDictionaryGetItemForKey(messageBodyDictionary, gamepadIndexKey.get())); + WKStringRef gamepadID = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, gamepadIDKey.get())); + WKUInt64Ref axisCount = static_cast<WKUInt64Ref>(WKDictionaryGetItemForKey(messageBodyDictionary, axisCountKey.get())); + WKUInt64Ref buttonCount = static_cast<WKUInt64Ref>(WKDictionaryGetItemForKey(messageBodyDictionary, buttonCountKey.get())); + + WebCoreTestSupport::setMockGamepadDetails(WKUInt64GetValue(gamepadIndex), toWTFString(gamepadID), WKUInt64GetValue(axisCount), WKUInt64GetValue(buttonCount)); + return nullptr; + } + + if (WKStringIsEqualToUTF8CString(messageName, "SetMockGamepadAxisValue")) { + ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID()); + + WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody); + WKRetainPtr<WKStringRef> gamepadIndexKey(AdoptWK, WKStringCreateWithUTF8CString("GamepadIndex")); + WKRetainPtr<WKStringRef> axisIndexKey(AdoptWK, WKStringCreateWithUTF8CString("AxisIndex")); + WKRetainPtr<WKStringRef> valueKey(AdoptWK, WKStringCreateWithUTF8CString("Value")); + + WKUInt64Ref gamepadIndex = static_cast<WKUInt64Ref>(WKDictionaryGetItemForKey(messageBodyDictionary, gamepadIndexKey.get())); + WKUInt64Ref axisIndex = static_cast<WKUInt64Ref>(WKDictionaryGetItemForKey(messageBodyDictionary, axisIndexKey.get())); + WKDoubleRef value = static_cast<WKDoubleRef>(WKDictionaryGetItemForKey(messageBodyDictionary, valueKey.get())); + + WebCoreTestSupport::setMockGamepadAxisValue(WKUInt64GetValue(gamepadIndex), WKUInt64GetValue(axisIndex), WKDoubleGetValue(value)); + + return nullptr; + } + + if (WKStringIsEqualToUTF8CString(messageName, "SetMockGamepadButtonValue")) { + ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID()); + + WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody); + WKRetainPtr<WKStringRef> gamepadIndexKey(AdoptWK, WKStringCreateWithUTF8CString("GamepadIndex")); + WKRetainPtr<WKStringRef> buttonIndexKey(AdoptWK, WKStringCreateWithUTF8CString("ButtonIndex")); + WKRetainPtr<WKStringRef> valueKey(AdoptWK, WKStringCreateWithUTF8CString("Value")); + + WKUInt64Ref gamepadIndex = static_cast<WKUInt64Ref>(WKDictionaryGetItemForKey(messageBodyDictionary, gamepadIndexKey.get())); + WKUInt64Ref buttonIndex = static_cast<WKUInt64Ref>(WKDictionaryGetItemForKey(messageBodyDictionary, buttonIndexKey.get())); + WKDoubleRef value = static_cast<WKDoubleRef>(WKDictionaryGetItemForKey(messageBodyDictionary, valueKey.get())); + + WebCoreTestSupport::setMockGamepadButtonValue(WKUInt64GetValue(gamepadIndex), WKUInt64GetValue(buttonIndex), WKDoubleGetValue(value)); + + return nullptr; + } +#endif // PLATFORM(MAC) + + if (WKStringIsEqualToUTF8CString(messageName, "UserMediaPermissionRequestCountForOrigin")) { + ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID()); + WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody); + + WKRetainPtr<WKStringRef> originKey(AdoptWK, WKStringCreateWithUTF8CString("origin")); + WKStringRef originWK = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, originKey.get())); + + WKRetainPtr<WKStringRef> parentOriginKey(AdoptWK, WKStringCreateWithUTF8CString("parentOrigin")); + WKStringRef parentOriginWK = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, parentOriginKey.get())); + + unsigned count = TestController::singleton().userMediaPermissionRequestCountForOrigin(originWK, parentOriginWK); + WKRetainPtr<WKUInt64Ref> result(AdoptWK, WKUInt64Create(count)); + return result; + } + + if (WKStringIsEqualToUTF8CString(messageName, "SetStatisticsPrevalentResource")) { + ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID()); + + WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody); + WKRetainPtr<WKStringRef> hostNameKey(AdoptWK, WKStringCreateWithUTF8CString("HostName")); + WKRetainPtr<WKStringRef> valueKey(AdoptWK, WKStringCreateWithUTF8CString("Value")); + + WKStringRef hostName = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, hostNameKey.get())); + WKBooleanRef value = static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(messageBodyDictionary, valueKey.get())); + + TestController::singleton().setStatisticsPrevalentResource(hostName, WKBooleanGetValue(value)); + return nullptr; + } + + if (WKStringIsEqualToUTF8CString(messageName, "IsStatisticsPrevalentResource")) { + ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID()); + + WKStringRef hostName = static_cast<WKStringRef>(messageBody); + bool isPrevalent = TestController::singleton().isStatisticsPrevalentResource(hostName); + WKRetainPtr<WKTypeRef> result(AdoptWK, WKBooleanCreate(isPrevalent)); + return result; + } + + if (WKStringIsEqualToUTF8CString(messageName, "SetStatisticsHasHadUserInteraction")) { + ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID()); + + WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody); + WKRetainPtr<WKStringRef> hostNameKey(AdoptWK, WKStringCreateWithUTF8CString("HostName")); + WKRetainPtr<WKStringRef> valueKey(AdoptWK, WKStringCreateWithUTF8CString("Value")); + + WKStringRef hostName = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, hostNameKey.get())); + WKBooleanRef value = static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(messageBodyDictionary, valueKey.get())); + + TestController::singleton().setStatisticsHasHadUserInteraction(hostName, WKBooleanGetValue(value)); + return nullptr; + } + + if (WKStringIsEqualToUTF8CString(messageName, "IsStatisticsHasHadUserInteraction")) { + ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID()); + + WKStringRef hostName = static_cast<WKStringRef>(messageBody); + bool hasHadUserInteraction = TestController::singleton().isStatisticsHasHadUserInteraction(hostName); + WKRetainPtr<WKTypeRef> result(AdoptWK, WKBooleanCreate(hasHadUserInteraction)); + return result; + } + + if (WKStringIsEqualToUTF8CString(messageName, "SetStatisticsTimeToLiveUserInteraction")) { + ASSERT(WKGetTypeID(messageBody) == WKDoubleGetTypeID()); + WKDoubleRef seconds = static_cast<WKDoubleRef>(messageBody); + TestController::singleton().setStatisticsTimeToLiveUserInteraction(WKDoubleGetValue(seconds)); + return nullptr; + } + + if (WKStringIsEqualToUTF8CString(messageName, "StatisticsFireDataModificationHandler")) { + TestController::singleton().statisticsFireDataModificationHandler(); + return nullptr; + } + + if (WKStringIsEqualToUTF8CString(messageName, "StatisticsNotifyPagesWhenDataRecordsWereScanned")) { + ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID()); + WKBooleanRef value = static_cast<WKBooleanRef>(messageBody); + TestController::singleton().setStatisticsNotifyPagesWhenDataRecordsWereScanned(WKBooleanGetValue(value)); + return nullptr; + } + + if (WKStringIsEqualToUTF8CString(messageName, "StatisticsShouldClassifyResourcesBeforeDataRecordsRemoval")) { + ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID()); + WKBooleanRef value = static_cast<WKBooleanRef>(messageBody); + TestController::singleton().setStatisticsShouldClassifyResourcesBeforeDataRecordsRemoval(WKBooleanGetValue(value)); + return nullptr; + } + + if (WKStringIsEqualToUTF8CString(messageName, "SetStatisticsMinimumTimeBetweeenDataRecordsRemoval")) { + ASSERT(WKGetTypeID(messageBody) == WKDoubleGetTypeID()); + WKDoubleRef seconds = static_cast<WKDoubleRef>(messageBody); + TestController::singleton().setStatisticsMinimumTimeBetweeenDataRecordsRemoval(WKDoubleGetValue(seconds)); + return nullptr; + } + + if (WKStringIsEqualToUTF8CString(messageName, "StatisticsResetToConsistentState")) { + TestController::singleton().statisticsResetToConsistentState(); + return nullptr; + } + ASSERT_NOT_REACHED(); - return 0; + return nullptr; +} + +void TestInvocation::runUISideScriptAfterUpdateCallback(WKErrorRef, void* context) +{ + UIScriptInvocationData* data = static_cast<UIScriptInvocationData*>(context); + if (TestInvocation* invocation = data->testInvocation) { + RELEASE_ASSERT(TestController::singleton().isCurrentInvocation(invocation)); + invocation->runUISideScript(data->scriptString.get(), data->callbackID); + } + delete data; +} + +void TestInvocation::runUISideScript(WKStringRef script, unsigned scriptCallbackID) +{ + m_pendingUIScriptInvocationData = nullptr; + + if (!m_UIScriptContext) + m_UIScriptContext = std::make_unique<UIScriptContext>(*this); + + m_UIScriptContext->runUIScript(toWTFString(script), scriptCallbackID); +} + +void TestInvocation::uiScriptDidComplete(const String& result, unsigned scriptCallbackID) +{ + WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CallUISideScriptCallback")); + + WKRetainPtr<WKMutableDictionaryRef> messageBody(AdoptWK, WKMutableDictionaryCreate()); + WKRetainPtr<WKStringRef> resultKey(AdoptWK, WKStringCreateWithUTF8CString("Result")); + WKRetainPtr<WKStringRef> callbackIDKey(AdoptWK, WKStringCreateWithUTF8CString("CallbackID")); + WKRetainPtr<WKUInt64Ref> callbackIDValue = adoptWK(WKUInt64Create(scriptCallbackID)); + + WKDictionarySetItem(messageBody.get(), resultKey.get(), toWK(result).get()); + WKDictionarySetItem(messageBody.get(), callbackIDKey.get(), callbackIDValue.get()); + + WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), messageBody.get()); } void TestInvocation::outputText(const WTF::String& text) @@ -694,4 +1014,34 @@ void TestInvocation::outputText(const WTF::String& text) m_textOutput.append(text); } +void TestInvocation::didBeginSwipe() +{ + WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CallDidBeginSwipeCallback")); + WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0); +} + +void TestInvocation::willEndSwipe() +{ + WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CallWillEndSwipeCallback")); + WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0); +} + +void TestInvocation::didEndSwipe() +{ + WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CallDidEndSwipeCallback")); + WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0); +} + +void TestInvocation::didRemoveSwipeSnapshot() +{ + WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CallDidRemoveSwipeSnapshotCallback")); + WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0); +} + +void TestInvocation::notifyDownloadDone() +{ + WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("NotifyDownloadDone")); + WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0); +} + } // namespace WTR |