416f6ef1a713ee8b4feae90e9f9ff380f0d99e44
[WebKit-https.git] / Tools / WebKitTestRunner / TestInvocation.cpp
1 /*
2  * Copyright (C) 2010-2017 Apple Inc. All rights reserved.
3  * Copyright (C) 2012 Intel Corporation. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
15  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
16  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
18  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
24  * THE POSSIBILITY OF SUCH DAMAGE.
25  */
26
27 #include "config.h"
28 #include "TestInvocation.h"
29
30 #include "PlatformWebView.h"
31 #include "StringFunctions.h"
32 #include "TestController.h"
33 #include "UIScriptController.h"
34 #include "WebCoreTestSupport.h"
35 #include <WebKit/WKContextPrivate.h>
36 #include <WebKit/WKData.h>
37 #include <WebKit/WKDictionary.h>
38 #include <WebKit/WKHTTPCookieStoreRef.h>
39 #include <WebKit/WKInspector.h>
40 #include <WebKit/WKPagePrivate.h>
41 #include <WebKit/WKRetainPtr.h>
42 #include <WebKit/WKWebsiteDataStoreRef.h>
43 #include <climits>
44 #include <cstdio>
45 #include <wtf/StdLibExtras.h>
46 #include <wtf/text/CString.h>
47
48 #if PLATFORM(MAC) && !PLATFORM(IOS_FAMILY)
49 #include <Carbon/Carbon.h>
50 #endif
51
52 #if PLATFORM(COCOA)
53 #include <WebKit/WKPagePrivateMac.h>
54 #endif
55
56 #if PLATFORM(WIN)
57 #include <io.h>
58 #define isatty _isatty
59 #else
60 #include <unistd.h>
61 #endif
62
63 using namespace JSC;
64 using namespace WebKit;
65 using namespace std;
66
67 namespace WTR {
68
69 TestInvocation::TestInvocation(WKURLRef url, const TestOptions& options)
70     : m_options(options)
71     , m_url(url)
72     , m_waitToDumpWatchdogTimer(RunLoop::main(), this, &TestInvocation::waitToDumpWatchdogTimerFired)
73 {
74     WKRetainPtr<WKStringRef> urlString = adoptWK(WKURLCopyString(m_url.get()));
75
76     size_t stringLength = WKStringGetLength(urlString.get());
77
78     Vector<char> urlVector;
79     urlVector.resize(stringLength + 1);
80
81     WKStringGetUTF8CString(urlString.get(), urlVector.data(), stringLength + 1);
82
83     m_urlString = String(urlVector.data(), stringLength);
84
85     // FIXME: Avoid mutating the setting via a test directory like this.
86     m_dumpFrameLoadCallbacks = urlContains("loading/") && !urlContains("://localhost");
87 }
88
89 TestInvocation::~TestInvocation()
90 {
91     if (m_pendingUIScriptInvocationData)
92         m_pendingUIScriptInvocationData->testInvocation = nullptr;
93 }
94
95 WKURLRef TestInvocation::url() const
96 {
97     return m_url.get();
98 }
99
100 bool TestInvocation::urlContains(const char* searchString) const
101 {
102     return m_urlString.containsIgnoringASCIICase(searchString);
103 }
104
105 void TestInvocation::setIsPixelTest(const std::string& expectedPixelHash)
106 {
107     m_dumpPixels = true;
108     m_expectedPixelHash = expectedPixelHash;
109 }
110
111 WTF::Seconds TestInvocation::shortTimeout() const
112 {
113     if (!m_timeout) {
114         // Running WKTR directly, without webkitpy.
115         return TestController::defaultShortTimeout;
116     }
117
118     // This is not exactly correct for the way short timeout is used - it should not depend on whether a test is "slow",
119     // but it currently does. There is no way to know what a normal test's timeout is, as webkitpy only passes timeouts
120     // for each test individually.
121     // But there shouldn't be any observable negative consequences from this.
122     return m_timeout / 4;
123 }
124
125 bool TestInvocation::shouldLogHistoryClientCallbacks() const
126 {
127     return urlContains("globalhistory/");
128 }
129
130 WKRetainPtr<WKMutableDictionaryRef> TestInvocation::createTestSettingsDictionary()
131 {
132     WKRetainPtr<WKMutableDictionaryRef> beginTestMessageBody = adoptWK(WKMutableDictionaryCreate());
133
134     WKRetainPtr<WKStringRef> useFlexibleViewportKey = adoptWK(WKStringCreateWithUTF8CString("UseFlexibleViewport"));
135     WKRetainPtr<WKBooleanRef> useFlexibleViewportValue = adoptWK(WKBooleanCreate(options().useFlexibleViewport));
136     WKDictionarySetItem(beginTestMessageBody.get(), useFlexibleViewportKey.get(), useFlexibleViewportValue.get());
137
138     WKRetainPtr<WKStringRef> dumpPixelsKey = adoptWK(WKStringCreateWithUTF8CString("DumpPixels"));
139     WKRetainPtr<WKBooleanRef> dumpPixelsValue = adoptWK(WKBooleanCreate(m_dumpPixels));
140     WKDictionarySetItem(beginTestMessageBody.get(), dumpPixelsKey.get(), dumpPixelsValue.get());
141
142     WKRetainPtr<WKStringRef> timeoutKey = adoptWK(WKStringCreateWithUTF8CString("Timeout"));
143     WKRetainPtr<WKUInt64Ref> timeoutValue = adoptWK(WKUInt64Create(m_timeout.milliseconds()));
144     WKDictionarySetItem(beginTestMessageBody.get(), timeoutKey.get(), timeoutValue.get());
145
146     WKRetainPtr<WKStringRef> dumpJSConsoleLogInStdErrKey = adoptWK(WKStringCreateWithUTF8CString("DumpJSConsoleLogInStdErr"));
147     WKRetainPtr<WKBooleanRef> dumpJSConsoleLogInStdErrValue = adoptWK(WKBooleanCreate(m_dumpJSConsoleLogInStdErr));
148     WKDictionarySetItem(beginTestMessageBody.get(), dumpJSConsoleLogInStdErrKey.get(), dumpJSConsoleLogInStdErrValue.get());
149
150     WKRetainPtr<WKStringRef> additionalSupportedImageTypesKey = adoptWK(WKStringCreateWithUTF8CString("additionalSupportedImageTypes"));
151     WKRetainPtr<WKStringRef> additionalSupportedImageTypesValue = adoptWK(WKStringCreateWithUTF8CString(options().additionalSupportedImageTypes.c_str()));
152     WKDictionarySetItem(beginTestMessageBody.get(), additionalSupportedImageTypesKey.get(), additionalSupportedImageTypesValue.get());
153
154     return beginTestMessageBody;
155 }
156
157 void TestInvocation::invoke()
158 {
159     TestController::singleton().configureViewForTest(*this);
160
161     WKPageSetAddsVisitedLinks(TestController::singleton().mainWebView()->page(), false);
162
163     m_textOutput.clear();
164
165     TestController::singleton().setShouldLogHistoryClientCallbacks(shouldLogHistoryClientCallbacks());
166
167     WKHTTPCookieStoreSetHTTPCookieAcceptPolicy(WKWebsiteDataStoreGetHTTPCookieStore(TestController::defaultWebsiteDataStore()), kWKHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain, nullptr, nullptr);
168
169     // FIXME: We should clear out visited links here.
170
171     WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("BeginTest"));
172     auto beginTestMessageBody = createTestSettingsDictionary();
173     WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), beginTestMessageBody.get());
174
175     m_startedTesting = true;
176
177     bool shouldOpenExternalURLs = false;
178
179     TestController::singleton().runUntil(m_gotInitialResponse, TestController::noTimeout);
180     if (m_error)
181         goto end;
182
183     WKPageLoadURLWithShouldOpenExternalURLsPolicy(TestController::singleton().mainWebView()->page(), m_url.get(), shouldOpenExternalURLs);
184
185     TestController::singleton().runUntil(m_gotFinalMessage, TestController::noTimeout);
186     if (m_error)
187         goto end;
188
189     dumpResults();
190
191 end:
192 #if !PLATFORM(IOS_FAMILY)
193     if (m_gotInitialResponse)
194         WKInspectorClose(WKPageGetInspector(TestController::singleton().mainWebView()->page()));
195 #endif // !PLATFORM(IOS_FAMILY)
196
197     if (TestController::singleton().resetStateToConsistentValues(m_options, TestController::ResetStage::AfterTest))
198         return;
199
200     // The process is unresponsive, so let's start a new one.
201     TestController::singleton().terminateWebContentProcess();
202     // Make sure that we have a process, as invoke() will need one to send bundle messages for the next test.
203     TestController::singleton().reattachPageToWebProcess();
204 }
205
206 void TestInvocation::dumpWebProcessUnresponsiveness(const char* errorMessage)
207 {
208     fprintf(stderr, "%s", errorMessage);
209     char buffer[1024] = { };
210 #if PLATFORM(COCOA)
211     pid_t pid = WKPageGetProcessIdentifier(TestController::singleton().mainWebView()->page());
212     snprintf(buffer, sizeof(buffer), "#PROCESS UNRESPONSIVE - %s (pid %ld)\n", TestController::webProcessName(), static_cast<long>(pid));
213 #else
214     snprintf(buffer, sizeof(buffer), "#PROCESS UNRESPONSIVE - %s\n", TestController::webProcessName());
215 #endif
216
217     dump(errorMessage, buffer, true);
218     
219     if (!TestController::singleton().usingServerMode())
220         return;
221     
222     if (isatty(fileno(stdin)) || isatty(fileno(stderr)))
223         fputs("Grab an image of the stack, then hit enter...\n", stderr);
224     
225     if (!fgets(buffer, sizeof(buffer), stdin) || strcmp(buffer, "#SAMPLE FINISHED\n"))
226         fprintf(stderr, "Failed receive expected sample response, got:\n\t\"%s\"\nContinuing...\n", buffer);
227 }
228
229 void TestInvocation::dump(const char* textToStdout, const char* textToStderr, bool seenError)
230 {
231     printf("Content-Type: text/plain\n");
232     if (textToStdout)
233         fputs(textToStdout, stdout);
234     if (textToStderr)
235         fputs(textToStderr, stderr);
236
237     fputs("#EOF\n", stdout);
238     fputs("#EOF\n", stderr);
239     if (seenError)
240         fputs("#EOF\n", stdout);
241     fflush(stdout);
242     fflush(stderr);
243 }
244
245 void TestInvocation::forceRepaintDoneCallback(WKErrorRef error, void* context)
246 {
247     // The context may not be valid any more, e.g. if WebKit is invalidating callbacks at process exit.
248     if (error)
249         return;
250
251     TestInvocation* testInvocation = static_cast<TestInvocation*>(context);
252     RELEASE_ASSERT(TestController::singleton().isCurrentInvocation(testInvocation));
253
254     testInvocation->m_gotRepaint = true;
255     TestController::singleton().notifyDone();
256 }
257
258 void TestInvocation::dumpResults()
259 {
260     if (m_shouldDumpResourceLoadStatistics)
261         m_textOutput.append(m_savedResourceLoadStatistics.isNull() ? TestController::singleton().dumpResourceLoadStatistics() : m_savedResourceLoadStatistics);
262
263     if (m_shouldDumpAdClickAttribution)
264         m_textOutput.append(TestController::singleton().dumpAdClickAttribution());
265     
266     if (m_textOutput.length() || !m_audioResult)
267         dump(m_textOutput.toString().utf8().data());
268     else
269         dumpAudio(m_audioResult.get());
270
271     if (m_dumpPixels) {
272         if (m_pixelResult)
273             dumpPixelsAndCompareWithExpected(SnapshotResultType::WebContents, m_repaintRects.get(), m_pixelResult.get());
274         else if (m_pixelResultIsPending) {
275             m_gotRepaint = false;
276             WKPageForceRepaint(TestController::singleton().mainWebView()->page(), this, TestInvocation::forceRepaintDoneCallback);
277             TestController::singleton().runUntil(m_gotRepaint, TestController::noTimeout);
278             dumpPixelsAndCompareWithExpected(SnapshotResultType::WebView, m_repaintRects.get());
279         }
280     }
281
282     fputs("#EOF\n", stdout);
283     fflush(stdout);
284     fflush(stderr);
285 }
286
287 void TestInvocation::dumpAudio(WKDataRef audioData)
288 {
289     size_t length = WKDataGetSize(audioData);
290     if (!length)
291         return;
292
293     const unsigned char* data = WKDataGetBytes(audioData);
294
295     printf("Content-Type: audio/wav\n");
296     printf("Content-Length: %lu\n", static_cast<unsigned long>(length));
297
298     fwrite(data, 1, length, stdout);
299     printf("#EOF\n");
300     fprintf(stderr, "#EOF\n");
301 }
302
303 bool TestInvocation::compareActualHashToExpectedAndDumpResults(const char actualHash[33])
304 {
305     // Compute the hash of the bitmap context pixels
306     fprintf(stdout, "\nActualHash: %s\n", actualHash);
307
308     if (!m_expectedPixelHash.length())
309         return false;
310
311     ASSERT(m_expectedPixelHash.length() == 32);
312     fprintf(stdout, "\nExpectedHash: %s\n", m_expectedPixelHash.c_str());
313
314     // FIXME: Do case insensitive compare.
315     return m_expectedPixelHash == actualHash;
316 }
317
318 void TestInvocation::didReceiveMessageFromInjectedBundle(WKStringRef messageName, WKTypeRef messageBody)
319 {
320     if (WKStringIsEqualToUTF8CString(messageName, "Error")) {
321         // Set all states to true to stop spinning the runloop.
322         m_gotInitialResponse = true;
323         m_gotFinalMessage = true;
324         m_error = true;
325         TestController::singleton().notifyDone();
326         return;
327     }
328
329     if (WKStringIsEqualToUTF8CString(messageName, "Ack")) {
330         ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID());
331         WKStringRef messageBodyString = static_cast<WKStringRef>(messageBody);
332         if (WKStringIsEqualToUTF8CString(messageBodyString, "BeginTest")) {
333             m_gotInitialResponse = true;
334             TestController::singleton().notifyDone();
335             return;
336         }
337
338         ASSERT_NOT_REACHED();
339     }
340
341     if (WKStringIsEqualToUTF8CString(messageName, "Done")) {
342         ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
343         WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
344
345         WKRetainPtr<WKStringRef> pixelResultIsPendingKey = adoptWK(WKStringCreateWithUTF8CString("PixelResultIsPending"));
346         WKBooleanRef pixelResultIsPending = static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(messageBodyDictionary, pixelResultIsPendingKey.get()));
347         m_pixelResultIsPending = WKBooleanGetValue(pixelResultIsPending);
348
349         if (!m_pixelResultIsPending) {
350             WKRetainPtr<WKStringRef> pixelResultKey = adoptWK(WKStringCreateWithUTF8CString("PixelResult"));
351             m_pixelResult = static_cast<WKImageRef>(WKDictionaryGetItemForKey(messageBodyDictionary, pixelResultKey.get()));
352             ASSERT(!m_pixelResult || m_dumpPixels);
353         }
354
355         WKRetainPtr<WKStringRef> repaintRectsKey = adoptWK(WKStringCreateWithUTF8CString("RepaintRects"));
356         m_repaintRects = static_cast<WKArrayRef>(WKDictionaryGetItemForKey(messageBodyDictionary, repaintRectsKey.get()));
357
358         WKRetainPtr<WKStringRef> audioResultKey =  adoptWK(WKStringCreateWithUTF8CString("AudioResult"));
359         m_audioResult = static_cast<WKDataRef>(WKDictionaryGetItemForKey(messageBodyDictionary, audioResultKey.get()));
360
361         done();
362         return;
363     }
364
365     if (WKStringIsEqualToUTF8CString(messageName, "TextOutput")) {
366         ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID());
367         WKStringRef textOutput = static_cast<WKStringRef>(messageBody);
368         m_textOutput.append(toWTFString(textOutput));
369         return;
370     }
371
372     if (WKStringIsEqualToUTF8CString(messageName, "DumpToStdErr")) {
373         ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID());
374         WKStringRef textOutput = static_cast<WKStringRef>(messageBody);
375         fprintf(stderr, "%s", toWTFString(textOutput).utf8().data());
376         return;
377     }
378
379     if (WKStringIsEqualToUTF8CString(messageName, "BeforeUnloadReturnValue")) {
380         ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
381         WKBooleanRef beforeUnloadReturnValue = static_cast<WKBooleanRef>(messageBody);
382         TestController::singleton().setBeforeUnloadReturnValue(WKBooleanGetValue(beforeUnloadReturnValue));
383         return;
384     }
385     
386     if (WKStringIsEqualToUTF8CString(messageName, "AddChromeInputField")) {
387         TestController::singleton().mainWebView()->addChromeInputField();
388         WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CallAddChromeInputFieldCallback"));
389         WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0);
390         return;
391     }
392
393     if (WKStringIsEqualToUTF8CString(messageName, "RemoveChromeInputField")) {
394         TestController::singleton().mainWebView()->removeChromeInputField();
395         WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CallRemoveChromeInputFieldCallback"));
396         WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0);
397         return;
398     }
399     
400     if (WKStringIsEqualToUTF8CString(messageName, "FocusWebView")) {
401         TestController::singleton().mainWebView()->makeWebViewFirstResponder();
402         WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CallFocusWebViewCallback"));
403         WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0);
404         return;
405     }
406
407     if (WKStringIsEqualToUTF8CString(messageName, "SetBackingScaleFactor")) {
408         ASSERT(WKGetTypeID(messageBody) == WKDoubleGetTypeID());
409         double backingScaleFactor = WKDoubleGetValue(static_cast<WKDoubleRef>(messageBody));
410         WKPageSetCustomBackingScaleFactor(TestController::singleton().mainWebView()->page(), backingScaleFactor);
411
412         WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CallSetBackingScaleFactorCallback"));
413         WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0);
414         return;
415     }
416
417     if (WKStringIsEqualToUTF8CString(messageName, "SimulateWebNotificationClick")) {
418         ASSERT(WKGetTypeID(messageBody) == WKUInt64GetTypeID());
419         uint64_t notificationID = WKUInt64GetValue(static_cast<WKUInt64Ref>(messageBody));
420         TestController::singleton().simulateWebNotificationClick(notificationID);
421         return;
422     }
423
424     if (WKStringIsEqualToUTF8CString(messageName, "SetAddsVisitedLinks")) {
425         ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
426         WKBooleanRef enabledWK = static_cast<WKBooleanRef>(messageBody);
427         WKPageSetAddsVisitedLinks(TestController::singleton().mainWebView()->page(), WKBooleanGetValue(enabledWK));
428         return;
429     }
430
431     if (WKStringIsEqualToUTF8CString(messageName, "SetGeolocationPermission")) {
432         ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
433         WKBooleanRef enabledWK = static_cast<WKBooleanRef>(messageBody);
434         TestController::singleton().setGeolocationPermission(WKBooleanGetValue(enabledWK));
435         return;
436     }
437
438     if (WKStringIsEqualToUTF8CString(messageName, "SetMockGeolocationPosition")) {
439         ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
440         WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
441
442         WKRetainPtr<WKStringRef> latitudeKeyWK = adoptWK(WKStringCreateWithUTF8CString("latitude"));
443         WKDoubleRef latitudeWK = static_cast<WKDoubleRef>(WKDictionaryGetItemForKey(messageBodyDictionary, latitudeKeyWK.get()));
444         double latitude = WKDoubleGetValue(latitudeWK);
445
446         WKRetainPtr<WKStringRef> longitudeKeyWK = adoptWK(WKStringCreateWithUTF8CString("longitude"));
447         WKDoubleRef longitudeWK = static_cast<WKDoubleRef>(WKDictionaryGetItemForKey(messageBodyDictionary, longitudeKeyWK.get()));
448         double longitude = WKDoubleGetValue(longitudeWK);
449
450         WKRetainPtr<WKStringRef> accuracyKeyWK = adoptWK(WKStringCreateWithUTF8CString("accuracy"));
451         WKDoubleRef accuracyWK = static_cast<WKDoubleRef>(WKDictionaryGetItemForKey(messageBodyDictionary, accuracyKeyWK.get()));
452         double accuracy = WKDoubleGetValue(accuracyWK);
453
454         WKRetainPtr<WKStringRef> providesAltitudeKeyWK = adoptWK(WKStringCreateWithUTF8CString("providesAltitude"));
455         WKBooleanRef providesAltitudeWK = static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(messageBodyDictionary, providesAltitudeKeyWK.get()));
456         bool providesAltitude = WKBooleanGetValue(providesAltitudeWK);
457
458         WKRetainPtr<WKStringRef> altitudeKeyWK = adoptWK(WKStringCreateWithUTF8CString("altitude"));
459         WKDoubleRef altitudeWK = static_cast<WKDoubleRef>(WKDictionaryGetItemForKey(messageBodyDictionary, altitudeKeyWK.get()));
460         double altitude = WKDoubleGetValue(altitudeWK);
461
462         WKRetainPtr<WKStringRef> providesAltitudeAccuracyKeyWK = adoptWK(WKStringCreateWithUTF8CString("providesAltitudeAccuracy"));
463         WKBooleanRef providesAltitudeAccuracyWK = static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(messageBodyDictionary, providesAltitudeAccuracyKeyWK.get()));
464         bool providesAltitudeAccuracy = WKBooleanGetValue(providesAltitudeAccuracyWK);
465
466         WKRetainPtr<WKStringRef> altitudeAccuracyKeyWK = adoptWK(WKStringCreateWithUTF8CString("altitudeAccuracy"));
467         WKDoubleRef altitudeAccuracyWK = static_cast<WKDoubleRef>(WKDictionaryGetItemForKey(messageBodyDictionary, altitudeAccuracyKeyWK.get()));
468         double altitudeAccuracy = WKDoubleGetValue(altitudeAccuracyWK);
469
470         WKRetainPtr<WKStringRef> providesHeadingKeyWK = adoptWK(WKStringCreateWithUTF8CString("providesHeading"));
471         WKBooleanRef providesHeadingWK = static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(messageBodyDictionary, providesHeadingKeyWK.get()));
472         bool providesHeading = WKBooleanGetValue(providesHeadingWK);
473
474         WKRetainPtr<WKStringRef> headingKeyWK = adoptWK(WKStringCreateWithUTF8CString("heading"));
475         WKDoubleRef headingWK = static_cast<WKDoubleRef>(WKDictionaryGetItemForKey(messageBodyDictionary, headingKeyWK.get()));
476         double heading = WKDoubleGetValue(headingWK);
477
478         WKRetainPtr<WKStringRef> providesSpeedKeyWK = adoptWK(WKStringCreateWithUTF8CString("providesSpeed"));
479         WKBooleanRef providesSpeedWK = static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(messageBodyDictionary, providesSpeedKeyWK.get()));
480         bool providesSpeed = WKBooleanGetValue(providesSpeedWK);
481
482         WKRetainPtr<WKStringRef> speedKeyWK = adoptWK(WKStringCreateWithUTF8CString("speed"));
483         WKDoubleRef speedWK = static_cast<WKDoubleRef>(WKDictionaryGetItemForKey(messageBodyDictionary, speedKeyWK.get()));
484         double speed = WKDoubleGetValue(speedWK);
485
486         WKRetainPtr<WKStringRef> providesFloorLevelKeyWK = adoptWK(WKStringCreateWithUTF8CString("providesFloorLevel"));
487         WKBooleanRef providesFloorLevelWK = static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(messageBodyDictionary, providesFloorLevelKeyWK.get()));
488         bool providesFloorLevel = WKBooleanGetValue(providesFloorLevelWK);
489
490         WKRetainPtr<WKStringRef> floorLevelKeyWK = adoptWK(WKStringCreateWithUTF8CString("floorLevel"));
491         WKDoubleRef floorLevelWK = static_cast<WKDoubleRef>(WKDictionaryGetItemForKey(messageBodyDictionary, floorLevelKeyWK.get()));
492         double floorLevel = WKDoubleGetValue(floorLevelWK);
493
494         TestController::singleton().setMockGeolocationPosition(latitude, longitude, accuracy, providesAltitude, altitude, providesAltitudeAccuracy, altitudeAccuracy, providesHeading, heading, providesSpeed, speed, providesFloorLevel, floorLevel);
495         return;
496     }
497
498     if (WKStringIsEqualToUTF8CString(messageName, "SetMockGeolocationPositionUnavailableError")) {
499         ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID());
500         WKStringRef errorMessage = static_cast<WKStringRef>(messageBody);
501         TestController::singleton().setMockGeolocationPositionUnavailableError(errorMessage);
502         return;
503     }
504
505     if (WKStringIsEqualToUTF8CString(messageName, "SetUserMediaPermission")) {
506         ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
507         WKBooleanRef enabledWK = static_cast<WKBooleanRef>(messageBody);
508         TestController::singleton().setUserMediaPermission(WKBooleanGetValue(enabledWK));
509         return;
510     }
511
512     if (WKStringIsEqualToUTF8CString(messageName, "ResetUserMediaPermission")) {
513         TestController::singleton().resetUserMediaPermission();
514         return;
515     }
516
517     if (WKStringIsEqualToUTF8CString(messageName, "SetUserMediaPersistentPermissionForOrigin")) {
518         ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
519         WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
520
521         WKRetainPtr<WKStringRef> permissionKeyWK = adoptWK(WKStringCreateWithUTF8CString("permission"));
522         WKBooleanRef permissionWK = static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(messageBodyDictionary, permissionKeyWK.get()));
523         bool permission = WKBooleanGetValue(permissionWK);
524
525         WKRetainPtr<WKStringRef> originKey = adoptWK(WKStringCreateWithUTF8CString("origin"));
526         WKStringRef originWK = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, originKey.get()));
527
528         WKRetainPtr<WKStringRef> parentOriginKey = adoptWK(WKStringCreateWithUTF8CString("parentOrigin"));
529         WKStringRef parentOriginWK = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, parentOriginKey.get()));
530
531         TestController::singleton().setUserMediaPersistentPermissionForOrigin(permission, originWK, parentOriginWK);
532         return;
533     }
534
535     if (WKStringIsEqualToUTF8CString(messageName, "ResetUserMediaPermissionRequestCountForOrigin")) {
536         ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
537         WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
538
539         WKRetainPtr<WKStringRef> originKey = adoptWK(WKStringCreateWithUTF8CString("origin"));
540         WKStringRef originWK = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, originKey.get()));
541
542         WKRetainPtr<WKStringRef> parentOriginKey = adoptWK(WKStringCreateWithUTF8CString("parentOrigin"));
543         WKStringRef parentOriginWK = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, parentOriginKey.get()));
544         
545         TestController::singleton().resetUserMediaPermissionRequestCountForOrigin(originWK, parentOriginWK);
546         return;
547     }
548
549     if (WKStringIsEqualToUTF8CString(messageName, "SetCustomPolicyDelegate")) {
550         ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
551         WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
552
553         WKRetainPtr<WKStringRef> enabledKeyWK = adoptWK(WKStringCreateWithUTF8CString("enabled"));
554         WKBooleanRef enabledWK = static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(messageBodyDictionary, enabledKeyWK.get()));
555         bool enabled = WKBooleanGetValue(enabledWK);
556
557         WKRetainPtr<WKStringRef> permissiveKeyWK = adoptWK(WKStringCreateWithUTF8CString("permissive"));
558         WKBooleanRef permissiveWK = static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(messageBodyDictionary, permissiveKeyWK.get()));
559         bool permissive = WKBooleanGetValue(permissiveWK);
560
561         TestController::singleton().setCustomPolicyDelegate(enabled, permissive);
562         return;
563     }
564
565     if (WKStringIsEqualToUTF8CString(messageName, "SetHidden")) {
566         ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
567         WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
568
569         WKRetainPtr<WKStringRef> isInitialKeyWK = adoptWK(WKStringCreateWithUTF8CString("hidden"));
570         WKBooleanRef hiddenWK = static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(messageBodyDictionary, isInitialKeyWK.get()));
571         bool hidden = WKBooleanGetValue(hiddenWK);
572
573         TestController::singleton().setHidden(hidden);
574         return;
575     }
576
577     if (WKStringIsEqualToUTF8CString(messageName, "ProcessWorkQueue")) {
578         if (TestController::singleton().workQueueManager().processWorkQueue()) {
579             WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("WorkQueueProcessedCallback"));
580             WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0);
581         }
582         return;
583     }
584
585     if (WKStringIsEqualToUTF8CString(messageName, "QueueBackNavigation")) {
586         ASSERT(WKGetTypeID(messageBody) == WKUInt64GetTypeID());
587         uint64_t stepCount = WKUInt64GetValue(static_cast<WKUInt64Ref>(messageBody));
588         TestController::singleton().workQueueManager().queueBackNavigation(stepCount);
589         return;
590     }
591
592     if (WKStringIsEqualToUTF8CString(messageName, "QueueForwardNavigation")) {
593         ASSERT(WKGetTypeID(messageBody) == WKUInt64GetTypeID());
594         uint64_t stepCount = WKUInt64GetValue(static_cast<WKUInt64Ref>(messageBody));
595         TestController::singleton().workQueueManager().queueForwardNavigation(stepCount);
596         return;
597     }
598
599     if (WKStringIsEqualToUTF8CString(messageName, "QueueLoad")) {
600         ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
601         WKDictionaryRef loadDataDictionary = static_cast<WKDictionaryRef>(messageBody);
602
603         WKRetainPtr<WKStringRef> urlKey = adoptWK(WKStringCreateWithUTF8CString("url"));
604         WKStringRef urlWK = static_cast<WKStringRef>(WKDictionaryGetItemForKey(loadDataDictionary, urlKey.get()));
605
606         WKRetainPtr<WKStringRef> targetKey = adoptWK(WKStringCreateWithUTF8CString("target"));
607         WKStringRef targetWK = static_cast<WKStringRef>(WKDictionaryGetItemForKey(loadDataDictionary, targetKey.get()));
608
609         WKRetainPtr<WKStringRef> shouldOpenExternalURLsKey = adoptWK(WKStringCreateWithUTF8CString("shouldOpenExternalURLs"));
610         WKBooleanRef shouldOpenExternalURLsValueWK = static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(loadDataDictionary, shouldOpenExternalURLsKey.get()));
611
612         TestController::singleton().workQueueManager().queueLoad(toWTFString(urlWK), toWTFString(targetWK), WKBooleanGetValue(shouldOpenExternalURLsValueWK));
613         return;
614     }
615
616     if (WKStringIsEqualToUTF8CString(messageName, "QueueLoadHTMLString")) {
617         ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
618         WKDictionaryRef loadDataDictionary = static_cast<WKDictionaryRef>(messageBody);
619
620         WKRetainPtr<WKStringRef> contentKey = adoptWK(WKStringCreateWithUTF8CString("content"));
621         WKStringRef contentWK = static_cast<WKStringRef>(WKDictionaryGetItemForKey(loadDataDictionary, contentKey.get()));
622
623         WKRetainPtr<WKStringRef> baseURLKey = adoptWK(WKStringCreateWithUTF8CString("baseURL"));
624         WKStringRef baseURLWK = static_cast<WKStringRef>(WKDictionaryGetItemForKey(loadDataDictionary, baseURLKey.get()));
625
626         WKRetainPtr<WKStringRef> unreachableURLKey = adoptWK(WKStringCreateWithUTF8CString("unreachableURL"));
627         WKStringRef unreachableURLWK = static_cast<WKStringRef>(WKDictionaryGetItemForKey(loadDataDictionary, unreachableURLKey.get()));
628
629         TestController::singleton().workQueueManager().queueLoadHTMLString(toWTFString(contentWK), baseURLWK ? toWTFString(baseURLWK) : String(), unreachableURLWK ? toWTFString(unreachableURLWK) : String());
630         return;
631     }
632
633     if (WKStringIsEqualToUTF8CString(messageName, "QueueReload")) {
634         TestController::singleton().workQueueManager().queueReload();
635         return;
636     }
637
638     if (WKStringIsEqualToUTF8CString(messageName, "QueueLoadingScript")) {
639         ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID());
640         WKStringRef script = static_cast<WKStringRef>(messageBody);
641         TestController::singleton().workQueueManager().queueLoadingScript(toWTFString(script));
642         return;
643     }
644
645     if (WKStringIsEqualToUTF8CString(messageName, "QueueNonLoadingScript")) {
646         ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID());
647         WKStringRef script = static_cast<WKStringRef>(messageBody);
648         TestController::singleton().workQueueManager().queueNonLoadingScript(toWTFString(script));
649         return;
650     }
651
652     if (WKStringIsEqualToUTF8CString(messageName, "SetRejectsProtectionSpaceAndContinueForAuthenticationChallenges")) {
653         ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
654         WKBooleanRef value = static_cast<WKBooleanRef>(messageBody);
655         TestController::singleton().setRejectsProtectionSpaceAndContinueForAuthenticationChallenges(WKBooleanGetValue(value));
656         return;
657     }
658
659     if (WKStringIsEqualToUTF8CString(messageName, "SetHandlesAuthenticationChallenges")) {
660         ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
661         WKBooleanRef value = static_cast<WKBooleanRef>(messageBody);
662         TestController::singleton().setHandlesAuthenticationChallenges(WKBooleanGetValue(value));
663         return;
664     }
665
666     if (WKStringIsEqualToUTF8CString(messageName, "SetShouldLogCanAuthenticateAgainstProtectionSpace")) {
667         ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
668         WKBooleanRef value = static_cast<WKBooleanRef>(messageBody);
669         TestController::singleton().setShouldLogCanAuthenticateAgainstProtectionSpace(WKBooleanGetValue(value));
670         return;
671     }
672
673     if (WKStringIsEqualToUTF8CString(messageName, "SetShouldLogDownloadCallbacks")) {
674         ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
675         WKBooleanRef value = static_cast<WKBooleanRef>(messageBody);
676         TestController::singleton().setShouldLogDownloadCallbacks(WKBooleanGetValue(value));
677         return;
678     }
679
680     if (WKStringIsEqualToUTF8CString(messageName, "SetAuthenticationUsername")) {
681         ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID());
682         WKStringRef username = static_cast<WKStringRef>(messageBody);
683         TestController::singleton().setAuthenticationUsername(toWTFString(username));
684         return;
685     }
686
687     if (WKStringIsEqualToUTF8CString(messageName, "SetAuthenticationPassword")) {
688         ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID());
689         WKStringRef password = static_cast<WKStringRef>(messageBody);
690         TestController::singleton().setAuthenticationPassword(toWTFString(password));
691         return;
692     }
693
694     if (WKStringIsEqualToUTF8CString(messageName, "SetBlockAllPlugins")) {
695         ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
696         WKBooleanRef shouldBlock = static_cast<WKBooleanRef>(messageBody);
697         TestController::singleton().setBlockAllPlugins(WKBooleanGetValue(shouldBlock));
698         return;
699     }
700
701     if (WKStringIsEqualToUTF8CString(messageName, "SetPluginSupportedMode")) {
702         ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID());
703         WKStringRef mode = static_cast<WKStringRef>(messageBody);
704         TestController::singleton().setPluginSupportedMode(toWTFString(mode));
705         return;
706     }
707
708     if (WKStringIsEqualToUTF8CString(messageName, "SetShouldDecideNavigationPolicyAfterDelay")) {
709         ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
710         WKBooleanRef value = static_cast<WKBooleanRef>(messageBody);
711         TestController::singleton().setShouldDecideNavigationPolicyAfterDelay(WKBooleanGetValue(value));
712         return;
713     }
714
715     if (WKStringIsEqualToUTF8CString(messageName, "SetShouldDecideResponsePolicyAfterDelay")) {
716         ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
717         WKBooleanRef value = static_cast<WKBooleanRef>(messageBody);
718         TestController::singleton().setShouldDecideResponsePolicyAfterDelay(WKBooleanGetValue(value));
719         return;
720     }
721
722     if (WKStringIsEqualToUTF8CString(messageName, "SetNavigationGesturesEnabled")) {
723         ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
724         WKBooleanRef value = static_cast<WKBooleanRef>(messageBody);
725         TestController::singleton().setNavigationGesturesEnabled(WKBooleanGetValue(value));
726         return;
727     }
728     
729     if (WKStringIsEqualToUTF8CString(messageName, "SetIgnoresViewportScaleLimits")) {
730         ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
731         WKBooleanRef value = static_cast<WKBooleanRef>(messageBody);
732         TestController::singleton().setIgnoresViewportScaleLimits(WKBooleanGetValue(value));
733         return;
734     }
735
736     if (WKStringIsEqualToUTF8CString(messageName, "SetShouldDownloadUndisplayableMIMETypes")) {
737         ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
738         WKBooleanRef value = static_cast<WKBooleanRef>(messageBody);
739         TestController::singleton().setShouldDownloadUndisplayableMIMETypes(WKBooleanGetValue(value));
740         return;
741     }
742
743     if (WKStringIsEqualToUTF8CString(messageName, "SetShouldAllowDeviceOrientationAndMotionAccess")) {
744         ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
745         WKBooleanRef value = static_cast<WKBooleanRef>(messageBody);
746         TestController::singleton().setShouldAllowDeviceOrientationAndMotionAccess(WKBooleanGetValue(value));
747         return;
748     }
749
750     if (WKStringIsEqualToUTF8CString(messageName, "SetStatisticsShouldBlockThirdPartyCookiesOnSitesWithoutUserInteraction")) {
751         ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
752         WKBooleanRef value = static_cast<WKBooleanRef>(messageBody);
753         TestController::singleton().setStatisticsShouldBlockThirdPartyCookies(WKBooleanGetValue(value), true);
754         return;
755     }
756
757     if (WKStringIsEqualToUTF8CString(messageName, "SetStatisticsShouldBlockThirdPartyCookies")) {
758         ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
759         WKBooleanRef value = static_cast<WKBooleanRef>(messageBody);
760         TestController::singleton().setStatisticsShouldBlockThirdPartyCookies(WKBooleanGetValue(value), false);
761         return;
762     }
763     
764     if (WKStringIsEqualToUTF8CString(messageName, "SetInAppBrowserPrivacyEnabled")) {
765         ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
766         WKBooleanRef value = static_cast<WKBooleanRef>(messageBody);
767         TestController::singleton().setInAppBrowserPrivacyEnabled(WKBooleanGetValue(value));
768         return;
769     }
770
771     if (WKStringIsEqualToUTF8CString(messageName, "RunUIProcessScript")) {
772         WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
773         WKRetainPtr<WKStringRef> scriptKey = adoptWK(WKStringCreateWithUTF8CString("Script"));
774         WKRetainPtr<WKStringRef> callbackIDKey = adoptWK(WKStringCreateWithUTF8CString("CallbackID"));
775
776         UIScriptInvocationData* invocationData = new UIScriptInvocationData();
777         invocationData->testInvocation = this;
778         invocationData->callbackID = (unsigned)WKUInt64GetValue(static_cast<WKUInt64Ref>(WKDictionaryGetItemForKey(messageBodyDictionary, callbackIDKey.get())));
779         invocationData->scriptString = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, scriptKey.get()));
780         m_pendingUIScriptInvocationData = invocationData;
781         WKPageCallAfterNextPresentationUpdate(TestController::singleton().mainWebView()->page(), invocationData, runUISideScriptAfterUpdateCallback);
782         return;
783     }
784
785     if (WKStringIsEqualToUTF8CString(messageName, "InstallCustomMenuAction")) {
786         auto messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
787         WKRetainPtr<WKStringRef> nameKey = adoptWK(WKStringCreateWithUTF8CString("name"));
788         WKRetainPtr<WKStringRef> name = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, nameKey.get()));
789         WKRetainPtr<WKStringRef> dismissesAutomaticallyKey = adoptWK(WKStringCreateWithUTF8CString("dismissesAutomatically"));
790         auto dismissesAutomatically = static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(messageBodyDictionary, dismissesAutomaticallyKey.get()));
791         TestController::singleton().installCustomMenuAction(toWTFString(name.get()), WKBooleanGetValue(dismissesAutomatically));
792         return;
793     }
794
795     if (WKStringIsEqualToUTF8CString(messageName, "SetAllowedMenuActions")) {
796         auto messageBodyArray = static_cast<WKArrayRef>(messageBody);
797         auto size = WKArrayGetSize(messageBodyArray);
798         Vector<String> actions;
799         actions.reserveInitialCapacity(size);
800         for (size_t index = 0; index < size; ++index)
801             actions.append(toWTFString(static_cast<WKStringRef>(WKArrayGetItemAtIndex(messageBodyArray, index))));
802         TestController::singleton().setAllowedMenuActions(actions);
803         return;
804     }
805
806     if (WKStringIsEqualToUTF8CString(messageName, "SetOpenPanelFileURLs")) {
807         TestController::singleton().setOpenPanelFileURLs(static_cast<WKArrayRef>(messageBody));
808         return;
809     }
810     
811     if (WKStringIsEqualToUTF8CString(messageName, "GetWebViewCategory")) {
812         TestController::singleton().getWebViewCategory();
813         return;
814     }
815
816 #if PLATFORM(IOS_FAMILY)
817     if (WKStringIsEqualToUTF8CString(messageName, "SetOpenPanelFileURLsMediaIcon")) {
818         TestController::singleton().setOpenPanelFileURLsMediaIcon(static_cast<WKDataRef>(messageBody));
819         return;
820     }
821 #endif
822     
823     if (WKStringIsEqualToUTF8CString(messageName, "GetPrevalentDomains")) {
824         TestController::singleton().getPrevalentDomains();
825         return;
826     }
827
828     ASSERT_NOT_REACHED();
829 }
830
831 WKRetainPtr<WKTypeRef> TestInvocation::didReceiveSynchronousMessageFromInjectedBundle(WKStringRef messageName, WKTypeRef messageBody)
832 {
833     if (WKStringIsEqualToUTF8CString(messageName, "Initialization")) {
834         auto settings = createTestSettingsDictionary();
835         WKRetainPtr<WKStringRef> resumeTestingKey = adoptWK(WKStringCreateWithUTF8CString("ResumeTesting"));
836         WKRetainPtr<WKBooleanRef> resumeTestingValue = adoptWK(WKBooleanCreate(m_startedTesting));
837         WKDictionarySetItem(settings.get(), resumeTestingKey.get(), resumeTestingValue.get());
838         return settings;
839     }
840
841     if (WKStringIsEqualToUTF8CString(messageName, "SetDumpPixels")) {
842         ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
843         m_dumpPixels = WKBooleanGetValue(static_cast<WKBooleanRef>(messageBody));
844         return nullptr;
845     }
846     if (WKStringIsEqualToUTF8CString(messageName, "GetDumpPixels"))
847         return adoptWK(WKBooleanCreate(m_dumpPixels));
848
849     if (WKStringIsEqualToUTF8CString(messageName, "SetWhatToDump")) {
850         ASSERT(WKGetTypeID(messageBody) == WKUInt64GetTypeID());
851         m_whatToDump = static_cast<WhatToDump>(WKUInt64GetValue(static_cast<WKUInt64Ref>(messageBody)));
852         return nullptr;
853     }
854     if (WKStringIsEqualToUTF8CString(messageName, "GetWhatToDump"))
855         return adoptWK(WKUInt64Create(static_cast<uint64_t>(m_whatToDump)));
856
857     if (WKStringIsEqualToUTF8CString(messageName, "SetWaitUntilDone")) {
858         ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
859         setWaitUntilDone(static_cast<unsigned char>(WKBooleanGetValue(static_cast<WKBooleanRef>(messageBody))));
860         return nullptr;
861     }
862     if (WKStringIsEqualToUTF8CString(messageName, "GetWaitUntilDone"))
863         return adoptWK(WKBooleanCreate(m_waitUntilDone));
864
865     if (WKStringIsEqualToUTF8CString(messageName, "SetDumpFrameLoadCallbacks")) {
866         ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
867         m_dumpFrameLoadCallbacks = static_cast<unsigned char>(WKBooleanGetValue(static_cast<WKBooleanRef>(messageBody)));
868         return nullptr;
869     }
870     if (WKStringIsEqualToUTF8CString(messageName, "GetDumpFrameLoadCallbacks"))
871         return adoptWK(WKBooleanCreate(m_dumpFrameLoadCallbacks));
872
873     if (WKStringIsEqualToUTF8CString(messageName, "SetCanOpenWindows")) {
874         ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
875         m_canOpenWindows = static_cast<unsigned char>(WKBooleanGetValue(static_cast<WKBooleanRef>(messageBody)));
876         return nullptr;
877     }
878
879     if (WKStringIsEqualToUTF8CString(messageName, "SetWindowIsKey")) {
880         ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
881         WKBooleanRef isKeyValue = static_cast<WKBooleanRef>(messageBody);
882         TestController::singleton().mainWebView()->setWindowIsKey(WKBooleanGetValue(isKeyValue));
883         return nullptr;
884     }
885
886     if (WKStringIsEqualToUTF8CString(messageName, "SetViewSize")) {
887         ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
888
889         WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
890         WKRetainPtr<WKStringRef> widthKey = adoptWK(WKStringCreateWithUTF8CString("width"));
891         WKRetainPtr<WKStringRef> heightKey = adoptWK(WKStringCreateWithUTF8CString("height"));
892
893         WKDoubleRef widthWK = static_cast<WKDoubleRef>(WKDictionaryGetItemForKey(messageBodyDictionary, widthKey.get()));
894         WKDoubleRef heightWK = static_cast<WKDoubleRef>(WKDictionaryGetItemForKey(messageBodyDictionary, heightKey.get()));
895
896         TestController::singleton().mainWebView()->resizeTo(WKDoubleGetValue(widthWK), WKDoubleGetValue(heightWK));
897         return nullptr;
898     }
899
900     if (WKStringIsEqualToUTF8CString(messageName, "IsGeolocationClientActive")) {
901         bool isActive = TestController::singleton().isGeolocationProviderActive();
902         WKRetainPtr<WKTypeRef> result = adoptWK(WKBooleanCreate(isActive));
903         return result;
904     }
905
906     if (WKStringIsEqualToUTF8CString(messageName, "SetCacheModel")) {
907         ASSERT(WKGetTypeID(messageBody) == WKUInt64GetTypeID());
908         uint64_t model = WKUInt64GetValue(static_cast<WKUInt64Ref>(messageBody));
909         WKWebsiteDataStoreSetCacheModelSynchronouslyForTesting(TestController::defaultWebsiteDataStore(), model);
910         return nullptr;
911     }
912
913     if (WKStringIsEqualToUTF8CString(messageName, "IsWorkQueueEmpty")) {
914         bool isEmpty = TestController::singleton().workQueueManager().isWorkQueueEmpty();
915         WKRetainPtr<WKTypeRef> result = adoptWK(WKBooleanCreate(isEmpty));
916         return result;
917     }
918
919     if (WKStringIsEqualToUTF8CString(messageName, "DidReceiveServerRedirectForProvisionalNavigation")) {
920         WKRetainPtr<WKBooleanRef> result = adoptWK(WKBooleanCreate(TestController::singleton().didReceiveServerRedirectForProvisionalNavigation()));
921         return result;
922     }
923
924     if (WKStringIsEqualToUTF8CString(messageName, "ClearDidReceiveServerRedirectForProvisionalNavigation")) {
925         TestController::singleton().clearDidReceiveServerRedirectForProvisionalNavigation();
926         return nullptr;
927     }
928
929     if (WKStringIsEqualToUTF8CString(messageName, "SecureEventInputIsEnabled")) {
930 #if PLATFORM(MAC) && !PLATFORM(IOS_FAMILY)
931         WKRetainPtr<WKBooleanRef> result = adoptWK(WKBooleanCreate(IsSecureEventInputEnabled()));
932 #else
933         WKRetainPtr<WKBooleanRef> result = adoptWK(WKBooleanCreate(false));
934 #endif
935         return result;
936     }
937
938     if (WKStringIsEqualToUTF8CString(messageName, "SetCustomUserAgent")) {
939         WKStringRef userAgent = static_cast<WKStringRef>(messageBody);
940         WKPageSetCustomUserAgent(TestController::singleton().mainWebView()->page(), userAgent);
941         return nullptr;
942     }
943
944     if (WKStringIsEqualToUTF8CString(messageName, "GetAllStorageAccessEntries")) {
945         TestController::singleton().getAllStorageAccessEntries();
946         return nullptr;
947     }
948
949     if (WKStringIsEqualToUTF8CString(messageName, "SetAllowsAnySSLCertificate")) {
950         TestController::singleton().setAllowsAnySSLCertificate(WKBooleanGetValue(static_cast<WKBooleanRef>(messageBody)));
951         return nullptr;
952     }
953     
954     if (WKStringIsEqualToUTF8CString(messageName, "SetShouldSwapToEphemeralSessionOnNextNavigation")) {
955         TestController::singleton().setShouldSwapToEphemeralSessionOnNextNavigation(WKBooleanGetValue(static_cast<WKBooleanRef>(messageBody)));
956         return nullptr;
957     }
958     
959     if (WKStringIsEqualToUTF8CString(messageName, "SetShouldSwapToDefaultSessionOnNextNavigation")) {
960         TestController::singleton().setShouldSwapToDefaultSessionOnNextNavigation(WKBooleanGetValue(static_cast<WKBooleanRef>(messageBody)));
961         return nullptr;
962     }
963
964     if (WKStringIsEqualToUTF8CString(messageName, "ImageCountInGeneralPasteboard")) {
965         unsigned count = TestController::singleton().imageCountInGeneralPasteboard();
966         WKRetainPtr<WKUInt64Ref> result = adoptWK(WKUInt64Create(count));
967         return result;
968     }
969     
970     if (WKStringIsEqualToUTF8CString(messageName, "DeleteAllIndexedDatabases")) {
971         WKWebsiteDataStoreRemoveAllIndexedDatabases(TestController::defaultWebsiteDataStore(), nullptr, { });
972         return nullptr;
973     }
974
975     if (WKStringIsEqualToUTF8CString(messageName, "AddMockMediaDevice")) {
976         ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
977
978         WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
979         WKRetainPtr<WKStringRef> persistentIDKey = adoptWK(WKStringCreateWithUTF8CString("PersistentID"));
980         WKRetainPtr<WKStringRef> labelKey = adoptWK(WKStringCreateWithUTF8CString("Label"));
981         WKRetainPtr<WKStringRef> typeKey = adoptWK(WKStringCreateWithUTF8CString("Type"));
982
983         auto persistentID = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, persistentIDKey.get()));
984         auto label = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, labelKey.get()));
985         auto type = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, typeKey.get()));
986
987         TestController::singleton().addMockMediaDevice(persistentID, label, type);
988         return nullptr;
989     }
990
991     if (WKStringIsEqualToUTF8CString(messageName, "ClearMockMediaDevices")) {
992         TestController::singleton().clearMockMediaDevices();
993         return nullptr;
994     }
995
996     if (WKStringIsEqualToUTF8CString(messageName, "RemoveMockMediaDevice")) {
997         WKStringRef persistentId = static_cast<WKStringRef>(messageBody);
998
999         TestController::singleton().removeMockMediaDevice(persistentId);
1000         return nullptr;
1001     }
1002
1003     if (WKStringIsEqualToUTF8CString(messageName, "ResetMockMediaDevices")) {
1004         TestController::singleton().resetMockMediaDevices();
1005         return nullptr;
1006     }
1007
1008     if (WKStringIsEqualToUTF8CString(messageName, "SetMockCameraOrientation")) {
1009         TestController::singleton().setMockCameraOrientation(WKUInt64GetValue(static_cast<WKUInt64Ref>(messageBody)));
1010         return nullptr;
1011     }
1012
1013     if (WKStringIsEqualToUTF8CString(messageName, "IsMockRealtimeMediaSourceCenterEnabled")) {
1014         bool isMockRealtimeMediaSourceCenterEnabled = TestController::singleton().isMockRealtimeMediaSourceCenterEnabled();
1015         return adoptWK(WKBooleanCreate(isMockRealtimeMediaSourceCenterEnabled));
1016     }
1017     
1018     if (WKStringIsEqualToUTF8CString(messageName, "HasAppBoundSession")) {
1019         bool hasAppBoundSession = TestController::singleton().hasAppBoundSession();
1020         return adoptWK(WKBooleanCreate(hasAppBoundSession));
1021     }
1022
1023 #if PLATFORM(MAC)
1024     if (WKStringIsEqualToUTF8CString(messageName, "ConnectMockGamepad")) {
1025         ASSERT(WKGetTypeID(messageBody) == WKUInt64GetTypeID());
1026
1027         uint64_t index = WKUInt64GetValue(static_cast<WKUInt64Ref>(messageBody));
1028         WebCoreTestSupport::connectMockGamepad(index);
1029         
1030         return nullptr;
1031     }
1032
1033     if (WKStringIsEqualToUTF8CString(messageName, "DisconnectMockGamepad")) {
1034         ASSERT(WKGetTypeID(messageBody) == WKUInt64GetTypeID());
1035
1036         uint64_t index = WKUInt64GetValue(static_cast<WKUInt64Ref>(messageBody));
1037         WebCoreTestSupport::disconnectMockGamepad(index);
1038
1039         return nullptr;
1040     }
1041
1042     if (WKStringIsEqualToUTF8CString(messageName, "SetMockGamepadDetails")) {
1043         ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
1044
1045         WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
1046         WKRetainPtr<WKStringRef> gamepadIndexKey = adoptWK(WKStringCreateWithUTF8CString("GamepadIndex"));
1047         WKRetainPtr<WKStringRef> gamepadIDKey = adoptWK(WKStringCreateWithUTF8CString("GamepadID"));
1048         WKRetainPtr<WKStringRef> mappingKey = adoptWK(WKStringCreateWithUTF8CString("Mapping"));
1049         WKRetainPtr<WKStringRef> axisCountKey = adoptWK(WKStringCreateWithUTF8CString("AxisCount"));
1050         WKRetainPtr<WKStringRef> buttonCountKey = adoptWK(WKStringCreateWithUTF8CString("ButtonCount"));
1051
1052         WKUInt64Ref gamepadIndex = static_cast<WKUInt64Ref>(WKDictionaryGetItemForKey(messageBodyDictionary, gamepadIndexKey.get()));
1053         WKStringRef gamepadID = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, gamepadIDKey.get()));
1054         WKStringRef mapping = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, mappingKey.get()));
1055         WKUInt64Ref axisCount = static_cast<WKUInt64Ref>(WKDictionaryGetItemForKey(messageBodyDictionary, axisCountKey.get()));
1056         WKUInt64Ref buttonCount = static_cast<WKUInt64Ref>(WKDictionaryGetItemForKey(messageBodyDictionary, buttonCountKey.get()));
1057
1058         WebCoreTestSupport::setMockGamepadDetails(WKUInt64GetValue(gamepadIndex), toWTFString(gamepadID), toWTFString(mapping), WKUInt64GetValue(axisCount), WKUInt64GetValue(buttonCount));
1059         return nullptr;
1060     }
1061
1062     if (WKStringIsEqualToUTF8CString(messageName, "SetMockGamepadAxisValue")) {
1063         ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
1064
1065         WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
1066         WKRetainPtr<WKStringRef> gamepadIndexKey = adoptWK(WKStringCreateWithUTF8CString("GamepadIndex"));
1067         WKRetainPtr<WKStringRef> axisIndexKey = adoptWK(WKStringCreateWithUTF8CString("AxisIndex"));
1068         WKRetainPtr<WKStringRef> valueKey = adoptWK(WKStringCreateWithUTF8CString("Value"));
1069
1070         WKUInt64Ref gamepadIndex = static_cast<WKUInt64Ref>(WKDictionaryGetItemForKey(messageBodyDictionary, gamepadIndexKey.get()));
1071         WKUInt64Ref axisIndex = static_cast<WKUInt64Ref>(WKDictionaryGetItemForKey(messageBodyDictionary, axisIndexKey.get()));
1072         WKDoubleRef value = static_cast<WKDoubleRef>(WKDictionaryGetItemForKey(messageBodyDictionary, valueKey.get()));
1073
1074         WebCoreTestSupport::setMockGamepadAxisValue(WKUInt64GetValue(gamepadIndex), WKUInt64GetValue(axisIndex), WKDoubleGetValue(value));
1075
1076         return nullptr;
1077     }
1078
1079     if (WKStringIsEqualToUTF8CString(messageName, "SetMockGamepadButtonValue")) {
1080         ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
1081
1082         WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
1083         WKRetainPtr<WKStringRef> gamepadIndexKey = adoptWK(WKStringCreateWithUTF8CString("GamepadIndex"));
1084         WKRetainPtr<WKStringRef> buttonIndexKey = adoptWK(WKStringCreateWithUTF8CString("ButtonIndex"));
1085         WKRetainPtr<WKStringRef> valueKey = adoptWK(WKStringCreateWithUTF8CString("Value"));
1086
1087         WKUInt64Ref gamepadIndex = static_cast<WKUInt64Ref>(WKDictionaryGetItemForKey(messageBodyDictionary, gamepadIndexKey.get()));
1088         WKUInt64Ref buttonIndex = static_cast<WKUInt64Ref>(WKDictionaryGetItemForKey(messageBodyDictionary, buttonIndexKey.get()));
1089         WKDoubleRef value = static_cast<WKDoubleRef>(WKDictionaryGetItemForKey(messageBodyDictionary, valueKey.get()));
1090
1091         WebCoreTestSupport::setMockGamepadButtonValue(WKUInt64GetValue(gamepadIndex), WKUInt64GetValue(buttonIndex), WKDoubleGetValue(value));
1092
1093         return nullptr;
1094     }
1095 #endif // PLATFORM(MAC)
1096
1097     if (WKStringIsEqualToUTF8CString(messageName, "UserMediaPermissionRequestCountForOrigin")) {
1098         ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
1099         WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
1100
1101         WKRetainPtr<WKStringRef> originKey = adoptWK(WKStringCreateWithUTF8CString("origin"));
1102         WKStringRef originWK = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, originKey.get()));
1103
1104         WKRetainPtr<WKStringRef> parentOriginKey = adoptWK(WKStringCreateWithUTF8CString("parentOrigin"));
1105         WKStringRef parentOriginWK = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, parentOriginKey.get()));
1106         
1107         unsigned count = TestController::singleton().userMediaPermissionRequestCountForOrigin(originWK, parentOriginWK);
1108         WKRetainPtr<WKUInt64Ref> result = adoptWK(WKUInt64Create(count));
1109         return result;
1110     }
1111     if (WKStringIsEqualToUTF8CString(messageName, "IsDoingMediaCapture")) {
1112         WKRetainPtr<WKTypeRef> result = adoptWK(WKBooleanCreate(TestController::singleton().isDoingMediaCapture()));
1113         return result;
1114     }
1115
1116     if (WKStringIsEqualToUTF8CString(messageName, "SetStatisticsEnabled")) {
1117         ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
1118         WKBooleanRef value = static_cast<WKBooleanRef>(messageBody);
1119         TestController::singleton().setStatisticsEnabled(WKBooleanGetValue(value));
1120         return nullptr;
1121     }
1122
1123     if (WKStringIsEqualToUTF8CString(messageName, "IsStatisticsEphemeral")) {
1124         bool isEphemeral = TestController::singleton().isStatisticsEphemeral();
1125         WKRetainPtr<WKTypeRef> result = adoptWK(WKBooleanCreate(isEphemeral));
1126         return result;
1127     }
1128
1129     if (WKStringIsEqualToUTF8CString(messageName, "SetStatisticsDebugMode")) {
1130         ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
1131         WKBooleanRef value = static_cast<WKBooleanRef>(messageBody);
1132         TestController::singleton().setStatisticsDebugMode(WKBooleanGetValue(value));
1133         return nullptr;
1134     }
1135     
1136     if (WKStringIsEqualToUTF8CString(messageName, "SetStatisticsPrevalentResourceForDebugMode")) {
1137         ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID());
1138         WKStringRef hostName = static_cast<WKStringRef>(messageBody);
1139         TestController::singleton().setStatisticsPrevalentResourceForDebugMode(hostName);
1140         return nullptr;
1141     }
1142     
1143     if (WKStringIsEqualToUTF8CString(messageName, "SetStatisticsLastSeen")) {
1144         ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
1145         
1146         WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
1147         WKRetainPtr<WKStringRef> hostNameKey = adoptWK(WKStringCreateWithUTF8CString("HostName"));
1148         WKRetainPtr<WKStringRef> valueKey = adoptWK(WKStringCreateWithUTF8CString("Value"));
1149         
1150         WKStringRef hostName = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, hostNameKey.get()));
1151         WKDoubleRef value = static_cast<WKDoubleRef>(WKDictionaryGetItemForKey(messageBodyDictionary, valueKey.get()));
1152         
1153         TestController::singleton().setStatisticsLastSeen(hostName, WKDoubleGetValue(value));
1154         
1155         return nullptr;
1156     }
1157     
1158     if (WKStringIsEqualToUTF8CString(messageName, "SetStatisticsMergeStatistic")) {
1159         ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
1160
1161         WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
1162         WKRetainPtr<WKStringRef> hostNameKey = adoptWK(WKStringCreateWithUTF8CString("HostName"));
1163         WKRetainPtr<WKStringRef> topFrameDomain1Key = adoptWK(WKStringCreateWithUTF8CString("TopFrameDomain1"));
1164         WKRetainPtr<WKStringRef> topFrameDomain2Key = adoptWK(WKStringCreateWithUTF8CString("TopFrameDomain2"));
1165         WKRetainPtr<WKStringRef> lastSeenKey = adoptWK(WKStringCreateWithUTF8CString("LastSeen"));
1166         WKRetainPtr<WKStringRef> hadUserInteractionKey = adoptWK(WKStringCreateWithUTF8CString("HadUserInteraction"));
1167         WKRetainPtr<WKStringRef> mostRecentUserInteractionKey = adoptWK(WKStringCreateWithUTF8CString("MostRecentUserInteraction"));
1168         WKRetainPtr<WKStringRef> isGrandfatheredKey = adoptWK(WKStringCreateWithUTF8CString("IsGrandfathered"));
1169         WKRetainPtr<WKStringRef> isPrevalentKey = adoptWK(WKStringCreateWithUTF8CString("IsPrevalent"));
1170         WKRetainPtr<WKStringRef> isVeryPrevalentKey = adoptWK(WKStringCreateWithUTF8CString("IsVeryPrevalent"));
1171         WKRetainPtr<WKStringRef> dataRecordsRemovedKey = adoptWK(WKStringCreateWithUTF8CString("DataRecordsRemoved"));
1172         WKRetainPtr<WKStringRef> timesAccessedFirstPartyInteractionKey = adoptWK(WKStringCreateWithUTF8CString("TimesAccessedFirstPartyInteraction"));
1173
1174         WKStringRef hostName = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, hostNameKey.get()));
1175         WKStringRef topFrameDomain1 = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, topFrameDomain1Key.get()));
1176         WKStringRef topFrameDomain2 = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, topFrameDomain2Key.get()));
1177         WKDoubleRef lastSeen = static_cast<WKDoubleRef>(WKDictionaryGetItemForKey(messageBodyDictionary, lastSeenKey.get()));
1178         WKBooleanRef hadUserInteraction = static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(messageBodyDictionary, hadUserInteractionKey.get()));
1179         WKDoubleRef mostRecentUserInteraction = static_cast<WKDoubleRef>(WKDictionaryGetItemForKey(messageBodyDictionary, mostRecentUserInteractionKey.get()));
1180         WKBooleanRef isGrandfathered = static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(messageBodyDictionary, isGrandfatheredKey.get()));
1181         WKBooleanRef isPrevalent = static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(messageBodyDictionary, isPrevalentKey.get()));
1182         WKBooleanRef isVeryPrevalent = static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(messageBodyDictionary, isVeryPrevalentKey.get()));
1183         WKUInt64Ref dataRecordsRemoved = static_cast<WKUInt64Ref>(WKDictionaryGetItemForKey(messageBodyDictionary, dataRecordsRemovedKey.get()));
1184         
1185         TestController::singleton().setStatisticsMergeStatistic(hostName, topFrameDomain1, topFrameDomain2, WKDoubleGetValue(lastSeen), WKBooleanGetValue(hadUserInteraction), WKDoubleGetValue(mostRecentUserInteraction), WKBooleanGetValue(isGrandfathered), WKBooleanGetValue(isPrevalent), WKBooleanGetValue(isVeryPrevalent), WKUInt64GetValue(dataRecordsRemoved));
1186
1187         return nullptr;
1188     }
1189     
1190     if (WKStringIsEqualToUTF8CString(messageName, "SetStatisticsPrevalentResource")) {
1191         ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
1192
1193         WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
1194         WKRetainPtr<WKStringRef> hostNameKey = adoptWK(WKStringCreateWithUTF8CString("HostName"));
1195         WKRetainPtr<WKStringRef> valueKey = adoptWK(WKStringCreateWithUTF8CString("Value"));
1196
1197         WKStringRef hostName = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, hostNameKey.get()));
1198         WKBooleanRef value = static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(messageBodyDictionary, valueKey.get()));
1199
1200         TestController::singleton().setStatisticsPrevalentResource(hostName, WKBooleanGetValue(value));
1201         return nullptr;
1202     }
1203
1204     if (WKStringIsEqualToUTF8CString(messageName, "SetStatisticsVeryPrevalentResource")) {
1205         ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
1206         
1207         WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
1208         WKRetainPtr<WKStringRef> hostNameKey = adoptWK(WKStringCreateWithUTF8CString("HostName"));
1209         WKRetainPtr<WKStringRef> valueKey = adoptWK(WKStringCreateWithUTF8CString("Value"));
1210         
1211         WKStringRef hostName = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, hostNameKey.get()));
1212         WKBooleanRef value = static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(messageBodyDictionary, valueKey.get()));
1213         
1214         TestController::singleton().setStatisticsVeryPrevalentResource(hostName, WKBooleanGetValue(value));
1215         return nullptr;
1216     }
1217     
1218     if (WKStringIsEqualToUTF8CString(messageName, "dumpResourceLoadStatistics")) {
1219         dumpResourceLoadStatistics();
1220         return nullptr;
1221     }
1222
1223     if (WKStringIsEqualToUTF8CString(messageName, "IsStatisticsPrevalentResource")) {
1224         ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID());
1225
1226         WKStringRef hostName = static_cast<WKStringRef>(messageBody);
1227         bool isPrevalent = TestController::singleton().isStatisticsPrevalentResource(hostName);
1228         WKRetainPtr<WKTypeRef> result = adoptWK(WKBooleanCreate(isPrevalent));
1229         return result;
1230     }
1231
1232     if (WKStringIsEqualToUTF8CString(messageName, "IsStatisticsVeryPrevalentResource")) {
1233         ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID());
1234         
1235         WKStringRef hostName = static_cast<WKStringRef>(messageBody);
1236         bool isPrevalent = TestController::singleton().isStatisticsVeryPrevalentResource(hostName);
1237         WKRetainPtr<WKTypeRef> result = adoptWK(WKBooleanCreate(isPrevalent));
1238         return result;
1239     }
1240     
1241     if (WKStringIsEqualToUTF8CString(messageName, "IsStatisticsRegisteredAsSubresourceUnder")) {
1242         ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
1243         
1244         WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
1245         WKRetainPtr<WKStringRef> subresourceHostKey = adoptWK(WKStringCreateWithUTF8CString("SubresourceHost"));
1246         WKRetainPtr<WKStringRef> topFrameHostKey = adoptWK(WKStringCreateWithUTF8CString("TopFrameHost"));
1247         
1248         WKStringRef subresourceHost = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, subresourceHostKey.get()));
1249         WKStringRef topFrameHost = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, topFrameHostKey.get()));
1250         
1251         bool isRegisteredAsSubresourceUnder = TestController::singleton().isStatisticsRegisteredAsSubresourceUnder(subresourceHost, topFrameHost);
1252         WKRetainPtr<WKTypeRef> result = adoptWK(WKBooleanCreate(isRegisteredAsSubresourceUnder));
1253         return result;
1254     }
1255     
1256     if (WKStringIsEqualToUTF8CString(messageName, "IsStatisticsRegisteredAsSubFrameUnder")) {
1257         ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
1258         
1259         WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
1260         WKRetainPtr<WKStringRef> subFrameHostKey = adoptWK(WKStringCreateWithUTF8CString("SubFrameHost"));
1261         WKRetainPtr<WKStringRef> topFrameHostKey = adoptWK(WKStringCreateWithUTF8CString("TopFrameHost"));
1262         
1263         WKStringRef subFrameHost = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, subFrameHostKey.get()));
1264         WKStringRef topFrameHost = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, topFrameHostKey.get()));
1265
1266         bool isRegisteredAsSubFrameUnder = TestController::singleton().isStatisticsRegisteredAsSubFrameUnder(subFrameHost, topFrameHost);
1267         WKRetainPtr<WKTypeRef> result = adoptWK(WKBooleanCreate(isRegisteredAsSubFrameUnder));
1268         return result;
1269     }
1270     
1271     if (WKStringIsEqualToUTF8CString(messageName, "IsStatisticsRegisteredAsRedirectingTo")) {
1272         ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
1273         
1274         WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
1275         WKRetainPtr<WKStringRef> hostRedirectedFromKey = adoptWK(WKStringCreateWithUTF8CString("HostRedirectedFrom"));
1276         WKRetainPtr<WKStringRef> hostRedirectedToKey = adoptWK(WKStringCreateWithUTF8CString("HostRedirectedTo"));
1277         
1278         WKStringRef hostRedirectedFrom = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, hostRedirectedFromKey.get()));
1279         WKStringRef hostRedirectedTo = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, hostRedirectedToKey.get()));
1280         
1281         bool isRegisteredAsRedirectingTo = TestController::singleton().isStatisticsRegisteredAsRedirectingTo(hostRedirectedFrom, hostRedirectedTo);
1282         WKRetainPtr<WKTypeRef> result = adoptWK(WKBooleanCreate(isRegisteredAsRedirectingTo));
1283         return result;
1284     }
1285     
1286     if (WKStringIsEqualToUTF8CString(messageName, "SetStatisticsHasHadUserInteraction")) {
1287         ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
1288         
1289         WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
1290         WKRetainPtr<WKStringRef> hostNameKey = adoptWK(WKStringCreateWithUTF8CString("HostName"));
1291         WKRetainPtr<WKStringRef> valueKey = adoptWK(WKStringCreateWithUTF8CString("Value"));
1292         
1293         WKStringRef hostName = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, hostNameKey.get()));
1294         WKBooleanRef value = static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(messageBodyDictionary, valueKey.get()));
1295         
1296         TestController::singleton().setStatisticsHasHadUserInteraction(hostName, WKBooleanGetValue(value));
1297         return nullptr;
1298     }
1299
1300     if (WKStringIsEqualToUTF8CString(messageName, "IsStatisticsHasHadUserInteraction")) {
1301         ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID());
1302         
1303         WKStringRef hostName = static_cast<WKStringRef>(messageBody);
1304         bool hasHadUserInteraction = TestController::singleton().isStatisticsHasHadUserInteraction(hostName);
1305         WKRetainPtr<WKTypeRef> result = adoptWK(WKBooleanCreate(hasHadUserInteraction));
1306         return result;
1307     }
1308     
1309     if (WKStringIsEqualToUTF8CString(messageName, "IsStatisticsOnlyInDatabaseOnce")) {
1310         ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
1311         
1312         WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
1313         auto subHostKey = adoptWK(WKStringCreateWithUTF8CString("SubHost"));
1314         auto topHostKey = adoptWK(WKStringCreateWithUTF8CString("TopHost"));
1315         
1316         WKStringRef subHost = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, subHostKey.get()));
1317         WKStringRef topHost = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, topHostKey.get()));
1318
1319         bool statisticInDatabaseOnce = TestController::singleton().isStatisticsOnlyInDatabaseOnce(subHost, topHost);
1320         return adoptWK(WKBooleanCreate(statisticInDatabaseOnce));
1321     }
1322     
1323     if (WKStringIsEqualToUTF8CString(messageName, "SetStatisticsGrandfathered")) {
1324         ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
1325         
1326         WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
1327         WKRetainPtr<WKStringRef> hostNameKey = adoptWK(WKStringCreateWithUTF8CString("HostName"));
1328         WKRetainPtr<WKStringRef> valueKey = adoptWK(WKStringCreateWithUTF8CString("Value"));
1329         
1330         WKStringRef hostName = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, hostNameKey.get()));
1331         WKBooleanRef value = static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(messageBodyDictionary, valueKey.get()));
1332         
1333         TestController::singleton().setStatisticsGrandfathered(hostName, WKBooleanGetValue(value));
1334         return nullptr;
1335     }
1336     
1337     if (WKStringIsEqualToUTF8CString(messageName, "IsStatisticsGrandfathered")) {
1338         ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID());
1339         
1340         WKStringRef hostName = static_cast<WKStringRef>(messageBody);
1341         bool isGrandfathered = TestController::singleton().isStatisticsGrandfathered(hostName);
1342         WKRetainPtr<WKTypeRef> result = adoptWK(WKBooleanCreate(isGrandfathered));
1343         return result;
1344     }
1345
1346     if (WKStringIsEqualToUTF8CString(messageName, "SetUseITPDatabase")) {
1347         ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
1348
1349         WKBooleanRef value = static_cast<WKBooleanRef>(messageBody);
1350         TestController::singleton().setUseITPDatabase(WKBooleanGetValue(value));
1351         return nullptr;
1352     }
1353     
1354     if (WKStringIsEqualToUTF8CString(messageName, "SetStatisticsSubframeUnderTopFrameOrigin")) {
1355         ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
1356         
1357         WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
1358         WKRetainPtr<WKStringRef> hostNameKey = adoptWK(WKStringCreateWithUTF8CString("HostName"));
1359         WKRetainPtr<WKStringRef> topFrameHostNameKey = adoptWK(WKStringCreateWithUTF8CString("TopFrameHostName"));
1360         
1361         WKStringRef hostName = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, hostNameKey.get()));
1362         WKStringRef topFrameHostName = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, topFrameHostNameKey.get()));
1363
1364         TestController::singleton().setStatisticsSubframeUnderTopFrameOrigin(hostName, topFrameHostName);
1365         return nullptr;
1366     }
1367     
1368     if (WKStringIsEqualToUTF8CString(messageName, "SetStatisticsSubresourceUnderTopFrameOrigin")) {
1369         ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
1370         
1371         WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
1372         WKRetainPtr<WKStringRef> hostNameKey = adoptWK(WKStringCreateWithUTF8CString("HostName"));
1373         WKRetainPtr<WKStringRef> topFrameHostNameKey = adoptWK(WKStringCreateWithUTF8CString("TopFrameHostName"));
1374         
1375         WKStringRef hostName = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, hostNameKey.get()));
1376         WKStringRef topFrameHostName = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, topFrameHostNameKey.get()));
1377         
1378         TestController::singleton().setStatisticsSubresourceUnderTopFrameOrigin(hostName, topFrameHostName);
1379         return nullptr;
1380     }
1381     
1382     if (WKStringIsEqualToUTF8CString(messageName, "SetStatisticsSubresourceUniqueRedirectTo")) {
1383         ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
1384         
1385         WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
1386         WKRetainPtr<WKStringRef> hostNameKey = adoptWK(WKStringCreateWithUTF8CString("HostName"));
1387         WKRetainPtr<WKStringRef> hostNameRedirectedToKey = adoptWK(WKStringCreateWithUTF8CString("HostNameRedirectedTo"));
1388         
1389         WKStringRef hostName = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, hostNameKey.get()));
1390         WKStringRef hostNameRedirectedTo = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, hostNameRedirectedToKey.get()));
1391         
1392         TestController::singleton().setStatisticsSubresourceUniqueRedirectTo(hostName, hostNameRedirectedTo);
1393         return nullptr;
1394     }
1395
1396     if (WKStringIsEqualToUTF8CString(messageName, "SetStatisticsSubresourceUniqueRedirectFrom")) {
1397         ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
1398         
1399         WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
1400         WKRetainPtr<WKStringRef> hostNameKey = adoptWK(WKStringCreateWithUTF8CString("HostName"));
1401         WKRetainPtr<WKStringRef> hostNameRedirectedFromKey = adoptWK(WKStringCreateWithUTF8CString("HostNameRedirectedFrom"));
1402         
1403         WKStringRef hostName = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, hostNameKey.get()));
1404         WKStringRef hostNameRedirectedFrom = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, hostNameRedirectedFromKey.get()));
1405         
1406         TestController::singleton().setStatisticsSubresourceUniqueRedirectFrom(hostName, hostNameRedirectedFrom);
1407         return nullptr;
1408     }
1409     
1410     if (WKStringIsEqualToUTF8CString(messageName, "SetStatisticsTopFrameUniqueRedirectTo")) {
1411         ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
1412         
1413         WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
1414         WKRetainPtr<WKStringRef> hostNameKey = adoptWK(WKStringCreateWithUTF8CString("HostName"));
1415         WKRetainPtr<WKStringRef> hostNameRedirectedToKey = adoptWK(WKStringCreateWithUTF8CString("HostNameRedirectedTo"));
1416         
1417         WKStringRef hostName = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, hostNameKey.get()));
1418         WKStringRef hostNameRedirectedTo = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, hostNameRedirectedToKey.get()));
1419         
1420         TestController::singleton().setStatisticsTopFrameUniqueRedirectTo(hostName, hostNameRedirectedTo);
1421         return nullptr;
1422     }
1423     
1424     if (WKStringIsEqualToUTF8CString(messageName, "SetStatisticsTopFrameUniqueRedirectFrom")) {
1425         ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
1426         
1427         WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
1428         WKRetainPtr<WKStringRef> hostNameKey = adoptWK(WKStringCreateWithUTF8CString("HostName"));
1429         WKRetainPtr<WKStringRef> hostNameRedirectedFromKey = adoptWK(WKStringCreateWithUTF8CString("HostNameRedirectedFrom"));
1430         
1431         WKStringRef hostName = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, hostNameKey.get()));
1432         WKStringRef hostNameRedirectedFrom = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, hostNameRedirectedFromKey.get()));
1433         
1434         TestController::singleton().setStatisticsTopFrameUniqueRedirectFrom(hostName, hostNameRedirectedFrom);
1435         return nullptr;
1436     }
1437     
1438     if (WKStringIsEqualToUTF8CString(messageName, "SetStatisticsCrossSiteLoadWithLinkDecoration")) {
1439         ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
1440         
1441         WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
1442         auto fromHostKey = adoptWK(WKStringCreateWithUTF8CString("FromHost"));
1443         auto toHostKey = adoptWK(WKStringCreateWithUTF8CString("ToHost"));
1444
1445         WKStringRef fromHost = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, fromHostKey.get()));
1446         WKStringRef toHost = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, toHostKey.get()));
1447         
1448         TestController::singleton().setStatisticsCrossSiteLoadWithLinkDecoration(fromHost, toHost);
1449         return nullptr;
1450     }
1451
1452     if (WKStringIsEqualToUTF8CString(messageName, "SetStatisticsTimeToLiveUserInteraction")) {
1453         ASSERT(WKGetTypeID(messageBody) == WKDoubleGetTypeID());
1454         WKDoubleRef seconds = static_cast<WKDoubleRef>(messageBody);
1455         TestController::singleton().setStatisticsTimeToLiveUserInteraction(WKDoubleGetValue(seconds));
1456         return nullptr;
1457     }
1458     
1459     if (WKStringIsEqualToUTF8CString(messageName, "StatisticsProcessStatisticsAndDataRecords")) {
1460         TestController::singleton().statisticsProcessStatisticsAndDataRecords();
1461         return nullptr;
1462     }
1463     
1464     if (WKStringIsEqualToUTF8CString(messageName, "StatisticsUpdateCookieBlocking")) {
1465         TestController::singleton().statisticsUpdateCookieBlocking();
1466         return nullptr;
1467     }
1468
1469     if (WKStringIsEqualToUTF8CString(messageName, "StatisticsSubmitTelemetry")) {
1470         TestController::singleton().statisticsSubmitTelemetry();
1471         return nullptr;
1472     }
1473     
1474     if (WKStringIsEqualToUTF8CString(messageName, "StatisticsNotifyPagesWhenDataRecordsWereScanned")) {
1475         ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
1476         WKBooleanRef value = static_cast<WKBooleanRef>(messageBody);
1477         TestController::singleton().setStatisticsNotifyPagesWhenDataRecordsWereScanned(WKBooleanGetValue(value));
1478         return nullptr;
1479     }
1480
1481     if (WKStringIsEqualToUTF8CString(messageName, "StatisticsSetIsRunningTest")) {
1482         ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
1483         WKBooleanRef value = static_cast<WKBooleanRef>(messageBody);
1484         TestController::singleton().setStatisticsIsRunningTest(WKBooleanGetValue(value));
1485         return nullptr;
1486     }
1487     
1488     if (WKStringIsEqualToUTF8CString(messageName, "StatisticsNotifyPagesWhenTelemetryWasCaptured")) {
1489         ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
1490         WKBooleanRef value = static_cast<WKBooleanRef>(messageBody);
1491         TestController::singleton().setStatisticsNotifyPagesWhenTelemetryWasCaptured(WKBooleanGetValue(value));
1492         return nullptr;
1493     }
1494     
1495     if (WKStringIsEqualToUTF8CString(messageName, "StatisticsShouldClassifyResourcesBeforeDataRecordsRemoval")) {
1496         ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
1497         WKBooleanRef value = static_cast<WKBooleanRef>(messageBody);
1498         TestController::singleton().setStatisticsShouldClassifyResourcesBeforeDataRecordsRemoval(WKBooleanGetValue(value));
1499         return nullptr;
1500     }
1501
1502     if (WKStringIsEqualToUTF8CString(messageName, "SetStatisticsMinimumTimeBetweenDataRecordsRemoval")) {
1503         ASSERT(WKGetTypeID(messageBody) == WKDoubleGetTypeID());
1504         WKDoubleRef seconds = static_cast<WKDoubleRef>(messageBody);
1505         TestController::singleton().setStatisticsMinimumTimeBetweenDataRecordsRemoval(WKDoubleGetValue(seconds));
1506         return nullptr;
1507     }
1508     
1509     if (WKStringIsEqualToUTF8CString(messageName, "SetStatisticsGrandfatheringTime")) {
1510         ASSERT(WKGetTypeID(messageBody) == WKDoubleGetTypeID());
1511         WKDoubleRef seconds = static_cast<WKDoubleRef>(messageBody);
1512         TestController::singleton().setStatisticsGrandfatheringTime(WKDoubleGetValue(seconds));
1513         return nullptr;
1514     }
1515     
1516     if (WKStringIsEqualToUTF8CString(messageName, "SetMaxStatisticsEntries")) {
1517         ASSERT(WKGetTypeID(messageBody) == WKUInt64GetTypeID());
1518         WKUInt64Ref entries = static_cast<WKUInt64Ref>(messageBody);
1519         TestController::singleton().setStatisticsMaxStatisticsEntries(WKUInt64GetValue(entries));
1520         return nullptr;
1521     }
1522     
1523     if (WKStringIsEqualToUTF8CString(messageName, "SetPruneEntriesDownTo")) {
1524         ASSERT(WKGetTypeID(messageBody) == WKUInt64GetTypeID());
1525         WKUInt64Ref entries = static_cast<WKUInt64Ref>(messageBody);
1526         TestController::singleton().setStatisticsPruneEntriesDownTo(WKUInt64GetValue(entries));
1527         return nullptr;
1528     }
1529     
1530     if (WKStringIsEqualToUTF8CString(messageName, "StatisticsClearInMemoryAndPersistentStore")) {
1531         TestController::singleton().statisticsClearInMemoryAndPersistentStore();
1532         return nullptr;
1533     }
1534     
1535     if (WKStringIsEqualToUTF8CString(messageName, "StatisticsClearInMemoryAndPersistentStoreModifiedSinceHours")) {
1536         ASSERT(WKGetTypeID(messageBody) == WKUInt64GetTypeID());
1537         WKUInt64Ref hours = static_cast<WKUInt64Ref>(messageBody);
1538         TestController::singleton().statisticsClearInMemoryAndPersistentStoreModifiedSinceHours(WKUInt64GetValue(hours));
1539         return nullptr;
1540     }
1541     
1542     if (WKStringIsEqualToUTF8CString(messageName, "StatisticsClearThroughWebsiteDataRemoval")) {
1543         TestController::singleton().statisticsClearThroughWebsiteDataRemoval();
1544         return nullptr;
1545     }
1546
1547     if (WKStringIsEqualToUTF8CString(messageName, "StatisticsDeleteCookiesForHost")) {
1548         ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
1549         
1550         WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
1551         WKRetainPtr<WKStringRef> hostNameKey = adoptWK(WKStringCreateWithUTF8CString("HostName"));
1552         WKRetainPtr<WKStringRef> valueKey = adoptWK(WKStringCreateWithUTF8CString("IncludeHttpOnlyCookies"));
1553         
1554         WKStringRef hostName = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, hostNameKey.get()));
1555         WKBooleanRef includeHttpOnlyCookies = static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(messageBodyDictionary, valueKey.get()));
1556         
1557         TestController::singleton().statisticsDeleteCookiesForHost(hostName, WKBooleanGetValue(includeHttpOnlyCookies));
1558         return nullptr;
1559     }
1560
1561     if (WKStringIsEqualToUTF8CString(messageName, "IsStatisticsHasLocalStorage")) {
1562         ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID());
1563         
1564         WKStringRef hostName = static_cast<WKStringRef>(messageBody);
1565         bool hasLocalStorage = TestController::singleton().isStatisticsHasLocalStorage(hostName);
1566         auto result = adoptWK(WKBooleanCreate(hasLocalStorage));
1567         return result;
1568     }
1569
1570     if (WKStringIsEqualToUTF8CString(messageName, "SetStatisticsCacheMaxAgeCap")) {
1571         ASSERT(WKGetTypeID(messageBody) == WKDoubleGetTypeID());
1572         WKDoubleRef seconds = static_cast<WKDoubleRef>(messageBody);
1573         TestController::singleton().setStatisticsCacheMaxAgeCap(WKDoubleGetValue(seconds));
1574         return nullptr;
1575     }
1576
1577     if (WKStringIsEqualToUTF8CString(messageName, "StatisticsResetToConsistentState")) {
1578         if (m_shouldDumpResourceLoadStatistics)
1579             m_savedResourceLoadStatistics = TestController::singleton().dumpResourceLoadStatistics();
1580         TestController::singleton().statisticsResetToConsistentState();
1581         return nullptr;
1582     }
1583
1584     if (WKStringIsEqualToUTF8CString(messageName, "HasStatisticsIsolatedSession")) {
1585         ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID());
1586         
1587         WKStringRef hostName = static_cast<WKStringRef>(messageBody);
1588         bool hasIsolatedSession = TestController::singleton().hasStatisticsIsolatedSession(hostName);
1589         auto result = adoptWK(WKBooleanCreate(hasIsolatedSession));
1590         return result;
1591     }
1592     
1593     if (WKStringIsEqualToUTF8CString(messageName, "SetStatisticsShouldDowngradeReferrer")) {
1594         ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
1595         WKBooleanRef value = static_cast<WKBooleanRef>(messageBody);
1596         TestController::singleton().setStatisticsShouldDowngradeReferrer(WKBooleanGetValue(value));
1597         return nullptr;
1598     }
1599     
1600     if (WKStringIsEqualToUTF8CString(messageName, "SetStatisticsFirstPartyWebsiteDataRemovalMode")) {
1601         ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
1602         WKBooleanRef value = static_cast<WKBooleanRef>(messageBody);
1603         TestController::singleton().setStatisticsFirstPartyWebsiteDataRemovalMode(WKBooleanGetValue(value));
1604         return nullptr;
1605     }
1606     
1607     if (WKStringIsEqualToUTF8CString(messageName, "RemoveAllSessionCredentials")) {
1608         TestController::singleton().removeAllSessionCredentials();
1609         return nullptr;
1610     }
1611
1612     if (WKStringIsEqualToUTF8CString(messageName, "ClearDOMCache")) {
1613         ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID());
1614         WKStringRef origin = static_cast<WKStringRef>(messageBody);
1615
1616         TestController::singleton().clearDOMCache(origin);
1617         return nullptr;
1618     }
1619
1620     if (WKStringIsEqualToUTF8CString(messageName, "ClearDOMCaches")) {
1621         TestController::singleton().clearDOMCaches();
1622         return nullptr;
1623     }
1624
1625     if (WKStringIsEqualToUTF8CString(messageName, "HasDOMCache")) {
1626         ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID());
1627         WKStringRef origin = static_cast<WKStringRef>(messageBody);
1628
1629         bool hasDOMCache = TestController::singleton().hasDOMCache(origin);
1630         WKRetainPtr<WKTypeRef> result = adoptWK(WKBooleanCreate(hasDOMCache));
1631         return result;
1632     }
1633
1634     if (WKStringIsEqualToUTF8CString(messageName, "DOMCacheSize")) {
1635         ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID());
1636         WKStringRef origin = static_cast<WKStringRef>(messageBody);
1637
1638         auto domCacheSize = TestController::singleton().domCacheSize(origin);
1639         WKRetainPtr<WKTypeRef> result = adoptWK(WKUInt64Create(domCacheSize));
1640         return result;
1641     }
1642
1643     if (WKStringIsEqualToUTF8CString(messageName, "SetAllowStorageQuotaIncrease")) {
1644         ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
1645         auto canIncrease = WKBooleanGetValue(static_cast<WKBooleanRef>(messageBody));
1646         TestController::singleton().setAllowStorageQuotaIncrease(canIncrease);
1647         return nullptr;
1648     }
1649
1650     if (WKStringIsEqualToUTF8CString(messageName, "InjectUserScript")) {
1651         ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID());
1652         WKStringRef script = static_cast<WKStringRef>(messageBody);
1653
1654         TestController::singleton().injectUserScript(script);
1655         return nullptr;
1656     }
1657
1658     if (WKStringIsEqualToUTF8CString(messageName, "GetApplicationManifest")) {
1659 #ifdef __BLOCKS__
1660         WKPageGetApplicationManifest_b(TestController::singleton().mainWebView()->page(), ^{
1661             WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("DidGetApplicationManifest"));
1662             WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0);
1663         });
1664 #else
1665         // FIXME: Add API for loading the manifest on non-__BLOCKS__ ports.
1666         ASSERT_NOT_REACHED();
1667 #endif
1668         return nullptr;
1669     }
1670
1671     if (WKStringIsEqualToUTF8CString(messageName, "SendDisplayConfigurationChangedMessageForTesting")) {
1672         TestController::singleton().sendDisplayConfigurationChangedMessageForTesting();
1673         return nullptr;
1674     }
1675
1676     if (WKStringIsEqualToUTF8CString(messageName, "SetServiceWorkerFetchTimeout")) {
1677         ASSERT(WKGetTypeID(messageBody) == WKDoubleGetTypeID());
1678         WKDoubleRef seconds = static_cast<WKDoubleRef>(messageBody);
1679         TestController::singleton().setServiceWorkerFetchTimeoutForTesting(WKDoubleGetValue(seconds));
1680         return nullptr;
1681     }
1682
1683     if (WKStringIsEqualToUTF8CString(messageName, "SetUseSeparateServiceWorkerProcess")) {
1684         ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
1685         auto useSeparateServiceWorkerProcess = WKBooleanGetValue(static_cast<WKBooleanRef>(messageBody));
1686         WKContextSetUseSeparateServiceWorkerProcess(TestController::singleton().context(), useSeparateServiceWorkerProcess);
1687         return nullptr;
1688     }
1689
1690     if (WKStringIsEqualToUTF8CString(messageName, "TerminateNetworkProcess")) {
1691         ASSERT(!messageBody);
1692         TestController::singleton().terminateNetworkProcess();
1693         return nullptr;
1694     }
1695
1696     if (WKStringIsEqualToUTF8CString(messageName, "TerminateServiceWorkers")) {
1697         ASSERT(!messageBody);
1698         TestController::singleton().terminateServiceWorkers();
1699         return nullptr;
1700     }
1701
1702     if (WKStringIsEqualToUTF8CString(messageName, "AddTestKeyToKeychain")) {
1703         ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
1704         WKDictionaryRef testKeyDictionary = static_cast<WKDictionaryRef>(messageBody);
1705
1706         WKRetainPtr<WKStringRef> privateKeyKey = adoptWK(WKStringCreateWithUTF8CString("PrivateKey"));
1707         WKStringRef privateKeyWK = static_cast<WKStringRef>(WKDictionaryGetItemForKey(testKeyDictionary, privateKeyKey.get()));
1708
1709         WKRetainPtr<WKStringRef> attrLabelKey = adoptWK(WKStringCreateWithUTF8CString("AttrLabel"));
1710         WKStringRef attrLabelWK = static_cast<WKStringRef>(WKDictionaryGetItemForKey(testKeyDictionary, attrLabelKey.get()));
1711
1712         WKRetainPtr<WKStringRef> applicationTagKey = adoptWK(WKStringCreateWithUTF8CString("ApplicationTag"));
1713         WKStringRef applicationTagWK = static_cast<WKStringRef>(WKDictionaryGetItemForKey(testKeyDictionary, applicationTagKey.get()));
1714
1715         TestController::singleton().addTestKeyToKeychain(toWTFString(privateKeyWK), toWTFString(attrLabelWK), toWTFString(applicationTagWK));
1716         return nullptr;
1717     }
1718
1719     if (WKStringIsEqualToUTF8CString(messageName, "CleanUpKeychain")) {
1720         ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
1721         WKDictionaryRef testDictionary = static_cast<WKDictionaryRef>(messageBody);
1722
1723         WKRetainPtr<WKStringRef> attrLabelKey = adoptWK(WKStringCreateWithUTF8CString("AttrLabel"));
1724         WKStringRef attrLabelWK = static_cast<WKStringRef>(WKDictionaryGetItemForKey(testDictionary, attrLabelKey.get()));
1725
1726         WKRetainPtr<WKStringRef> applicationTagKey = adoptWK(WKStringCreateWithUTF8CString("ApplicationTag"));
1727         WKStringRef applicationTagWK = static_cast<WKStringRef>(WKDictionaryGetItemForKey(testDictionary, applicationTagKey.get()));
1728
1729         TestController::singleton().cleanUpKeychain(toWTFString(attrLabelWK), applicationTagWK ? toWTFString(applicationTagWK) : String());
1730         return nullptr;
1731     }
1732
1733     if (WKStringIsEqualToUTF8CString(messageName, "KeyExistsInKeychain")) {
1734         ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
1735         WKDictionaryRef testDictionary = static_cast<WKDictionaryRef>(messageBody);
1736
1737         WKRetainPtr<WKStringRef> attrLabelKey = adoptWK(WKStringCreateWithUTF8CString("AttrLabel"));
1738         WKStringRef attrLabelWK = static_cast<WKStringRef>(WKDictionaryGetItemForKey(testDictionary, attrLabelKey.get()));
1739
1740         WKRetainPtr<WKStringRef> applicationTagKey = adoptWK(WKStringCreateWithUTF8CString("ApplicationTag"));
1741         WKStringRef applicationTagWK = static_cast<WKStringRef>(WKDictionaryGetItemForKey(testDictionary, applicationTagKey.get()));
1742
1743         bool keyExistsInKeychain = TestController::singleton().keyExistsInKeychain(toWTFString(attrLabelWK), toWTFString(applicationTagWK));
1744         WKRetainPtr<WKTypeRef> result = adoptWK(WKBooleanCreate(keyExistsInKeychain));
1745         return result;
1746     }
1747
1748     if (WKStringIsEqualToUTF8CString(messageName, "ServerTrustEvaluationCallbackCallsCount")) {
1749         WKRetainPtr<WKTypeRef> result = adoptWK(WKUInt64Create(TestController::singleton().serverTrustEvaluationCallbackCallsCount()));
1750         return result;
1751     }
1752
1753     if (WKStringIsEqualToUTF8CString(messageName, "ShouldDismissJavaScriptAlertsAsynchronously")) {
1754         ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
1755         WKBooleanRef value = static_cast<WKBooleanRef>(messageBody);
1756         TestController::singleton().setShouldDismissJavaScriptAlertsAsynchronously(WKBooleanGetValue(value));
1757         return nullptr;
1758     }
1759
1760     if (WKStringIsEqualToUTF8CString(messageName, "AbortModal")) {
1761         TestController::singleton().abortModal();
1762         return nullptr;
1763     }
1764
1765     if (WKStringIsEqualToUTF8CString(messageName, "DumpAdClickAttribution")) {
1766         dumpAdClickAttribution();
1767         return nullptr;
1768     }
1769     
1770     if (WKStringIsEqualToUTF8CString(messageName, "ClearAdClickAttribution")) {
1771         TestController::singleton().clearAdClickAttribution();
1772         return nullptr;
1773     }
1774
1775     if (WKStringIsEqualToUTF8CString(messageName, "ClearAdClickAttributionsThroughWebsiteDataRemoval")) {
1776         TestController::singleton().clearAdClickAttributionsThroughWebsiteDataRemoval();
1777         return nullptr;
1778     }
1779
1780     if (WKStringIsEqualToUTF8CString(messageName, "SetAdClickAttributionOverrideTimerForTesting")) {
1781         ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
1782         WKBooleanRef value = static_cast<WKBooleanRef>(messageBody);
1783         TestController::singleton().setAdClickAttributionOverrideTimerForTesting(WKBooleanGetValue(value));
1784         return nullptr;
1785     }
1786     
1787     if (WKStringIsEqualToUTF8CString(messageName, "SetAdClickAttributionConversionURLForTesting")) {
1788         ASSERT(WKGetTypeID(messageBody) == WKURLGetTypeID());
1789         WKURLRef url = static_cast<WKURLRef>(messageBody);
1790         TestController::singleton().setAdClickAttributionConversionURLForTesting(url);
1791         return nullptr;
1792     }
1793
1794     if (WKStringIsEqualToUTF8CString(messageName, "MarkAdClickAttributionsAsExpiredForTesting")) {
1795         TestController::singleton().markAdClickAttributionsAsExpiredForTesting();
1796         return nullptr;
1797     }
1798
1799     if (WKStringIsEqualToUTF8CString(messageName, "SyncLocalStorage")) {
1800         TestController::singleton().syncLocalStorage();
1801         return nullptr;
1802     }
1803
1804     ASSERT_NOT_REACHED();
1805     return nullptr;
1806 }
1807
1808 void TestInvocation::runUISideScriptAfterUpdateCallback(WKErrorRef, void* context)
1809 {
1810     UIScriptInvocationData* data = static_cast<UIScriptInvocationData*>(context);
1811     if (TestInvocation* invocation = data->testInvocation) {
1812         RELEASE_ASSERT(TestController::singleton().isCurrentInvocation(invocation));
1813         invocation->runUISideScript(data->scriptString.get(), data->callbackID);
1814     }
1815     delete data;
1816 }
1817
1818 void TestInvocation::runUISideScript(WKStringRef script, unsigned scriptCallbackID)
1819 {
1820     m_pendingUIScriptInvocationData = nullptr;
1821
1822     if (!m_UIScriptContext)
1823         m_UIScriptContext = makeUnique<UIScriptContext>(*this);
1824     
1825     m_UIScriptContext->runUIScript(toWTFString(script), scriptCallbackID);
1826 }
1827
1828 void TestInvocation::uiScriptDidComplete(const String& result, unsigned scriptCallbackID)
1829 {
1830     WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CallUISideScriptCallback"));
1831
1832     WKRetainPtr<WKMutableDictionaryRef> messageBody = adoptWK(WKMutableDictionaryCreate());
1833     WKRetainPtr<WKStringRef> resultKey = adoptWK(WKStringCreateWithUTF8CString("Result"));
1834     WKRetainPtr<WKStringRef> callbackIDKey = adoptWK(WKStringCreateWithUTF8CString("CallbackID"));
1835     WKRetainPtr<WKUInt64Ref> callbackIDValue = adoptWK(WKUInt64Create(scriptCallbackID));
1836
1837     WKDictionarySetItem(messageBody.get(), resultKey.get(), toWK(result).get());
1838     WKDictionarySetItem(messageBody.get(), callbackIDKey.get(), callbackIDValue.get());
1839
1840     WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), messageBody.get());
1841 }
1842
1843 void TestInvocation::outputText(const WTF::String& text)
1844 {
1845     m_textOutput.append(text);
1846 }
1847
1848 void TestInvocation::didBeginSwipe()
1849 {
1850     WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CallDidBeginSwipeCallback"));
1851     WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0);
1852 }
1853
1854 void TestInvocation::willEndSwipe()
1855 {
1856     WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CallWillEndSwipeCallback"));
1857     WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0);
1858 }
1859
1860 void TestInvocation::didEndSwipe()
1861 {
1862     WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CallDidEndSwipeCallback"));
1863     WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0);
1864 }
1865
1866 void TestInvocation::didRemoveSwipeSnapshot()
1867 {
1868     WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CallDidRemoveSwipeSnapshotCallback"));
1869     WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0);
1870 }
1871
1872 void TestInvocation::notifyDownloadDone()
1873 {
1874     WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("NotifyDownloadDone"));
1875     WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0);
1876 }
1877
1878 void TestInvocation::didClearStatisticsThroughWebsiteDataRemoval()
1879 {
1880     WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CallDidClearStatisticsThroughWebsiteDataRemoval"));
1881     WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0);
1882 }
1883
1884 void TestInvocation::didSetShouldDowngradeReferrer()
1885 {
1886     WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CallDidSetShouldDowngradeReferrer"));
1887     WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0);
1888 }
1889
1890 void TestInvocation::didSetShouldBlockThirdPartyCookies()
1891 {
1892     WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CallDidSetShouldBlockThirdPartyCookies"));
1893     WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), nullptr);
1894 }
1895
1896 void TestInvocation::didSetInAppBrowserPrivacyEnabled()
1897 {
1898     WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CallDidSetInAppBrowserPrivacyEnabled"));
1899     WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), nullptr);
1900 }
1901
1902 void TestInvocation::didSetFirstPartyWebsiteDataRemovalMode()
1903 {
1904     WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CallDidSetFirstPartyWebsiteDataRemovalMode"));
1905     WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), nullptr);
1906 }
1907
1908 void TestInvocation::didResetStatisticsToConsistentState()
1909 {
1910     WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CallDidResetStatisticsToConsistentState"));
1911     WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0);
1912 }
1913
1914 void TestInvocation::didSetBlockCookiesForHost()
1915 {
1916     WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CallDidSetBlockCookiesForHost"));
1917     WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0);
1918 }
1919
1920 void TestInvocation::didSetStatisticsDebugMode()
1921 {
1922     WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CallDidSetStatisticsDebugMode"));
1923     WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0);
1924 }
1925
1926 void TestInvocation::didSetPrevalentResourceForDebugMode()
1927 {
1928     WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CallDidSetPrevalentResourceForDebugMode"));
1929     WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0);
1930 }
1931
1932 void TestInvocation::didSetLastSeen()
1933 {
1934     WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CallDidSetLastSeen"));
1935     WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0);
1936 }
1937
1938 void TestInvocation::didMergeStatistic()
1939 {
1940     WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CallDidMergeStatistic"));
1941     WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0);
1942 }
1943
1944 void TestInvocation::didSetPrevalentResource()
1945 {
1946     WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CallDidSetPrevalentResource"));
1947     WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0);
1948 }
1949
1950 void TestInvocation::didSetVeryPrevalentResource()
1951 {
1952     WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CallDidSetVeryPrevalentResource"));
1953     WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0);
1954 }
1955
1956 void TestInvocation::didSetHasHadUserInteraction()
1957 {
1958     WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CallDidSetHasHadUserInteraction"));
1959     WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0);
1960 }
1961
1962 void TestInvocation::didReceiveAllStorageAccessEntries(Vector<String>& domains)
1963 {
1964     WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CallDidReceiveAllStorageAccessEntries"));
1965     
1966     WKRetainPtr<WKMutableArrayRef> messageBody = adoptWK(WKMutableArrayCreate());
1967     for (auto& domain : domains)
1968         WKArrayAppendItem(messageBody.get(), adoptWK(WKStringCreateWithUTF8CString(domain.utf8().data())).get());
1969     
1970     WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), messageBody.get());
1971 }
1972
1973 void TestInvocation::didReceivePrevalentDomains(Vector<String>&& domains)
1974 {
1975     WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CallDidReceivePrevalentDomains"));
1976     
1977     WKRetainPtr<WKMutableArrayRef> messageBody = adoptWK(WKMutableArrayCreate());
1978     for (auto& domain : domains)
1979         WKArrayAppendItem(messageBody.get(), adoptWK(WKStringCreateWithUTF8CString(domain.utf8().data())).get());
1980
1981     WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), messageBody.get());
1982 }
1983
1984 void TestInvocation::didReceiveWebViewCategory(String& webViewCategory)
1985 {
1986     WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CallDidReceiveWebViewCategory"));
1987     
1988     WKRetainPtr<WKStringRef> messageBody = adoptWK(WKStringCreateWithUTF8CString(webViewCategory.utf8().data()));
1989     WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), messageBody.get());
1990 }
1991
1992 void TestInvocation::didRemoveAllSessionCredentials()
1993 {
1994     WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CallDidRemoveAllSessionCredentialsCallback"));
1995     WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0);
1996 }
1997
1998 void TestInvocation::dumpResourceLoadStatistics()
1999 {
2000     m_shouldDumpResourceLoadStatistics = true;
2001 }
2002
2003 void TestInvocation::dumpAdClickAttribution()
2004 {
2005     m_shouldDumpAdClickAttribution = true;
2006 }
2007
2008 void TestInvocation::performCustomMenuAction()
2009 {
2010     WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("PerformCustomMenuAction"));
2011     WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0);
2012 }
2013
2014 void TestInvocation::initializeWaitToDumpWatchdogTimerIfNeeded()
2015 {
2016     if (m_waitToDumpWatchdogTimer.isActive())
2017         return;
2018
2019     m_waitToDumpWatchdogTimer.startOneShot(m_timeout);
2020 }
2021
2022 void TestInvocation::invalidateWaitToDumpWatchdogTimer()
2023 {
2024     m_waitToDumpWatchdogTimer.stop();
2025 }
2026
2027 void TestInvocation::waitToDumpWatchdogTimerFired()
2028 {
2029     invalidateWaitToDumpWatchdogTimer();
2030
2031 #if PLATFORM(COCOA)
2032     char buffer[1024];
2033     snprintf(buffer, sizeof(buffer), "#PID UNRESPONSIVE - %s (pid %d)\n", getprogname(), getpid());
2034     outputText(buffer);
2035 #endif
2036     outputText("FAIL: Timed out waiting for notifyDone to be called\n\n");
2037     done();
2038 }
2039
2040 void TestInvocation::setWaitUntilDone(bool waitUntilDone)
2041 {
2042     m_waitUntilDone = waitUntilDone;
2043     if (waitUntilDone && TestController::singleton().useWaitToDumpWatchdogTimer())
2044         initializeWaitToDumpWatchdogTimerIfNeeded();
2045 }
2046
2047 void TestInvocation::done()
2048 {
2049     m_gotFinalMessage = true;
2050     invalidateWaitToDumpWatchdogTimer();
2051     RunLoop::main().dispatch([] {
2052         TestController::singleton().notifyDone();
2053     });
2054 }
2055
2056 void TestInvocation::willCreateNewPage()
2057 {
2058     if (m_UIScriptContext && m_UIScriptContext->callbackWithID(CallbackTypeWillCreateNewPage))
2059         m_UIScriptContext->fireCallback(CallbackTypeWillCreateNewPage);
2060 }
2061
2062 } // namespace WTR