/* * 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 * 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 "UIScriptController.h" #include "WebCoreTestSupport.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #if PLATFORM(MAC) && !PLATFORM(IOS) #include #endif #if PLATFORM(COCOA) #include #endif using namespace JSC; using namespace WebKit; using namespace std; namespace WTR { TestInvocation::TestInvocation(WKURLRef url, const TestOptions& options) : m_options(options) , m_url(url) { WKRetainPtr urlString = adoptWK(WKURLCopyString(m_url.get())); size_t stringLength = WKStringGetLength(urlString.get()); Vector 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; } WKURLRef TestInvocation::url() const { return m_url.get(); } bool TestInvocation::urlContains(const char* searchString) const { return m_urlString.contains(searchString, false); } void TestInvocation::setIsPixelTest(const std::string& expectedPixelHash) { m_dumpPixels = true; m_expectedPixelHash = expectedPixelHash; } double TestInvocation::shortTimeout() const { if (!m_timeout) { // Running WKTR directly, without webkitpy. return TestController::defaultShortTimeout; } // 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; } bool TestInvocation::shouldLogFrameLoadDelegates() const { return urlContains("loading/"); } bool TestInvocation::shouldLogHistoryClientCallbacks() const { return urlContains("globalhistory/"); } void TestInvocation::invoke() { TestController::singleton().configureViewForTest(*this); WKPageSetAddsVisitedLinks(TestController::singleton().mainWebView()->page(), false); m_textOutput.clear(); TestController::singleton().setShouldLogHistoryClientCallbacks(shouldLogHistoryClientCallbacks()); WKCookieManagerSetHTTPCookieAcceptPolicy(WKContextGetCookieManager(TestController::singleton().context()), kWKHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain); // FIXME: We should clear out visited links here. WKRetainPtr messageName = adoptWK(WKStringCreateWithUTF8CString("BeginTest")); WKRetainPtr beginTestMessageBody = adoptWK(WKMutableDictionaryCreate()); WKRetainPtr dumpFrameLoadDelegatesKey = adoptWK(WKStringCreateWithUTF8CString("DumpFrameLoadDelegates")); WKRetainPtr dumpFrameLoadDelegatesValue = adoptWK(WKBooleanCreate(shouldLogFrameLoadDelegates())); WKDictionarySetItem(beginTestMessageBody.get(), dumpFrameLoadDelegatesKey.get(), dumpFrameLoadDelegatesValue.get()); WKRetainPtr useFlexibleViewportKey = adoptWK(WKStringCreateWithUTF8CString("UseFlexibleViewport")); WKRetainPtr useFlexibleViewportValue = adoptWK(WKBooleanCreate(options().useFlexibleViewport)); WKDictionarySetItem(beginTestMessageBody.get(), useFlexibleViewportKey.get(), useFlexibleViewportValue.get()); WKRetainPtr dumpPixelsKey = adoptWK(WKStringCreateWithUTF8CString("DumpPixels")); WKRetainPtr dumpPixelsValue = adoptWK(WKBooleanCreate(m_dumpPixels)); WKDictionarySetItem(beginTestMessageBody.get(), dumpPixelsKey.get(), dumpPixelsValue.get()); WKRetainPtr useWaitToDumpWatchdogTimerKey = adoptWK(WKStringCreateWithUTF8CString("UseWaitToDumpWatchdogTimer")); WKRetainPtr useWaitToDumpWatchdogTimerValue = adoptWK(WKBooleanCreate(TestController::singleton().useWaitToDumpWatchdogTimer())); WKDictionarySetItem(beginTestMessageBody.get(), useWaitToDumpWatchdogTimerKey.get(), useWaitToDumpWatchdogTimerValue.get()); WKRetainPtr timeoutKey = adoptWK(WKStringCreateWithUTF8CString("Timeout")); WKRetainPtr timeoutValue = adoptWK(WKUInt64Create(m_timeout)); WKDictionarySetItem(beginTestMessageBody.get(), timeoutKey.get(), timeoutValue.get()); WKRetainPtr dumpJSConsoleLogInStdErrKey = adoptWK(WKStringCreateWithUTF8CString("DumpJSConsoleLogInStdErr")); WKRetainPtr dumpJSConsoleLogInStdErrValue = adoptWK(WKBooleanCreate(m_dumpJSConsoleLogInStdErr)); WKDictionarySetItem(beginTestMessageBody.get(), dumpJSConsoleLogInStdErrKey.get(), dumpJSConsoleLogInStdErrValue.get()); 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; goto end; } if (m_error) goto end; WKPageLoadURLWithShouldOpenExternalURLsPolicy(TestController::singleton().mainWebView()->page(), m_url.get(), shouldOpenExternalURLs); TestController::singleton().runUntil(m_gotFinalMessage, TestController::noTimeout); if (m_error) goto end; dumpResults(); end: #if !PLATFORM(IOS) if (m_gotInitialResponse) WKInspectorClose(WKPageGetInspector(TestController::singleton().mainWebView()->page())); #endif // !PLATFORM(IOS) if (m_webProcessIsUnresponsive) 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() { dumpWebProcessUnresponsiveness(m_errorMessage.c_str()); } void TestInvocation::dumpWebProcessUnresponsiveness(const char* errorMessage) { 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(pid)); #else snprintf(buffer, sizeof(buffer), "#PROCESS UNRESPONSIVE - %s\n", TestController::webProcessName()); #endif 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) { printf("Content-Type: text/plain\n"); if (textToStdout) fputs(textToStdout, stdout); if (textToStderr) fputs(textToStderr, stderr); fputs("#EOF\n", stdout); fputs("#EOF\n", stderr); if (seenError) fputs("#EOF\n", stdout); fflush(stdout); fflush(stderr); } 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(context); RELEASE_ASSERT(TestController::singleton().isCurrentInvocation(testInvocation)); testInvocation->m_gotRepaint = true; TestController::singleton().notifyDone(); } void TestInvocation::dumpResults() { if (m_textOutput.length() || !m_audioResult) dump(m_textOutput.toString().utf8().data()); else dumpAudio(m_audioResult.get()); 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::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 windowSnapshot = TestController::singleton().mainWebView()->windowSnapshotImage(); dumpPixelsAndCompareWithExpected(windowSnapshot.get(), m_repaintRects.get(), TestInvocation::SnapshotResultType::WebView); } } fputs("#EOF\n", stdout); fflush(stdout); fflush(stderr); } void TestInvocation::dumpAudio(WKDataRef audioData) { size_t length = WKDataGetSize(audioData); if (!length) return; const unsigned char* data = WKDataGetBytes(audioData); printf("Content-Type: audio/wav\n"); printf("Content-Length: %lu\n", static_cast(length)); fwrite(data, 1, length, stdout); printf("#EOF\n"); fprintf(stderr, "#EOF\n"); } 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; m_errorMessage = "FAIL\n"; TestController::singleton().notifyDone(); return; } if (WKStringIsEqualToUTF8CString(messageName, "Ack")) { ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID()); WKStringRef messageBodyString = static_cast(messageBody); if (WKStringIsEqualToUTF8CString(messageBodyString, "BeginTest")) { m_gotInitialResponse = true; TestController::singleton().notifyDone(); return; } ASSERT_NOT_REACHED(); } if (WKStringIsEqualToUTF8CString(messageName, "Done")) { ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID()); WKDictionaryRef messageBodyDictionary = static_cast(messageBody); WKRetainPtr pixelResultIsPendingKey = adoptWK(WKStringCreateWithUTF8CString("PixelResultIsPending")); WKBooleanRef pixelResultIsPending = static_cast(WKDictionaryGetItemForKey(messageBodyDictionary, pixelResultIsPendingKey.get())); m_pixelResultIsPending = WKBooleanGetValue(pixelResultIsPending); if (!m_pixelResultIsPending) { WKRetainPtr pixelResultKey = adoptWK(WKStringCreateWithUTF8CString("PixelResult")); m_pixelResult = static_cast(WKDictionaryGetItemForKey(messageBodyDictionary, pixelResultKey.get())); ASSERT(!m_pixelResult || m_dumpPixels); } WKRetainPtr repaintRectsKey = adoptWK(WKStringCreateWithUTF8CString("RepaintRects")); m_repaintRects = static_cast(WKDictionaryGetItemForKey(messageBodyDictionary, repaintRectsKey.get())); WKRetainPtr audioResultKey = adoptWK(WKStringCreateWithUTF8CString("AudioResult")); m_audioResult = static_cast(WKDictionaryGetItemForKey(messageBodyDictionary, audioResultKey.get())); m_gotFinalMessage = true; TestController::singleton().notifyDone(); return; } if (WKStringIsEqualToUTF8CString(messageName, "TextOutput")) { ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID()); WKStringRef textOutput = static_cast(messageBody); m_textOutput.append(toWTFString(textOutput)); return; } if (WKStringIsEqualToUTF8CString(messageName, "DumpToStdErr")) { ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID()); WKStringRef textOutput = static_cast(messageBody); fprintf(stderr, "%s", toWTFString(textOutput).utf8().data()); return; } if (WKStringIsEqualToUTF8CString(messageName, "BeforeUnloadReturnValue")) { ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID()); WKBooleanRef beforeUnloadReturnValue = static_cast(messageBody); TestController::singleton().setBeforeUnloadReturnValue(WKBooleanGetValue(beforeUnloadReturnValue)); return; } if (WKStringIsEqualToUTF8CString(messageName, "AddChromeInputField")) { TestController::singleton().mainWebView()->addChromeInputField(); WKRetainPtr messageName = adoptWK(WKStringCreateWithUTF8CString("CallAddChromeInputFieldCallback")); WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0); return; } if (WKStringIsEqualToUTF8CString(messageName, "RemoveChromeInputField")) { TestController::singleton().mainWebView()->removeChromeInputField(); WKRetainPtr messageName = adoptWK(WKStringCreateWithUTF8CString("CallRemoveChromeInputFieldCallback")); WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0); return; } if (WKStringIsEqualToUTF8CString(messageName, "FocusWebView")) { TestController::singleton().mainWebView()->makeWebViewFirstResponder(); WKRetainPtr messageName = adoptWK(WKStringCreateWithUTF8CString("CallFocusWebViewCallback")); WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0); return; } if (WKStringIsEqualToUTF8CString(messageName, "SetBackingScaleFactor")) { ASSERT(WKGetTypeID(messageBody) == WKDoubleGetTypeID()); double backingScaleFactor = WKDoubleGetValue(static_cast(messageBody)); WKPageSetCustomBackingScaleFactor(TestController::singleton().mainWebView()->page(), backingScaleFactor); WKRetainPtr messageName = adoptWK(WKStringCreateWithUTF8CString("CallSetBackingScaleFactorCallback")); WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0); return; } if (WKStringIsEqualToUTF8CString(messageName, "SimulateWebNotificationClick")) { ASSERT(WKGetTypeID(messageBody) == WKUInt64GetTypeID()); uint64_t notificationID = WKUInt64GetValue(static_cast(messageBody)); TestController::singleton().simulateWebNotificationClick(notificationID); return; } if (WKStringIsEqualToUTF8CString(messageName, "SetAddsVisitedLinks")) { ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID()); WKBooleanRef enabledWK = static_cast(messageBody); WKPageSetAddsVisitedLinks(TestController::singleton().mainWebView()->page(), WKBooleanGetValue(enabledWK)); return; } if (WKStringIsEqualToUTF8CString(messageName, "SetGeolocationPermission")) { ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID()); WKBooleanRef enabledWK = static_cast(messageBody); TestController::singleton().setGeolocationPermission(WKBooleanGetValue(enabledWK)); return; } if (WKStringIsEqualToUTF8CString(messageName, "SetMockGeolocationPosition")) { ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID()); WKDictionaryRef messageBodyDictionary = static_cast(messageBody); WKRetainPtr latitudeKeyWK(AdoptWK, WKStringCreateWithUTF8CString("latitude")); WKDoubleRef latitudeWK = static_cast(WKDictionaryGetItemForKey(messageBodyDictionary, latitudeKeyWK.get())); double latitude = WKDoubleGetValue(latitudeWK); WKRetainPtr longitudeKeyWK(AdoptWK, WKStringCreateWithUTF8CString("longitude")); WKDoubleRef longitudeWK = static_cast(WKDictionaryGetItemForKey(messageBodyDictionary, longitudeKeyWK.get())); double longitude = WKDoubleGetValue(longitudeWK); WKRetainPtr accuracyKeyWK(AdoptWK, WKStringCreateWithUTF8CString("accuracy")); WKDoubleRef accuracyWK = static_cast(WKDictionaryGetItemForKey(messageBodyDictionary, accuracyKeyWK.get())); double accuracy = WKDoubleGetValue(accuracyWK); WKRetainPtr providesAltitudeKeyWK(AdoptWK, WKStringCreateWithUTF8CString("providesAltitude")); WKBooleanRef providesAltitudeWK = static_cast(WKDictionaryGetItemForKey(messageBodyDictionary, providesAltitudeKeyWK.get())); bool providesAltitude = WKBooleanGetValue(providesAltitudeWK); WKRetainPtr altitudeKeyWK(AdoptWK, WKStringCreateWithUTF8CString("altitude")); WKDoubleRef altitudeWK = static_cast(WKDictionaryGetItemForKey(messageBodyDictionary, altitudeKeyWK.get())); double altitude = WKDoubleGetValue(altitudeWK); WKRetainPtr providesAltitudeAccuracyKeyWK(AdoptWK, WKStringCreateWithUTF8CString("providesAltitudeAccuracy")); WKBooleanRef providesAltitudeAccuracyWK = static_cast(WKDictionaryGetItemForKey(messageBodyDictionary, providesAltitudeAccuracyKeyWK.get())); bool providesAltitudeAccuracy = WKBooleanGetValue(providesAltitudeAccuracyWK); WKRetainPtr altitudeAccuracyKeyWK(AdoptWK, WKStringCreateWithUTF8CString("altitudeAccuracy")); WKDoubleRef altitudeAccuracyWK = static_cast(WKDictionaryGetItemForKey(messageBodyDictionary, altitudeAccuracyKeyWK.get())); double altitudeAccuracy = WKDoubleGetValue(altitudeAccuracyWK); WKRetainPtr providesHeadingKeyWK(AdoptWK, WKStringCreateWithUTF8CString("providesHeading")); WKBooleanRef providesHeadingWK = static_cast(WKDictionaryGetItemForKey(messageBodyDictionary, providesHeadingKeyWK.get())); bool providesHeading = WKBooleanGetValue(providesHeadingWK); WKRetainPtr headingKeyWK(AdoptWK, WKStringCreateWithUTF8CString("heading")); WKDoubleRef headingWK = static_cast(WKDictionaryGetItemForKey(messageBodyDictionary, headingKeyWK.get())); double heading = WKDoubleGetValue(headingWK); WKRetainPtr providesSpeedKeyWK(AdoptWK, WKStringCreateWithUTF8CString("providesSpeed")); WKBooleanRef providesSpeedWK = static_cast(WKDictionaryGetItemForKey(messageBodyDictionary, providesSpeedKeyWK.get())); bool providesSpeed = WKBooleanGetValue(providesSpeedWK); WKRetainPtr speedKeyWK(AdoptWK, WKStringCreateWithUTF8CString("speed")); WKDoubleRef speedWK = static_cast(WKDictionaryGetItemForKey(messageBodyDictionary, speedKeyWK.get())); double speed = WKDoubleGetValue(speedWK); 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(messageBody); TestController::singleton().setMockGeolocationPositionUnavailableError(errorMessage); return; } if (WKStringIsEqualToUTF8CString(messageName, "SetUserMediaPermission")) { ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID()); WKBooleanRef enabledWK = static_cast(messageBody); TestController::singleton().setUserMediaPermission(WKBooleanGetValue(enabledWK)); return; } if (WKStringIsEqualToUTF8CString(messageName, "SetUserMediaPersistentPermissionForOrigin")) { ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID()); WKDictionaryRef messageBodyDictionary = static_cast(messageBody); WKRetainPtr permissionKeyWK(AdoptWK, WKStringCreateWithUTF8CString("permission")); WKBooleanRef permissionWK = static_cast(WKDictionaryGetItemForKey(messageBodyDictionary, permissionKeyWK.get())); bool permission = WKBooleanGetValue(permissionWK); WKRetainPtr originKey(AdoptWK, WKStringCreateWithUTF8CString("origin")); WKStringRef originWK = static_cast(WKDictionaryGetItemForKey(messageBodyDictionary, originKey.get())); WKRetainPtr parentOriginKey(AdoptWK, WKStringCreateWithUTF8CString("parentOrigin")); WKStringRef parentOriginWK = static_cast(WKDictionaryGetItemForKey(messageBodyDictionary, parentOriginKey.get())); TestController::singleton().setUserMediaPersistentPermissionForOrigin(permission, originWK, parentOriginWK); return; } if (WKStringIsEqualToUTF8CString(messageName, "ResetUserMediaPermissionRequestCountForOrigin")) { ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID()); WKDictionaryRef messageBodyDictionary = static_cast(messageBody); WKRetainPtr originKey(AdoptWK, WKStringCreateWithUTF8CString("origin")); WKStringRef originWK = static_cast(WKDictionaryGetItemForKey(messageBodyDictionary, originKey.get())); WKRetainPtr parentOriginKey(AdoptWK, WKStringCreateWithUTF8CString("parentOrigin")); WKStringRef parentOriginWK = static_cast(WKDictionaryGetItemForKey(messageBodyDictionary, parentOriginKey.get())); TestController::singleton().resetUserMediaPermissionRequestCountForOrigin(originWK, parentOriginWK); return; } if (WKStringIsEqualToUTF8CString(messageName, "SetCacheModel")) { ASSERT(WKGetTypeID(messageBody) == WKUInt64GetTypeID()); uint64_t model = WKUInt64GetValue(static_cast(messageBody)); WKContextSetCacheModel(TestController::singleton().context(), model); return; } if (WKStringIsEqualToUTF8CString(messageName, "SetCustomPolicyDelegate")) { ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID()); WKDictionaryRef messageBodyDictionary = static_cast(messageBody); WKRetainPtr enabledKeyWK(AdoptWK, WKStringCreateWithUTF8CString("enabled")); WKBooleanRef enabledWK = static_cast(WKDictionaryGetItemForKey(messageBodyDictionary, enabledKeyWK.get())); bool enabled = WKBooleanGetValue(enabledWK); WKRetainPtr permissiveKeyWK(AdoptWK, WKStringCreateWithUTF8CString("permissive")); WKBooleanRef permissiveWK = static_cast(WKDictionaryGetItemForKey(messageBodyDictionary, permissiveKeyWK.get())); bool permissive = WKBooleanGetValue(permissiveWK); TestController::singleton().setCustomPolicyDelegate(enabled, permissive); return; } if (WKStringIsEqualToUTF8CString(messageName, "SetHidden")) { ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID()); WKDictionaryRef messageBodyDictionary = static_cast(messageBody); WKRetainPtr isInitialKeyWK(AdoptWK, WKStringCreateWithUTF8CString("hidden")); WKBooleanRef hiddenWK = static_cast(WKDictionaryGetItemForKey(messageBodyDictionary, isInitialKeyWK.get())); bool hidden = WKBooleanGetValue(hiddenWK); TestController::singleton().setHidden(hidden); return; } if (WKStringIsEqualToUTF8CString(messageName, "ProcessWorkQueue")) { if (TestController::singleton().workQueueManager().processWorkQueue()) { WKRetainPtr messageName = adoptWK(WKStringCreateWithUTF8CString("WorkQueueProcessedCallback")); WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0); } return; } if (WKStringIsEqualToUTF8CString(messageName, "QueueBackNavigation")) { ASSERT(WKGetTypeID(messageBody) == WKUInt64GetTypeID()); uint64_t stepCount = WKUInt64GetValue(static_cast(messageBody)); TestController::singleton().workQueueManager().queueBackNavigation(stepCount); return; } if (WKStringIsEqualToUTF8CString(messageName, "QueueForwardNavigation")) { ASSERT(WKGetTypeID(messageBody) == WKUInt64GetTypeID()); uint64_t stepCount = WKUInt64GetValue(static_cast(messageBody)); TestController::singleton().workQueueManager().queueForwardNavigation(stepCount); return; } if (WKStringIsEqualToUTF8CString(messageName, "QueueLoad")) { ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID()); WKDictionaryRef loadDataDictionary = static_cast(messageBody); WKRetainPtr urlKey(AdoptWK, WKStringCreateWithUTF8CString("url")); WKStringRef urlWK = static_cast(WKDictionaryGetItemForKey(loadDataDictionary, urlKey.get())); WKRetainPtr targetKey(AdoptWK, WKStringCreateWithUTF8CString("target")); WKStringRef targetWK = static_cast(WKDictionaryGetItemForKey(loadDataDictionary, targetKey.get())); WKRetainPtr shouldOpenExternalURLsKey(AdoptWK, WKStringCreateWithUTF8CString("shouldOpenExternalURLs")); WKBooleanRef shouldOpenExternalURLsValueWK = static_cast(WKDictionaryGetItemForKey(loadDataDictionary, shouldOpenExternalURLsKey.get())); TestController::singleton().workQueueManager().queueLoad(toWTFString(urlWK), toWTFString(targetWK), WKBooleanGetValue(shouldOpenExternalURLsValueWK)); return; } if (WKStringIsEqualToUTF8CString(messageName, "QueueLoadHTMLString")) { ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID()); WKDictionaryRef loadDataDictionary = static_cast(messageBody); WKRetainPtr contentKey(AdoptWK, WKStringCreateWithUTF8CString("content")); WKStringRef contentWK = static_cast(WKDictionaryGetItemForKey(loadDataDictionary, contentKey.get())); WKRetainPtr baseURLKey(AdoptWK, WKStringCreateWithUTF8CString("baseURL")); WKStringRef baseURLWK = static_cast(WKDictionaryGetItemForKey(loadDataDictionary, baseURLKey.get())); WKRetainPtr unreachableURLKey(AdoptWK, WKStringCreateWithUTF8CString("unreachableURL")); WKStringRef unreachableURLWK = static_cast(WKDictionaryGetItemForKey(loadDataDictionary, unreachableURLKey.get())); TestController::singleton().workQueueManager().queueLoadHTMLString(toWTFString(contentWK), baseURLWK ? toWTFString(baseURLWK) : String(), unreachableURLWK ? toWTFString(unreachableURLWK) : String()); return; } if (WKStringIsEqualToUTF8CString(messageName, "QueueReload")) { TestController::singleton().workQueueManager().queueReload(); return; } if (WKStringIsEqualToUTF8CString(messageName, "QueueLoadingScript")) { ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID()); WKStringRef script = static_cast(messageBody); TestController::singleton().workQueueManager().queueLoadingScript(toWTFString(script)); return; } if (WKStringIsEqualToUTF8CString(messageName, "QueueNonLoadingScript")) { ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID()); WKStringRef script = static_cast(messageBody); TestController::singleton().workQueueManager().queueNonLoadingScript(toWTFString(script)); return; } if (WKStringIsEqualToUTF8CString(messageName, "SetRejectsProtectionSpaceAndContinueForAuthenticationChallenges")) { ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID()); WKBooleanRef value = static_cast(messageBody); TestController::singleton().setRejectsProtectionSpaceAndContinueForAuthenticationChallenges(WKBooleanGetValue(value)); return; } if (WKStringIsEqualToUTF8CString(messageName, "SetHandlesAuthenticationChallenges")) { ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID()); WKBooleanRef value = static_cast(messageBody); TestController::singleton().setHandlesAuthenticationChallenges(WKBooleanGetValue(value)); return; } if (WKStringIsEqualToUTF8CString(messageName, "SetShouldLogCanAuthenticateAgainstProtectionSpace")) { ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID()); WKBooleanRef value = static_cast(messageBody); TestController::singleton().setShouldLogCanAuthenticateAgainstProtectionSpace(WKBooleanGetValue(value)); return; } if (WKStringIsEqualToUTF8CString(messageName, "SetAuthenticationUsername")) { ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID()); WKStringRef username = static_cast(messageBody); TestController::singleton().setAuthenticationUsername(toWTFString(username)); return; } if (WKStringIsEqualToUTF8CString(messageName, "SetAuthenticationPassword")) { ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID()); WKStringRef password = static_cast(messageBody); TestController::singleton().setAuthenticationPassword(toWTFString(password)); return; } if (WKStringIsEqualToUTF8CString(messageName, "SetBlockAllPlugins")) { ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID()); WKBooleanRef shouldBlock = static_cast(messageBody); TestController::singleton().setBlockAllPlugins(WKBooleanGetValue(shouldBlock)); return; } if (WKStringIsEqualToUTF8CString(messageName, "SetShouldDecideNavigationPolicyAfterDelay")) { ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID()); WKBooleanRef value = static_cast(messageBody); TestController::singleton().setShouldDecideNavigationPolicyAfterDelay(WKBooleanGetValue(value)); return; } if (WKStringIsEqualToUTF8CString(messageName, "SetNavigationGesturesEnabled")) { ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID()); WKBooleanRef value = static_cast(messageBody); TestController::singleton().setNavigationGesturesEnabled(WKBooleanGetValue(value)); return; } if (WKStringIsEqualToUTF8CString(messageName, "SetIgnoresViewportScaleLimits")) { ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID()); WKBooleanRef value = static_cast(messageBody); TestController::singleton().setIgnoresViewportScaleLimits(WKBooleanGetValue(value)); return; } if (WKStringIsEqualToUTF8CString(messageName, "SetShouldDownloadUndisplayableMIMETypes")) { ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID()); WKBooleanRef value = static_cast(messageBody); TestController::singleton().setShouldDownloadUndisplayableMIMETypes(WKBooleanGetValue(value)); return; } if (WKStringIsEqualToUTF8CString(messageName, "RunUIProcessScript")) { WKDictionaryRef messageBodyDictionary = static_cast(messageBody); WKRetainPtr scriptKey(AdoptWK, WKStringCreateWithUTF8CString("Script")); WKRetainPtr callbackIDKey(AdoptWK, WKStringCreateWithUTF8CString("CallbackID")); UIScriptInvocationData* invocationData = new UIScriptInvocationData(); invocationData->testInvocation = this; invocationData->callbackID = (unsigned)WKUInt64GetValue(static_cast(WKDictionaryGetItemForKey(messageBodyDictionary, callbackIDKey.get()))); invocationData->scriptString = static_cast(WKDictionaryGetItemForKey(messageBodyDictionary, scriptKey.get())); m_pendingUIScriptInvocationData = invocationData; WKPageCallAfterNextPresentationUpdate(TestController::singleton().mainWebView()->page(), invocationData, runUISideScriptAfterUpdateCallback); return; } ASSERT_NOT_REACHED(); } WKRetainPtr TestInvocation::didReceiveSynchronousMessageFromInjectedBundle(WKStringRef messageName, WKTypeRef messageBody) { if (WKStringIsEqualToUTF8CString(messageName, "SetWindowIsKey")) { ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID()); WKBooleanRef isKeyValue = static_cast(messageBody); TestController::singleton().mainWebView()->setWindowIsKey(WKBooleanGetValue(isKeyValue)); return nullptr; } if (WKStringIsEqualToUTF8CString(messageName, "SetViewSize")) { ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID()); WKDictionaryRef messageBodyDictionary = static_cast(messageBody); WKRetainPtr widthKey(AdoptWK, WKStringCreateWithUTF8CString("width")); WKRetainPtr heightKey(AdoptWK, WKStringCreateWithUTF8CString("height")); WKDoubleRef widthWK = static_cast(WKDictionaryGetItemForKey(messageBodyDictionary, widthKey.get())); WKDoubleRef heightWK = static_cast(WKDictionaryGetItemForKey(messageBodyDictionary, heightKey.get())); TestController::singleton().mainWebView()->resizeTo(WKDoubleGetValue(widthWK), WKDoubleGetValue(heightWK)); return nullptr; } if (WKStringIsEqualToUTF8CString(messageName, "IsGeolocationClientActive")) { bool isActive = TestController::singleton().isGeolocationProviderActive(); WKRetainPtr result(AdoptWK, WKBooleanCreate(isActive)); return result; } if (WKStringIsEqualToUTF8CString(messageName, "IsWorkQueueEmpty")) { bool isEmpty = TestController::singleton().workQueueManager().isWorkQueueEmpty(); WKRetainPtr result(AdoptWK, WKBooleanCreate(isEmpty)); return result; } if (WKStringIsEqualToUTF8CString(messageName, "SecureEventInputIsEnabled")) { #if PLATFORM(MAC) && !PLATFORM(IOS) WKRetainPtr result(AdoptWK, WKBooleanCreate(IsSecureEventInputEnabled())); #else WKRetainPtr result(AdoptWK, WKBooleanCreate(false)); #endif return result; } if (WKStringIsEqualToUTF8CString(messageName, "SetAlwaysAcceptCookies")) { WKBooleanRef accept = static_cast(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 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(messageBody)); WebCoreTestSupport::connectMockGamepad(index); return nullptr; } if (WKStringIsEqualToUTF8CString(messageName, "DisconnectMockGamepad")) { ASSERT(WKGetTypeID(messageBody) == WKUInt64GetTypeID()); uint64_t index = WKUInt64GetValue(static_cast(messageBody)); WebCoreTestSupport::disconnectMockGamepad(index); return nullptr; } if (WKStringIsEqualToUTF8CString(messageName, "SetMockGamepadDetails")) { ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID()); WKDictionaryRef messageBodyDictionary = static_cast(messageBody); WKRetainPtr gamepadIndexKey(AdoptWK, WKStringCreateWithUTF8CString("GamepadIndex")); WKRetainPtr gamepadIDKey(AdoptWK, WKStringCreateWithUTF8CString("GamepadID")); WKRetainPtr axisCountKey(AdoptWK, WKStringCreateWithUTF8CString("AxisCount")); WKRetainPtr buttonCountKey(AdoptWK, WKStringCreateWithUTF8CString("ButtonCount")); WKUInt64Ref gamepadIndex = static_cast(WKDictionaryGetItemForKey(messageBodyDictionary, gamepadIndexKey.get())); WKStringRef gamepadID = static_cast(WKDictionaryGetItemForKey(messageBodyDictionary, gamepadIDKey.get())); WKUInt64Ref axisCount = static_cast(WKDictionaryGetItemForKey(messageBodyDictionary, axisCountKey.get())); WKUInt64Ref buttonCount = static_cast(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(messageBody); WKRetainPtr gamepadIndexKey(AdoptWK, WKStringCreateWithUTF8CString("GamepadIndex")); WKRetainPtr axisIndexKey(AdoptWK, WKStringCreateWithUTF8CString("AxisIndex")); WKRetainPtr valueKey(AdoptWK, WKStringCreateWithUTF8CString("Value")); WKUInt64Ref gamepadIndex = static_cast(WKDictionaryGetItemForKey(messageBodyDictionary, gamepadIndexKey.get())); WKUInt64Ref axisIndex = static_cast(WKDictionaryGetItemForKey(messageBodyDictionary, axisIndexKey.get())); WKDoubleRef value = static_cast(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(messageBody); WKRetainPtr gamepadIndexKey(AdoptWK, WKStringCreateWithUTF8CString("GamepadIndex")); WKRetainPtr buttonIndexKey(AdoptWK, WKStringCreateWithUTF8CString("ButtonIndex")); WKRetainPtr valueKey(AdoptWK, WKStringCreateWithUTF8CString("Value")); WKUInt64Ref gamepadIndex = static_cast(WKDictionaryGetItemForKey(messageBodyDictionary, gamepadIndexKey.get())); WKUInt64Ref buttonIndex = static_cast(WKDictionaryGetItemForKey(messageBodyDictionary, buttonIndexKey.get())); WKDoubleRef value = static_cast(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(messageBody); WKRetainPtr originKey(AdoptWK, WKStringCreateWithUTF8CString("origin")); WKStringRef originWK = static_cast(WKDictionaryGetItemForKey(messageBodyDictionary, originKey.get())); WKRetainPtr parentOriginKey(AdoptWK, WKStringCreateWithUTF8CString("parentOrigin")); WKStringRef parentOriginWK = static_cast(WKDictionaryGetItemForKey(messageBodyDictionary, parentOriginKey.get())); unsigned count = TestController::singleton().userMediaPermissionRequestCountForOrigin(originWK, parentOriginWK); WKRetainPtr result(AdoptWK, WKUInt64Create(count)); return result; } if (WKStringIsEqualToUTF8CString(messageName, "SetStatisticsPrevalentResource")) { ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID()); WKDictionaryRef messageBodyDictionary = static_cast(messageBody); WKRetainPtr hostNameKey(AdoptWK, WKStringCreateWithUTF8CString("HostName")); WKRetainPtr valueKey(AdoptWK, WKStringCreateWithUTF8CString("Value")); WKStringRef hostName = static_cast(WKDictionaryGetItemForKey(messageBodyDictionary, hostNameKey.get())); WKBooleanRef value = static_cast(WKDictionaryGetItemForKey(messageBodyDictionary, valueKey.get())); TestController::singleton().setStatisticsPrevalentResource(hostName, WKBooleanGetValue(value)); return nullptr; } if (WKStringIsEqualToUTF8CString(messageName, "IsStatisticsPrevalentResource")) { ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID()); WKStringRef hostName = static_cast(messageBody); bool isPrevalent = TestController::singleton().isStatisticsPrevalentResource(hostName); WKRetainPtr result(AdoptWK, WKBooleanCreate(isPrevalent)); return result; } if (WKStringIsEqualToUTF8CString(messageName, "SetStatisticsHasHadUserInteraction")) { ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID()); WKDictionaryRef messageBodyDictionary = static_cast(messageBody); WKRetainPtr hostNameKey(AdoptWK, WKStringCreateWithUTF8CString("HostName")); WKRetainPtr valueKey(AdoptWK, WKStringCreateWithUTF8CString("Value")); WKStringRef hostName = static_cast(WKDictionaryGetItemForKey(messageBodyDictionary, hostNameKey.get())); WKBooleanRef value = static_cast(WKDictionaryGetItemForKey(messageBodyDictionary, valueKey.get())); TestController::singleton().setStatisticsHasHadUserInteraction(hostName, WKBooleanGetValue(value)); return nullptr; } if (WKStringIsEqualToUTF8CString(messageName, "IsStatisticsHasHadUserInteraction")) { ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID()); WKStringRef hostName = static_cast(messageBody); bool hasHadUserInteraction = TestController::singleton().isStatisticsHasHadUserInteraction(hostName); WKRetainPtr result(AdoptWK, WKBooleanCreate(hasHadUserInteraction)); return result; } if (WKStringIsEqualToUTF8CString(messageName, "SetStatisticsTimeToLiveUserInteraction")) { ASSERT(WKGetTypeID(messageBody) == WKDoubleGetTypeID()); WKDoubleRef seconds = static_cast(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(messageBody); TestController::singleton().setStatisticsNotifyPagesWhenDataRecordsWereScanned(WKBooleanGetValue(value)); return nullptr; } if (WKStringIsEqualToUTF8CString(messageName, "StatisticsShouldClassifyResourcesBeforeDataRecordsRemoval")) { ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID()); WKBooleanRef value = static_cast(messageBody); TestController::singleton().setStatisticsShouldClassifyResourcesBeforeDataRecordsRemoval(WKBooleanGetValue(value)); return nullptr; } if (WKStringIsEqualToUTF8CString(messageName, "SetStatisticsMinimumTimeBetweeenDataRecordsRemoval")) { ASSERT(WKGetTypeID(messageBody) == WKDoubleGetTypeID()); WKDoubleRef seconds = static_cast(messageBody); TestController::singleton().setStatisticsMinimumTimeBetweeenDataRecordsRemoval(WKDoubleGetValue(seconds)); return nullptr; } if (WKStringIsEqualToUTF8CString(messageName, "StatisticsResetToConsistentState")) { TestController::singleton().statisticsResetToConsistentState(); return nullptr; } ASSERT_NOT_REACHED(); return nullptr; } void TestInvocation::runUISideScriptAfterUpdateCallback(WKErrorRef, void* context) { UIScriptInvocationData* data = static_cast(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(*this); m_UIScriptContext->runUIScript(toWTFString(script), scriptCallbackID); } void TestInvocation::uiScriptDidComplete(const String& result, unsigned scriptCallbackID) { WKRetainPtr messageName = adoptWK(WKStringCreateWithUTF8CString("CallUISideScriptCallback")); WKRetainPtr messageBody(AdoptWK, WKMutableDictionaryCreate()); WKRetainPtr resultKey(AdoptWK, WKStringCreateWithUTF8CString("Result")); WKRetainPtr callbackIDKey(AdoptWK, WKStringCreateWithUTF8CString("CallbackID")); WKRetainPtr 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) { m_textOutput.append(text); } void TestInvocation::didBeginSwipe() { WKRetainPtr messageName = adoptWK(WKStringCreateWithUTF8CString("CallDidBeginSwipeCallback")); WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0); } void TestInvocation::willEndSwipe() { WKRetainPtr messageName = adoptWK(WKStringCreateWithUTF8CString("CallWillEndSwipeCallback")); WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0); } void TestInvocation::didEndSwipe() { WKRetainPtr messageName = adoptWK(WKStringCreateWithUTF8CString("CallDidEndSwipeCallback")); WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0); } void TestInvocation::didRemoveSwipeSnapshot() { WKRetainPtr messageName = adoptWK(WKStringCreateWithUTF8CString("CallDidRemoveSwipeSnapshotCallback")); WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0); } void TestInvocation::notifyDownloadDone() { WKRetainPtr messageName = adoptWK(WKStringCreateWithUTF8CString("NotifyDownloadDone")); WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0); } } // namespace WTR