1 | /* |
2 | * Copyright (C) 2010-2017 Apple Inc. All rights reserved. |
3 | * |
4 | * Redistribution and use in source and binary forms, with or without |
5 | * modification, are permitted provided that the following conditions |
6 | * are met: |
7 | * 1. Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. |
9 | * 2. Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. |
12 | * |
13 | * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' |
14 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
15 | * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
16 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS |
17 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
18 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
19 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
20 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
21 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
22 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
23 | * THE POSSIBILITY OF SUCH DAMAGE. |
24 | */ |
25 | |
26 | #include "config.h" |
27 | #include "TestRunner.h" |
28 | |
29 | #include "InjectedBundle.h" |
30 | #include "InjectedBundlePage.h" |
31 | #include "JSTestRunner.h" |
32 | #include "PlatformWebView.h" |
33 | #include "StringFunctions.h" |
34 | #include "TestController.h" |
35 | #include <JavaScriptCore/JSCTestRunnerUtils.h> |
36 | #include <WebCore/ResourceLoadObserver.h> |
37 | #include <WebKit/WKBundle.h> |
38 | #include <WebKit/WKBundleBackForwardList.h> |
39 | #include <WebKit/WKBundleFrame.h> |
40 | #include <WebKit/WKBundleFramePrivate.h> |
41 | #include <WebKit/WKBundleInspector.h> |
42 | #include <WebKit/WKBundleNodeHandlePrivate.h> |
43 | #include <WebKit/WKBundlePage.h> |
44 | #include <WebKit/WKBundlePagePrivate.h> |
45 | #include <WebKit/WKBundlePrivate.h> |
46 | #include <WebKit/WKBundleScriptWorld.h> |
47 | #include <WebKit/WKData.h> |
48 | #include <WebKit/WKNumber.h> |
49 | #include <WebKit/WKPagePrivate.h> |
50 | #include <WebKit/WKRetainPtr.h> |
51 | #include <WebKit/WKSerializedScriptValue.h> |
52 | #include <WebKit/WebKit2_C.h> |
53 | #include <wtf/HashMap.h> |
54 | #include <wtf/Optional.h> |
55 | #include <wtf/StdLibExtras.h> |
56 | #include <wtf/text/CString.h> |
57 | #include <wtf/text/StringBuilder.h> |
58 | #include <wtf/text/StringConcatenateNumbers.h> |
59 | |
60 | namespace WTR { |
61 | |
62 | Ref<TestRunner> TestRunner::create() |
63 | { |
64 | return adoptRef(*new TestRunner); |
65 | } |
66 | |
67 | TestRunner::TestRunner() |
68 | : m_userStyleSheetLocation(adoptWK(WKStringCreateWithUTF8CString("" ))) |
69 | { |
70 | platformInitialize(); |
71 | } |
72 | |
73 | TestRunner::~TestRunner() |
74 | { |
75 | } |
76 | |
77 | JSClassRef TestRunner::wrapperClass() |
78 | { |
79 | return JSTestRunner::testRunnerClass(); |
80 | } |
81 | |
82 | void TestRunner::display() |
83 | { |
84 | WKBundlePageRef page = InjectedBundle::singleton().page()->page(); |
85 | WKBundlePageForceRepaint(page); |
86 | } |
87 | |
88 | void TestRunner::displayAndTrackRepaints() |
89 | { |
90 | WKBundlePageRef page = InjectedBundle::singleton().page()->page(); |
91 | WKBundlePageForceRepaint(page); |
92 | WKBundlePageSetTracksRepaints(page, true); |
93 | WKBundlePageResetTrackedRepaints(page); |
94 | } |
95 | |
96 | bool TestRunner::shouldDumpPixels() const |
97 | { |
98 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("GetDumpPixels" )); |
99 | WKTypeRef returnData = nullptr; |
100 | WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), nullptr, &returnData); |
101 | ASSERT(WKGetTypeID(returnData) == WKBooleanGetTypeID()); |
102 | return WKBooleanGetValue(adoptWK(static_cast<WKBooleanRef>(returnData)).get()); |
103 | } |
104 | |
105 | void TestRunner::setDumpPixels(bool dumpPixels) |
106 | { |
107 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("SetDumpPixels" )); |
108 | WKRetainPtr<WKBooleanRef> messageBody = adoptWK(WKBooleanCreate(dumpPixels)); |
109 | WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr); |
110 | } |
111 | |
112 | void TestRunner::dumpAsText(bool dumpPixels) |
113 | { |
114 | if (whatToDump() < WhatToDump::MainFrameText) |
115 | setWhatToDump(WhatToDump::MainFrameText); |
116 | setDumpPixels(dumpPixels); |
117 | } |
118 | |
119 | WhatToDump TestRunner::whatToDump() const |
120 | { |
121 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("GetWhatToDump" )); |
122 | WKTypeRef returnData = nullptr; |
123 | WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), nullptr, &returnData); |
124 | ASSERT(WKGetTypeID(returnData) == WKUInt64GetTypeID()); |
125 | return static_cast<WhatToDump>(WKUInt64GetValue(adoptWK(static_cast<WKUInt64Ref>(returnData)).get())); |
126 | } |
127 | |
128 | void TestRunner::setWhatToDump(WhatToDump whatToDump) |
129 | { |
130 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("SetWhatToDump" )); |
131 | WKRetainPtr<WKUInt64Ref> messageBody = adoptWK(WKUInt64Create(static_cast<uint64_t>(whatToDump))); |
132 | WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr); |
133 | } |
134 | |
135 | void TestRunner::setCustomPolicyDelegate(bool enabled, bool permissive) |
136 | { |
137 | m_policyDelegateEnabled = enabled; |
138 | m_policyDelegatePermissive = permissive; |
139 | |
140 | InjectedBundle::singleton().setCustomPolicyDelegate(enabled, permissive); |
141 | } |
142 | |
143 | void TestRunner::waitForPolicyDelegate() |
144 | { |
145 | setCustomPolicyDelegate(true); |
146 | waitUntilDone(); |
147 | } |
148 | |
149 | void TestRunner::waitUntilDownloadFinished() |
150 | { |
151 | m_shouldFinishAfterDownload = true; |
152 | waitUntilDone(); |
153 | } |
154 | |
155 | void TestRunner::waitUntilDone() |
156 | { |
157 | auto& injectedBundle = InjectedBundle::singleton(); |
158 | RELEASE_ASSERT(injectedBundle.isTestRunning()); |
159 | |
160 | setWaitUntilDone(true); |
161 | } |
162 | |
163 | void TestRunner::setWaitUntilDone(bool value) |
164 | { |
165 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("SetWaitUntilDone" )); |
166 | WKRetainPtr<WKBooleanRef> messageBody = adoptWK(WKBooleanCreate(value)); |
167 | WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr); |
168 | } |
169 | |
170 | bool TestRunner::shouldWaitUntilDone() const |
171 | { |
172 | WKRetainPtr<WKStringRef> messsageName = adoptWK(WKStringCreateWithUTF8CString("GetWaitUntilDone" )); |
173 | WKTypeRef returnData = nullptr; |
174 | WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messsageName.get(), nullptr, &returnData); |
175 | ASSERT(WKGetTypeID(returnData) == WKBooleanGetTypeID()); |
176 | return WKBooleanGetValue(adoptWK(static_cast<WKBooleanRef>(returnData)).get()); |
177 | } |
178 | |
179 | void TestRunner::notifyDone() |
180 | { |
181 | auto& injectedBundle = InjectedBundle::singleton(); |
182 | if (!injectedBundle.isTestRunning()) |
183 | return; |
184 | |
185 | if (shouldWaitUntilDone() && !injectedBundle.topLoadingFrame()) |
186 | injectedBundle.page()->dump(); |
187 | |
188 | // We don't call invalidateWaitToDumpWatchdogTimer() here, even if we continue to wait for a load to finish. |
189 | // The test is still subject to timeout checking - it is better to detect an async timeout inside WebKitTestRunner |
190 | // than to let webkitpy do that, because WebKitTestRunner will dump partial results. |
191 | |
192 | setWaitUntilDone(false); |
193 | } |
194 | |
195 | void TestRunner::forceImmediateCompletion() |
196 | { |
197 | auto& injectedBundle = InjectedBundle::singleton(); |
198 | if (!injectedBundle.isTestRunning()) |
199 | return; |
200 | |
201 | if (shouldWaitUntilDone() && injectedBundle.page()) |
202 | injectedBundle.page()->dump(); |
203 | |
204 | setWaitUntilDone(false); |
205 | } |
206 | |
207 | void TestRunner::setShouldDumpFrameLoadCallbacks(bool value) |
208 | { |
209 | WKRetainPtr<WKStringRef> messsageName = adoptWK(WKStringCreateWithUTF8CString("SetDumpFrameLoadCallbacks" )); |
210 | WKRetainPtr<WKBooleanRef> messageBody = adoptWK(WKBooleanCreate(value)); |
211 | WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messsageName.get(), messageBody.get(), nullptr); |
212 | } |
213 | |
214 | bool TestRunner::shouldDumpFrameLoadCallbacks() |
215 | { |
216 | WKRetainPtr<WKStringRef> messsageName = adoptWK(WKStringCreateWithUTF8CString("GetDumpFrameLoadCallbacks" )); |
217 | WKTypeRef returnData = nullptr; |
218 | WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messsageName.get(), nullptr, &returnData); |
219 | ASSERT(WKGetTypeID(returnData) == WKBooleanGetTypeID()); |
220 | return WKBooleanGetValue(adoptWK(static_cast<WKBooleanRef>(returnData)).get()); |
221 | } |
222 | |
223 | unsigned TestRunner::imageCountInGeneralPasteboard() const |
224 | { |
225 | return InjectedBundle::singleton().imageCountInGeneralPasteboard(); |
226 | } |
227 | |
228 | void TestRunner::addUserScript(JSStringRef source, bool runAtStart, bool allFrames) |
229 | { |
230 | WKRetainPtr<WKStringRef> sourceWK = toWK(source); |
231 | |
232 | WKBundlePageAddUserScript(InjectedBundle::singleton().page()->page(), sourceWK.get(), |
233 | (runAtStart ? kWKInjectAtDocumentStart : kWKInjectAtDocumentEnd), |
234 | (allFrames ? kWKInjectInAllFrames : kWKInjectInTopFrameOnly)); |
235 | } |
236 | |
237 | void TestRunner::addUserStyleSheet(JSStringRef source, bool allFrames) |
238 | { |
239 | WKRetainPtr<WKStringRef> sourceWK = toWK(source); |
240 | |
241 | WKBundlePageAddUserStyleSheet(InjectedBundle::singleton().page()->page(), sourceWK.get(), |
242 | (allFrames ? kWKInjectInAllFrames : kWKInjectInTopFrameOnly)); |
243 | } |
244 | |
245 | void TestRunner::keepWebHistory() |
246 | { |
247 | InjectedBundle::singleton().postSetAddsVisitedLinks(true); |
248 | } |
249 | |
250 | void TestRunner::execCommand(JSStringRef name, JSStringRef showUI, JSStringRef value) |
251 | { |
252 | WKBundlePageExecuteEditingCommand(InjectedBundle::singleton().page()->page(), toWK(name).get(), toWK(value).get()); |
253 | } |
254 | |
255 | static Optional<WKFindOptions> findOptionsFromArray(JSValueRef optionsArrayAsValue) |
256 | { |
257 | auto& injectedBundle = InjectedBundle::singleton(); |
258 | WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(injectedBundle.page()->page()); |
259 | JSContextRef context = WKBundleFrameGetJavaScriptContext(mainFrame); |
260 | auto lengthPropertyName = adopt(JSStringCreateWithUTF8CString("length" )); |
261 | JSObjectRef optionsArray = JSValueToObject(context, optionsArrayAsValue, 0); |
262 | JSValueRef lengthValue = JSObjectGetProperty(context, optionsArray, lengthPropertyName.get(), 0); |
263 | if (!JSValueIsNumber(context, lengthValue)) |
264 | return WTF::nullopt; |
265 | |
266 | WKFindOptions options = 0; |
267 | size_t length = static_cast<size_t>(JSValueToNumber(context, lengthValue, 0)); |
268 | for (size_t i = 0; i < length; ++i) { |
269 | JSValueRef value = JSObjectGetPropertyAtIndex(context, optionsArray, i, 0); |
270 | if (!JSValueIsString(context, value)) |
271 | continue; |
272 | |
273 | auto optionName = adopt(JSValueToStringCopy(context, value, 0)); |
274 | |
275 | if (JSStringIsEqualToUTF8CString(optionName.get(), "CaseInsensitive" )) |
276 | options |= kWKFindOptionsCaseInsensitive; |
277 | else if (JSStringIsEqualToUTF8CString(optionName.get(), "AtWordStarts" )) |
278 | options |= kWKFindOptionsAtWordStarts; |
279 | else if (JSStringIsEqualToUTF8CString(optionName.get(), "TreatMedialCapitalAsWordStart" )) |
280 | options |= kWKFindOptionsTreatMedialCapitalAsWordStart; |
281 | else if (JSStringIsEqualToUTF8CString(optionName.get(), "Backwards" )) |
282 | options |= kWKFindOptionsBackwards; |
283 | else if (JSStringIsEqualToUTF8CString(optionName.get(), "WrapAround" )) |
284 | options |= kWKFindOptionsWrapAround; |
285 | else if (JSStringIsEqualToUTF8CString(optionName.get(), "StartInSelection" )) { |
286 | // FIXME: No kWKFindOptionsStartInSelection. |
287 | } |
288 | } |
289 | return options; |
290 | } |
291 | |
292 | bool TestRunner::findString(JSStringRef target, JSValueRef optionsArrayAsValue) |
293 | { |
294 | if (auto options = findOptionsFromArray(optionsArrayAsValue)) |
295 | return WKBundlePageFindString(InjectedBundle::singleton().page()->page(), toWK(target).get(), *options); |
296 | |
297 | return false; |
298 | } |
299 | |
300 | void TestRunner::findStringMatchesInPage(JSStringRef target, JSValueRef optionsArrayAsValue) |
301 | { |
302 | if (auto options = findOptionsFromArray(optionsArrayAsValue)) |
303 | return WKBundlePageFindStringMatches(InjectedBundle::singleton().page()->page(), toWK(target).get(), *options); |
304 | } |
305 | |
306 | void TestRunner::replaceFindMatchesAtIndices(JSValueRef matchIndicesAsValue, JSStringRef replacementText, bool selectionOnly) |
307 | { |
308 | auto& bundle = InjectedBundle::singleton(); |
309 | auto mainFrame = WKBundlePageGetMainFrame(bundle.page()->page()); |
310 | auto context = WKBundleFrameGetJavaScriptContext(mainFrame); |
311 | auto lengthPropertyName = adopt(JSStringCreateWithUTF8CString("length" )); |
312 | auto matchIndicesObject = JSValueToObject(context, matchIndicesAsValue, 0); |
313 | auto lengthValue = JSObjectGetProperty(context, matchIndicesObject, lengthPropertyName.get(), 0); |
314 | if (!JSValueIsNumber(context, lengthValue)) |
315 | return; |
316 | |
317 | auto indices = adoptWK(WKMutableArrayCreate()); |
318 | auto length = static_cast<size_t>(JSValueToNumber(context, lengthValue, 0)); |
319 | for (size_t i = 0; i < length; ++i) { |
320 | auto value = JSObjectGetPropertyAtIndex(context, matchIndicesObject, i, 0); |
321 | if (!JSValueIsNumber(context, value)) |
322 | continue; |
323 | |
324 | auto index = adoptWK(WKUInt64Create(std::round(JSValueToNumber(context, value, nullptr)))); |
325 | WKArrayAppendItem(indices.get(), index.get()); |
326 | } |
327 | WKBundlePageReplaceStringMatches(bundle.page()->page(), indices.get(), toWK(replacementText).get(), selectionOnly); |
328 | } |
329 | |
330 | void TestRunner::clearAllDatabases() |
331 | { |
332 | WKBundleClearAllDatabases(InjectedBundle::singleton().bundle()); |
333 | |
334 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("DeleteAllIndexedDatabases" )); |
335 | WKRetainPtr<WKBooleanRef> messageBody = adoptWK(WKBooleanCreate(true)); |
336 | |
337 | WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr); |
338 | } |
339 | |
340 | void TestRunner::setDatabaseQuota(uint64_t quota) |
341 | { |
342 | return WKBundleSetDatabaseQuota(InjectedBundle::singleton().bundle(), quota); |
343 | } |
344 | |
345 | void TestRunner::clearAllApplicationCaches() |
346 | { |
347 | WKBundlePageClearApplicationCache(InjectedBundle::singleton().page()->page()); |
348 | } |
349 | |
350 | void TestRunner::clearApplicationCacheForOrigin(JSStringRef origin) |
351 | { |
352 | WKBundlePageClearApplicationCacheForOrigin(InjectedBundle::singleton().page()->page(), toWK(origin).get()); |
353 | } |
354 | |
355 | void TestRunner::setAppCacheMaximumSize(uint64_t size) |
356 | { |
357 | WKBundlePageSetAppCacheMaximumSize(InjectedBundle::singleton().page()->page(), size); |
358 | } |
359 | |
360 | long long TestRunner::applicationCacheDiskUsageForOrigin(JSStringRef origin) |
361 | { |
362 | return WKBundlePageGetAppCacheUsageForOrigin(InjectedBundle::singleton().page()->page(), toWK(origin).get()); |
363 | } |
364 | |
365 | void TestRunner::disallowIncreaseForApplicationCacheQuota() |
366 | { |
367 | m_disallowIncreaseForApplicationCacheQuota = true; |
368 | } |
369 | |
370 | void TestRunner::setIDBPerOriginQuota(uint64_t quota) |
371 | { |
372 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("SetIDBPerOriginQuota" )); |
373 | WKRetainPtr<WKUInt64Ref> messageBody = adoptWK(WKUInt64Create(quota)); |
374 | WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr); |
375 | } |
376 | |
377 | static inline JSValueRef stringArrayToJS(JSContextRef context, WKArrayRef strings) |
378 | { |
379 | const size_t count = WKArrayGetSize(strings); |
380 | |
381 | JSValueRef arrayResult = JSObjectMakeArray(context, 0, 0, 0); |
382 | JSObjectRef arrayObj = JSValueToObject(context, arrayResult, 0); |
383 | for (size_t i = 0; i < count; ++i) { |
384 | WKStringRef stringRef = static_cast<WKStringRef>(WKArrayGetItemAtIndex(strings, i)); |
385 | JSRetainPtr<JSStringRef> stringJS = toJS(stringRef); |
386 | JSObjectSetPropertyAtIndex(context, arrayObj, i, JSValueMakeString(context, stringJS.get()), 0); |
387 | } |
388 | |
389 | return arrayResult; |
390 | } |
391 | |
392 | JSValueRef TestRunner::originsWithApplicationCache() |
393 | { |
394 | WKBundlePageRef page = InjectedBundle::singleton().page()->page(); |
395 | |
396 | WKRetainPtr<WKArrayRef> origins = adoptWK(WKBundlePageCopyOriginsWithApplicationCache(page)); |
397 | |
398 | WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(page); |
399 | JSContextRef context = WKBundleFrameGetJavaScriptContext(mainFrame); |
400 | |
401 | return stringArrayToJS(context, origins.get()); |
402 | } |
403 | |
404 | bool TestRunner::isCommandEnabled(JSStringRef name) |
405 | { |
406 | return WKBundlePageIsEditingCommandEnabled(InjectedBundle::singleton().page()->page(), toWK(name).get()); |
407 | } |
408 | |
409 | void TestRunner::setCanOpenWindows() |
410 | { |
411 | WKRetainPtr<WKStringRef> messsageName = adoptWK(WKStringCreateWithUTF8CString("SetCanOpenWindows" )); |
412 | WKRetainPtr<WKBooleanRef> messageBody = adoptWK(WKBooleanCreate(true)); |
413 | WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messsageName.get(), messageBody.get(), nullptr); |
414 | } |
415 | |
416 | void TestRunner::setXSSAuditorEnabled(bool enabled) |
417 | { |
418 | WKRetainPtr<WKStringRef> key = adoptWK(WKStringCreateWithUTF8CString("WebKitXSSAuditorEnabled" )); |
419 | auto& injectedBundle = InjectedBundle::singleton(); |
420 | WKBundleOverrideBoolPreferenceForTestRunner(injectedBundle.bundle(), injectedBundle.pageGroup(), key.get(), enabled); |
421 | } |
422 | |
423 | void TestRunner::setMediaDevicesEnabled(bool enabled) |
424 | { |
425 | WKRetainPtr<WKStringRef> key = adoptWK(WKStringCreateWithUTF8CString("WebKitMediaDevicesEnabled" )); |
426 | auto& injectedBundle = InjectedBundle::singleton(); |
427 | WKBundleOverrideBoolPreferenceForTestRunner(injectedBundle.bundle(), injectedBundle.pageGroup(), key.get(), enabled); |
428 | } |
429 | |
430 | void TestRunner::setWebRTCMDNSICECandidatesEnabled(bool enabled) |
431 | { |
432 | WKRetainPtr<WKStringRef> key = adoptWK(WKStringCreateWithUTF8CString("WebKitWebRTCMDNSICECandidatesEnabled" )); |
433 | auto& injectedBundle = InjectedBundle::singleton(); |
434 | WKBundleOverrideBoolPreferenceForTestRunner(injectedBundle.bundle(), injectedBundle.pageGroup(), key.get(), enabled); |
435 | } |
436 | |
437 | void TestRunner::setWebRTCUnifiedPlanEnabled(bool enabled) |
438 | { |
439 | WKRetainPtr<WKStringRef> key = adoptWK(WKStringCreateWithUTF8CString("WebKitWebRTCUnifiedPlanEnabled" )); |
440 | auto& injectedBundle = InjectedBundle::singleton(); |
441 | WKBundleOverrideBoolPreferenceForTestRunner(injectedBundle.bundle(), injectedBundle.pageGroup(), key.get(), enabled); |
442 | } |
443 | |
444 | void TestRunner::setCustomUserAgent(JSStringRef userAgent) |
445 | { |
446 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("SetCustomUserAgent" )); |
447 | WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), toWK(userAgent).get(), nullptr); |
448 | } |
449 | |
450 | void TestRunner::setWebAPIStatisticsEnabled(bool enabled) |
451 | { |
452 | WKRetainPtr<WKStringRef> key = adoptWK(WKStringCreateWithUTF8CString("WebKitWebAPIStatisticsEnabled" )); |
453 | auto& injectedBundle = InjectedBundle::singleton(); |
454 | WKBundleOverrideBoolPreferenceForTestRunner(injectedBundle.bundle(), injectedBundle.pageGroup(), key.get(), enabled); |
455 | } |
456 | |
457 | void TestRunner::setModernMediaControlsEnabled(bool enabled) |
458 | { |
459 | WKRetainPtr<WKStringRef> key = adoptWK(WKStringCreateWithUTF8CString("WebKitModernMediaControlsEnabled" )); |
460 | auto& injectedBundle = InjectedBundle::singleton(); |
461 | WKBundleOverrideBoolPreferenceForTestRunner(injectedBundle.bundle(), injectedBundle.pageGroup(), key.get(), enabled); |
462 | } |
463 | |
464 | void TestRunner::setWebGL2Enabled(bool enabled) |
465 | { |
466 | WKRetainPtr<WKStringRef> key = adoptWK(WKStringCreateWithUTF8CString("WebKitWebGL2Enabled" )); |
467 | auto& injectedBundle = InjectedBundle::singleton(); |
468 | WKBundleOverrideBoolPreferenceForTestRunner(injectedBundle.bundle(), injectedBundle.pageGroup(), key.get(), enabled); |
469 | } |
470 | |
471 | void TestRunner::setWritableStreamAPIEnabled(bool enabled) |
472 | { |
473 | WKRetainPtr<WKStringRef> key = adoptWK(WKStringCreateWithUTF8CString("WebKitWritableStreamAPIEnabled" )); |
474 | auto& injectedBundle = InjectedBundle::singleton(); |
475 | WKBundleOverrideBoolPreferenceForTestRunner(injectedBundle.bundle(), injectedBundle.pageGroup(), key.get(), enabled); |
476 | } |
477 | |
478 | void TestRunner::setReadableByteStreamAPIEnabled(bool enabled) |
479 | { |
480 | WKRetainPtr<WKStringRef> key = adoptWK(WKStringCreateWithUTF8CString("WebKitReadableByteStreamAPIEnabled" )); |
481 | auto& injectedBundle = InjectedBundle::singleton(); |
482 | WKBundleOverrideBoolPreferenceForTestRunner(injectedBundle.bundle(), injectedBundle.pageGroup(), key.get(), enabled); |
483 | } |
484 | |
485 | void TestRunner::setEncryptedMediaAPIEnabled(bool enabled) |
486 | { |
487 | WKRetainPtr<WKStringRef> key = adoptWK(WKStringCreateWithUTF8CString("WebKitEncryptedMediaAPIEnabled" )); |
488 | auto& injectedBundle = InjectedBundle::singleton(); |
489 | WKBundleOverrideBoolPreferenceForTestRunner(injectedBundle.bundle(), injectedBundle.pageGroup(), key.get(), enabled); |
490 | } |
491 | |
492 | void TestRunner::setAllowsAnySSLCertificate(bool enabled) |
493 | { |
494 | auto& injectedBundle = InjectedBundle::singleton(); |
495 | injectedBundle.setAllowsAnySSLCertificate(enabled); |
496 | |
497 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("SetAllowsAnySSLCertificate" )); |
498 | WKRetainPtr<WKBooleanRef> messageBody = adoptWK(WKBooleanCreate(enabled)); |
499 | WKBundlePagePostSynchronousMessageForTesting(injectedBundle.page()->page(), messageName.get(), messageBody.get(), nullptr); |
500 | } |
501 | |
502 | void TestRunner::setAllowUniversalAccessFromFileURLs(bool enabled) |
503 | { |
504 | auto& injectedBundle = InjectedBundle::singleton(); |
505 | WKBundleSetAllowUniversalAccessFromFileURLs(injectedBundle.bundle(), injectedBundle.pageGroup(), enabled); |
506 | } |
507 | |
508 | void TestRunner::setAllowFileAccessFromFileURLs(bool enabled) |
509 | { |
510 | auto& injectedBundle = InjectedBundle::singleton(); |
511 | WKBundleSetAllowFileAccessFromFileURLs(injectedBundle.bundle(), injectedBundle.pageGroup(), enabled); |
512 | } |
513 | |
514 | void TestRunner::setNeedsStorageAccessFromFileURLsQuirk(bool needsQuirk) |
515 | { |
516 | auto& injectedBundle = InjectedBundle::singleton(); |
517 | WKBundleSetAllowStorageAccessFromFileURLS(injectedBundle.bundle(), injectedBundle.pageGroup(), needsQuirk); |
518 | } |
519 | |
520 | void TestRunner::setPluginsEnabled(bool enabled) |
521 | { |
522 | WKRetainPtr<WKStringRef> key = adoptWK(WKStringCreateWithUTF8CString("WebKitPluginsEnabled" )); |
523 | auto& injectedBundle = InjectedBundle::singleton(); |
524 | WKBundleOverrideBoolPreferenceForTestRunner(injectedBundle.bundle(), injectedBundle.pageGroup(), key.get(), enabled); |
525 | } |
526 | |
527 | void TestRunner::setJavaScriptCanAccessClipboard(bool enabled) |
528 | { |
529 | auto& injectedBundle = InjectedBundle::singleton(); |
530 | WKBundleSetJavaScriptCanAccessClipboard(injectedBundle.bundle(), injectedBundle.pageGroup(), enabled); |
531 | } |
532 | |
533 | void TestRunner::setPrivateBrowsingEnabled(bool enabled) |
534 | { |
535 | auto& injectedBundle = InjectedBundle::singleton(); |
536 | WKBundleSetPrivateBrowsingEnabled(injectedBundle.bundle(), injectedBundle.pageGroup(), enabled); |
537 | } |
538 | |
539 | void TestRunner::setUseDashboardCompatibilityMode(bool enabled) |
540 | { |
541 | #if ENABLE(DASHBOARD_SUPPORT) |
542 | auto& injectedBundle = InjectedBundle::singleton(); |
543 | WKBundleSetUseDashboardCompatibilityMode(injectedBundle.bundle(), injectedBundle.pageGroup(), enabled); |
544 | #else |
545 | UNUSED_PARAM(enabled); |
546 | #endif |
547 | } |
548 | |
549 | void TestRunner::(bool enabled) |
550 | { |
551 | auto& injectedBundle = InjectedBundle::singleton(); |
552 | WKBundleSetPopupBlockingEnabled(injectedBundle.bundle(), injectedBundle.pageGroup(), enabled); |
553 | } |
554 | |
555 | void TestRunner::setAuthorAndUserStylesEnabled(bool enabled) |
556 | { |
557 | auto& injectedBundle = InjectedBundle::singleton(); |
558 | WKBundleSetAuthorAndUserStylesEnabled(injectedBundle.bundle(), injectedBundle.pageGroup(), enabled); |
559 | } |
560 | |
561 | void TestRunner::addOriginAccessWhitelistEntry(JSStringRef sourceOrigin, JSStringRef destinationProtocol, JSStringRef destinationHost, bool allowDestinationSubdomains) |
562 | { |
563 | WKBundleAddOriginAccessWhitelistEntry(InjectedBundle::singleton().bundle(), toWK(sourceOrigin).get(), toWK(destinationProtocol).get(), toWK(destinationHost).get(), allowDestinationSubdomains); |
564 | } |
565 | |
566 | void TestRunner::removeOriginAccessWhitelistEntry(JSStringRef sourceOrigin, JSStringRef destinationProtocol, JSStringRef destinationHost, bool allowDestinationSubdomains) |
567 | { |
568 | WKBundleRemoveOriginAccessWhitelistEntry(InjectedBundle::singleton().bundle(), toWK(sourceOrigin).get(), toWK(destinationProtocol).get(), toWK(destinationHost).get(), allowDestinationSubdomains); |
569 | } |
570 | |
571 | bool TestRunner::isPageBoxVisible(int pageIndex) |
572 | { |
573 | auto& injectedBundle = InjectedBundle::singleton(); |
574 | WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(injectedBundle.page()->page()); |
575 | return WKBundleIsPageBoxVisible(injectedBundle.bundle(), mainFrame, pageIndex); |
576 | } |
577 | |
578 | void TestRunner::setValueForUser(JSContextRef context, JSValueRef element, JSStringRef value) |
579 | { |
580 | if (!element || !JSValueIsObject(context, element)) |
581 | return; |
582 | |
583 | WKRetainPtr<WKBundleNodeHandleRef> nodeHandle = adoptWK(WKBundleNodeHandleCreate(context, const_cast<JSObjectRef>(element))); |
584 | WKBundleNodeHandleSetHTMLInputElementValueForUser(nodeHandle.get(), toWK(value).get()); |
585 | } |
586 | |
587 | void TestRunner::setAudioResult(JSContextRef context, JSValueRef data) |
588 | { |
589 | auto& injectedBundle = InjectedBundle::singleton(); |
590 | // FIXME (123058): Use a JSC API to get buffer contents once such is exposed. |
591 | WKRetainPtr<WKDataRef> audioData = adoptWK(WKBundleCreateWKDataFromUInt8Array(injectedBundle.bundle(), context, data)); |
592 | injectedBundle.setAudioResult(audioData.get()); |
593 | setWhatToDump(WhatToDump::Audio); |
594 | setDumpPixels(false); |
595 | } |
596 | |
597 | unsigned TestRunner::windowCount() |
598 | { |
599 | return InjectedBundle::singleton().pageCount(); |
600 | } |
601 | |
602 | void TestRunner::clearBackForwardList() |
603 | { |
604 | WKBundleClearHistoryForTesting(InjectedBundle::singleton().page()->page()); |
605 | } |
606 | |
607 | // Object Creation |
608 | |
609 | void TestRunner::makeWindowObject(JSContextRef context, JSObjectRef windowObject, JSValueRef* exception) |
610 | { |
611 | setProperty(context, windowObject, "testRunner" , this, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete, exception); |
612 | } |
613 | |
614 | void TestRunner::showWebInspector() |
615 | { |
616 | WKBundleInspectorShow(WKBundlePageGetInspector(InjectedBundle::singleton().page()->page())); |
617 | } |
618 | |
619 | void TestRunner::closeWebInspector() |
620 | { |
621 | WKBundleInspectorClose(WKBundlePageGetInspector(InjectedBundle::singleton().page()->page())); |
622 | } |
623 | |
624 | void TestRunner::evaluateInWebInspector(JSStringRef script) |
625 | { |
626 | WKRetainPtr<WKStringRef> scriptWK = toWK(script); |
627 | WKBundleInspectorEvaluateScriptForTest(WKBundlePageGetInspector(InjectedBundle::singleton().page()->page()), scriptWK.get()); |
628 | } |
629 | |
630 | typedef WTF::HashMap<unsigned, WKRetainPtr<WKBundleScriptWorldRef> > WorldMap; |
631 | static WorldMap& worldMap() |
632 | { |
633 | static WorldMap& map = *new WorldMap; |
634 | return map; |
635 | } |
636 | |
637 | unsigned TestRunner::worldIDForWorld(WKBundleScriptWorldRef world) |
638 | { |
639 | WorldMap::const_iterator end = worldMap().end(); |
640 | for (WorldMap::const_iterator it = worldMap().begin(); it != end; ++it) { |
641 | if (it->value == world) |
642 | return it->key; |
643 | } |
644 | |
645 | return 0; |
646 | } |
647 | |
648 | void TestRunner::evaluateScriptInIsolatedWorld(JSContextRef context, unsigned worldID, JSStringRef script) |
649 | { |
650 | // A worldID of 0 always corresponds to a new world. Any other worldID corresponds to a world |
651 | // that is created once and cached forever. |
652 | WKRetainPtr<WKBundleScriptWorldRef> world; |
653 | if (!worldID) |
654 | world.adopt(WKBundleScriptWorldCreateWorld()); |
655 | else { |
656 | WKRetainPtr<WKBundleScriptWorldRef>& worldSlot = worldMap().add(worldID, nullptr).iterator->value; |
657 | if (!worldSlot) |
658 | worldSlot.adopt(WKBundleScriptWorldCreateWorld()); |
659 | world = worldSlot; |
660 | } |
661 | |
662 | WKBundleFrameRef frame = WKBundleFrameForJavaScriptContext(context); |
663 | if (!frame) |
664 | frame = WKBundlePageGetMainFrame(InjectedBundle::singleton().page()->page()); |
665 | |
666 | JSGlobalContextRef jsContext = WKBundleFrameGetJavaScriptContextForWorld(frame, world.get()); |
667 | JSEvaluateScript(jsContext, script, 0, 0, 0, 0); |
668 | } |
669 | |
670 | void TestRunner::setPOSIXLocale(JSStringRef locale) |
671 | { |
672 | char localeBuf[32]; |
673 | JSStringGetUTF8CString(locale, localeBuf, sizeof(localeBuf)); |
674 | setlocale(LC_ALL, localeBuf); |
675 | } |
676 | |
677 | void TestRunner::setTextDirection(JSStringRef direction) |
678 | { |
679 | WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(InjectedBundle::singleton().page()->page()); |
680 | return WKBundleFrameSetTextDirection(mainFrame, toWK(direction).get()); |
681 | } |
682 | |
683 | void TestRunner::setShouldStayOnPageAfterHandlingBeforeUnload(bool shouldStayOnPage) |
684 | { |
685 | InjectedBundle::singleton().postNewBeforeUnloadReturnValue(!shouldStayOnPage); |
686 | } |
687 | |
688 | bool TestRunner::didReceiveServerRedirectForProvisionalNavigation() const |
689 | { |
690 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("DidReceiveServerRedirectForProvisionalNavigation" )); |
691 | WKTypeRef returnData = nullptr; |
692 | WKBundlePagePostSynchronousMessageForTesting(InjectedBundle::singleton().page()->page(), messageName.get(), nullptr, &returnData); |
693 | ASSERT(WKGetTypeID(returnData) == WKBooleanGetTypeID()); |
694 | return WKBooleanGetValue(adoptWK(static_cast<WKBooleanRef>(returnData)).get()); |
695 | } |
696 | |
697 | void TestRunner::clearDidReceiveServerRedirectForProvisionalNavigation() |
698 | { |
699 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("ClearDidReceiveServerRedirectForProvisionalNavigation" )); |
700 | WKBundlePagePostSynchronousMessageForTesting(InjectedBundle::singleton().page()->page(), messageName.get(), nullptr, nullptr); |
701 | } |
702 | |
703 | void TestRunner::setPageVisibility(JSStringRef state) |
704 | { |
705 | InjectedBundle::singleton().setHidden(JSStringIsEqualToUTF8CString(state, "hidden" ) || JSStringIsEqualToUTF8CString(state, "prerender" )); |
706 | } |
707 | |
708 | void TestRunner::resetPageVisibility() |
709 | { |
710 | InjectedBundle::singleton().setHidden(false); |
711 | } |
712 | |
713 | typedef WTF::HashMap<unsigned, JSValueRef> CallbackMap; |
714 | static CallbackMap& callbackMap() |
715 | { |
716 | static CallbackMap& map = *new CallbackMap; |
717 | return map; |
718 | } |
719 | |
720 | enum { |
721 | AddChromeInputFieldCallbackID = 1, |
722 | RemoveChromeInputFieldCallbackID, |
723 | FocusWebViewCallbackID, |
724 | SetBackingScaleFactorCallbackID, |
725 | DidBeginSwipeCallbackID, |
726 | WillEndSwipeCallbackID, |
727 | DidEndSwipeCallbackID, |
728 | DidRemoveSwipeSnapshotCallbackID, |
729 | SetStatisticsDebugModeCallbackID, |
730 | SetStatisticsPrevalentResourceForDebugModeCallbackID, |
731 | SetStatisticsLastSeenCallbackID, |
732 | SetStatisticsPrevalentResourceCallbackID, |
733 | SetStatisticsVeryPrevalentResourceCallbackID, |
734 | SetStatisticsHasHadUserInteractionCallbackID, |
735 | StatisticsDidModifyDataRecordsCallbackID, |
736 | StatisticsDidScanDataRecordsCallbackID, |
737 | StatisticsDidRunTelemetryCallbackID, |
738 | StatisticsDidClearThroughWebsiteDataRemovalCallbackID, |
739 | StatisticsDidResetToConsistentStateCallbackID, |
740 | StatisticsDidSetBlockCookiesForHostCallbackID, |
741 | AllStorageAccessEntriesCallbackID, |
742 | DidRemoveAllSessionCredentialsCallbackID, |
743 | GetApplicationManifestCallbackID, |
744 | TextDidChangeInTextFieldCallbackID, |
745 | TextFieldDidBeginEditingCallbackID, |
746 | TextFieldDidEndEditingCallbackID, |
747 | , |
748 | FirstUIScriptCallbackID = 100 |
749 | }; |
750 | |
751 | static void cacheTestRunnerCallback(unsigned index, JSValueRef callback) |
752 | { |
753 | if (!callback) |
754 | return; |
755 | |
756 | if (callbackMap().contains(index)) { |
757 | InjectedBundle::singleton().outputText(makeString("FAIL: Tried to install a second TestRunner callback for the same event (id " , index, ")\n\n" )); |
758 | return; |
759 | } |
760 | |
761 | WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(InjectedBundle::singleton().page()->page()); |
762 | JSContextRef context = WKBundleFrameGetJavaScriptContext(mainFrame); |
763 | JSValueProtect(context, callback); |
764 | callbackMap().add(index, callback); |
765 | } |
766 | |
767 | static void callTestRunnerCallback(unsigned index, size_t argumentCount = 0, const JSValueRef arguments[] = nullptr) |
768 | { |
769 | if (!callbackMap().contains(index)) |
770 | return; |
771 | WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(InjectedBundle::singleton().page()->page()); |
772 | JSContextRef context = WKBundleFrameGetJavaScriptContext(mainFrame); |
773 | JSObjectRef callback = JSValueToObject(context, callbackMap().take(index), 0); |
774 | JSObjectCallAsFunction(context, callback, JSContextGetGlobalObject(context), argumentCount, arguments, 0); |
775 | JSValueUnprotect(context, callback); |
776 | } |
777 | |
778 | void TestRunner::clearTestRunnerCallbacks() |
779 | { |
780 | for (auto& iter : callbackMap()) { |
781 | WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(InjectedBundle::singleton().page()->page()); |
782 | JSContextRef context = WKBundleFrameGetJavaScriptContext(mainFrame); |
783 | JSObjectRef callback = JSValueToObject(context, iter.value, 0); |
784 | JSValueUnprotect(context, callback); |
785 | } |
786 | |
787 | callbackMap().clear(); |
788 | } |
789 | |
790 | void TestRunner::accummulateLogsForChannel(JSStringRef) |
791 | { |
792 | // FIXME: Implement getting the call to all processes. |
793 | } |
794 | |
795 | void TestRunner::addChromeInputField(JSValueRef callback) |
796 | { |
797 | cacheTestRunnerCallback(AddChromeInputFieldCallbackID, callback); |
798 | InjectedBundle::singleton().postAddChromeInputField(); |
799 | } |
800 | |
801 | void TestRunner::removeChromeInputField(JSValueRef callback) |
802 | { |
803 | cacheTestRunnerCallback(RemoveChromeInputFieldCallbackID, callback); |
804 | InjectedBundle::singleton().postRemoveChromeInputField(); |
805 | } |
806 | |
807 | void TestRunner::focusWebView(JSValueRef callback) |
808 | { |
809 | cacheTestRunnerCallback(FocusWebViewCallbackID, callback); |
810 | InjectedBundle::singleton().postFocusWebView(); |
811 | } |
812 | |
813 | void TestRunner::setBackingScaleFactor(double backingScaleFactor, JSValueRef callback) |
814 | { |
815 | cacheTestRunnerCallback(SetBackingScaleFactorCallbackID, callback); |
816 | InjectedBundle::singleton().postSetBackingScaleFactor(backingScaleFactor); |
817 | } |
818 | |
819 | void TestRunner::setWindowIsKey(bool isKey) |
820 | { |
821 | InjectedBundle::singleton().postSetWindowIsKey(isKey); |
822 | } |
823 | |
824 | void TestRunner::setViewSize(double width, double height) |
825 | { |
826 | InjectedBundle::singleton().postSetViewSize(width, height); |
827 | } |
828 | |
829 | void TestRunner::callAddChromeInputFieldCallback() |
830 | { |
831 | callTestRunnerCallback(AddChromeInputFieldCallbackID); |
832 | } |
833 | |
834 | void TestRunner::callRemoveChromeInputFieldCallback() |
835 | { |
836 | callTestRunnerCallback(RemoveChromeInputFieldCallbackID); |
837 | } |
838 | |
839 | void TestRunner::callFocusWebViewCallback() |
840 | { |
841 | callTestRunnerCallback(FocusWebViewCallbackID); |
842 | } |
843 | |
844 | void TestRunner::callSetBackingScaleFactorCallback() |
845 | { |
846 | callTestRunnerCallback(SetBackingScaleFactorCallbackID); |
847 | } |
848 | |
849 | static inline bool toBool(JSStringRef value) |
850 | { |
851 | return JSStringIsEqualToUTF8CString(value, "true" ) || JSStringIsEqualToUTF8CString(value, "1" ); |
852 | } |
853 | |
854 | void TestRunner::overridePreference(JSStringRef preference, JSStringRef value) |
855 | { |
856 | auto& injectedBundle = InjectedBundle::singleton(); |
857 | // FIXME: handle non-boolean preferences. |
858 | WKBundleOverrideBoolPreferenceForTestRunner(injectedBundle.bundle(), injectedBundle.pageGroup(), toWK(preference).get(), toBool(value)); |
859 | } |
860 | |
861 | void TestRunner::setAlwaysAcceptCookies(bool accept) |
862 | { |
863 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("SetAlwaysAcceptCookies" )); |
864 | |
865 | WKRetainPtr<WKBooleanRef> messageBody = adoptWK(WKBooleanCreate(accept)); |
866 | |
867 | WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr); |
868 | } |
869 | |
870 | void TestRunner::setOnlyAcceptFirstPartyCookies(bool accept) |
871 | { |
872 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("SetOnlyAcceptFirstPartyCookies" )); |
873 | |
874 | WKRetainPtr<WKBooleanRef> messageBody = adoptWK(WKBooleanCreate(accept)); |
875 | |
876 | WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr); |
877 | } |
878 | |
879 | double TestRunner::preciseTime() |
880 | { |
881 | return WallTime::now().secondsSinceEpoch().seconds(); |
882 | } |
883 | |
884 | void TestRunner::setRenderTreeDumpOptions(unsigned short options) |
885 | { |
886 | m_renderTreeDumpOptions = options; |
887 | } |
888 | |
889 | void TestRunner::setUserStyleSheetEnabled(bool enabled) |
890 | { |
891 | m_userStyleSheetEnabled = enabled; |
892 | |
893 | WKRetainPtr<WKStringRef> emptyUrl = adoptWK(WKStringCreateWithUTF8CString("" )); |
894 | WKStringRef location = enabled ? m_userStyleSheetLocation.get() : emptyUrl.get(); |
895 | auto& injectedBundle = InjectedBundle::singleton(); |
896 | WKBundleSetUserStyleSheetLocation(injectedBundle.bundle(), injectedBundle.pageGroup(), location); |
897 | } |
898 | |
899 | void TestRunner::setUserStyleSheetLocation(JSStringRef location) |
900 | { |
901 | m_userStyleSheetLocation = adoptWK(WKStringCreateWithJSString(location)); |
902 | |
903 | if (m_userStyleSheetEnabled) |
904 | setUserStyleSheetEnabled(true); |
905 | } |
906 | |
907 | void TestRunner::setSpatialNavigationEnabled(bool enabled) |
908 | { |
909 | auto& injectedBundle = InjectedBundle::singleton(); |
910 | WKBundleSetSpatialNavigationEnabled(injectedBundle.bundle(), injectedBundle.pageGroup(), enabled); |
911 | } |
912 | |
913 | void TestRunner::setTabKeyCyclesThroughElements(bool enabled) |
914 | { |
915 | auto& injectedBundle = InjectedBundle::singleton(); |
916 | WKBundleSetTabKeyCyclesThroughElements(injectedBundle.bundle(), injectedBundle.page()->page(), enabled); |
917 | } |
918 | |
919 | void TestRunner::setSerializeHTTPLoads() |
920 | { |
921 | // WK2 doesn't reorder loads. |
922 | } |
923 | |
924 | void TestRunner::dispatchPendingLoadRequests() |
925 | { |
926 | // WK2 doesn't keep pending requests. |
927 | } |
928 | |
929 | void TestRunner::setCacheModel(int model) |
930 | { |
931 | InjectedBundle::singleton().setCacheModel(model); |
932 | } |
933 | |
934 | void TestRunner::setAsynchronousSpellCheckingEnabled(bool enabled) |
935 | { |
936 | auto& injectedBundle = InjectedBundle::singleton(); |
937 | WKBundleSetAsynchronousSpellCheckingEnabled(injectedBundle.bundle(), injectedBundle.pageGroup(), enabled); |
938 | } |
939 | |
940 | void TestRunner::grantWebNotificationPermission(JSStringRef origin) |
941 | { |
942 | WKRetainPtr<WKStringRef> originWK = toWK(origin); |
943 | auto& injectedBundle = InjectedBundle::singleton(); |
944 | WKBundleSetWebNotificationPermission(injectedBundle.bundle(), injectedBundle.page()->page(), originWK.get(), true); |
945 | } |
946 | |
947 | void TestRunner::denyWebNotificationPermission(JSStringRef origin) |
948 | { |
949 | WKRetainPtr<WKStringRef> originWK = toWK(origin); |
950 | auto& injectedBundle = InjectedBundle::singleton(); |
951 | WKBundleSetWebNotificationPermission(injectedBundle.bundle(), injectedBundle.page()->page(), originWK.get(), false); |
952 | } |
953 | |
954 | void TestRunner::removeAllWebNotificationPermissions() |
955 | { |
956 | auto& injectedBundle = InjectedBundle::singleton(); |
957 | WKBundleRemoveAllWebNotificationPermissions(injectedBundle.bundle(), injectedBundle.page()->page()); |
958 | } |
959 | |
960 | void TestRunner::simulateWebNotificationClick(JSValueRef notification) |
961 | { |
962 | auto& injectedBundle = InjectedBundle::singleton(); |
963 | WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(injectedBundle.page()->page()); |
964 | JSContextRef context = WKBundleFrameGetJavaScriptContext(mainFrame); |
965 | uint64_t notificationID = WKBundleGetWebNotificationID(injectedBundle.bundle(), context, notification); |
966 | injectedBundle.postSimulateWebNotificationClick(notificationID); |
967 | } |
968 | |
969 | void TestRunner::setGeolocationPermission(bool enabled) |
970 | { |
971 | // FIXME: this should be done by frame. |
972 | InjectedBundle::singleton().setGeolocationPermission(enabled); |
973 | } |
974 | |
975 | bool TestRunner::isGeolocationProviderActive() |
976 | { |
977 | return InjectedBundle::singleton().isGeolocationProviderActive(); |
978 | } |
979 | |
980 | void TestRunner::setMockGeolocationPosition(double latitude, double longitude, double accuracy, JSValueRef jsAltitude, JSValueRef jsAltitudeAccuracy, JSValueRef jsHeading, JSValueRef jsSpeed, JSValueRef jsFloorLevel) |
981 | { |
982 | auto& injectedBundle = InjectedBundle::singleton(); |
983 | WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(injectedBundle.page()->page()); |
984 | JSContextRef context = WKBundleFrameGetJavaScriptContext(mainFrame); |
985 | |
986 | bool providesAltitude = false; |
987 | double altitude = 0.; |
988 | if (!JSValueIsUndefined(context, jsAltitude)) { |
989 | providesAltitude = true; |
990 | altitude = JSValueToNumber(context, jsAltitude, 0); |
991 | } |
992 | |
993 | bool providesAltitudeAccuracy = false; |
994 | double altitudeAccuracy = 0.; |
995 | if (!JSValueIsUndefined(context, jsAltitudeAccuracy)) { |
996 | providesAltitudeAccuracy = true; |
997 | altitudeAccuracy = JSValueToNumber(context, jsAltitudeAccuracy, 0); |
998 | } |
999 | |
1000 | bool providesHeading = false; |
1001 | double heading = 0.; |
1002 | if (!JSValueIsUndefined(context, jsHeading)) { |
1003 | providesHeading = true; |
1004 | heading = JSValueToNumber(context, jsHeading, 0); |
1005 | } |
1006 | |
1007 | bool providesSpeed = false; |
1008 | double speed = 0.; |
1009 | if (!JSValueIsUndefined(context, jsSpeed)) { |
1010 | providesSpeed = true; |
1011 | speed = JSValueToNumber(context, jsSpeed, 0); |
1012 | } |
1013 | |
1014 | bool providesFloorLevel = false; |
1015 | double floorLevel = 0.; |
1016 | if (!JSValueIsUndefined(context, jsFloorLevel)) { |
1017 | providesFloorLevel = true; |
1018 | floorLevel = JSValueToNumber(context, jsFloorLevel, 0); |
1019 | } |
1020 | |
1021 | injectedBundle.setMockGeolocationPosition(latitude, longitude, accuracy, providesAltitude, altitude, providesAltitudeAccuracy, altitudeAccuracy, providesHeading, heading, providesSpeed, speed, providesFloorLevel, floorLevel); |
1022 | } |
1023 | |
1024 | void TestRunner::setMockGeolocationPositionUnavailableError(JSStringRef message) |
1025 | { |
1026 | WKRetainPtr<WKStringRef> messageWK = toWK(message); |
1027 | InjectedBundle::singleton().setMockGeolocationPositionUnavailableError(messageWK.get()); |
1028 | } |
1029 | |
1030 | void TestRunner::setUserMediaPermission(bool enabled) |
1031 | { |
1032 | // FIXME: this should be done by frame. |
1033 | InjectedBundle::singleton().setUserMediaPermission(enabled); |
1034 | } |
1035 | |
1036 | void TestRunner::resetUserMediaPermission() |
1037 | { |
1038 | // FIXME: this should be done by frame. |
1039 | InjectedBundle::singleton().resetUserMediaPermission(); |
1040 | } |
1041 | |
1042 | bool TestRunner::isDoingMediaCapture() const |
1043 | { |
1044 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("IsDoingMediaCapture" )); |
1045 | WKTypeRef returnData = nullptr; |
1046 | WKBundlePagePostSynchronousMessageForTesting(InjectedBundle::singleton().page()->page(), messageName.get(), nullptr, &returnData); |
1047 | ASSERT(WKGetTypeID(returnData) == WKBooleanGetTypeID()); |
1048 | return WKBooleanGetValue(adoptWK(static_cast<WKBooleanRef>(returnData)).get()); |
1049 | } |
1050 | |
1051 | void TestRunner::setUserMediaPersistentPermissionForOrigin(bool permission, JSStringRef origin, JSStringRef parentOrigin) |
1052 | { |
1053 | WKRetainPtr<WKStringRef> originWK = toWK(origin); |
1054 | WKRetainPtr<WKStringRef> parentOriginWK = toWK(parentOrigin); |
1055 | InjectedBundle::singleton().setUserMediaPersistentPermissionForOrigin(permission, originWK.get(), parentOriginWK.get()); |
1056 | } |
1057 | |
1058 | unsigned TestRunner::userMediaPermissionRequestCountForOrigin(JSStringRef origin, JSStringRef parentOrigin) const |
1059 | { |
1060 | WKRetainPtr<WKStringRef> originWK = toWK(origin); |
1061 | WKRetainPtr<WKStringRef> parentOriginWK = toWK(parentOrigin); |
1062 | return InjectedBundle::singleton().userMediaPermissionRequestCountForOrigin(originWK.get(), parentOriginWK.get()); |
1063 | } |
1064 | |
1065 | void TestRunner::resetUserMediaPermissionRequestCountForOrigin(JSStringRef origin, JSStringRef parentOrigin) |
1066 | { |
1067 | WKRetainPtr<WKStringRef> originWK = toWK(origin); |
1068 | WKRetainPtr<WKStringRef> parentOriginWK = toWK(parentOrigin); |
1069 | InjectedBundle::singleton().resetUserMediaPermissionRequestCountForOrigin(originWK.get(), parentOriginWK.get()); |
1070 | } |
1071 | |
1072 | bool TestRunner::callShouldCloseOnWebView() |
1073 | { |
1074 | WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(InjectedBundle::singleton().page()->page()); |
1075 | return WKBundleFrameCallShouldCloseOnWebView(mainFrame); |
1076 | } |
1077 | |
1078 | void TestRunner::queueBackNavigation(unsigned howFarBackward) |
1079 | { |
1080 | InjectedBundle::singleton().queueBackNavigation(howFarBackward); |
1081 | } |
1082 | |
1083 | void TestRunner::queueForwardNavigation(unsigned howFarForward) |
1084 | { |
1085 | InjectedBundle::singleton().queueForwardNavigation(howFarForward); |
1086 | } |
1087 | |
1088 | void TestRunner::queueLoad(JSStringRef url, JSStringRef target, bool shouldOpenExternalURLs) |
1089 | { |
1090 | auto& injectedBundle = InjectedBundle::singleton(); |
1091 | WKRetainPtr<WKURLRef> baseURLWK = adoptWK(WKBundleFrameCopyURL(WKBundlePageGetMainFrame(injectedBundle.page()->page()))); |
1092 | WKRetainPtr<WKURLRef> urlWK = adoptWK(WKURLCreateWithBaseURL(baseURLWK.get(), toWTFString(toWK(url)).utf8().data())); |
1093 | WKRetainPtr<WKStringRef> urlStringWK = adoptWK(WKURLCopyString(urlWK.get())); |
1094 | |
1095 | injectedBundle.queueLoad(urlStringWK.get(), toWK(target).get(), shouldOpenExternalURLs); |
1096 | } |
1097 | |
1098 | void TestRunner::queueLoadHTMLString(JSStringRef content, JSStringRef baseURL, JSStringRef unreachableURL) |
1099 | { |
1100 | WKRetainPtr<WKStringRef> contentWK = toWK(content); |
1101 | WKRetainPtr<WKStringRef> baseURLWK = baseURL ? toWK(baseURL) : WKRetainPtr<WKStringRef>(); |
1102 | WKRetainPtr<WKStringRef> unreachableURLWK = unreachableURL ? toWK(unreachableURL) : WKRetainPtr<WKStringRef>(); |
1103 | |
1104 | InjectedBundle::singleton().queueLoadHTMLString(contentWK.get(), baseURLWK.get(), unreachableURLWK.get()); |
1105 | } |
1106 | |
1107 | void TestRunner::queueReload() |
1108 | { |
1109 | InjectedBundle::singleton().queueReload(); |
1110 | } |
1111 | |
1112 | void TestRunner::queueLoadingScript(JSStringRef script) |
1113 | { |
1114 | WKRetainPtr<WKStringRef> scriptWK = toWK(script); |
1115 | InjectedBundle::singleton().queueLoadingScript(scriptWK.get()); |
1116 | } |
1117 | |
1118 | void TestRunner::queueNonLoadingScript(JSStringRef script) |
1119 | { |
1120 | WKRetainPtr<WKStringRef> scriptWK = toWK(script); |
1121 | InjectedBundle::singleton().queueNonLoadingScript(scriptWK.get()); |
1122 | } |
1123 | |
1124 | void TestRunner::setRejectsProtectionSpaceAndContinueForAuthenticationChallenges(bool value) |
1125 | { |
1126 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("SetRejectsProtectionSpaceAndContinueForAuthenticationChallenges" )); |
1127 | WKRetainPtr<WKBooleanRef> messageBody = adoptWK(WKBooleanCreate(value)); |
1128 | WKBundlePagePostMessage(InjectedBundle::singleton().page()->page(), messageName.get(), messageBody.get()); |
1129 | } |
1130 | |
1131 | void TestRunner::setHandlesAuthenticationChallenges(bool handlesAuthenticationChallenges) |
1132 | { |
1133 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("SetHandlesAuthenticationChallenges" )); |
1134 | WKRetainPtr<WKBooleanRef> messageBody = adoptWK(WKBooleanCreate(handlesAuthenticationChallenges)); |
1135 | WKBundlePagePostMessage(InjectedBundle::singleton().page()->page(), messageName.get(), messageBody.get()); |
1136 | } |
1137 | |
1138 | void TestRunner::setShouldLogCanAuthenticateAgainstProtectionSpace(bool value) |
1139 | { |
1140 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("SetShouldLogCanAuthenticateAgainstProtectionSpace" )); |
1141 | WKRetainPtr<WKBooleanRef> messageBody = adoptWK(WKBooleanCreate(value)); |
1142 | WKBundlePagePostMessage(InjectedBundle::singleton().page()->page(), messageName.get(), messageBody.get()); |
1143 | } |
1144 | |
1145 | void TestRunner::setShouldLogDownloadCallbacks(bool value) |
1146 | { |
1147 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("SetShouldLogDownloadCallbacks" )); |
1148 | WKRetainPtr<WKBooleanRef> messageBody = adoptWK(WKBooleanCreate(value)); |
1149 | WKBundlePagePostMessage(InjectedBundle::singleton().page()->page(), messageName.get(), messageBody.get()); |
1150 | } |
1151 | |
1152 | void TestRunner::setAuthenticationUsername(JSStringRef username) |
1153 | { |
1154 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("SetAuthenticationUsername" )); |
1155 | WKRetainPtr<WKStringRef> messageBody = adoptWK(WKStringCreateWithJSString(username)); |
1156 | WKBundlePagePostMessage(InjectedBundle::singleton().page()->page(), messageName.get(), messageBody.get()); |
1157 | } |
1158 | |
1159 | void TestRunner::setAuthenticationPassword(JSStringRef password) |
1160 | { |
1161 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("SetAuthenticationPassword" )); |
1162 | WKRetainPtr<WKStringRef> messageBody = adoptWK(WKStringCreateWithJSString(password)); |
1163 | WKBundlePagePostMessage(InjectedBundle::singleton().page()->page(), messageName.get(), messageBody.get()); |
1164 | } |
1165 | |
1166 | bool TestRunner::secureEventInputIsEnabled() const |
1167 | { |
1168 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("SecureEventInputIsEnabled" )); |
1169 | WKTypeRef returnData = nullptr; |
1170 | WKBundlePagePostSynchronousMessageForTesting(InjectedBundle::singleton().page()->page(), messageName.get(), nullptr, &returnData); |
1171 | ASSERT(WKGetTypeID(returnData) == WKBooleanGetTypeID()); |
1172 | return WKBooleanGetValue(adoptWK(static_cast<WKBooleanRef>(returnData)).get()); |
1173 | } |
1174 | |
1175 | void TestRunner::setBlockAllPlugins(bool shouldBlock) |
1176 | { |
1177 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("SetBlockAllPlugins" )); |
1178 | WKRetainPtr<WKBooleanRef> messageBody = adoptWK(WKBooleanCreate(shouldBlock)); |
1179 | WKBundlePagePostMessage(InjectedBundle::singleton().page()->page(), messageName.get(), messageBody.get()); |
1180 | } |
1181 | |
1182 | void TestRunner::setPluginSupportedMode(JSStringRef mode) |
1183 | { |
1184 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("SetPluginSupportedMode" )); |
1185 | WKRetainPtr<WKStringRef> messageBody = adoptWK(WKStringCreateWithJSString(mode)); |
1186 | WKBundlePagePostMessage(InjectedBundle::singleton().page()->page(), messageName.get(), messageBody.get()); |
1187 | } |
1188 | |
1189 | JSValueRef TestRunner::failNextNewCodeBlock() |
1190 | { |
1191 | WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(InjectedBundle::singleton().page()->page()); |
1192 | JSContextRef context = WKBundleFrameGetJavaScriptContext(mainFrame); |
1193 | return JSC::failNextNewCodeBlock(context); |
1194 | } |
1195 | |
1196 | JSValueRef TestRunner::numberOfDFGCompiles(JSValueRef theFunction) |
1197 | { |
1198 | WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(InjectedBundle::singleton().page()->page()); |
1199 | JSContextRef context = WKBundleFrameGetJavaScriptContext(mainFrame); |
1200 | return JSC::numberOfDFGCompiles(context, theFunction); |
1201 | } |
1202 | |
1203 | JSValueRef TestRunner::neverInlineFunction(JSValueRef theFunction) |
1204 | { |
1205 | WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(InjectedBundle::singleton().page()->page()); |
1206 | JSContextRef context = WKBundleFrameGetJavaScriptContext(mainFrame); |
1207 | return JSC::setNeverInline(context, theFunction); |
1208 | } |
1209 | |
1210 | void TestRunner::setShouldDecideNavigationPolicyAfterDelay(bool value) |
1211 | { |
1212 | m_shouldDecideNavigationPolicyAfterDelay = value; |
1213 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("SetShouldDecideNavigationPolicyAfterDelay" )); |
1214 | WKRetainPtr<WKBooleanRef> messageBody = adoptWK(WKBooleanCreate(value)); |
1215 | WKBundlePagePostMessage(InjectedBundle::singleton().page()->page(), messageName.get(), messageBody.get()); |
1216 | } |
1217 | |
1218 | void TestRunner::setShouldDecideResponsePolicyAfterDelay(bool value) |
1219 | { |
1220 | m_shouldDecideResponsePolicyAfterDelay = value; |
1221 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("SetShouldDecideResponsePolicyAfterDelay" )); |
1222 | WKRetainPtr<WKBooleanRef> messageBody = adoptWK(WKBooleanCreate(value)); |
1223 | WKBundlePagePostMessage(InjectedBundle::singleton().page()->page(), messageName.get(), messageBody.get()); |
1224 | } |
1225 | |
1226 | void TestRunner::setNavigationGesturesEnabled(bool value) |
1227 | { |
1228 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("SetNavigationGesturesEnabled" )); |
1229 | WKRetainPtr<WKBooleanRef> messageBody = adoptWK(WKBooleanCreate(value)); |
1230 | WKBundlePagePostMessage(InjectedBundle::singleton().page()->page(), messageName.get(), messageBody.get()); |
1231 | } |
1232 | |
1233 | void TestRunner::setIgnoresViewportScaleLimits(bool value) |
1234 | { |
1235 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("SetIgnoresViewportScaleLimits" )); |
1236 | WKRetainPtr<WKBooleanRef> messageBody = adoptWK(WKBooleanCreate(value)); |
1237 | WKBundlePagePostMessage(InjectedBundle::singleton().page()->page(), messageName.get(), messageBody.get()); |
1238 | } |
1239 | |
1240 | void TestRunner::setShouldDownloadUndisplayableMIMETypes(bool value) |
1241 | { |
1242 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("SetShouldDownloadUndisplayableMIMETypes" )); |
1243 | WKRetainPtr<WKBooleanRef> messageBody = adoptWK(WKBooleanCreate(value)); |
1244 | WKBundlePagePostMessage(InjectedBundle::singleton().page()->page(), messageName.get(), messageBody.get()); |
1245 | } |
1246 | |
1247 | void TestRunner::setShouldAllowDeviceOrientationAndMotionAccess(bool value) |
1248 | { |
1249 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("SetShouldAllowDeviceOrientationAndMotionAccess" )); |
1250 | WKRetainPtr<WKBooleanRef> messageBody = adoptWK(WKBooleanCreate(value)); |
1251 | WKBundlePagePostMessage(InjectedBundle::singleton().page()->page(), messageName.get(), messageBody.get()); |
1252 | } |
1253 | |
1254 | void TestRunner::terminateNetworkProcess() |
1255 | { |
1256 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("TerminateNetworkProcess" )); |
1257 | WKBundlePagePostSynchronousMessageForTesting(InjectedBundle::singleton().page()->page(), messageName.get(), nullptr, nullptr); |
1258 | } |
1259 | |
1260 | void TestRunner::terminateServiceWorkerProcess() |
1261 | { |
1262 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("TerminateServiceWorkerProcess" )); |
1263 | WKBundlePagePostSynchronousMessageForTesting(InjectedBundle::singleton().page()->page(), messageName.get(), nullptr, nullptr); |
1264 | } |
1265 | |
1266 | static unsigned nextUIScriptCallbackID() |
1267 | { |
1268 | static unsigned callbackID = FirstUIScriptCallbackID; |
1269 | return callbackID++; |
1270 | } |
1271 | |
1272 | void TestRunner::runUIScript(JSStringRef script, JSValueRef callback) |
1273 | { |
1274 | unsigned callbackID = nextUIScriptCallbackID(); |
1275 | cacheTestRunnerCallback(callbackID, callback); |
1276 | |
1277 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("RunUIProcessScript" )); |
1278 | |
1279 | WKRetainPtr<WKMutableDictionaryRef> testDictionary = adoptWK(WKMutableDictionaryCreate()); |
1280 | |
1281 | WKRetainPtr<WKStringRef> scriptKey = adoptWK(WKStringCreateWithUTF8CString("Script" )); |
1282 | WKRetainPtr<WKStringRef> scriptValue = adoptWK(WKStringCreateWithJSString(script)); |
1283 | |
1284 | WKRetainPtr<WKStringRef> callbackIDKey = adoptWK(WKStringCreateWithUTF8CString("CallbackID" )); |
1285 | WKRetainPtr<WKUInt64Ref> callbackIDValue = adoptWK(WKUInt64Create(callbackID)); |
1286 | |
1287 | WKDictionarySetItem(testDictionary.get(), scriptKey.get(), scriptValue.get()); |
1288 | WKDictionarySetItem(testDictionary.get(), callbackIDKey.get(), callbackIDValue.get()); |
1289 | |
1290 | WKBundlePagePostMessage(InjectedBundle::singleton().page()->page(), messageName.get(), testDictionary.get()); |
1291 | } |
1292 | |
1293 | void TestRunner::runUIScriptCallback(unsigned callbackID, JSStringRef result) |
1294 | { |
1295 | WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(InjectedBundle::singleton().page()->page()); |
1296 | JSContextRef context = WKBundleFrameGetJavaScriptContext(mainFrame); |
1297 | |
1298 | JSValueRef resultValue = JSValueMakeString(context, result); |
1299 | callTestRunnerCallback(callbackID, 1, &resultValue); |
1300 | } |
1301 | |
1302 | void TestRunner::(JSValueRef actions) |
1303 | { |
1304 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("SetAllowedMenuActions" )); |
1305 | WKRetainPtr<WKMutableArrayRef> messageBody = adoptWK(WKMutableArrayCreate()); |
1306 | |
1307 | auto page = InjectedBundle::singleton().page()->page(); |
1308 | auto mainFrame = WKBundlePageGetMainFrame(page); |
1309 | auto context = WKBundleFrameGetJavaScriptContext(mainFrame); |
1310 | auto lengthPropertyName = adopt(JSStringCreateWithUTF8CString("length" )); |
1311 | auto actionsArray = JSValueToObject(context, actions, nullptr); |
1312 | auto lengthValue = JSObjectGetProperty(context, actionsArray, lengthPropertyName.get(), nullptr); |
1313 | if (!JSValueIsNumber(context, lengthValue)) |
1314 | return; |
1315 | |
1316 | auto length = static_cast<size_t>(JSValueToNumber(context, lengthValue, 0)); |
1317 | for (size_t i = 0; i < length; ++i) { |
1318 | auto value = JSObjectGetPropertyAtIndex(context, actionsArray, i, 0); |
1319 | if (!JSValueIsString(context, value)) |
1320 | continue; |
1321 | |
1322 | auto actionName = adopt(JSValueToStringCopy(context, value, 0)); |
1323 | WKRetainPtr<WKStringRef> action = adoptWK(WKStringCreateWithJSString(actionName.get())); |
1324 | WKArrayAppendItem(messageBody.get(), action.get()); |
1325 | } |
1326 | |
1327 | WKBundlePagePostMessage(page, messageName.get(), messageBody.get()); |
1328 | } |
1329 | |
1330 | void TestRunner::(JSStringRef name, bool dismissesAutomatically, JSValueRef callback) |
1331 | { |
1332 | cacheTestRunnerCallback(CustomMenuActionCallbackID, callback); |
1333 | |
1334 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("InstallCustomMenuAction" )); |
1335 | WKRetainPtr<WKMutableDictionaryRef> messageBody = adoptWK(WKMutableDictionaryCreate()); |
1336 | |
1337 | WKRetainPtr<WKStringRef> nameKey = adoptWK(WKStringCreateWithUTF8CString("name" )); |
1338 | WKRetainPtr<WKStringRef> nameValue = adoptWK(WKStringCreateWithJSString(name)); |
1339 | WKDictionarySetItem(messageBody.get(), nameKey.get(), nameValue.get()); |
1340 | |
1341 | WKRetainPtr<WKStringRef> dismissesAutomaticallyKey = adoptWK(WKStringCreateWithUTF8CString("dismissesAutomatically" )); |
1342 | WKRetainPtr<WKBooleanRef> dismissesAutomaticallyValue = adoptWK(WKBooleanCreate(dismissesAutomatically)); |
1343 | WKDictionarySetItem(messageBody.get(), dismissesAutomaticallyKey.get(), dismissesAutomaticallyValue.get()); |
1344 | |
1345 | WKBundlePagePostMessage(InjectedBundle::singleton().page()->page(), messageName.get(), messageBody.get()); |
1346 | } |
1347 | |
1348 | void TestRunner::installDidBeginSwipeCallback(JSValueRef callback) |
1349 | { |
1350 | cacheTestRunnerCallback(DidBeginSwipeCallbackID, callback); |
1351 | } |
1352 | |
1353 | void TestRunner::installWillEndSwipeCallback(JSValueRef callback) |
1354 | { |
1355 | cacheTestRunnerCallback(WillEndSwipeCallbackID, callback); |
1356 | } |
1357 | |
1358 | void TestRunner::installDidEndSwipeCallback(JSValueRef callback) |
1359 | { |
1360 | cacheTestRunnerCallback(DidEndSwipeCallbackID, callback); |
1361 | } |
1362 | |
1363 | void TestRunner::installDidRemoveSwipeSnapshotCallback(JSValueRef callback) |
1364 | { |
1365 | cacheTestRunnerCallback(DidRemoveSwipeSnapshotCallbackID, callback); |
1366 | } |
1367 | |
1368 | void TestRunner::callDidBeginSwipeCallback() |
1369 | { |
1370 | callTestRunnerCallback(DidBeginSwipeCallbackID); |
1371 | } |
1372 | |
1373 | void TestRunner::callWillEndSwipeCallback() |
1374 | { |
1375 | callTestRunnerCallback(WillEndSwipeCallbackID); |
1376 | } |
1377 | |
1378 | void TestRunner::callDidEndSwipeCallback() |
1379 | { |
1380 | callTestRunnerCallback(DidEndSwipeCallbackID); |
1381 | } |
1382 | |
1383 | void TestRunner::callDidRemoveSwipeSnapshotCallback() |
1384 | { |
1385 | callTestRunnerCallback(DidRemoveSwipeSnapshotCallbackID); |
1386 | } |
1387 | |
1388 | void TestRunner::setStatisticsDebugMode(bool value, JSValueRef completionHandler) |
1389 | { |
1390 | cacheTestRunnerCallback(SetStatisticsDebugModeCallbackID, completionHandler); |
1391 | |
1392 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("SetStatisticsDebugMode" )); |
1393 | WKRetainPtr<WKBooleanRef> messageBody = adoptWK(WKBooleanCreate(value)); |
1394 | WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr); |
1395 | |
1396 | } |
1397 | |
1398 | void TestRunner::statisticsCallDidSetDebugModeCallback() |
1399 | { |
1400 | callTestRunnerCallback(SetStatisticsDebugModeCallbackID); |
1401 | } |
1402 | |
1403 | void TestRunner::setStatisticsPrevalentResourceForDebugMode(JSStringRef hostName, JSValueRef completionHandler) |
1404 | { |
1405 | cacheTestRunnerCallback(SetStatisticsPrevalentResourceForDebugModeCallbackID, completionHandler); |
1406 | |
1407 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("SetStatisticsPrevalentResourceForDebugMode" )); |
1408 | WKRetainPtr<WKStringRef> messageBody = adoptWK(WKStringCreateWithJSString(hostName)); |
1409 | WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr); |
1410 | } |
1411 | |
1412 | void TestRunner::statisticsCallDidSetPrevalentResourceForDebugModeCallback() |
1413 | { |
1414 | callTestRunnerCallback(SetStatisticsPrevalentResourceForDebugModeCallbackID); |
1415 | } |
1416 | |
1417 | void TestRunner::setStatisticsLastSeen(JSStringRef hostName, double seconds, JSValueRef completionHandler) |
1418 | { |
1419 | cacheTestRunnerCallback(SetStatisticsLastSeenCallbackID, completionHandler); |
1420 | |
1421 | Vector<WKRetainPtr<WKStringRef>> keys; |
1422 | Vector<WKRetainPtr<WKTypeRef>> values; |
1423 | |
1424 | keys.append(adoptWK(WKStringCreateWithUTF8CString("HostName" ))); |
1425 | values.append(adoptWK(WKStringCreateWithJSString(hostName))); |
1426 | |
1427 | keys.append(adoptWK(WKStringCreateWithUTF8CString("Value" ))); |
1428 | values.append(adoptWK(WKDoubleCreate(seconds))); |
1429 | |
1430 | Vector<WKStringRef> rawKeys(keys.size()); |
1431 | Vector<WKTypeRef> rawValues(values.size()); |
1432 | |
1433 | for (size_t i = 0; i < keys.size(); ++i) { |
1434 | rawKeys[i] = keys[i].get(); |
1435 | rawValues[i] = values[i].get(); |
1436 | } |
1437 | |
1438 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("SetStatisticsLastSeen" )); |
1439 | WKRetainPtr<WKDictionaryRef> messageBody = adoptWK(WKDictionaryCreate(rawKeys.data(), rawValues.data(), rawKeys.size())); |
1440 | |
1441 | WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr); |
1442 | } |
1443 | |
1444 | void TestRunner::statisticsCallDidSetLastSeenCallback() |
1445 | { |
1446 | callTestRunnerCallback(SetStatisticsLastSeenCallbackID); |
1447 | } |
1448 | |
1449 | void TestRunner::setStatisticsPrevalentResource(JSStringRef hostName, bool value, JSValueRef completionHandler) |
1450 | { |
1451 | cacheTestRunnerCallback(SetStatisticsPrevalentResourceCallbackID, completionHandler); |
1452 | |
1453 | Vector<WKRetainPtr<WKStringRef>> keys; |
1454 | Vector<WKRetainPtr<WKTypeRef>> values; |
1455 | |
1456 | keys.append(adoptWK(WKStringCreateWithUTF8CString("HostName" ))); |
1457 | values.append(adoptWK(WKStringCreateWithJSString(hostName))); |
1458 | |
1459 | keys.append(adoptWK(WKStringCreateWithUTF8CString("Value" ))); |
1460 | values.append(adoptWK(WKBooleanCreate(value))); |
1461 | |
1462 | Vector<WKStringRef> rawKeys; |
1463 | Vector<WKTypeRef> rawValues; |
1464 | rawKeys.resize(keys.size()); |
1465 | rawValues.resize(values.size()); |
1466 | |
1467 | for (size_t i = 0; i < keys.size(); ++i) { |
1468 | rawKeys[i] = keys[i].get(); |
1469 | rawValues[i] = values[i].get(); |
1470 | } |
1471 | |
1472 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("SetStatisticsPrevalentResource" )); |
1473 | WKRetainPtr<WKDictionaryRef> messageBody = adoptWK(WKDictionaryCreate(rawKeys.data(), rawValues.data(), rawKeys.size())); |
1474 | |
1475 | WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr); |
1476 | } |
1477 | |
1478 | void TestRunner::statisticsCallDidSetPrevalentResourceCallback() |
1479 | { |
1480 | callTestRunnerCallback(SetStatisticsPrevalentResourceCallbackID); |
1481 | } |
1482 | |
1483 | void TestRunner::setStatisticsVeryPrevalentResource(JSStringRef hostName, bool value, JSValueRef completionHandler) |
1484 | { |
1485 | cacheTestRunnerCallback(SetStatisticsVeryPrevalentResourceCallbackID, completionHandler); |
1486 | |
1487 | Vector<WKRetainPtr<WKStringRef>> keys; |
1488 | Vector<WKRetainPtr<WKTypeRef>> values; |
1489 | |
1490 | keys.append(adoptWK(WKStringCreateWithUTF8CString("HostName" ))); |
1491 | values.append(adoptWK(WKStringCreateWithJSString(hostName))); |
1492 | |
1493 | keys.append(adoptWK(WKStringCreateWithUTF8CString("Value" ))); |
1494 | values.append(adoptWK(WKBooleanCreate(value))); |
1495 | |
1496 | Vector<WKStringRef> rawKeys; |
1497 | Vector<WKTypeRef> rawValues; |
1498 | rawKeys.resize(keys.size()); |
1499 | rawValues.resize(values.size()); |
1500 | |
1501 | for (size_t i = 0; i < keys.size(); ++i) { |
1502 | rawKeys[i] = keys[i].get(); |
1503 | rawValues[i] = values[i].get(); |
1504 | } |
1505 | |
1506 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("SetStatisticsVeryPrevalentResource" )); |
1507 | WKRetainPtr<WKDictionaryRef> messageBody = adoptWK(WKDictionaryCreate(rawKeys.data(), rawValues.data(), rawKeys.size())); |
1508 | |
1509 | WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr); |
1510 | } |
1511 | |
1512 | void TestRunner::statisticsCallDidSetVeryPrevalentResourceCallback() |
1513 | { |
1514 | callTestRunnerCallback(SetStatisticsVeryPrevalentResourceCallbackID); |
1515 | } |
1516 | |
1517 | void TestRunner::dumpResourceLoadStatistics() |
1518 | { |
1519 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("dumpResourceLoadStatistics" )); |
1520 | WKBundlePagePostSynchronousMessageForTesting(InjectedBundle::singleton().page()->page(), messageName.get(), nullptr, nullptr); |
1521 | } |
1522 | |
1523 | bool TestRunner::isStatisticsPrevalentResource(JSStringRef hostName) |
1524 | { |
1525 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("IsStatisticsPrevalentResource" )); |
1526 | WKRetainPtr<WKStringRef> messageBody = adoptWK(WKStringCreateWithJSString(hostName)); |
1527 | WKTypeRef returnData = nullptr; |
1528 | WKBundlePagePostSynchronousMessageForTesting(InjectedBundle::singleton().page()->page(), messageName.get(), messageBody.get(), &returnData); |
1529 | ASSERT(WKGetTypeID(returnData) == WKBooleanGetTypeID()); |
1530 | return WKBooleanGetValue(adoptWK(static_cast<WKBooleanRef>(returnData)).get()); |
1531 | } |
1532 | |
1533 | bool TestRunner::isStatisticsVeryPrevalentResource(JSStringRef hostName) |
1534 | { |
1535 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("IsStatisticsVeryPrevalentResource" )); |
1536 | WKRetainPtr<WKStringRef> messageBody = adoptWK(WKStringCreateWithJSString(hostName)); |
1537 | WKTypeRef returnData = nullptr; |
1538 | WKBundlePagePostSynchronousMessageForTesting(InjectedBundle::singleton().page()->page(), messageName.get(), messageBody.get(), &returnData); |
1539 | ASSERT(WKGetTypeID(returnData) == WKBooleanGetTypeID()); |
1540 | return WKBooleanGetValue(adoptWK(static_cast<WKBooleanRef>(returnData)).get()); |
1541 | } |
1542 | |
1543 | bool TestRunner::isStatisticsRegisteredAsSubresourceUnder(JSStringRef subresourceHost, JSStringRef topFrameHost) |
1544 | { |
1545 | Vector<WKRetainPtr<WKStringRef>> keys; |
1546 | Vector<WKRetainPtr<WKTypeRef>> values; |
1547 | |
1548 | keys.append(adoptWK(WKStringCreateWithUTF8CString("SubresourceHost" ))); |
1549 | values.append(adoptWK(WKStringCreateWithJSString(subresourceHost))); |
1550 | |
1551 | keys.append(adoptWK(WKStringCreateWithUTF8CString("TopFrameHost" ))); |
1552 | values.append(adoptWK(WKStringCreateWithJSString(topFrameHost))); |
1553 | |
1554 | Vector<WKStringRef> rawKeys(keys.size()); |
1555 | Vector<WKTypeRef> rawValues(values.size()); |
1556 | |
1557 | for (size_t i = 0; i < keys.size(); ++i) { |
1558 | rawKeys[i] = keys[i].get(); |
1559 | rawValues[i] = values[i].get(); |
1560 | } |
1561 | |
1562 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("IsStatisticsRegisteredAsSubresourceUnder" )); |
1563 | WKRetainPtr<WKDictionaryRef> messageBody = adoptWK(WKDictionaryCreate(rawKeys.data(), rawValues.data(), rawKeys.size())); |
1564 | WKTypeRef returnData = nullptr; |
1565 | WKBundlePagePostSynchronousMessageForTesting(InjectedBundle::singleton().page()->page(), messageName.get(), messageBody.get(), &returnData); |
1566 | ASSERT(WKGetTypeID(returnData) == WKBooleanGetTypeID()); |
1567 | return WKBooleanGetValue(adoptWK(static_cast<WKBooleanRef>(returnData)).get()); |
1568 | } |
1569 | |
1570 | bool TestRunner::isStatisticsRegisteredAsSubFrameUnder(JSStringRef subFrameHost, JSStringRef topFrameHost) |
1571 | { |
1572 | Vector<WKRetainPtr<WKStringRef>> keys; |
1573 | Vector<WKRetainPtr<WKTypeRef>> values; |
1574 | |
1575 | keys.append(adoptWK(WKStringCreateWithUTF8CString("SubFrameHost" ))); |
1576 | values.append(adoptWK(WKStringCreateWithJSString(subFrameHost))); |
1577 | |
1578 | keys.append(adoptWK(WKStringCreateWithUTF8CString("TopFrameHost" ))); |
1579 | values.append(adoptWK(WKStringCreateWithJSString(topFrameHost))); |
1580 | |
1581 | Vector<WKStringRef> rawKeys(keys.size()); |
1582 | Vector<WKTypeRef> rawValues(values.size()); |
1583 | |
1584 | for (size_t i = 0; i < keys.size(); ++i) { |
1585 | rawKeys[i] = keys[i].get(); |
1586 | rawValues[i] = values[i].get(); |
1587 | } |
1588 | |
1589 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("IsStatisticsRegisteredAsSubFrameUnder" )); |
1590 | WKRetainPtr<WKDictionaryRef> messageBody = adoptWK(WKDictionaryCreate(rawKeys.data(), rawValues.data(), rawKeys.size())); |
1591 | WKTypeRef returnData = nullptr; |
1592 | WKBundlePagePostSynchronousMessageForTesting(InjectedBundle::singleton().page()->page(), messageName.get(), messageBody.get(), &returnData); |
1593 | ASSERT(WKGetTypeID(returnData) == WKBooleanGetTypeID()); |
1594 | return WKBooleanGetValue(adoptWK(static_cast<WKBooleanRef>(returnData)).get()); |
1595 | } |
1596 | |
1597 | bool TestRunner::isStatisticsRegisteredAsRedirectingTo(JSStringRef hostRedirectedFrom, JSStringRef hostRedirectedTo) |
1598 | { |
1599 | Vector<WKRetainPtr<WKStringRef>> keys; |
1600 | Vector<WKRetainPtr<WKTypeRef>> values; |
1601 | |
1602 | keys.append(adoptWK(WKStringCreateWithUTF8CString("HostRedirectedFrom" ))); |
1603 | values.append(adoptWK(WKStringCreateWithJSString(hostRedirectedFrom))); |
1604 | |
1605 | keys.append(adoptWK(WKStringCreateWithUTF8CString("HostRedirectedTo" ))); |
1606 | values.append(adoptWK(WKStringCreateWithJSString(hostRedirectedTo))); |
1607 | |
1608 | Vector<WKStringRef> rawKeys(keys.size()); |
1609 | Vector<WKTypeRef> rawValues(values.size()); |
1610 | |
1611 | for (size_t i = 0; i < keys.size(); ++i) { |
1612 | rawKeys[i] = keys[i].get(); |
1613 | rawValues[i] = values[i].get(); |
1614 | } |
1615 | |
1616 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("IsStatisticsRegisteredAsRedirectingTo" )); |
1617 | WKRetainPtr<WKDictionaryRef> messageBody = adoptWK(WKDictionaryCreate(rawKeys.data(), rawValues.data(), rawKeys.size())); |
1618 | WKTypeRef returnData = nullptr; |
1619 | WKBundlePagePostSynchronousMessageForTesting(InjectedBundle::singleton().page()->page(), messageName.get(), messageBody.get(), &returnData); |
1620 | ASSERT(WKGetTypeID(returnData) == WKBooleanGetTypeID()); |
1621 | return WKBooleanGetValue(adoptWK(static_cast<WKBooleanRef>(returnData)).get()); |
1622 | } |
1623 | |
1624 | void TestRunner::setStatisticsHasHadUserInteraction(JSStringRef hostName, bool value, JSValueRef completionHandler) |
1625 | { |
1626 | cacheTestRunnerCallback(SetStatisticsHasHadUserInteractionCallbackID, completionHandler); |
1627 | |
1628 | Vector<WKRetainPtr<WKStringRef>> keys; |
1629 | Vector<WKRetainPtr<WKTypeRef>> values; |
1630 | |
1631 | keys.append(adoptWK(WKStringCreateWithUTF8CString("HostName" ))); |
1632 | values.append(adoptWK(WKStringCreateWithJSString(hostName))); |
1633 | |
1634 | keys.append(adoptWK(WKStringCreateWithUTF8CString("Value" ))); |
1635 | values.append(adoptWK(WKBooleanCreate(value))); |
1636 | |
1637 | Vector<WKStringRef> rawKeys; |
1638 | Vector<WKTypeRef> rawValues; |
1639 | rawKeys.resize(keys.size()); |
1640 | rawValues.resize(values.size()); |
1641 | |
1642 | for (size_t i = 0; i < keys.size(); ++i) { |
1643 | rawKeys[i] = keys[i].get(); |
1644 | rawValues[i] = values[i].get(); |
1645 | } |
1646 | |
1647 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("SetStatisticsHasHadUserInteraction" )); |
1648 | WKRetainPtr<WKDictionaryRef> messageBody = adoptWK(WKDictionaryCreate(rawKeys.data(), rawValues.data(), rawKeys.size())); |
1649 | |
1650 | WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr); |
1651 | } |
1652 | |
1653 | void TestRunner::statisticsCallDidSetHasHadUserInteractionCallback() |
1654 | { |
1655 | callTestRunnerCallback(SetStatisticsHasHadUserInteractionCallbackID); |
1656 | } |
1657 | |
1658 | bool TestRunner::isStatisticsHasHadUserInteraction(JSStringRef hostName) |
1659 | { |
1660 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("IsStatisticsHasHadUserInteraction" )); |
1661 | WKRetainPtr<WKStringRef> messageBody = adoptWK(WKStringCreateWithJSString(hostName)); |
1662 | WKTypeRef returnData = nullptr; |
1663 | WKBundlePagePostSynchronousMessageForTesting(InjectedBundle::singleton().page()->page(), messageName.get(), messageBody.get(), &returnData); |
1664 | ASSERT(WKGetTypeID(returnData) == WKBooleanGetTypeID()); |
1665 | return WKBooleanGetValue(adoptWK(static_cast<WKBooleanRef>(returnData)).get()); |
1666 | } |
1667 | |
1668 | void TestRunner::setStatisticsGrandfathered(JSStringRef hostName, bool value) |
1669 | { |
1670 | Vector<WKRetainPtr<WKStringRef>> keys; |
1671 | Vector<WKRetainPtr<WKTypeRef>> values; |
1672 | |
1673 | keys.append(adoptWK(WKStringCreateWithUTF8CString("HostName" ))); |
1674 | values.append(adoptWK(WKStringCreateWithJSString(hostName))); |
1675 | |
1676 | keys.append(adoptWK(WKStringCreateWithUTF8CString("Value" ))); |
1677 | values.append(adoptWK(WKBooleanCreate(value))); |
1678 | |
1679 | Vector<WKStringRef> rawKeys; |
1680 | Vector<WKTypeRef> rawValues; |
1681 | rawKeys.resize(keys.size()); |
1682 | rawValues.resize(values.size()); |
1683 | |
1684 | for (size_t i = 0; i < keys.size(); ++i) { |
1685 | rawKeys[i] = keys[i].get(); |
1686 | rawValues[i] = values[i].get(); |
1687 | } |
1688 | |
1689 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("SetStatisticsGrandfathered" )); |
1690 | WKRetainPtr<WKDictionaryRef> messageBody = adoptWK(WKDictionaryCreate(rawKeys.data(), rawValues.data(), rawKeys.size())); |
1691 | |
1692 | WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr); |
1693 | } |
1694 | |
1695 | bool TestRunner::isStatisticsGrandfathered(JSStringRef hostName) |
1696 | { |
1697 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("IsStatisticsGrandfathered" )); |
1698 | WKRetainPtr<WKStringRef> messageBody = adoptWK(WKStringCreateWithJSString(hostName)); |
1699 | WKTypeRef returnData = nullptr; |
1700 | WKBundlePagePostSynchronousMessageForTesting(InjectedBundle::singleton().page()->page(), messageName.get(), messageBody.get(), &returnData); |
1701 | ASSERT(WKGetTypeID(returnData) == WKBooleanGetTypeID()); |
1702 | return WKBooleanGetValue(adoptWK(static_cast<WKBooleanRef>(returnData)).get()); |
1703 | } |
1704 | |
1705 | void TestRunner::setStatisticsSubframeUnderTopFrameOrigin(JSStringRef hostName, JSStringRef topFrameHostName) |
1706 | { |
1707 | Vector<WKRetainPtr<WKStringRef>> keys; |
1708 | Vector<WKRetainPtr<WKTypeRef>> values; |
1709 | |
1710 | keys.append(adoptWK(WKStringCreateWithUTF8CString("HostName" ))); |
1711 | values.append(adoptWK(WKStringCreateWithJSString(hostName))); |
1712 | |
1713 | keys.append(adoptWK(WKStringCreateWithUTF8CString("TopFrameHostName" ))); |
1714 | values.append(adoptWK(WKStringCreateWithJSString(topFrameHostName))); |
1715 | |
1716 | Vector<WKStringRef> rawKeys(keys.size()); |
1717 | Vector<WKTypeRef> rawValues(values.size()); |
1718 | |
1719 | for (size_t i = 0; i < keys.size(); ++i) { |
1720 | rawKeys[i] = keys[i].get(); |
1721 | rawValues[i] = values[i].get(); |
1722 | } |
1723 | |
1724 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("SetStatisticsSubframeUnderTopFrameOrigin" )); |
1725 | WKRetainPtr<WKDictionaryRef> messageBody = adoptWK(WKDictionaryCreate(rawKeys.data(), rawValues.data(), rawKeys.size())); |
1726 | WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr); |
1727 | } |
1728 | |
1729 | void TestRunner::setStatisticsSubresourceUnderTopFrameOrigin(JSStringRef hostName, JSStringRef topFrameHostName) |
1730 | { |
1731 | Vector<WKRetainPtr<WKStringRef>> keys; |
1732 | Vector<WKRetainPtr<WKTypeRef>> values; |
1733 | |
1734 | keys.append(adoptWK(WKStringCreateWithUTF8CString("HostName" ))); |
1735 | values.append(adoptWK(WKStringCreateWithJSString(hostName))); |
1736 | |
1737 | keys.append(adoptWK(WKStringCreateWithUTF8CString("TopFrameHostName" ))); |
1738 | values.append(adoptWK(WKStringCreateWithJSString(topFrameHostName))); |
1739 | |
1740 | Vector<WKStringRef> rawKeys(keys.size()); |
1741 | Vector<WKTypeRef> rawValues(values.size()); |
1742 | |
1743 | for (size_t i = 0; i < keys.size(); ++i) { |
1744 | rawKeys[i] = keys[i].get(); |
1745 | rawValues[i] = values[i].get(); |
1746 | } |
1747 | |
1748 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("SetStatisticsSubresourceUnderTopFrameOrigin" )); |
1749 | WKRetainPtr<WKDictionaryRef> messageBody = adoptWK(WKDictionaryCreate(rawKeys.data(), rawValues.data(), rawKeys.size())); |
1750 | WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr); |
1751 | } |
1752 | |
1753 | void TestRunner::setStatisticsSubresourceUniqueRedirectTo(JSStringRef hostName, JSStringRef hostNameRedirectedTo) |
1754 | { |
1755 | Vector<WKRetainPtr<WKStringRef>> keys; |
1756 | Vector<WKRetainPtr<WKTypeRef>> values; |
1757 | |
1758 | keys.append(adoptWK(WKStringCreateWithUTF8CString("HostName" ))); |
1759 | values.append(adoptWK(WKStringCreateWithJSString(hostName))); |
1760 | |
1761 | keys.append(adoptWK(WKStringCreateWithUTF8CString("HostNameRedirectedTo" ))); |
1762 | values.append(adoptWK(WKStringCreateWithJSString(hostNameRedirectedTo))); |
1763 | |
1764 | Vector<WKStringRef> rawKeys(keys.size()); |
1765 | Vector<WKTypeRef> rawValues(values.size()); |
1766 | |
1767 | for (size_t i = 0; i < keys.size(); ++i) { |
1768 | rawKeys[i] = keys[i].get(); |
1769 | rawValues[i] = values[i].get(); |
1770 | } |
1771 | |
1772 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("SetStatisticsSubresourceUniqueRedirectTo" )); |
1773 | WKRetainPtr<WKDictionaryRef> messageBody = adoptWK(WKDictionaryCreate(rawKeys.data(), rawValues.data(), rawKeys.size())); |
1774 | WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr); |
1775 | } |
1776 | |
1777 | |
1778 | void TestRunner::setStatisticsSubresourceUniqueRedirectFrom(JSStringRef hostName, JSStringRef hostNameRedirectedFrom) |
1779 | { |
1780 | Vector<WKRetainPtr<WKStringRef>> keys; |
1781 | Vector<WKRetainPtr<WKTypeRef>> values; |
1782 | |
1783 | keys.append(adoptWK(WKStringCreateWithUTF8CString("HostName" ))); |
1784 | values.append(adoptWK(WKStringCreateWithJSString(hostName))); |
1785 | |
1786 | keys.append(adoptWK(WKStringCreateWithUTF8CString("HostNameRedirectedFrom" ))); |
1787 | values.append(adoptWK(WKStringCreateWithJSString(hostNameRedirectedFrom))); |
1788 | |
1789 | Vector<WKStringRef> rawKeys(keys.size()); |
1790 | Vector<WKTypeRef> rawValues(values.size()); |
1791 | |
1792 | for (size_t i = 0; i < keys.size(); ++i) { |
1793 | rawKeys[i] = keys[i].get(); |
1794 | rawValues[i] = values[i].get(); |
1795 | } |
1796 | |
1797 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("SetStatisticsSubresourceUniqueRedirectFrom" )); |
1798 | WKRetainPtr<WKDictionaryRef> messageBody = adoptWK(WKDictionaryCreate(rawKeys.data(), rawValues.data(), rawKeys.size())); |
1799 | WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr); |
1800 | } |
1801 | |
1802 | void TestRunner::setStatisticsTopFrameUniqueRedirectTo(JSStringRef hostName, JSStringRef hostNameRedirectedTo) |
1803 | { |
1804 | Vector<WKRetainPtr<WKStringRef>> keys; |
1805 | Vector<WKRetainPtr<WKTypeRef>> values; |
1806 | |
1807 | keys.append(adoptWK(WKStringCreateWithUTF8CString("HostName" ))); |
1808 | values.append(adoptWK(WKStringCreateWithJSString(hostName))); |
1809 | |
1810 | keys.append(adoptWK(WKStringCreateWithUTF8CString("HostNameRedirectedTo" ))); |
1811 | values.append(adoptWK(WKStringCreateWithJSString(hostNameRedirectedTo))); |
1812 | |
1813 | Vector<WKStringRef> rawKeys(keys.size()); |
1814 | Vector<WKTypeRef> rawValues(values.size()); |
1815 | |
1816 | for (size_t i = 0; i < keys.size(); ++i) { |
1817 | rawKeys[i] = keys[i].get(); |
1818 | rawValues[i] = values[i].get(); |
1819 | } |
1820 | |
1821 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("SetStatisticsTopFrameUniqueRedirectTo" )); |
1822 | WKRetainPtr<WKDictionaryRef> messageBody = adoptWK(WKDictionaryCreate(rawKeys.data(), rawValues.data(), rawKeys.size())); |
1823 | WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr); |
1824 | } |
1825 | |
1826 | void TestRunner::setStatisticsTopFrameUniqueRedirectFrom(JSStringRef hostName, JSStringRef hostNameRedirectedFrom) |
1827 | { |
1828 | Vector<WKRetainPtr<WKStringRef>> keys; |
1829 | Vector<WKRetainPtr<WKTypeRef>> values; |
1830 | |
1831 | keys.append(adoptWK(WKStringCreateWithUTF8CString("HostName" ))); |
1832 | values.append(adoptWK(WKStringCreateWithJSString(hostName))); |
1833 | |
1834 | keys.append(adoptWK(WKStringCreateWithUTF8CString("HostNameRedirectedFrom" ))); |
1835 | values.append(adoptWK(WKStringCreateWithJSString(hostNameRedirectedFrom))); |
1836 | |
1837 | Vector<WKStringRef> rawKeys(keys.size()); |
1838 | Vector<WKTypeRef> rawValues(values.size()); |
1839 | |
1840 | for (size_t i = 0; i < keys.size(); ++i) { |
1841 | rawKeys[i] = keys[i].get(); |
1842 | rawValues[i] = values[i].get(); |
1843 | } |
1844 | |
1845 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("SetStatisticsTopFrameUniqueRedirectFrom" )); |
1846 | WKRetainPtr<WKDictionaryRef> messageBody = adoptWK(WKDictionaryCreate(rawKeys.data(), rawValues.data(), rawKeys.size())); |
1847 | WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr); |
1848 | } |
1849 | |
1850 | void TestRunner::setStatisticsCrossSiteLoadWithLinkDecoration(JSStringRef fromHost, JSStringRef toHost) |
1851 | { |
1852 | Vector<WKRetainPtr<WKStringRef>> keys; |
1853 | Vector<WKRetainPtr<WKTypeRef>> values; |
1854 | |
1855 | keys.append(adoptWK(WKStringCreateWithUTF8CString("FromHost" ))); |
1856 | values.append(adoptWK(WKStringCreateWithJSString(fromHost))); |
1857 | |
1858 | keys.append(adoptWK(WKStringCreateWithUTF8CString("ToHost" ))); |
1859 | values.append(adoptWK(WKStringCreateWithJSString(toHost))); |
1860 | |
1861 | Vector<WKStringRef> rawKeys(keys.size()); |
1862 | Vector<WKTypeRef> rawValues(values.size()); |
1863 | |
1864 | for (size_t i = 0; i < keys.size(); ++i) { |
1865 | rawKeys[i] = keys[i].get(); |
1866 | rawValues[i] = values[i].get(); |
1867 | } |
1868 | |
1869 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("SetStatisticsCrossSiteLoadWithLinkDecoration" )); |
1870 | WKRetainPtr<WKDictionaryRef> messageBody = adoptWK(WKDictionaryCreate(rawKeys.data(), rawValues.data(), rawKeys.size())); |
1871 | WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr); |
1872 | } |
1873 | |
1874 | void TestRunner::setStatisticsTimeToLiveUserInteraction(double seconds) |
1875 | { |
1876 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("SetStatisticsTimeToLiveUserInteraction" )); |
1877 | WKRetainPtr<WKDoubleRef> messageBody = adoptWK(WKDoubleCreate(seconds)); |
1878 | WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr); |
1879 | } |
1880 | |
1881 | void TestRunner::installStatisticsDidModifyDataRecordsCallback(JSValueRef callback) |
1882 | { |
1883 | cacheTestRunnerCallback(StatisticsDidModifyDataRecordsCallbackID, callback); |
1884 | } |
1885 | |
1886 | void TestRunner::statisticsDidModifyDataRecordsCallback() |
1887 | { |
1888 | callTestRunnerCallback(StatisticsDidModifyDataRecordsCallbackID); |
1889 | } |
1890 | |
1891 | void TestRunner::installStatisticsDidScanDataRecordsCallback(JSValueRef callback) |
1892 | { |
1893 | cacheTestRunnerCallback(StatisticsDidScanDataRecordsCallbackID, callback); |
1894 | |
1895 | bool notifyPagesWhenDataRecordsWereScanned = !!callback; |
1896 | |
1897 | // Setting a callback implies we expect to receive callbacks. So register for them. |
1898 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("StatisticsNotifyPagesWhenDataRecordsWereScanned" )); |
1899 | WKRetainPtr<WKBooleanRef> messageBody = adoptWK(WKBooleanCreate(notifyPagesWhenDataRecordsWereScanned)); |
1900 | WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr); |
1901 | } |
1902 | |
1903 | void TestRunner::statisticsDidScanDataRecordsCallback() |
1904 | { |
1905 | callTestRunnerCallback(StatisticsDidScanDataRecordsCallbackID); |
1906 | } |
1907 | |
1908 | void TestRunner::installStatisticsDidRunTelemetryCallback(JSValueRef callback) |
1909 | { |
1910 | cacheTestRunnerCallback(StatisticsDidRunTelemetryCallbackID, callback); |
1911 | } |
1912 | |
1913 | void TestRunner::statisticsDidRunTelemetryCallback(unsigned totalPrevalentResources, unsigned totalPrevalentResourcesWithUserInteraction, unsigned top3SubframeUnderTopFrameOrigins) |
1914 | { |
1915 | WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(InjectedBundle::singleton().page()->page()); |
1916 | JSContextRef context = WKBundleFrameGetJavaScriptContext(mainFrame); |
1917 | |
1918 | StringBuilder stringBuilder; |
1919 | stringBuilder.appendLiteral("{ \"totalPrevalentResources\" : " ); |
1920 | stringBuilder.appendNumber(totalPrevalentResources); |
1921 | stringBuilder.appendLiteral(", \"totalPrevalentResourcesWithUserInteraction\" : " ); |
1922 | stringBuilder.appendNumber(totalPrevalentResourcesWithUserInteraction); |
1923 | stringBuilder.appendLiteral(", \"top3SubframeUnderTopFrameOrigins\" : " ); |
1924 | stringBuilder.appendNumber(top3SubframeUnderTopFrameOrigins); |
1925 | stringBuilder.appendLiteral(" }" ); |
1926 | |
1927 | JSValueRef result = JSValueMakeFromJSONString(context, adopt(JSStringCreateWithUTF8CString(stringBuilder.toString().utf8().data())).get()); |
1928 | |
1929 | callTestRunnerCallback(StatisticsDidRunTelemetryCallbackID, 1, &result); |
1930 | } |
1931 | |
1932 | void TestRunner::statisticsNotifyObserver() |
1933 | { |
1934 | InjectedBundle::singleton().statisticsNotifyObserver(); |
1935 | } |
1936 | |
1937 | void TestRunner::statisticsProcessStatisticsAndDataRecords() |
1938 | { |
1939 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("StatisticsProcessStatisticsAndDataRecords" )); |
1940 | WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), nullptr, nullptr); |
1941 | } |
1942 | |
1943 | void TestRunner::statisticsUpdateCookieBlocking(JSValueRef completionHandler) |
1944 | { |
1945 | cacheTestRunnerCallback(StatisticsDidSetBlockCookiesForHostCallbackID, completionHandler); |
1946 | |
1947 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("StatisticsUpdateCookieBlocking" )); |
1948 | WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), nullptr, nullptr); |
1949 | } |
1950 | |
1951 | void TestRunner::statisticsCallDidSetBlockCookiesForHostCallback() |
1952 | { |
1953 | callTestRunnerCallback(StatisticsDidSetBlockCookiesForHostCallbackID); |
1954 | } |
1955 | |
1956 | void TestRunner::statisticsSubmitTelemetry() |
1957 | { |
1958 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("StatisticsSubmitTelemetry" )); |
1959 | WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), nullptr, nullptr); |
1960 | } |
1961 | |
1962 | void TestRunner::setStatisticsNotifyPagesWhenDataRecordsWereScanned(bool value) |
1963 | { |
1964 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("StatisticsNotifyPagesWhenDataRecordsWereScanned" )); |
1965 | WKRetainPtr<WKBooleanRef> messageBody = adoptWK(WKBooleanCreate(value)); |
1966 | WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr); |
1967 | } |
1968 | |
1969 | void TestRunner::setStatisticsIsRunningTest(bool value) |
1970 | { |
1971 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("StatisticsSetIsRunningTest" )); |
1972 | WKRetainPtr<WKBooleanRef> messageBody = adoptWK(WKBooleanCreate(value)); |
1973 | WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr); |
1974 | } |
1975 | |
1976 | void TestRunner::setStatisticsShouldClassifyResourcesBeforeDataRecordsRemoval(bool value) |
1977 | { |
1978 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("StatisticsShouldClassifyResourcesBeforeDataRecordsRemoval" )); |
1979 | WKRetainPtr<WKBooleanRef> messageBody = adoptWK(WKBooleanCreate(value)); |
1980 | WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr); |
1981 | } |
1982 | |
1983 | void TestRunner::setStatisticsNotifyPagesWhenTelemetryWasCaptured(bool value) |
1984 | { |
1985 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("StatisticsNotifyPagesWhenTelemetryWasCaptured" )); |
1986 | WKRetainPtr<WKBooleanRef> messageBody = adoptWK(WKBooleanCreate(value)); |
1987 | WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr); |
1988 | } |
1989 | |
1990 | void TestRunner::setStatisticsMinimumTimeBetweenDataRecordsRemoval(double seconds) |
1991 | { |
1992 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("SetStatisticsMinimumTimeBetweenDataRecordsRemoval" )); |
1993 | WKRetainPtr<WKDoubleRef> messageBody = adoptWK(WKDoubleCreate(seconds)); |
1994 | WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr); |
1995 | } |
1996 | |
1997 | void TestRunner::setStatisticsGrandfatheringTime(double seconds) |
1998 | { |
1999 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("SetStatisticsGrandfatheringTime" )); |
2000 | WKRetainPtr<WKDoubleRef> messageBody = adoptWK(WKDoubleCreate(seconds)); |
2001 | WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr); |
2002 | } |
2003 | |
2004 | void TestRunner::setStatisticsMaxStatisticsEntries(unsigned entries) |
2005 | { |
2006 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("SetMaxStatisticsEntries" )); |
2007 | WKRetainPtr<WKTypeRef> messageBody = adoptWK(WKUInt64Create(entries)); |
2008 | WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr); |
2009 | } |
2010 | |
2011 | void TestRunner::setStatisticsPruneEntriesDownTo(unsigned entries) |
2012 | { |
2013 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("SetPruneEntriesDownTo" )); |
2014 | WKRetainPtr<WKTypeRef> messageBody = adoptWK(WKUInt64Create(entries)); |
2015 | WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr); |
2016 | } |
2017 | |
2018 | void TestRunner::statisticsClearInMemoryAndPersistentStore(JSValueRef callback) |
2019 | { |
2020 | cacheTestRunnerCallback(StatisticsDidClearThroughWebsiteDataRemovalCallbackID, callback); |
2021 | |
2022 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("StatisticsClearInMemoryAndPersistentStore" )); |
2023 | WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), nullptr, nullptr); |
2024 | } |
2025 | |
2026 | void TestRunner::statisticsClearInMemoryAndPersistentStoreModifiedSinceHours(unsigned hours, JSValueRef callback) |
2027 | { |
2028 | cacheTestRunnerCallback(StatisticsDidClearThroughWebsiteDataRemovalCallbackID, callback); |
2029 | |
2030 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("StatisticsClearInMemoryAndPersistentStoreModifiedSinceHours" )); |
2031 | WKRetainPtr<WKTypeRef> messageBody = adoptWK(WKUInt64Create(hours)); |
2032 | WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr); |
2033 | } |
2034 | |
2035 | void TestRunner::statisticsClearThroughWebsiteDataRemoval(JSValueRef callback) |
2036 | { |
2037 | cacheTestRunnerCallback(StatisticsDidClearThroughWebsiteDataRemovalCallbackID, callback); |
2038 | |
2039 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("StatisticsClearThroughWebsiteDataRemoval" )); |
2040 | WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), nullptr, nullptr); |
2041 | } |
2042 | |
2043 | void TestRunner::statisticsDeleteCookiesForHost(JSStringRef hostName, bool includeHttpOnlyCookies) |
2044 | { |
2045 | Vector<WKRetainPtr<WKStringRef>> keys; |
2046 | Vector<WKRetainPtr<WKTypeRef>> values; |
2047 | |
2048 | keys.append(adoptWK(WKStringCreateWithUTF8CString("HostName" ))); |
2049 | values.append(adoptWK(WKStringCreateWithJSString(hostName))); |
2050 | |
2051 | keys.append(adoptWK(WKStringCreateWithUTF8CString("IncludeHttpOnlyCookies" ))); |
2052 | values.append(adoptWK(WKBooleanCreate(includeHttpOnlyCookies))); |
2053 | |
2054 | Vector<WKStringRef> rawKeys; |
2055 | Vector<WKTypeRef> rawValues; |
2056 | rawKeys.resize(keys.size()); |
2057 | rawValues.resize(values.size()); |
2058 | |
2059 | for (size_t i = 0; i < keys.size(); ++i) { |
2060 | rawKeys[i] = keys[i].get(); |
2061 | rawValues[i] = values[i].get(); |
2062 | } |
2063 | |
2064 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("StatisticsDeleteCookiesForHost" )); |
2065 | WKRetainPtr<WKDictionaryRef> messageBody = adoptWK(WKDictionaryCreate(rawKeys.data(), rawValues.data(), rawKeys.size())); |
2066 | WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr); |
2067 | } |
2068 | |
2069 | bool TestRunner::isStatisticsHasLocalStorage(JSStringRef hostName) |
2070 | { |
2071 | auto messageName = adoptWK(WKStringCreateWithUTF8CString("IsStatisticsHasLocalStorage" )); |
2072 | auto messageBody = adoptWK(WKStringCreateWithJSString(hostName)); |
2073 | WKTypeRef returnData = nullptr; |
2074 | WKBundlePagePostSynchronousMessageForTesting(InjectedBundle::singleton().page()->page(), messageName.get(), messageBody.get(), &returnData); |
2075 | ASSERT(WKGetTypeID(returnData) == WKBooleanGetTypeID()); |
2076 | return WKBooleanGetValue(adoptWK(static_cast<WKBooleanRef>(returnData)).get()); |
2077 | } |
2078 | |
2079 | void TestRunner::setStatisticsCacheMaxAgeCap(double seconds) |
2080 | { |
2081 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("SetStatisticsCacheMaxAgeCap" )); |
2082 | WKRetainPtr<WKDoubleRef> messageBody = adoptWK(WKDoubleCreate(seconds)); |
2083 | WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr); |
2084 | } |
2085 | |
2086 | void TestRunner::statisticsCallClearThroughWebsiteDataRemovalCallback() |
2087 | { |
2088 | callTestRunnerCallback(StatisticsDidClearThroughWebsiteDataRemovalCallbackID); |
2089 | } |
2090 | |
2091 | void TestRunner::statisticsResetToConsistentState(JSValueRef completionHandler) |
2092 | { |
2093 | cacheTestRunnerCallback(StatisticsDidResetToConsistentStateCallbackID, completionHandler); |
2094 | |
2095 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("StatisticsResetToConsistentState" )); |
2096 | WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), nullptr, nullptr); |
2097 | } |
2098 | |
2099 | void TestRunner::statisticsCallDidResetToConsistentStateCallback() |
2100 | { |
2101 | callTestRunnerCallback(StatisticsDidResetToConsistentStateCallbackID); |
2102 | } |
2103 | |
2104 | void TestRunner::installTextDidChangeInTextFieldCallback(JSValueRef callback) |
2105 | { |
2106 | cacheTestRunnerCallback(TextDidChangeInTextFieldCallbackID, callback); |
2107 | } |
2108 | |
2109 | void TestRunner::textDidChangeInTextFieldCallback() |
2110 | { |
2111 | callTestRunnerCallback(TextDidChangeInTextFieldCallbackID); |
2112 | } |
2113 | |
2114 | void TestRunner::installTextFieldDidBeginEditingCallback(JSValueRef callback) |
2115 | { |
2116 | cacheTestRunnerCallback(TextFieldDidBeginEditingCallbackID, callback); |
2117 | } |
2118 | |
2119 | void TestRunner::textFieldDidBeginEditingCallback() |
2120 | { |
2121 | callTestRunnerCallback(TextFieldDidBeginEditingCallbackID); |
2122 | } |
2123 | |
2124 | void TestRunner::installTextFieldDidEndEditingCallback(JSValueRef callback) |
2125 | { |
2126 | cacheTestRunnerCallback(TextFieldDidEndEditingCallbackID, callback); |
2127 | } |
2128 | |
2129 | void TestRunner::textFieldDidEndEditingCallback() |
2130 | { |
2131 | callTestRunnerCallback(TextFieldDidEndEditingCallbackID); |
2132 | } |
2133 | |
2134 | void TestRunner::setStorageAccessAPIEnabled(bool enabled) |
2135 | { |
2136 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("SetStorageAccessAPIEnabled" )); |
2137 | |
2138 | WKRetainPtr<WKBooleanRef> messageBody = adoptWK(WKBooleanCreate(enabled)); |
2139 | |
2140 | WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr); |
2141 | } |
2142 | |
2143 | void TestRunner::getAllStorageAccessEntries(JSValueRef callback) |
2144 | { |
2145 | cacheTestRunnerCallback(AllStorageAccessEntriesCallbackID, callback); |
2146 | |
2147 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("GetAllStorageAccessEntries" )); |
2148 | WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), nullptr, nullptr); |
2149 | } |
2150 | |
2151 | void TestRunner::callDidReceiveAllStorageAccessEntriesCallback(Vector<String>& domains) |
2152 | { |
2153 | WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(InjectedBundle::singleton().page()->page()); |
2154 | JSContextRef context = WKBundleFrameGetJavaScriptContext(mainFrame); |
2155 | |
2156 | StringBuilder stringBuilder; |
2157 | stringBuilder.appendLiteral("[" ); |
2158 | bool firstDomain = true; |
2159 | for (auto& domain : domains) { |
2160 | if (firstDomain) |
2161 | firstDomain = false; |
2162 | else |
2163 | stringBuilder.appendLiteral(", " ); |
2164 | stringBuilder.appendLiteral("\"" ); |
2165 | stringBuilder.append(domain); |
2166 | stringBuilder.appendLiteral("\"" ); |
2167 | } |
2168 | stringBuilder.appendLiteral("]" ); |
2169 | |
2170 | JSValueRef result = JSValueMakeFromJSONString(context, adopt(JSStringCreateWithUTF8CString(stringBuilder.toString().utf8().data())).get()); |
2171 | |
2172 | callTestRunnerCallback(AllStorageAccessEntriesCallbackID, 1, &result); |
2173 | } |
2174 | |
2175 | void TestRunner::addMockMediaDevice(JSStringRef persistentId, JSStringRef label, const char* type) |
2176 | { |
2177 | Vector<WKRetainPtr<WKStringRef>> keys; |
2178 | Vector<WKRetainPtr<WKTypeRef>> values; |
2179 | |
2180 | keys.append(adoptWK(WKStringCreateWithUTF8CString("PersistentID" ))); |
2181 | values.append(toWK(persistentId)); |
2182 | |
2183 | keys.append(adoptWK(WKStringCreateWithUTF8CString("Label" ))); |
2184 | values.append(toWK(label)); |
2185 | |
2186 | keys.append(adoptWK(WKStringCreateWithUTF8CString("Type" ))); |
2187 | values.append(adoptWK(WKStringCreateWithUTF8CString(type))); |
2188 | |
2189 | Vector<WKStringRef> rawKeys; |
2190 | Vector<WKTypeRef> rawValues; |
2191 | rawKeys.resize(keys.size()); |
2192 | rawValues.resize(values.size()); |
2193 | |
2194 | for (size_t i = 0; i < keys.size(); ++i) { |
2195 | rawKeys[i] = keys[i].get(); |
2196 | rawValues[i] = values[i].get(); |
2197 | } |
2198 | |
2199 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("AddMockMediaDevice" )); |
2200 | WKRetainPtr<WKDictionaryRef> messageBody = adoptWK(WKDictionaryCreate(rawKeys.data(), rawValues.data(), rawKeys.size())); |
2201 | |
2202 | WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr); |
2203 | } |
2204 | |
2205 | void TestRunner::addMockCameraDevice(JSStringRef persistentId, JSStringRef label) |
2206 | { |
2207 | addMockMediaDevice(persistentId, label, "camera" ); |
2208 | } |
2209 | |
2210 | void TestRunner::addMockMicrophoneDevice(JSStringRef persistentId, JSStringRef label) |
2211 | { |
2212 | addMockMediaDevice(persistentId, label, "microphone" ); |
2213 | } |
2214 | |
2215 | void TestRunner::addMockScreenDevice(JSStringRef persistentId, JSStringRef label) |
2216 | { |
2217 | addMockMediaDevice(persistentId, label, "screen" ); |
2218 | } |
2219 | |
2220 | void TestRunner::clearMockMediaDevices() |
2221 | { |
2222 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("ClearMockMediaDevices" )); |
2223 | WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), nullptr, nullptr); |
2224 | } |
2225 | |
2226 | void TestRunner::removeMockMediaDevice(JSStringRef persistentId) |
2227 | { |
2228 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("RemoveMockMediaDevice" )); |
2229 | WKRetainPtr<WKTypeRef> messageBody(toWK(persistentId)); |
2230 | |
2231 | WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr); |
2232 | } |
2233 | |
2234 | void TestRunner::resetMockMediaDevices() |
2235 | { |
2236 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("ResetMockMediaDevices" )); |
2237 | WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), nullptr, nullptr); |
2238 | } |
2239 | |
2240 | #if PLATFORM(MAC) |
2241 | void TestRunner::connectMockGamepad(unsigned index) |
2242 | { |
2243 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("ConnectMockGamepad" )); |
2244 | WKRetainPtr<WKTypeRef> messageBody = adoptWK(WKUInt64Create(index)); |
2245 | |
2246 | WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr); |
2247 | } |
2248 | |
2249 | void TestRunner::disconnectMockGamepad(unsigned index) |
2250 | { |
2251 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("DisconnectMockGamepad" )); |
2252 | WKRetainPtr<WKTypeRef> messageBody = adoptWK(WKUInt64Create(index)); |
2253 | |
2254 | WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr); |
2255 | } |
2256 | |
2257 | void TestRunner::setMockGamepadDetails(unsigned index, JSStringRef gamepadID, unsigned axisCount, unsigned buttonCount) |
2258 | { |
2259 | Vector<WKRetainPtr<WKStringRef>> keys; |
2260 | Vector<WKRetainPtr<WKTypeRef>> values; |
2261 | |
2262 | keys.append(adoptWK(WKStringCreateWithUTF8CString("GamepadID" ))); |
2263 | values.append(toWK(gamepadID)); |
2264 | |
2265 | keys.append(adoptWK(WKStringCreateWithUTF8CString("GamepadIndex" ))); |
2266 | values.append(adoptWK(WKUInt64Create(index))); |
2267 | |
2268 | keys.append(adoptWK(WKStringCreateWithUTF8CString("AxisCount" ))); |
2269 | values.append(adoptWK(WKUInt64Create(axisCount))); |
2270 | |
2271 | keys.append(adoptWK(WKStringCreateWithUTF8CString("ButtonCount" ))); |
2272 | values.append(adoptWK(WKUInt64Create(buttonCount))); |
2273 | |
2274 | Vector<WKStringRef> rawKeys; |
2275 | Vector<WKTypeRef> rawValues; |
2276 | rawKeys.resize(keys.size()); |
2277 | rawValues.resize(values.size()); |
2278 | |
2279 | for (size_t i = 0; i < keys.size(); ++i) { |
2280 | rawKeys[i] = keys[i].get(); |
2281 | rawValues[i] = values[i].get(); |
2282 | } |
2283 | |
2284 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("SetMockGamepadDetails" )); |
2285 | WKRetainPtr<WKDictionaryRef> messageBody = adoptWK(WKDictionaryCreate(rawKeys.data(), rawValues.data(), rawKeys.size())); |
2286 | |
2287 | WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr); |
2288 | } |
2289 | |
2290 | void TestRunner::setMockGamepadAxisValue(unsigned index, unsigned axisIndex, double value) |
2291 | { |
2292 | Vector<WKRetainPtr<WKStringRef>> keys; |
2293 | Vector<WKRetainPtr<WKTypeRef>> values; |
2294 | |
2295 | keys.append(adoptWK(WKStringCreateWithUTF8CString("GamepadIndex" ))); |
2296 | values.append(adoptWK(WKUInt64Create(index))); |
2297 | |
2298 | keys.append(adoptWK(WKStringCreateWithUTF8CString("AxisIndex" ))); |
2299 | values.append(adoptWK(WKUInt64Create(axisIndex))); |
2300 | |
2301 | keys.append(adoptWK(WKStringCreateWithUTF8CString("Value" ))); |
2302 | values.append(adoptWK(WKDoubleCreate(value))); |
2303 | |
2304 | Vector<WKStringRef> rawKeys; |
2305 | Vector<WKTypeRef> rawValues; |
2306 | rawKeys.resize(keys.size()); |
2307 | rawValues.resize(values.size()); |
2308 | |
2309 | for (size_t i = 0; i < keys.size(); ++i) { |
2310 | rawKeys[i] = keys[i].get(); |
2311 | rawValues[i] = values[i].get(); |
2312 | } |
2313 | |
2314 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("SetMockGamepadAxisValue" )); |
2315 | WKRetainPtr<WKDictionaryRef> messageBody = adoptWK(WKDictionaryCreate(rawKeys.data(), rawValues.data(), rawKeys.size())); |
2316 | |
2317 | WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr); |
2318 | } |
2319 | |
2320 | void TestRunner::setMockGamepadButtonValue(unsigned index, unsigned buttonIndex, double value) |
2321 | { |
2322 | Vector<WKRetainPtr<WKStringRef>> keys; |
2323 | Vector<WKRetainPtr<WKTypeRef>> values; |
2324 | |
2325 | keys.append(adoptWK(WKStringCreateWithUTF8CString("GamepadIndex" ))); |
2326 | values.append(adoptWK(WKUInt64Create(index))); |
2327 | |
2328 | keys.append(adoptWK(WKStringCreateWithUTF8CString("ButtonIndex" ))); |
2329 | values.append(adoptWK(WKUInt64Create(buttonIndex))); |
2330 | |
2331 | keys.append(adoptWK(WKStringCreateWithUTF8CString("Value" ))); |
2332 | values.append(adoptWK(WKDoubleCreate(value))); |
2333 | |
2334 | Vector<WKStringRef> rawKeys; |
2335 | Vector<WKTypeRef> rawValues; |
2336 | rawKeys.resize(keys.size()); |
2337 | rawValues.resize(values.size()); |
2338 | |
2339 | for (size_t i = 0; i < keys.size(); ++i) { |
2340 | rawKeys[i] = keys[i].get(); |
2341 | rawValues[i] = values[i].get(); |
2342 | } |
2343 | |
2344 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("SetMockGamepadButtonValue" )); |
2345 | WKRetainPtr<WKDictionaryRef> messageBody = adoptWK(WKDictionaryCreate(rawKeys.data(), rawValues.data(), rawKeys.size())); |
2346 | |
2347 | WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr); |
2348 | } |
2349 | #else |
2350 | void TestRunner::connectMockGamepad(unsigned) |
2351 | { |
2352 | } |
2353 | |
2354 | void TestRunner::disconnectMockGamepad(unsigned) |
2355 | { |
2356 | } |
2357 | |
2358 | void TestRunner::setMockGamepadDetails(unsigned, JSStringRef, unsigned, unsigned) |
2359 | { |
2360 | } |
2361 | |
2362 | void TestRunner::setMockGamepadAxisValue(unsigned, unsigned, double) |
2363 | { |
2364 | } |
2365 | |
2366 | void TestRunner::setMockGamepadButtonValue(unsigned, unsigned, double) |
2367 | { |
2368 | } |
2369 | #endif // PLATFORM(MAC) |
2370 | |
2371 | void TestRunner::setOpenPanelFiles(JSValueRef filesValue) |
2372 | { |
2373 | WKBundlePageRef page = InjectedBundle::singleton().page()->page(); |
2374 | JSContextRef context = WKBundleFrameGetJavaScriptContext(WKBundlePageGetMainFrame(page)); |
2375 | |
2376 | if (!JSValueIsArray(context, filesValue)) |
2377 | return; |
2378 | |
2379 | JSObjectRef files = JSValueToObject(context, filesValue, nullptr); |
2380 | static auto lengthProperty = adopt(JSStringCreateWithUTF8CString("length" )); |
2381 | JSValueRef filesLengthValue = JSObjectGetProperty(context, files, lengthProperty.get(), nullptr); |
2382 | if (!JSValueIsNumber(context, filesLengthValue)) |
2383 | return; |
2384 | |
2385 | auto fileURLs = adoptWK(WKMutableArrayCreate()); |
2386 | auto filesLength = static_cast<size_t>(JSValueToNumber(context, filesLengthValue, nullptr)); |
2387 | for (size_t i = 0; i < filesLength; ++i) { |
2388 | JSValueRef fileValue = JSObjectGetPropertyAtIndex(context, files, i, nullptr); |
2389 | if (!JSValueIsString(context, fileValue)) |
2390 | continue; |
2391 | |
2392 | auto file = adopt(JSValueToStringCopy(context, fileValue, nullptr)); |
2393 | size_t fileBufferSize = JSStringGetMaximumUTF8CStringSize(file.get()) + 1; |
2394 | auto fileBuffer = std::make_unique<char[]>(fileBufferSize); |
2395 | JSStringGetUTF8CString(file.get(), fileBuffer.get(), fileBufferSize); |
2396 | |
2397 | WKArrayAppendItem(fileURLs.get(), adoptWK(WKURLCreateWithBaseURL(m_testURL.get(), fileBuffer.get())).get()); |
2398 | } |
2399 | |
2400 | static auto messageName = adoptWK(WKStringCreateWithUTF8CString("SetOpenPanelFileURLs" )); |
2401 | WKBundlePagePostMessage(page, messageName.get(), fileURLs.get()); |
2402 | } |
2403 | |
2404 | #if PLATFORM(IOS_FAMILY) |
2405 | void TestRunner::setOpenPanelFilesMediaIcon(JSValueRef data) |
2406 | { |
2407 | WKBundlePageRef page = InjectedBundle::singleton().page()->page(); |
2408 | JSContextRef context = WKBundleFrameGetJavaScriptContext(WKBundlePageGetMainFrame(page)); |
2409 | |
2410 | auto& injectedBundle = InjectedBundle::singleton(); |
2411 | // FIXME (123058): Use a JSC API to get buffer contents once such is exposed. |
2412 | WKRetainPtr<WKDataRef> iconData = adoptWK(WKBundleCreateWKDataFromUInt8Array(injectedBundle.bundle(), context, data)); |
2413 | |
2414 | static auto messageName = adoptWK(WKStringCreateWithUTF8CString("SetOpenPanelFileURLsMediaIcon" )); |
2415 | WKBundlePagePostMessage(page, messageName.get(), iconData.get()); |
2416 | } |
2417 | #else |
2418 | void TestRunner::setOpenPanelFilesMediaIcon(JSValueRef) |
2419 | { |
2420 | } |
2421 | #endif // PLATFORM(IOS_FAMILY) |
2422 | |
2423 | void TestRunner::removeAllSessionCredentials(JSValueRef callback) |
2424 | { |
2425 | cacheTestRunnerCallback(DidRemoveAllSessionCredentialsCallbackID, callback); |
2426 | |
2427 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("RemoveAllSessionCredentials" )); |
2428 | WKRetainPtr<WKBooleanRef> messageBody = adoptWK(WKBooleanCreate(true)); |
2429 | |
2430 | WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr); |
2431 | } |
2432 | |
2433 | void TestRunner::callDidRemoveAllSessionCredentialsCallback() |
2434 | { |
2435 | callTestRunnerCallback(DidRemoveAllSessionCredentialsCallbackID); |
2436 | } |
2437 | |
2438 | void TestRunner::clearDOMCache(JSStringRef origin) |
2439 | { |
2440 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("ClearDOMCache" )); |
2441 | WKRetainPtr<WKStringRef> messageBody = adoptWK(WKStringCreateWithJSString(origin)); |
2442 | WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr); |
2443 | } |
2444 | |
2445 | void TestRunner::clearDOMCaches() |
2446 | { |
2447 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("ClearDOMCaches" )); |
2448 | WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), nullptr, nullptr); |
2449 | } |
2450 | |
2451 | bool TestRunner::hasDOMCache(JSStringRef origin) |
2452 | { |
2453 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("HasDOMCache" )); |
2454 | WKRetainPtr<WKStringRef> messageBody = adoptWK(WKStringCreateWithJSString(origin)); |
2455 | WKTypeRef returnData = nullptr; |
2456 | WKBundlePagePostSynchronousMessageForTesting(InjectedBundle::singleton().page()->page(), messageName.get(), messageBody.get(), &returnData); |
2457 | ASSERT(WKGetTypeID(returnData) == WKBooleanGetTypeID()); |
2458 | return WKBooleanGetValue(adoptWK(static_cast<WKBooleanRef>(returnData)).get()); |
2459 | } |
2460 | |
2461 | uint64_t TestRunner::domCacheSize(JSStringRef origin) |
2462 | { |
2463 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("DOMCacheSize" )); |
2464 | WKRetainPtr<WKStringRef> messageBody = adoptWK(WKStringCreateWithJSString(origin)); |
2465 | WKTypeRef returnData = nullptr; |
2466 | WKBundlePagePostSynchronousMessageForTesting(InjectedBundle::singleton().page()->page(), messageName.get(), messageBody.get(), &returnData); |
2467 | return WKUInt64GetValue(static_cast<WKUInt64Ref>(returnData)); |
2468 | } |
2469 | |
2470 | void TestRunner::setAllowStorageQuotaIncrease(bool willIncrease) |
2471 | { |
2472 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("SetAllowStorageQuotaIncrease" )); |
2473 | WKRetainPtr<WKBooleanRef> messageBody = adoptWK(WKBooleanCreate(willIncrease)); |
2474 | WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr); |
2475 | } |
2476 | |
2477 | void TestRunner::getApplicationManifestThen(JSValueRef callback) |
2478 | { |
2479 | cacheTestRunnerCallback(GetApplicationManifestCallbackID, callback); |
2480 | |
2481 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("GetApplicationManifest" )); |
2482 | WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), nullptr, nullptr); |
2483 | } |
2484 | |
2485 | void TestRunner::didGetApplicationManifest() |
2486 | { |
2487 | callTestRunnerCallback(GetApplicationManifestCallbackID); |
2488 | } |
2489 | |
2490 | void TestRunner::() |
2491 | { |
2492 | callTestRunnerCallback(CustomMenuActionCallbackID); |
2493 | } |
2494 | |
2495 | size_t TestRunner::userScriptInjectedCount() const |
2496 | { |
2497 | return InjectedBundle::singleton().userScriptInjectedCount(); |
2498 | } |
2499 | |
2500 | void TestRunner::injectUserScript(JSStringRef script) |
2501 | { |
2502 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("InjectUserScript" )); |
2503 | WKRetainPtr<WKStringRef> messageBody = adoptWK(WKStringCreateWithJSString(script)); |
2504 | WKBundlePagePostSynchronousMessageForTesting(InjectedBundle::singleton().page()->page(), messageName.get(), messageBody.get(), nullptr); |
2505 | } |
2506 | |
2507 | void TestRunner::sendDisplayConfigurationChangedMessageForTesting() |
2508 | { |
2509 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("SendDisplayConfigurationChangedMessageForTesting" )); |
2510 | WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), nullptr, nullptr); |
2511 | } |
2512 | |
2513 | // WebAuthN |
2514 | void TestRunner::setWebAuthenticationMockConfiguration(JSValueRef configurationValue) |
2515 | { |
2516 | auto& injectedBundle = InjectedBundle::singleton(); |
2517 | WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(injectedBundle.page()->page()); |
2518 | JSContextRef context = WKBundleFrameGetJavaScriptContext(mainFrame); |
2519 | if (!JSValueIsObject(context, configurationValue)) |
2520 | return; |
2521 | JSObjectRef configuration = JSValueToObject(context, configurationValue, 0); |
2522 | |
2523 | Vector<WKRetainPtr<WKStringRef>> configurationKeys; |
2524 | Vector<WKRetainPtr<WKTypeRef>> configurationValues; |
2525 | |
2526 | JSRetainPtr<JSStringRef> silentFailurePropertyName(Adopt, JSStringCreateWithUTF8CString("silentFailure" )); |
2527 | JSValueRef silentFailureValue = JSObjectGetProperty(context, configuration, silentFailurePropertyName.get(), 0); |
2528 | if (!JSValueIsUndefined(context, silentFailureValue)) { |
2529 | if (!JSValueIsBoolean(context, silentFailureValue)) |
2530 | return; |
2531 | bool silentFailure = JSValueToBoolean(context, silentFailureValue); |
2532 | configurationKeys.append(adoptWK(WKStringCreateWithUTF8CString("SilentFailure" ))); |
2533 | configurationValues.append(adoptWK(WKBooleanCreate(silentFailure)).get()); |
2534 | } |
2535 | |
2536 | JSRetainPtr<JSStringRef> localPropertyName(Adopt, JSStringCreateWithUTF8CString("local" )); |
2537 | JSValueRef localValue = JSObjectGetProperty(context, configuration, localPropertyName.get(), 0); |
2538 | if (!JSValueIsUndefined(context, localValue) && !JSValueIsNull(context, localValue)) { |
2539 | if (!JSValueIsObject(context, localValue)) |
2540 | return; |
2541 | JSObjectRef local = JSValueToObject(context, localValue, 0); |
2542 | |
2543 | JSRetainPtr<JSStringRef> acceptAuthenticationPropertyName(Adopt, JSStringCreateWithUTF8CString("acceptAuthentication" )); |
2544 | JSValueRef acceptAuthenticationValue = JSObjectGetProperty(context, local, acceptAuthenticationPropertyName.get(), 0); |
2545 | if (!JSValueIsBoolean(context, acceptAuthenticationValue)) |
2546 | return; |
2547 | bool acceptAuthentication = JSValueToBoolean(context, acceptAuthenticationValue); |
2548 | |
2549 | JSRetainPtr<JSStringRef> acceptAttestationPropertyName(Adopt, JSStringCreateWithUTF8CString("acceptAttestation" )); |
2550 | JSValueRef acceptAttestationValue = JSObjectGetProperty(context, local, acceptAttestationPropertyName.get(), 0); |
2551 | if (!JSValueIsBoolean(context, acceptAttestationValue)) |
2552 | return; |
2553 | bool acceptAttestation = JSValueToBoolean(context, acceptAttestationValue); |
2554 | |
2555 | Vector<WKRetainPtr<WKStringRef>> localKeys; |
2556 | Vector<WKRetainPtr<WKTypeRef>> localValues; |
2557 | localKeys.append(adoptWK(WKStringCreateWithUTF8CString("AcceptAuthentication" ))); |
2558 | localValues.append(adoptWK(WKBooleanCreate(acceptAuthentication)).get()); |
2559 | localKeys.append(adoptWK(WKStringCreateWithUTF8CString("AcceptAttestation" ))); |
2560 | localValues.append(adoptWK(WKBooleanCreate(acceptAttestation)).get()); |
2561 | |
2562 | if (acceptAttestation) { |
2563 | JSRetainPtr<JSStringRef> privateKeyBase64PropertyName(Adopt, JSStringCreateWithUTF8CString("privateKeyBase64" )); |
2564 | JSValueRef privateKeyBase64Value = JSObjectGetProperty(context, local, privateKeyBase64PropertyName.get(), 0); |
2565 | if (!JSValueIsString(context, privateKeyBase64Value)) |
2566 | return; |
2567 | |
2568 | JSRetainPtr<JSStringRef> userCertificateBase64PropertyName(Adopt, JSStringCreateWithUTF8CString("userCertificateBase64" )); |
2569 | JSValueRef userCertificateBase64Value = JSObjectGetProperty(context, local, userCertificateBase64PropertyName.get(), 0); |
2570 | if (!JSValueIsString(context, userCertificateBase64Value)) |
2571 | return; |
2572 | |
2573 | JSRetainPtr<JSStringRef> intermediateCACertificateBase64PropertyName(Adopt, JSStringCreateWithUTF8CString("intermediateCACertificateBase64" )); |
2574 | JSValueRef intermediateCACertificateBase64Value = JSObjectGetProperty(context, local, intermediateCACertificateBase64PropertyName.get(), 0); |
2575 | if (!JSValueIsString(context, intermediateCACertificateBase64Value)) |
2576 | return; |
2577 | |
2578 | localKeys.append(adoptWK(WKStringCreateWithUTF8CString("PrivateKeyBase64" ))); |
2579 | localValues.append(toWK(adopt(JSValueToStringCopy(context, privateKeyBase64Value, 0)).get())); |
2580 | localKeys.append(adoptWK(WKStringCreateWithUTF8CString("UserCertificateBase64" ))); |
2581 | localValues.append(toWK(adopt(JSValueToStringCopy(context, userCertificateBase64Value, 0)).get())); |
2582 | localKeys.append(adoptWK(WKStringCreateWithUTF8CString("IntermediateCACertificateBase64" ))); |
2583 | localValues.append(toWK(adopt(JSValueToStringCopy(context, intermediateCACertificateBase64Value, 0)).get())); |
2584 | } |
2585 | |
2586 | Vector<WKStringRef> rawLocalKeys; |
2587 | Vector<WKTypeRef> rawLocalValues; |
2588 | rawLocalKeys.resize(localKeys.size()); |
2589 | rawLocalValues.resize(localValues.size()); |
2590 | for (size_t i = 0; i < localKeys.size(); ++i) { |
2591 | rawLocalKeys[i] = localKeys[i].get(); |
2592 | rawLocalValues[i] = localValues[i].get(); |
2593 | } |
2594 | |
2595 | configurationKeys.append(adoptWK(WKStringCreateWithUTF8CString("Local" ))); |
2596 | configurationValues.append(adoptWK(WKDictionaryCreate(rawLocalKeys.data(), rawLocalValues.data(), rawLocalKeys.size()))); |
2597 | } |
2598 | |
2599 | JSRetainPtr<JSStringRef> hidPropertyName(Adopt, JSStringCreateWithUTF8CString("hid" )); |
2600 | JSValueRef hidValue = JSObjectGetProperty(context, configuration, hidPropertyName.get(), 0); |
2601 | if (!JSValueIsUndefined(context, hidValue) && !JSValueIsNull(context, hidValue)) { |
2602 | if (!JSValueIsObject(context, hidValue)) |
2603 | return; |
2604 | JSObjectRef hid = JSValueToObject(context, hidValue, 0); |
2605 | |
2606 | JSRetainPtr<JSStringRef> stagePropertyName(Adopt, JSStringCreateWithUTF8CString("stage" )); |
2607 | JSValueRef stageValue = JSObjectGetProperty(context, hid, stagePropertyName.get(), 0); |
2608 | if (!JSValueIsString(context, stageValue)) |
2609 | return; |
2610 | |
2611 | JSRetainPtr<JSStringRef> subStagePropertyName(Adopt, JSStringCreateWithUTF8CString("subStage" )); |
2612 | JSValueRef subStageValue = JSObjectGetProperty(context, hid, subStagePropertyName.get(), 0); |
2613 | if (!JSValueIsString(context, subStageValue)) |
2614 | return; |
2615 | |
2616 | JSRetainPtr<JSStringRef> errorPropertyName(Adopt, JSStringCreateWithUTF8CString("error" )); |
2617 | JSValueRef errorValue = JSObjectGetProperty(context, hid, errorPropertyName.get(), 0); |
2618 | if (!JSValueIsString(context, errorValue)) |
2619 | return; |
2620 | |
2621 | Vector<WKRetainPtr<WKStringRef>> hidKeys; |
2622 | Vector<WKRetainPtr<WKTypeRef>> hidValues; |
2623 | hidKeys.append(adoptWK(WKStringCreateWithUTF8CString("Stage" ))); |
2624 | hidValues.append(toWK(adopt(JSValueToStringCopy(context, stageValue, 0)).get())); |
2625 | hidKeys.append(adoptWK(WKStringCreateWithUTF8CString("SubStage" ))); |
2626 | hidValues.append(toWK(adopt(JSValueToStringCopy(context, subStageValue, 0)).get())); |
2627 | hidKeys.append(adoptWK(WKStringCreateWithUTF8CString("Error" ))); |
2628 | hidValues.append(toWK(adopt(JSValueToStringCopy(context, errorValue, 0)).get())); |
2629 | |
2630 | JSRetainPtr<JSStringRef> payloadBase64PropertyName(Adopt, JSStringCreateWithUTF8CString("payloadBase64" )); |
2631 | JSValueRef payloadBase64Value = JSObjectGetProperty(context, hid, payloadBase64PropertyName.get(), 0); |
2632 | if (!JSValueIsUndefined(context, payloadBase64Value) && !JSValueIsNull(context, payloadBase64Value)) { |
2633 | if (!JSValueIsArray(context, payloadBase64Value)) |
2634 | return; |
2635 | |
2636 | JSObjectRef payloadBase64 = JSValueToObject(context, payloadBase64Value, nullptr); |
2637 | static auto lengthProperty = adopt(JSStringCreateWithUTF8CString("length" )); |
2638 | JSValueRef payloadBase64LengthValue = JSObjectGetProperty(context, payloadBase64, lengthProperty.get(), nullptr); |
2639 | if (!JSValueIsNumber(context, payloadBase64LengthValue)) |
2640 | return; |
2641 | |
2642 | auto payloadBase64s = adoptWK(WKMutableArrayCreate()); |
2643 | auto payloadBase64Length = static_cast<size_t>(JSValueToNumber(context, payloadBase64LengthValue, nullptr)); |
2644 | for (size_t i = 0; i < payloadBase64Length; ++i) { |
2645 | JSValueRef payloadBase64Value = JSObjectGetPropertyAtIndex(context, payloadBase64, i, nullptr); |
2646 | if (!JSValueIsString(context, payloadBase64Value)) |
2647 | continue; |
2648 | WKArrayAppendItem(payloadBase64s.get(), toWK(adopt(JSValueToStringCopy(context, payloadBase64Value, 0)).get()).get()); |
2649 | } |
2650 | |
2651 | hidKeys.append(adoptWK(WKStringCreateWithUTF8CString("PayloadBase64" ))); |
2652 | hidValues.append(payloadBase64s); |
2653 | } |
2654 | |
2655 | JSRetainPtr<JSStringRef> isU2fPropertyName(Adopt, JSStringCreateWithUTF8CString("isU2f" )); |
2656 | JSValueRef isU2fValue = JSObjectGetProperty(context, hid, isU2fPropertyName.get(), 0); |
2657 | if (!JSValueIsUndefined(context, isU2fValue) && !JSValueIsNull(context, isU2fValue)) { |
2658 | if (!JSValueIsBoolean(context, isU2fValue)) |
2659 | return; |
2660 | bool isU2f = JSValueToBoolean(context, isU2fValue); |
2661 | hidKeys.append(adoptWK(WKStringCreateWithUTF8CString("IsU2f" ))); |
2662 | hidValues.append(adoptWK(WKBooleanCreate(isU2f)).get()); |
2663 | } |
2664 | |
2665 | JSRetainPtr<JSStringRef> keepAlivePropertyName(Adopt, JSStringCreateWithUTF8CString("keepAlive" )); |
2666 | JSValueRef keepAliveValue = JSObjectGetProperty(context, hid, keepAlivePropertyName.get(), 0); |
2667 | if (!JSValueIsUndefined(context, keepAliveValue) && !JSValueIsNull(context, keepAliveValue)) { |
2668 | if (!JSValueIsBoolean(context, keepAliveValue)) |
2669 | return; |
2670 | bool keepAlive = JSValueToBoolean(context, keepAliveValue); |
2671 | hidKeys.append(adoptWK(WKStringCreateWithUTF8CString("KeepAlive" ))); |
2672 | hidValues.append(adoptWK(WKBooleanCreate(keepAlive)).get()); |
2673 | } |
2674 | |
2675 | JSRetainPtr<JSStringRef> fastDataArrivalPropertyName(Adopt, JSStringCreateWithUTF8CString("fastDataArrival" )); |
2676 | JSValueRef fastDataArrivalValue = JSObjectGetProperty(context, hid, fastDataArrivalPropertyName.get(), 0); |
2677 | if (!JSValueIsUndefined(context, fastDataArrivalValue) && !JSValueIsNull(context, fastDataArrivalValue)) { |
2678 | if (!JSValueIsBoolean(context, fastDataArrivalValue)) |
2679 | return; |
2680 | bool fastDataArrival = JSValueToBoolean(context, fastDataArrivalValue); |
2681 | hidKeys.append(adoptWK(WKStringCreateWithUTF8CString("FastDataArrival" ))); |
2682 | hidValues.append(adoptWK(WKBooleanCreate(fastDataArrival)).get()); |
2683 | } |
2684 | |
2685 | JSRetainPtr<JSStringRef> continueAfterErrorDataPropertyName(Adopt, JSStringCreateWithUTF8CString("continueAfterErrorData" )); |
2686 | JSValueRef continueAfterErrorDataValue = JSObjectGetProperty(context, hid, continueAfterErrorDataPropertyName.get(), 0); |
2687 | if (!JSValueIsUndefined(context, continueAfterErrorDataValue) && !JSValueIsNull(context, continueAfterErrorDataValue)) { |
2688 | if (!JSValueIsBoolean(context, continueAfterErrorDataValue)) |
2689 | return; |
2690 | bool continueAfterErrorData = JSValueToBoolean(context, continueAfterErrorDataValue); |
2691 | hidKeys.append(adoptWK(WKStringCreateWithUTF8CString("ContinueAfterErrorData" ))); |
2692 | hidValues.append(adoptWK(WKBooleanCreate(continueAfterErrorData)).get()); |
2693 | } |
2694 | |
2695 | JSRetainPtr<JSStringRef> canDowngradePropertyName(Adopt, JSStringCreateWithUTF8CString("canDowngrade" )); |
2696 | JSValueRef canDowngradeValue = JSObjectGetProperty(context, hid, canDowngradePropertyName.get(), 0); |
2697 | if (!JSValueIsUndefined(context, canDowngradeValue) && !JSValueIsNull(context, canDowngradeValue)) { |
2698 | if (!JSValueIsBoolean(context, canDowngradeValue)) |
2699 | return; |
2700 | bool canDowngrade = JSValueToBoolean(context, canDowngradeValue); |
2701 | hidKeys.append(adoptWK(WKStringCreateWithUTF8CString("CanDowngrade" ))); |
2702 | hidValues.append(adoptWK(WKBooleanCreate(canDowngrade)).get()); |
2703 | } |
2704 | |
2705 | Vector<WKStringRef> rawHidKeys; |
2706 | Vector<WKTypeRef> rawHidValues; |
2707 | rawHidKeys.resize(hidKeys.size()); |
2708 | rawHidValues.resize(hidValues.size()); |
2709 | for (size_t i = 0; i < hidKeys.size(); ++i) { |
2710 | rawHidKeys[i] = hidKeys[i].get(); |
2711 | rawHidValues[i] = hidValues[i].get(); |
2712 | } |
2713 | |
2714 | configurationKeys.append(adoptWK(WKStringCreateWithUTF8CString("Hid" ))); |
2715 | configurationValues.append(adoptWK(WKDictionaryCreate(rawHidKeys.data(), rawHidValues.data(), rawHidKeys.size()))); |
2716 | } |
2717 | |
2718 | Vector<WKStringRef> rawConfigurationKeys; |
2719 | Vector<WKTypeRef> rawConfigurationValues; |
2720 | rawConfigurationKeys.resize(configurationKeys.size()); |
2721 | rawConfigurationValues.resize(configurationValues.size()); |
2722 | for (size_t i = 0; i < configurationKeys.size(); ++i) { |
2723 | rawConfigurationKeys[i] = configurationKeys[i].get(); |
2724 | rawConfigurationValues[i] = configurationValues[i].get(); |
2725 | } |
2726 | |
2727 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("SetWebAuthenticationMockConfiguration" )); |
2728 | WKRetainPtr<WKDictionaryRef> messageBody = adoptWK(WKDictionaryCreate(rawConfigurationKeys.data(), rawConfigurationValues.data(), rawConfigurationKeys.size())); |
2729 | |
2730 | WKBundlePostSynchronousMessage(injectedBundle.bundle(), messageName.get(), messageBody.get(), nullptr); |
2731 | } |
2732 | |
2733 | void TestRunner::addTestKeyToKeychain(JSStringRef privateKeyBase64, JSStringRef attrLabel, JSStringRef applicationTagBase64) |
2734 | { |
2735 | Vector<WKRetainPtr<WKStringRef>> keys; |
2736 | Vector<WKRetainPtr<WKTypeRef>> values; |
2737 | |
2738 | keys.append(adoptWK(WKStringCreateWithUTF8CString("PrivateKey" ))); |
2739 | values.append(toWK(privateKeyBase64)); |
2740 | |
2741 | keys.append(adoptWK(WKStringCreateWithUTF8CString("AttrLabel" ))); |
2742 | values.append(toWK(attrLabel)); |
2743 | |
2744 | keys.append(adoptWK(WKStringCreateWithUTF8CString("ApplicationTag" ))); |
2745 | values.append(toWK(applicationTagBase64)); |
2746 | |
2747 | Vector<WKStringRef> rawKeys; |
2748 | Vector<WKTypeRef> rawValues; |
2749 | rawKeys.resize(keys.size()); |
2750 | rawValues.resize(values.size()); |
2751 | |
2752 | for (size_t i = 0; i < keys.size(); ++i) { |
2753 | rawKeys[i] = keys[i].get(); |
2754 | rawValues[i] = values[i].get(); |
2755 | } |
2756 | |
2757 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("AddTestKeyToKeychain" )); |
2758 | WKRetainPtr<WKDictionaryRef> messageBody = adoptWK(WKDictionaryCreate(rawKeys.data(), rawValues.data(), rawKeys.size())); |
2759 | |
2760 | WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr); |
2761 | } |
2762 | |
2763 | void TestRunner::cleanUpKeychain(JSStringRef attrLabel) |
2764 | { |
2765 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CleanUpKeychain" )); |
2766 | WKRetainPtr<WKStringRef> messageBody = adoptWK(WKStringCreateWithJSString(attrLabel)); |
2767 | |
2768 | WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr); |
2769 | } |
2770 | |
2771 | bool TestRunner::keyExistsInKeychain(JSStringRef attrLabel, JSStringRef applicationTagBase64) |
2772 | { |
2773 | Vector<WKRetainPtr<WKStringRef>> keys; |
2774 | Vector<WKRetainPtr<WKTypeRef>> values; |
2775 | |
2776 | keys.append(adoptWK(WKStringCreateWithUTF8CString("AttrLabel" ))); |
2777 | values.append(toWK(attrLabel)); |
2778 | |
2779 | keys.append(adoptWK(WKStringCreateWithUTF8CString("ApplicationTag" ))); |
2780 | values.append(toWK(applicationTagBase64)); |
2781 | |
2782 | Vector<WKStringRef> rawKeys; |
2783 | Vector<WKTypeRef> rawValues; |
2784 | rawKeys.resize(keys.size()); |
2785 | rawValues.resize(values.size()); |
2786 | |
2787 | for (size_t i = 0; i < keys.size(); ++i) { |
2788 | rawKeys[i] = keys[i].get(); |
2789 | rawValues[i] = values[i].get(); |
2790 | } |
2791 | |
2792 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("KeyExistsInKeychain" )); |
2793 | WKRetainPtr<WKDictionaryRef> messageBody = adoptWK(WKDictionaryCreate(rawKeys.data(), rawValues.data(), rawKeys.size())); |
2794 | |
2795 | WKTypeRef returnData = nullptr; |
2796 | WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), &returnData); |
2797 | ASSERT(WKGetTypeID(returnData) == WKBooleanGetTypeID()); |
2798 | return WKBooleanGetValue(adoptWK(static_cast<WKBooleanRef>(returnData)).get()); |
2799 | } |
2800 | |
2801 | void TestRunner::setCanHandleHTTPSServerTrustEvaluation(bool canHandle) |
2802 | { |
2803 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("SetCanHandleHTTPSServerTrustEvaluation" )); |
2804 | WKRetainPtr<WKBooleanRef> messageBody = adoptWK(WKBooleanCreate(canHandle)); |
2805 | WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr); |
2806 | } |
2807 | |
2808 | bool TestRunner::canDoServerTrustEvaluationInNetworkProcess() |
2809 | { |
2810 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CanDoServerTrustEvaluationInNetworkProcess" )); |
2811 | WKTypeRef returnData = nullptr; |
2812 | WKBundlePagePostSynchronousMessageForTesting(InjectedBundle::singleton().page()->page(), messageName.get(), nullptr, &returnData); |
2813 | ASSERT(WKGetTypeID(returnData) == WKBooleanGetTypeID()); |
2814 | return WKBooleanGetValue(adoptWK(static_cast<WKBooleanRef>(returnData)).get()); |
2815 | } |
2816 | |
2817 | unsigned long TestRunner::serverTrustEvaluationCallbackCallsCount() |
2818 | { |
2819 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("ServerTrustEvaluationCallbackCallsCount" )); |
2820 | WKTypeRef returnData = nullptr; |
2821 | WKBundlePagePostSynchronousMessageForTesting(InjectedBundle::singleton().page()->page(), messageName.get(), nullptr, &returnData); |
2822 | ASSERT(WKGetTypeID(returnData) == WKUInt64GetTypeID()); |
2823 | return WKUInt64GetValue(adoptWK(static_cast<WKUInt64Ref>(returnData)).get()); |
2824 | } |
2825 | |
2826 | void TestRunner::setShouldDismissJavaScriptAlertsAsynchronously(bool shouldDismissAsynchronously) |
2827 | { |
2828 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("ShouldDismissJavaScriptAlertsAsynchronously" )); |
2829 | WKRetainPtr<WKBooleanRef> messageBody = adoptWK(WKBooleanCreate(shouldDismissAsynchronously)); |
2830 | WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr); |
2831 | } |
2832 | |
2833 | void TestRunner::abortModal() |
2834 | { |
2835 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("AbortModal" )); |
2836 | WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), nullptr, nullptr); |
2837 | } |
2838 | |
2839 | void TestRunner::dumpAdClickAttribution() |
2840 | { |
2841 | auto messageName = adoptWK(WKStringCreateWithUTF8CString("DumpAdClickAttribution" )); |
2842 | WKBundlePagePostSynchronousMessageForTesting(InjectedBundle::singleton().page()->page(), messageName.get(), nullptr, nullptr); |
2843 | } |
2844 | |
2845 | void TestRunner::clearAdClickAttribution() |
2846 | { |
2847 | auto messageName = adoptWK(WKStringCreateWithUTF8CString("ClearAdClickAttribution" )); |
2848 | WKBundlePagePostSynchronousMessageForTesting(InjectedBundle::singleton().page()->page(), messageName.get(), nullptr, nullptr); |
2849 | } |
2850 | |
2851 | void TestRunner::clearAdClickAttributionsThroughWebsiteDataRemoval() |
2852 | { |
2853 | auto messageName = adoptWK(WKStringCreateWithUTF8CString("ClearAdClickAttributionsThroughWebsiteDataRemoval" )); |
2854 | WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), nullptr, nullptr); |
2855 | } |
2856 | |
2857 | void TestRunner::setAdClickAttributionOverrideTimerForTesting(bool value) |
2858 | { |
2859 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("SetAdClickAttributionOverrideTimerForTesting" )); |
2860 | WKRetainPtr<WKBooleanRef> messageBody = adoptWK(WKBooleanCreate(value)); |
2861 | WKBundlePagePostSynchronousMessageForTesting(InjectedBundle::singleton().page()->page(), messageName.get(), messageBody.get(), nullptr); |
2862 | } |
2863 | |
2864 | void TestRunner::setAdClickAttributionConversionURLForTesting(JSStringRef urlString) |
2865 | { |
2866 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("SetAdClickAttributionConversionURLForTesting" )); |
2867 | auto wtfURLString = toWTFString(WKStringCreateWithJSString(urlString)); |
2868 | WKRetainPtr<WKURLRef> messageBody = adoptWK(WKURLCreateWithUTF8CString(wtfURLString.utf8().data())); |
2869 | WKBundlePagePostSynchronousMessageForTesting(InjectedBundle::singleton().page()->page(), messageName.get(), messageBody.get(), nullptr); |
2870 | } |
2871 | |
2872 | void TestRunner::markAdClickAttributionsAsExpiredForTesting() |
2873 | { |
2874 | WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("MarkAdClickAttributionsAsExpiredForTesting" )); |
2875 | WKBundlePagePostSynchronousMessageForTesting(InjectedBundle::singleton().page()->page(), messageName.get(), nullptr, nullptr); |
2876 | } |
2877 | |
2878 | } // namespace WTR |
2879 | |