diff options
Diffstat (limited to 'Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp')
-rw-r--r-- | Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp | 853 |
1 files changed, 716 insertions, 137 deletions
diff --git a/Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp b/Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp index 2b30f5df6..6f7eb0c07 100644 --- a/Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp +++ b/Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010, 2011, 2012, 2013 Apple Inc. All rights reserved. + * Copyright (C) 2010-2017 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -33,20 +33,22 @@ #include "StringFunctions.h" #include "TestController.h" #include <JavaScriptCore/JSCTestRunnerUtils.h> -#include <WebKit2/WKBundle.h> -#include <WebKit2/WKBundleBackForwardList.h> -#include <WebKit2/WKBundleFrame.h> -#include <WebKit2/WKBundleFramePrivate.h> -#include <WebKit2/WKBundleInspector.h> -#include <WebKit2/WKBundleNodeHandlePrivate.h> -#include <WebKit2/WKBundlePage.h> -#include <WebKit2/WKBundlePagePrivate.h> -#include <WebKit2/WKBundlePrivate.h> -#include <WebKit2/WKBundleScriptWorld.h> -#include <WebKit2/WKData.h> -#include <WebKit2/WKRetainPtr.h> -#include <WebKit2/WKSerializedScriptValue.h> -#include <WebKit2/WebKit2_C.h> +#include <WebCore/ResourceLoadObserver.h> +#include <WebKit/WKBundle.h> +#include <WebKit/WKBundleBackForwardList.h> +#include <WebKit/WKBundleFrame.h> +#include <WebKit/WKBundleFramePrivate.h> +#include <WebKit/WKBundleInspector.h> +#include <WebKit/WKBundleNodeHandlePrivate.h> +#include <WebKit/WKBundlePage.h> +#include <WebKit/WKBundlePagePrivate.h> +#include <WebKit/WKBundlePrivate.h> +#include <WebKit/WKBundleScriptWorld.h> +#include <WebKit/WKData.h> +#include <WebKit/WKPagePrivate.h> +#include <WebKit/WKRetainPtr.h> +#include <WebKit/WKSerializedScriptValue.h> +#include <WebKit/WebKit2_C.h> #include <wtf/CurrentTime.h> #include <wtf/HashMap.h> #include <wtf/StdLibExtras.h> @@ -55,11 +57,9 @@ namespace WTR { -const double TestRunner::waitToDumpWatchdogTimerInterval = 30; - -PassRefPtr<TestRunner> TestRunner::create() +Ref<TestRunner> TestRunner::create() { - return adoptRef(new TestRunner); + return adoptRef(*new TestRunner); } TestRunner::TestRunner() @@ -93,10 +93,14 @@ TestRunner::TestRunner() , m_policyDelegatePermissive(false) , m_globalFlag(false) , m_customFullScreenBehavior(false) + , m_timeout(30000) , m_databaseDefaultQuota(-1) , m_databaseMaxQuota(-1) , m_userStyleSheetEnabled(false) , m_userStyleSheetLocation(adoptWK(WKStringCreateWithUTF8CString(""))) +#if PLATFORM(GTK) + , m_waitToDumpWatchdogTimer(RunLoop::main(), this, &TestRunner::waitToDumpWatchdogTimerFired) +#endif { platformInitialize(); } @@ -112,7 +116,7 @@ JSClassRef TestRunner::wrapperClass() void TestRunner::display() { - WKBundlePageRef page = InjectedBundle::shared().page()->page(); + WKBundlePageRef page = InjectedBundle::singleton().page()->page(); WKBundlePageForceRepaint(page); WKBundlePageSetTracksRepaints(page, true); WKBundlePageResetTrackedRepaints(page); @@ -130,7 +134,7 @@ void TestRunner::setCustomPolicyDelegate(bool enabled, bool permissive) m_policyDelegateEnabled = enabled; m_policyDelegatePermissive = permissive; - InjectedBundle::shared().setCustomPolicyDelegate(enabled, permissive); + InjectedBundle::singleton().setCustomPolicyDelegate(enabled, permissive); } void TestRunner::waitForPolicyDelegate() @@ -139,42 +143,58 @@ void TestRunner::waitForPolicyDelegate() waitUntilDone(); } +void TestRunner::waitUntilDownloadFinished() +{ + m_shouldFinishAfterDownload = true; + waitUntilDone(); +} + void TestRunner::waitUntilDone() { m_waitToDump = true; - if (InjectedBundle::shared().useWaitToDumpWatchdogTimer()) + if (InjectedBundle::singleton().useWaitToDumpWatchdogTimer()) initializeWaitToDumpWatchdogTimerIfNeeded(); } void TestRunner::waitToDumpWatchdogTimerFired() { invalidateWaitToDumpWatchdogTimer(); - InjectedBundle::shared().outputText("FAIL: Timed out waiting for notifyDone to be called\n\n"); - InjectedBundle::shared().done(); + auto& injectedBundle = InjectedBundle::singleton(); +#if PLATFORM(COCOA) + char buffer[1024]; + snprintf(buffer, sizeof(buffer), "#PID UNRESPONSIVE - %s (pid %d)\n", getprogname(), getpid()); + injectedBundle.outputText(buffer); +#endif + injectedBundle.outputText("FAIL: Timed out waiting for notifyDone to be called\n\n"); + injectedBundle.done(); } void TestRunner::notifyDone() { - if (!InjectedBundle::shared().isTestRunning()) + auto& injectedBundle = InjectedBundle::singleton(); + if (!injectedBundle.isTestRunning()) return; - if (m_waitToDump && !InjectedBundle::shared().topLoadingFrame()) - InjectedBundle::shared().page()->dump(); + if (m_waitToDump && !injectedBundle.topLoadingFrame()) + injectedBundle.page()->dump(); + + // We don't call invalidateWaitToDumpWatchdogTimer() here, even if we continue to wait for a load to finish. + // The test is still subject to timeout checking - it is better to detect an async timeout inside WebKitTestRunner + // than to let webkitpy do that, because WebKitTestRunner will dump partial results. m_waitToDump = false; } -void TestRunner::setCustomTimeout(int timeout) +unsigned TestRunner::imageCountInGeneralPasteboard() const { - m_timeout = timeout; + return InjectedBundle::singleton().imageCountInGeneralPasteboard(); } void TestRunner::addUserScript(JSStringRef source, bool runAtStart, bool allFrames) { WKRetainPtr<WKStringRef> sourceWK = toWK(source); - WKRetainPtr<WKBundleScriptWorldRef> scriptWorld(AdoptWK, WKBundleScriptWorldCreateWorld()); - WKBundleAddUserScript(InjectedBundle::shared().bundle(), InjectedBundle::shared().pageGroup(), scriptWorld.get(), sourceWK.get(), 0, 0, 0, + WKBundlePageAddUserScript(InjectedBundle::singleton().page()->page(), sourceWK.get(), (runAtStart ? kWKInjectAtDocumentStart : kWKInjectAtDocumentEnd), (allFrames ? kWKInjectInAllFrames : kWKInjectInTopFrameOnly)); } @@ -182,27 +202,27 @@ void TestRunner::addUserScript(JSStringRef source, bool runAtStart, bool allFram void TestRunner::addUserStyleSheet(JSStringRef source, bool allFrames) { WKRetainPtr<WKStringRef> sourceWK = toWK(source); - WKRetainPtr<WKBundleScriptWorldRef> scriptWorld(AdoptWK, WKBundleScriptWorldCreateWorld()); - WKBundleAddUserStyleSheet(InjectedBundle::shared().bundle(), InjectedBundle::shared().pageGroup(), scriptWorld.get(), sourceWK.get(), 0, 0, 0, + WKBundlePageAddUserStyleSheet(InjectedBundle::singleton().page()->page(), sourceWK.get(), (allFrames ? kWKInjectInAllFrames : kWKInjectInTopFrameOnly)); } void TestRunner::keepWebHistory() { - WKBundleSetShouldTrackVisitedLinks(InjectedBundle::shared().bundle(), true); + InjectedBundle::singleton().postSetAddsVisitedLinks(true); } void TestRunner::execCommand(JSStringRef name, JSStringRef argument) { - WKBundlePageExecuteEditingCommand(InjectedBundle::shared().page()->page(), toWK(name).get(), toWK(argument).get()); + WKBundlePageExecuteEditingCommand(InjectedBundle::singleton().page()->page(), toWK(name).get(), toWK(argument).get()); } bool TestRunner::findString(JSStringRef target, JSValueRef optionsArrayAsValue) { WKFindOptions options = 0; - WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(InjectedBundle::shared().page()->page()); + auto& injectedBundle = InjectedBundle::singleton(); + WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(injectedBundle.page()->page()); JSContextRef context = WKBundleFrameGetJavaScriptContext(mainFrame); JSRetainPtr<JSStringRef> lengthPropertyName(Adopt, JSStringCreateWithUTF8CString("length")); JSObjectRef optionsArray = JSValueToObject(context, optionsArrayAsValue, 0); @@ -233,37 +253,42 @@ bool TestRunner::findString(JSStringRef target, JSValueRef optionsArrayAsValue) } } - return WKBundlePageFindString(InjectedBundle::shared().page()->page(), toWK(target).get(), options); + return WKBundlePageFindString(injectedBundle.page()->page(), toWK(target).get(), options); } void TestRunner::clearAllDatabases() { - WKBundleClearAllDatabases(InjectedBundle::shared().bundle()); + WKBundleClearAllDatabases(InjectedBundle::singleton().bundle()); + + WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("DeleteAllIndexedDatabases")); + WKRetainPtr<WKBooleanRef> messageBody(AdoptWK, WKBooleanCreate(true)); + + WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr); } void TestRunner::setDatabaseQuota(uint64_t quota) { - return WKBundleSetDatabaseQuota(InjectedBundle::shared().bundle(), quota); + return WKBundleSetDatabaseQuota(InjectedBundle::singleton().bundle(), quota); } void TestRunner::clearAllApplicationCaches() { - WKBundleClearApplicationCache(InjectedBundle::shared().bundle()); + WKBundlePageClearApplicationCache(InjectedBundle::singleton().page()->page()); } void TestRunner::clearApplicationCacheForOrigin(JSStringRef origin) { - WKBundleClearApplicationCacheForOrigin(InjectedBundle::shared().bundle(), toWK(origin).get()); + WKBundlePageClearApplicationCacheForOrigin(InjectedBundle::singleton().page()->page(), toWK(origin).get()); } void TestRunner::setAppCacheMaximumSize(uint64_t size) { - WKBundleSetAppCacheMaximumSize(InjectedBundle::shared().bundle(), size); + WKBundlePageSetAppCacheMaximumSize(InjectedBundle::singleton().page()->page(), size); } long long TestRunner::applicationCacheDiskUsageForOrigin(JSStringRef origin) { - return WKBundleGetAppCacheUsageForOrigin(InjectedBundle::shared().bundle(), toWK(origin).get()); + return WKBundlePageGetAppCacheUsageForOrigin(InjectedBundle::singleton().page()->page(), toWK(origin).get()); } void TestRunner::disallowIncreaseForApplicationCacheQuota() @@ -275,21 +300,24 @@ static inline JSValueRef stringArrayToJS(JSContextRef context, WKArrayRef string { const size_t count = WKArrayGetSize(strings); - auto jsStringsArray = std::make_unique<JSValueRef[]>(count); + JSValueRef arrayResult = JSObjectMakeArray(context, 0, 0, 0); + JSObjectRef arrayObj = JSValueToObject(context, arrayResult, 0); for (size_t i = 0; i < count; ++i) { WKStringRef stringRef = static_cast<WKStringRef>(WKArrayGetItemAtIndex(strings, i)); JSRetainPtr<JSStringRef> stringJS = toJS(stringRef); - jsStringsArray[i] = JSValueMakeString(context, stringJS.get()); + JSObjectSetPropertyAtIndex(context, arrayObj, i, JSValueMakeString(context, stringJS.get()), 0); } - return JSObjectMakeArray(context, count, jsStringsArray.get(), 0); + return arrayResult; } JSValueRef TestRunner::originsWithApplicationCache() { - WKRetainPtr<WKArrayRef> origins(AdoptWK, WKBundleCopyOriginsWithApplicationCache(InjectedBundle::shared().bundle())); + WKBundlePageRef page = InjectedBundle::singleton().page()->page(); + + WKRetainPtr<WKArrayRef> origins(AdoptWK, WKBundlePageCopyOriginsWithApplicationCache(page)); - WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(InjectedBundle::shared().page()->page()); + WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(page); JSContextRef context = WKBundleFrameGetJavaScriptContext(mainFrame); return stringArrayToJS(context, origins.get()); @@ -297,70 +325,174 @@ JSValueRef TestRunner::originsWithApplicationCache() bool TestRunner::isCommandEnabled(JSStringRef name) { - return WKBundlePageIsEditingCommandEnabled(InjectedBundle::shared().page()->page(), toWK(name).get()); + return WKBundlePageIsEditingCommandEnabled(InjectedBundle::singleton().page()->page(), toWK(name).get()); } void TestRunner::setCanOpenWindows(bool) { - // It's not clear if or why any tests require opening windows be forbidden. - // For now, just ignore this setting, and if we find later it's needed we can add it. + // The test plugins/get-url-with-blank-target.html requires that the embedding client forbid + // opening windows (by omitting a call to this function) so as to test that NPN_GetURL() + // with a blank target will return an error. + // + // It is not clear if we should implement this functionality or remove it and plugins/get-url-with-blank-target.html + // per the remark in <https://trac.webkit.org/changeset/64504/trunk/LayoutTests/platform/mac-wk2/Skipped>. + // For now, just ignore this setting. } void TestRunner::setXSSAuditorEnabled(bool enabled) { WKRetainPtr<WKStringRef> key(AdoptWK, WKStringCreateWithUTF8CString("WebKitXSSAuditorEnabled")); - WKBundleOverrideBoolPreferenceForTestRunner(InjectedBundle::shared().bundle(), InjectedBundle::shared().pageGroup(), key.get(), enabled); + auto& injectedBundle = InjectedBundle::singleton(); + WKBundleOverrideBoolPreferenceForTestRunner(injectedBundle.bundle(), injectedBundle.pageGroup(), key.get(), enabled); +} + +void TestRunner::setShadowDOMEnabled(bool enabled) +{ + WKRetainPtr<WKStringRef> key(AdoptWK, WKStringCreateWithUTF8CString("WebKitShadowDOMEnabled")); + auto& injectedBundle = InjectedBundle::singleton(); + WKBundleOverrideBoolPreferenceForTestRunner(injectedBundle.bundle(), injectedBundle.pageGroup(), key.get(), enabled); +} + +void TestRunner::setCustomElementsEnabled(bool enabled) +{ + WKRetainPtr<WKStringRef> key(AdoptWK, WKStringCreateWithUTF8CString("WebKitCustomElementsEnabled")); + auto& injectedBundle = InjectedBundle::singleton(); + WKBundleOverrideBoolPreferenceForTestRunner(injectedBundle.bundle(), injectedBundle.pageGroup(), key.get(), enabled); +} + +void TestRunner::setSubtleCryptoEnabled(bool enabled) +{ + WKRetainPtr<WKStringRef> key(AdoptWK, WKStringCreateWithUTF8CString("WebKitSubtleCryptoEnabled")); + auto& injectedBundle = InjectedBundle::singleton(); + WKBundleOverrideBoolPreferenceForTestRunner(injectedBundle.bundle(), injectedBundle.pageGroup(), key.get(), enabled); +} + +void TestRunner::setMediaStreamEnabled(bool enabled) +{ + WKRetainPtr<WKStringRef> key(AdoptWK, WKStringCreateWithUTF8CString("WebKitMediaStreamEnabled")); + auto& injectedBundle = InjectedBundle::singleton(); + WKBundleOverrideBoolPreferenceForTestRunner(injectedBundle.bundle(), injectedBundle.pageGroup(), key.get(), enabled); +} + +void TestRunner::setPeerConnectionEnabled(bool enabled) +{ + WKRetainPtr<WKStringRef> key(AdoptWK, WKStringCreateWithUTF8CString("WebKitPeerConnectionEnabled")); + auto& injectedBundle = InjectedBundle::singleton(); + WKBundleOverrideBoolPreferenceForTestRunner(injectedBundle.bundle(), injectedBundle.pageGroup(), key.get(), enabled); +} + +void TestRunner::setModernMediaControlsEnabled(bool enabled) +{ + WKRetainPtr<WKStringRef> key(AdoptWK, WKStringCreateWithUTF8CString("WebKitModernMediaControlsEnabled")); + auto& injectedBundle = InjectedBundle::singleton(); + WKBundleOverrideBoolPreferenceForTestRunner(injectedBundle.bundle(), injectedBundle.pageGroup(), key.get(), enabled); +} + +void TestRunner::setWebGL2Enabled(bool enabled) +{ + WKRetainPtr<WKStringRef> key(AdoptWK, WKStringCreateWithUTF8CString("WebKitWebGL2Enabled")); + auto& injectedBundle = InjectedBundle::singleton(); + WKBundleOverrideBoolPreferenceForTestRunner(injectedBundle.bundle(), injectedBundle.pageGroup(), key.get(), enabled); +} + +void TestRunner::setFetchAPIEnabled(bool enabled) +{ + WKRetainPtr<WKStringRef> key(AdoptWK, WKStringCreateWithUTF8CString("WebKitFetchAPIEnabled")); + auto& injectedBundle = InjectedBundle::singleton(); + WKBundleOverrideBoolPreferenceForTestRunner(injectedBundle.bundle(), injectedBundle.pageGroup(), key.get(), enabled); +} + +void TestRunner::setDownloadAttributeEnabled(bool enabled) +{ + WKRetainPtr<WKStringRef> key(AdoptWK, WKStringCreateWithUTF8CString("WebKitDownloadAttributeEnabled")); + auto& injectedBundle = InjectedBundle::singleton(); + WKBundleOverrideBoolPreferenceForTestRunner(injectedBundle.bundle(), injectedBundle.pageGroup(), key.get(), enabled); +} + +void TestRunner::setEncryptedMediaAPIEnabled(bool enabled) +{ + WKRetainPtr<WKStringRef> key(AdoptWK, WKStringCreateWithUTF8CString("WebKitEncryptedMediaAPIEnabled")); + auto& injectedBundle = InjectedBundle::singleton(); + WKBundleOverrideBoolPreferenceForTestRunner(injectedBundle.bundle(), injectedBundle.pageGroup(), key.get(), enabled); +} + +void TestRunner::setAllowsAnySSLCertificate(bool enabled) +{ + InjectedBundle::singleton().setAllowsAnySSLCertificate(enabled); } void TestRunner::setAllowUniversalAccessFromFileURLs(bool enabled) { - WKBundleSetAllowUniversalAccessFromFileURLs(InjectedBundle::shared().bundle(), InjectedBundle::shared().pageGroup(), enabled); + auto& injectedBundle = InjectedBundle::singleton(); + WKBundleSetAllowUniversalAccessFromFileURLs(injectedBundle.bundle(), injectedBundle.pageGroup(), enabled); } void TestRunner::setAllowFileAccessFromFileURLs(bool enabled) { - WKBundleSetAllowFileAccessFromFileURLs(InjectedBundle::shared().bundle(), InjectedBundle::shared().pageGroup(), enabled); + auto& injectedBundle = InjectedBundle::singleton(); + WKBundleSetAllowFileAccessFromFileURLs(injectedBundle.bundle(), injectedBundle.pageGroup(), enabled); } +void TestRunner::setNeedsStorageAccessFromFileURLsQuirk(bool needsQuirk) +{ + auto& injectedBundle = InjectedBundle::singleton(); + WKBundleSetAllowStorageAccessFromFileURLS(injectedBundle.bundle(), injectedBundle.pageGroup(), needsQuirk); +} + void TestRunner::setPluginsEnabled(bool enabled) { - WKBundleSetPluginsEnabled(InjectedBundle::shared().bundle(), InjectedBundle::shared().pageGroup(), enabled); + WKRetainPtr<WKStringRef> key(AdoptWK, WKStringCreateWithUTF8CString("WebKitPluginsEnabled")); + auto& injectedBundle = InjectedBundle::singleton(); + WKBundleOverrideBoolPreferenceForTestRunner(injectedBundle.bundle(), injectedBundle.pageGroup(), key.get(), enabled); } void TestRunner::setJavaScriptCanAccessClipboard(bool enabled) { - WKBundleSetJavaScriptCanAccessClipboard(InjectedBundle::shared().bundle(), InjectedBundle::shared().pageGroup(), enabled); + auto& injectedBundle = InjectedBundle::singleton(); + WKBundleSetJavaScriptCanAccessClipboard(injectedBundle.bundle(), injectedBundle.pageGroup(), enabled); } void TestRunner::setPrivateBrowsingEnabled(bool enabled) { - WKBundleSetPrivateBrowsingEnabled(InjectedBundle::shared().bundle(), InjectedBundle::shared().pageGroup(), enabled); + auto& injectedBundle = InjectedBundle::singleton(); + WKBundleSetPrivateBrowsingEnabled(injectedBundle.bundle(), injectedBundle.pageGroup(), enabled); } +void TestRunner::setUseDashboardCompatibilityMode(bool enabled) +{ +#if ENABLE(DASHBOARD_SUPPORT) + auto& injectedBundle = InjectedBundle::singleton(); + WKBundleSetUseDashboardCompatibilityMode(injectedBundle.bundle(), injectedBundle.pageGroup(), enabled); +#endif +} + void TestRunner::setPopupBlockingEnabled(bool enabled) { - WKBundleSetPopupBlockingEnabled(InjectedBundle::shared().bundle(), InjectedBundle::shared().pageGroup(), enabled); + auto& injectedBundle = InjectedBundle::singleton(); + WKBundleSetPopupBlockingEnabled(injectedBundle.bundle(), injectedBundle.pageGroup(), enabled); } void TestRunner::setAuthorAndUserStylesEnabled(bool enabled) { - WKBundleSetAuthorAndUserStylesEnabled(InjectedBundle::shared().bundle(), InjectedBundle::shared().pageGroup(), enabled); + auto& injectedBundle = InjectedBundle::singleton(); + WKBundleSetAuthorAndUserStylesEnabled(injectedBundle.bundle(), injectedBundle.pageGroup(), enabled); } void TestRunner::addOriginAccessWhitelistEntry(JSStringRef sourceOrigin, JSStringRef destinationProtocol, JSStringRef destinationHost, bool allowDestinationSubdomains) { - WKBundleAddOriginAccessWhitelistEntry(InjectedBundle::shared().bundle(), toWK(sourceOrigin).get(), toWK(destinationProtocol).get(), toWK(destinationHost).get(), allowDestinationSubdomains); + WKBundleAddOriginAccessWhitelistEntry(InjectedBundle::singleton().bundle(), toWK(sourceOrigin).get(), toWK(destinationProtocol).get(), toWK(destinationHost).get(), allowDestinationSubdomains); } void TestRunner::removeOriginAccessWhitelistEntry(JSStringRef sourceOrigin, JSStringRef destinationProtocol, JSStringRef destinationHost, bool allowDestinationSubdomains) { - WKBundleRemoveOriginAccessWhitelistEntry(InjectedBundle::shared().bundle(), toWK(sourceOrigin).get(), toWK(destinationProtocol).get(), toWK(destinationHost).get(), allowDestinationSubdomains); + WKBundleRemoveOriginAccessWhitelistEntry(InjectedBundle::singleton().bundle(), toWK(sourceOrigin).get(), toWK(destinationProtocol).get(), toWK(destinationHost).get(), allowDestinationSubdomains); } bool TestRunner::isPageBoxVisible(int pageIndex) { - WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(InjectedBundle::shared().page()->page()); - return WKBundleIsPageBoxVisible(InjectedBundle::shared().bundle(), mainFrame, pageIndex); + auto& injectedBundle = InjectedBundle::singleton(); + WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(injectedBundle.page()->page()); + return WKBundleIsPageBoxVisible(injectedBundle.bundle(), mainFrame, pageIndex); } void TestRunner::setValueForUser(JSContextRef context, JSValueRef element, JSStringRef value) @@ -374,21 +506,22 @@ void TestRunner::setValueForUser(JSContextRef context, JSValueRef element, JSStr void TestRunner::setAudioResult(JSContextRef context, JSValueRef data) { + auto& injectedBundle = InjectedBundle::singleton(); // FIXME (123058): Use a JSC API to get buffer contents once such is exposed. - WKRetainPtr<WKDataRef> audioData(AdoptWK, WKBundleCreateWKDataFromUInt8Array(InjectedBundle::shared().bundle(), context, data)); - InjectedBundle::shared().setAudioResult(audioData.get()); + WKRetainPtr<WKDataRef> audioData(AdoptWK, WKBundleCreateWKDataFromUInt8Array(injectedBundle.bundle(), context, data)); + injectedBundle.setAudioResult(audioData.get()); m_whatToDump = Audio; m_dumpPixels = false; } unsigned TestRunner::windowCount() { - return InjectedBundle::shared().pageCount(); + return InjectedBundle::singleton().pageCount(); } void TestRunner::clearBackForwardList() { - WKBundleBackForwardListClear(WKBundlePageGetBackForwardList(InjectedBundle::shared().page()->page())); + WKBundleBackForwardListClear(WKBundlePageGetBackForwardList(InjectedBundle::singleton().page()->page())); } // Object Creation @@ -400,24 +533,18 @@ void TestRunner::makeWindowObject(JSContextRef context, JSObjectRef windowObject void TestRunner::showWebInspector() { -#if ENABLE(INSPECTOR) - WKBundleInspectorShow(WKBundlePageGetInspector(InjectedBundle::shared().page()->page())); -#endif // ENABLE(INSPECTOR) + WKBundleInspectorShow(WKBundlePageGetInspector(InjectedBundle::singleton().page()->page())); } void TestRunner::closeWebInspector() { -#if ENABLE(INSPECTOR) - WKBundleInspectorClose(WKBundlePageGetInspector(InjectedBundle::shared().page()->page())); -#endif // ENABLE(INSPECTOR) + WKBundleInspectorClose(WKBundlePageGetInspector(InjectedBundle::singleton().page()->page())); } -void TestRunner::evaluateInWebInspector(long callID, JSStringRef script) +void TestRunner::evaluateInWebInspector(JSStringRef script) { -#if ENABLE(INSPECTOR) WKRetainPtr<WKStringRef> scriptWK = toWK(script); - WKBundleInspectorEvaluateScriptForTest(WKBundlePageGetInspector(InjectedBundle::shared().page()->page()), callID, scriptWK.get()); -#endif // ENABLE(INSPECTOR) + WKBundleInspectorEvaluateScriptForTest(WKBundlePageGetInspector(InjectedBundle::singleton().page()->page()), scriptWK.get()); } typedef WTF::HashMap<unsigned, WKRetainPtr<WKBundleScriptWorldRef> > WorldMap; @@ -454,7 +581,7 @@ void TestRunner::evaluateScriptInIsolatedWorld(JSContextRef context, unsigned wo WKBundleFrameRef frame = WKBundleFrameForJavaScriptContext(context); if (!frame) - frame = WKBundlePageGetMainFrame(InjectedBundle::shared().page()->page()); + frame = WKBundlePageGetMainFrame(InjectedBundle::singleton().page()->page()); JSGlobalContextRef jsContext = WKBundleFrameGetJavaScriptContextForWorld(frame, world.get()); JSEvaluateScript(jsContext, script, 0, 0, 0, 0); @@ -469,35 +596,28 @@ void TestRunner::setPOSIXLocale(JSStringRef locale) void TestRunner::setTextDirection(JSStringRef direction) { - WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(InjectedBundle::shared().page()->page()); + WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(InjectedBundle::singleton().page()->page()); return WKBundleFrameSetTextDirection(mainFrame, toWK(direction).get()); } void TestRunner::setShouldStayOnPageAfterHandlingBeforeUnload(bool shouldStayOnPage) { - InjectedBundle::shared().postNewBeforeUnloadReturnValue(!shouldStayOnPage); + InjectedBundle::singleton().postNewBeforeUnloadReturnValue(!shouldStayOnPage); } void TestRunner::setDefersLoading(bool shouldDeferLoading) { - WKBundlePageSetDefersLoading(InjectedBundle::shared().page()->page(), shouldDeferLoading); + WKBundlePageSetDefersLoading(InjectedBundle::singleton().page()->page(), shouldDeferLoading); } void TestRunner::setPageVisibility(JSStringRef state) { - WKPageVisibilityState visibilityState = kWKPageVisibilityStateVisible; - - if (JSStringIsEqualToUTF8CString(state, "hidden")) - visibilityState = kWKPageVisibilityStateHidden; - else if (JSStringIsEqualToUTF8CString(state, "prerender")) - visibilityState = kWKPageVisibilityStatePrerender; - - InjectedBundle::shared().setVisibilityState(visibilityState, false); + InjectedBundle::singleton().setHidden(JSStringIsEqualToUTF8CString(state, "hidden") || JSStringIsEqualToUTF8CString(state, "prerender")); } void TestRunner::resetPageVisibility() { - InjectedBundle::shared().setVisibilityState(kWKPageVisibilityStateVisible, true); + InjectedBundle::singleton().setHidden(false); } typedef WTF::HashMap<unsigned, JSValueRef> CallbackMap; @@ -511,7 +631,13 @@ enum { AddChromeInputFieldCallbackID = 1, RemoveChromeInputFieldCallbackID, FocusWebViewCallbackID, - SetBackingScaleFactorCallbackID + SetBackingScaleFactorCallbackID, + DidBeginSwipeCallbackID, + WillEndSwipeCallbackID, + DidEndSwipeCallbackID, + DidRemoveSwipeSnapshotCallbackID, + StatisticsDidModifyDataRecordsCallbackID, + FirstUIScriptCallbackID = 100 }; static void cacheTestRunnerCallback(unsigned index, JSValueRef callback) @@ -519,50 +645,77 @@ static void cacheTestRunnerCallback(unsigned index, JSValueRef callback) if (!callback) return; - WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(InjectedBundle::shared().page()->page()); + if (callbackMap().contains(index)) { + InjectedBundle::singleton().outputText(String::format("FAIL: Tried to install a second TestRunner callback for the same event (id %d)\n\n", index)); + return; + } + + WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(InjectedBundle::singleton().page()->page()); JSContextRef context = WKBundleFrameGetJavaScriptContext(mainFrame); JSValueProtect(context, callback); callbackMap().add(index, callback); } -static void callTestRunnerCallback(unsigned index) +static void callTestRunnerCallback(unsigned index, size_t argumentCount = 0, const JSValueRef arguments[] = nullptr) { if (!callbackMap().contains(index)) return; - WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(InjectedBundle::shared().page()->page()); + WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(InjectedBundle::singleton().page()->page()); JSContextRef context = WKBundleFrameGetJavaScriptContext(mainFrame); JSObjectRef callback = JSValueToObject(context, callbackMap().take(index), 0); - JSObjectCallAsFunction(context, callback, JSContextGetGlobalObject(context), 0, 0, 0); + JSObjectCallAsFunction(context, callback, JSContextGetGlobalObject(context), argumentCount, arguments, 0); JSValueUnprotect(context, callback); } +void TestRunner::clearTestRunnerCallbacks() +{ + for (auto& iter : callbackMap()) { + WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(InjectedBundle::singleton().page()->page()); + JSContextRef context = WKBundleFrameGetJavaScriptContext(mainFrame); + JSObjectRef callback = JSValueToObject(context, iter.value, 0); + JSValueUnprotect(context, callback); + } + + callbackMap().clear(); +} + +void TestRunner::accummulateLogsForChannel(JSStringRef) +{ + // FIXME: Implement getting the call to all processes. +} + void TestRunner::addChromeInputField(JSValueRef callback) { cacheTestRunnerCallback(AddChromeInputFieldCallbackID, callback); - InjectedBundle::shared().postAddChromeInputField(); + InjectedBundle::singleton().postAddChromeInputField(); } void TestRunner::removeChromeInputField(JSValueRef callback) { cacheTestRunnerCallback(RemoveChromeInputFieldCallbackID, callback); - InjectedBundle::shared().postRemoveChromeInputField(); + InjectedBundle::singleton().postRemoveChromeInputField(); } void TestRunner::focusWebView(JSValueRef callback) { cacheTestRunnerCallback(FocusWebViewCallbackID, callback); - InjectedBundle::shared().postFocusWebView(); + InjectedBundle::singleton().postFocusWebView(); } void TestRunner::setBackingScaleFactor(double backingScaleFactor, JSValueRef callback) { cacheTestRunnerCallback(SetBackingScaleFactorCallbackID, callback); - InjectedBundle::shared().postSetBackingScaleFactor(backingScaleFactor); + InjectedBundle::singleton().postSetBackingScaleFactor(backingScaleFactor); } void TestRunner::setWindowIsKey(bool isKey) { - InjectedBundle::shared().postSetWindowIsKey(isKey); + InjectedBundle::singleton().postSetWindowIsKey(isKey); +} + +void TestRunner::setViewSize(double width, double height) +{ + InjectedBundle::singleton().postSetViewSize(width, height); } void TestRunner::callAddChromeInputFieldCallback() @@ -592,13 +745,18 @@ static inline bool toBool(JSStringRef value) void TestRunner::overridePreference(JSStringRef preference, JSStringRef value) { + auto& injectedBundle = InjectedBundle::singleton(); // FIXME: handle non-boolean preferences. - WKBundleOverrideBoolPreferenceForTestRunner(InjectedBundle::shared().bundle(), InjectedBundle::shared().pageGroup(), toWK(preference).get(), toBool(value)); + WKBundleOverrideBoolPreferenceForTestRunner(injectedBundle.bundle(), injectedBundle.pageGroup(), toWK(preference).get(), toBool(value)); } void TestRunner::setAlwaysAcceptCookies(bool accept) { - WKBundleSetAlwaysAcceptCookies(InjectedBundle::shared().bundle(), accept); + WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("SetAlwaysAcceptCookies")); + + WKRetainPtr<WKBooleanRef> messageBody(AdoptWK, WKBooleanCreate(accept)); + + WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr); } double TestRunner::preciseTime() @@ -612,7 +770,8 @@ void TestRunner::setUserStyleSheetEnabled(bool enabled) WKRetainPtr<WKStringRef> emptyUrl = adoptWK(WKStringCreateWithUTF8CString("")); WKStringRef location = enabled ? m_userStyleSheetLocation.get() : emptyUrl.get(); - WKBundleSetUserStyleSheetLocation(InjectedBundle::shared().bundle(), InjectedBundle::shared().pageGroup(), location); + auto& injectedBundle = InjectedBundle::singleton(); + WKBundleSetUserStyleSheetLocation(injectedBundle.bundle(), injectedBundle.pageGroup(), location); } void TestRunner::setUserStyleSheetLocation(JSStringRef location) @@ -625,68 +784,81 @@ void TestRunner::setUserStyleSheetLocation(JSStringRef location) void TestRunner::setSpatialNavigationEnabled(bool enabled) { - WKBundleSetSpatialNavigationEnabled(InjectedBundle::shared().bundle(), InjectedBundle::shared().pageGroup(), enabled); + auto& injectedBundle = InjectedBundle::singleton(); + WKBundleSetSpatialNavigationEnabled(injectedBundle.bundle(), injectedBundle.pageGroup(), enabled); } void TestRunner::setTabKeyCyclesThroughElements(bool enabled) { - WKBundleSetTabKeyCyclesThroughElements(InjectedBundle::shared().bundle(), InjectedBundle::shared().page()->page(), enabled); + auto& injectedBundle = InjectedBundle::singleton(); + WKBundleSetTabKeyCyclesThroughElements(injectedBundle.bundle(), injectedBundle.page()->page(), enabled); } void TestRunner::setSerializeHTTPLoads() { - WKBundleSetSerialLoadingEnabled(InjectedBundle::shared().bundle(), true); + // WK2 doesn't reorder loads. } void TestRunner::dispatchPendingLoadRequests() { - WKBundleDispatchPendingLoadRequests(InjectedBundle::shared().bundle()); + // WK2 doesn't keep pending requests. } void TestRunner::setCacheModel(int model) { - WKBundleSetCacheModel(InjectedBundle::shared().bundle(), model); + InjectedBundle::singleton().setCacheModel(model); } void TestRunner::setAsynchronousSpellCheckingEnabled(bool enabled) { - WKBundleSetAsynchronousSpellCheckingEnabled(InjectedBundle::shared().bundle(), InjectedBundle::shared().pageGroup(), enabled); + auto& injectedBundle = InjectedBundle::singleton(); + WKBundleSetAsynchronousSpellCheckingEnabled(injectedBundle.bundle(), injectedBundle.pageGroup(), enabled); } void TestRunner::grantWebNotificationPermission(JSStringRef origin) { WKRetainPtr<WKStringRef> originWK = toWK(origin); - WKBundleSetWebNotificationPermission(InjectedBundle::shared().bundle(), InjectedBundle::shared().page()->page(), originWK.get(), true); + auto& injectedBundle = InjectedBundle::singleton(); + WKBundleSetWebNotificationPermission(injectedBundle.bundle(), injectedBundle.page()->page(), originWK.get(), true); } void TestRunner::denyWebNotificationPermission(JSStringRef origin) { WKRetainPtr<WKStringRef> originWK = toWK(origin); - WKBundleSetWebNotificationPermission(InjectedBundle::shared().bundle(), InjectedBundle::shared().page()->page(), originWK.get(), false); + auto& injectedBundle = InjectedBundle::singleton(); + WKBundleSetWebNotificationPermission(injectedBundle.bundle(), injectedBundle.page()->page(), originWK.get(), false); } void TestRunner::removeAllWebNotificationPermissions() { - WKBundleRemoveAllWebNotificationPermissions(InjectedBundle::shared().bundle(), InjectedBundle::shared().page()->page()); + auto& injectedBundle = InjectedBundle::singleton(); + WKBundleRemoveAllWebNotificationPermissions(injectedBundle.bundle(), injectedBundle.page()->page()); } void TestRunner::simulateWebNotificationClick(JSValueRef notification) { - WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(InjectedBundle::shared().page()->page()); + auto& injectedBundle = InjectedBundle::singleton(); + WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(injectedBundle.page()->page()); JSContextRef context = WKBundleFrameGetJavaScriptContext(mainFrame); - uint64_t notificationID = WKBundleGetWebNotificationID(InjectedBundle::shared().bundle(), context, notification); - InjectedBundle::shared().postSimulateWebNotificationClick(notificationID); + uint64_t notificationID = WKBundleGetWebNotificationID(injectedBundle.bundle(), context, notification); + injectedBundle.postSimulateWebNotificationClick(notificationID); } void TestRunner::setGeolocationPermission(bool enabled) { // FIXME: this should be done by frame. - InjectedBundle::shared().setGeolocationPermission(enabled); + InjectedBundle::singleton().setGeolocationPermission(enabled); +} + +bool TestRunner::isGeolocationProviderActive() +{ + return InjectedBundle::singleton().isGeolocationProviderActive(); } void TestRunner::setMockGeolocationPosition(double latitude, double longitude, double accuracy, JSValueRef jsAltitude, JSValueRef jsAltitudeAccuracy, JSValueRef jsHeading, JSValueRef jsSpeed) { - WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(InjectedBundle::shared().page()->page()); + auto& injectedBundle = InjectedBundle::singleton(); + WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(injectedBundle.page()->page()); JSContextRef context = WKBundleFrameGetJavaScriptContext(mainFrame); bool providesAltitude = false; @@ -717,38 +889,66 @@ void TestRunner::setMockGeolocationPosition(double latitude, double longitude, d speed = JSValueToNumber(context, jsSpeed, 0); } - InjectedBundle::shared().setMockGeolocationPosition(latitude, longitude, accuracy, providesAltitude, altitude, providesAltitudeAccuracy, altitudeAccuracy, providesHeading, heading, providesSpeed, speed); + injectedBundle.setMockGeolocationPosition(latitude, longitude, accuracy, providesAltitude, altitude, providesAltitudeAccuracy, altitudeAccuracy, providesHeading, heading, providesSpeed, speed); } void TestRunner::setMockGeolocationPositionUnavailableError(JSStringRef message) { WKRetainPtr<WKStringRef> messageWK = toWK(message); - InjectedBundle::shared().setMockGeolocationPositionUnavailableError(messageWK.get()); + InjectedBundle::singleton().setMockGeolocationPositionUnavailableError(messageWK.get()); +} + +void TestRunner::setUserMediaPermission(bool enabled) +{ + // FIXME: this should be done by frame. + InjectedBundle::singleton().setUserMediaPermission(enabled); +} + +void TestRunner::setUserMediaPersistentPermissionForOrigin(bool permission, JSStringRef origin, JSStringRef parentOrigin) +{ + WKRetainPtr<WKStringRef> originWK = toWK(origin); + WKRetainPtr<WKStringRef> parentOriginWK = toWK(parentOrigin); + InjectedBundle::singleton().setUserMediaPersistentPermissionForOrigin(permission, originWK.get(), parentOriginWK.get()); +} + +unsigned TestRunner::userMediaPermissionRequestCountForOrigin(JSStringRef origin, JSStringRef parentOrigin) const +{ + WKRetainPtr<WKStringRef> originWK = toWK(origin); + WKRetainPtr<WKStringRef> parentOriginWK = toWK(parentOrigin); + return InjectedBundle::singleton().userMediaPermissionRequestCountForOrigin(originWK.get(), parentOriginWK.get()); +} + +void TestRunner::resetUserMediaPermissionRequestCountForOrigin(JSStringRef origin, JSStringRef parentOrigin) +{ + WKRetainPtr<WKStringRef> originWK = toWK(origin); + WKRetainPtr<WKStringRef> parentOriginWK = toWK(parentOrigin); + InjectedBundle::singleton().resetUserMediaPermissionRequestCountForOrigin(originWK.get(), parentOriginWK.get()); } bool TestRunner::callShouldCloseOnWebView() { - WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(InjectedBundle::shared().page()->page()); + WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(InjectedBundle::singleton().page()->page()); return WKBundleFrameCallShouldCloseOnWebView(mainFrame); } void TestRunner::queueBackNavigation(unsigned howFarBackward) { - InjectedBundle::shared().queueBackNavigation(howFarBackward); + InjectedBundle::singleton().queueBackNavigation(howFarBackward); } void TestRunner::queueForwardNavigation(unsigned howFarForward) { - InjectedBundle::shared().queueForwardNavigation(howFarForward); + InjectedBundle::singleton().queueForwardNavigation(howFarForward); } -void TestRunner::queueLoad(JSStringRef url, JSStringRef target) +void TestRunner::queueLoad(JSStringRef url, JSStringRef target, bool shouldOpenExternalURLs) { - WKRetainPtr<WKURLRef> baseURLWK(AdoptWK, WKBundleFrameCopyURL(WKBundlePageGetMainFrame(InjectedBundle::shared().page()->page()))); + auto& injectedBundle = InjectedBundle::singleton(); + WKRetainPtr<WKURLRef> baseURLWK(AdoptWK, WKBundleFrameCopyURL(WKBundlePageGetMainFrame(injectedBundle.page()->page()))); WKRetainPtr<WKURLRef> urlWK(AdoptWK, WKURLCreateWithBaseURL(baseURLWK.get(), toWTFString(toWK(url)).utf8().data())); WKRetainPtr<WKStringRef> urlStringWK(AdoptWK, WKURLCopyString(urlWK.get())); - InjectedBundle::shared().queueLoad(urlStringWK.get(), toWK(target).get()); + injectedBundle.queueLoad(urlStringWK.get(), toWK(target).get(), shouldOpenExternalURLs); } void TestRunner::queueLoadHTMLString(JSStringRef content, JSStringRef baseURL, JSStringRef unreachableURL) @@ -757,45 +957,59 @@ void TestRunner::queueLoadHTMLString(JSStringRef content, JSStringRef baseURL, J WKRetainPtr<WKStringRef> baseURLWK = baseURL ? toWK(baseURL) : WKRetainPtr<WKStringRef>(); WKRetainPtr<WKStringRef> unreachableURLWK = unreachableURL ? toWK(unreachableURL) : WKRetainPtr<WKStringRef>(); - InjectedBundle::shared().queueLoadHTMLString(contentWK.get(), baseURLWK.get(), unreachableURLWK.get()); + InjectedBundle::singleton().queueLoadHTMLString(contentWK.get(), baseURLWK.get(), unreachableURLWK.get()); } void TestRunner::queueReload() { - InjectedBundle::shared().queueReload(); + InjectedBundle::singleton().queueReload(); } void TestRunner::queueLoadingScript(JSStringRef script) { WKRetainPtr<WKStringRef> scriptWK = toWK(script); - InjectedBundle::shared().queueLoadingScript(scriptWK.get()); + InjectedBundle::singleton().queueLoadingScript(scriptWK.get()); } void TestRunner::queueNonLoadingScript(JSStringRef script) { WKRetainPtr<WKStringRef> scriptWK = toWK(script); - InjectedBundle::shared().queueNonLoadingScript(scriptWK.get()); + InjectedBundle::singleton().queueNonLoadingScript(scriptWK.get()); } +void TestRunner::setRejectsProtectionSpaceAndContinueForAuthenticationChallenges(bool value) +{ + WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("SetRejectsProtectionSpaceAndContinueForAuthenticationChallenges")); + WKRetainPtr<WKBooleanRef> messageBody(AdoptWK, WKBooleanCreate(value)); + WKBundlePagePostMessage(InjectedBundle::singleton().page()->page(), messageName.get(), messageBody.get()); +} + void TestRunner::setHandlesAuthenticationChallenges(bool handlesAuthenticationChallenges) { - WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("SetHandlesAuthenticationChallenge")); + WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("SetHandlesAuthenticationChallenges")); WKRetainPtr<WKBooleanRef> messageBody(AdoptWK, WKBooleanCreate(handlesAuthenticationChallenges)); - WKBundlePostMessage(InjectedBundle::shared().bundle(), messageName.get(), messageBody.get()); + WKBundlePagePostMessage(InjectedBundle::singleton().page()->page(), messageName.get(), messageBody.get()); +} + +void TestRunner::setShouldLogCanAuthenticateAgainstProtectionSpace(bool value) +{ + WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("SetShouldLogCanAuthenticateAgainstProtectionSpace")); + WKRetainPtr<WKBooleanRef> messageBody(AdoptWK, WKBooleanCreate(value)); + WKBundlePagePostMessage(InjectedBundle::singleton().page()->page(), messageName.get(), messageBody.get()); } void TestRunner::setAuthenticationUsername(JSStringRef username) { WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("SetAuthenticationUsername")); WKRetainPtr<WKStringRef> messageBody(AdoptWK, WKStringCreateWithJSString(username)); - WKBundlePostMessage(InjectedBundle::shared().bundle(), messageName.get(), messageBody.get()); + WKBundlePagePostMessage(InjectedBundle::singleton().page()->page(), messageName.get(), messageBody.get()); } void TestRunner::setAuthenticationPassword(JSStringRef password) { WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("SetAuthenticationPassword")); WKRetainPtr<WKStringRef> messageBody(AdoptWK, WKStringCreateWithJSString(password)); - WKBundlePostMessage(InjectedBundle::shared().bundle(), messageName.get(), messageBody.get()); + WKBundlePagePostMessage(InjectedBundle::singleton().page()->page(), messageName.get(), messageBody.get()); } bool TestRunner::secureEventInputIsEnabled() const @@ -803,7 +1017,7 @@ bool TestRunner::secureEventInputIsEnabled() const WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("SecureEventInputIsEnabled")); WKTypeRef returnData = 0; - WKBundlePostSynchronousMessage(InjectedBundle::shared().bundle(), messageName.get(), 0, &returnData); + WKBundlePagePostSynchronousMessageForTesting(InjectedBundle::singleton().page()->page(), messageName.get(), 0, &returnData); return WKBooleanGetValue(static_cast<WKBooleanRef>(returnData)); } @@ -811,21 +1025,386 @@ void TestRunner::setBlockAllPlugins(bool shouldBlock) { WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("SetBlockAllPlugins")); WKRetainPtr<WKBooleanRef> messageBody(AdoptWK, WKBooleanCreate(shouldBlock)); - WKBundlePostMessage(InjectedBundle::shared().bundle(), messageName.get(), messageBody.get()); + WKBundlePagePostMessage(InjectedBundle::singleton().page()->page(), messageName.get(), messageBody.get()); +} + +JSValueRef TestRunner::failNextNewCodeBlock() +{ + WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(InjectedBundle::singleton().page()->page()); + JSContextRef context = WKBundleFrameGetJavaScriptContext(mainFrame); + return JSC::failNextNewCodeBlock(context); } JSValueRef TestRunner::numberOfDFGCompiles(JSValueRef theFunction) { - WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(InjectedBundle::shared().page()->page()); + WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(InjectedBundle::singleton().page()->page()); JSContextRef context = WKBundleFrameGetJavaScriptContext(mainFrame); return JSC::numberOfDFGCompiles(context, theFunction); } JSValueRef TestRunner::neverInlineFunction(JSValueRef theFunction) { - WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(InjectedBundle::shared().page()->page()); + WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(InjectedBundle::singleton().page()->page()); JSContextRef context = WKBundleFrameGetJavaScriptContext(mainFrame); return JSC::setNeverInline(context, theFunction); } +void TestRunner::setShouldDecideNavigationPolicyAfterDelay(bool value) +{ + m_shouldDecideNavigationPolicyAfterDelay = value; + WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("SetShouldDecideNavigationPolicyAfterDelay")); + WKRetainPtr<WKBooleanRef> messageBody(AdoptWK, WKBooleanCreate(value)); + WKBundlePagePostMessage(InjectedBundle::singleton().page()->page(), messageName.get(), messageBody.get()); +} + +void TestRunner::setNavigationGesturesEnabled(bool value) +{ + WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("SetNavigationGesturesEnabled")); + WKRetainPtr<WKBooleanRef> messageBody(AdoptWK, WKBooleanCreate(value)); + WKBundlePagePostMessage(InjectedBundle::singleton().page()->page(), messageName.get(), messageBody.get()); +} + +void TestRunner::setIgnoresViewportScaleLimits(bool value) +{ + WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("SetIgnoresViewportScaleLimits")); + WKRetainPtr<WKBooleanRef> messageBody(AdoptWK, WKBooleanCreate(value)); + WKBundlePagePostMessage(InjectedBundle::singleton().page()->page(), messageName.get(), messageBody.get()); +} + +void TestRunner::setShouldDownloadUndisplayableMIMETypes(bool value) +{ + WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("SetShouldDownloadUndisplayableMIMETypes")); + WKRetainPtr<WKBooleanRef> messageBody(AdoptWK, WKBooleanCreate(value)); + WKBundlePagePostMessage(InjectedBundle::singleton().page()->page(), messageName.get(), messageBody.get()); +} + +static unsigned nextUIScriptCallbackID() +{ + static unsigned callbackID = FirstUIScriptCallbackID; + return callbackID++; +} + +void TestRunner::runUIScript(JSStringRef script, JSValueRef callback) +{ + unsigned callbackID = nextUIScriptCallbackID(); + cacheTestRunnerCallback(callbackID, callback); + + WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("RunUIProcessScript")); + + WKRetainPtr<WKMutableDictionaryRef> testDictionary(AdoptWK, WKMutableDictionaryCreate()); + + WKRetainPtr<WKStringRef> scriptKey(AdoptWK, WKStringCreateWithUTF8CString("Script")); + WKRetainPtr<WKStringRef> scriptValue(AdoptWK, WKStringCreateWithJSString(script)); + + WKRetainPtr<WKStringRef> callbackIDKey(AdoptWK, WKStringCreateWithUTF8CString("CallbackID")); + WKRetainPtr<WKUInt64Ref> callbackIDValue = adoptWK(WKUInt64Create(callbackID)); + + WKDictionarySetItem(testDictionary.get(), scriptKey.get(), scriptValue.get()); + WKDictionarySetItem(testDictionary.get(), callbackIDKey.get(), callbackIDValue.get()); + + WKBundlePagePostMessage(InjectedBundle::singleton().page()->page(), messageName.get(), testDictionary.get()); +} + +void TestRunner::runUIScriptCallback(unsigned callbackID, JSStringRef result) +{ + WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(InjectedBundle::singleton().page()->page()); + JSContextRef context = WKBundleFrameGetJavaScriptContext(mainFrame); + + JSValueRef resultValue = JSValueMakeString(context, result); + callTestRunnerCallback(callbackID, 1, &resultValue); +} + +void TestRunner::installDidBeginSwipeCallback(JSValueRef callback) +{ + cacheTestRunnerCallback(DidBeginSwipeCallbackID, callback); +} + +void TestRunner::installWillEndSwipeCallback(JSValueRef callback) +{ + cacheTestRunnerCallback(WillEndSwipeCallbackID, callback); +} + +void TestRunner::installDidEndSwipeCallback(JSValueRef callback) +{ + cacheTestRunnerCallback(DidEndSwipeCallbackID, callback); +} + +void TestRunner::installDidRemoveSwipeSnapshotCallback(JSValueRef callback) +{ + cacheTestRunnerCallback(DidRemoveSwipeSnapshotCallbackID, callback); +} + +void TestRunner::callDidBeginSwipeCallback() +{ + callTestRunnerCallback(DidBeginSwipeCallbackID); +} + +void TestRunner::callWillEndSwipeCallback() +{ + callTestRunnerCallback(WillEndSwipeCallbackID); +} + +void TestRunner::callDidEndSwipeCallback() +{ + callTestRunnerCallback(DidEndSwipeCallbackID); +} + +void TestRunner::callDidRemoveSwipeSnapshotCallback() +{ + callTestRunnerCallback(DidRemoveSwipeSnapshotCallbackID); +} + +void TestRunner::setStatisticsPrevalentResource(JSStringRef hostName, bool value) +{ + Vector<WKRetainPtr<WKStringRef>> keys; + Vector<WKRetainPtr<WKTypeRef>> values; + + keys.append({ AdoptWK, WKStringCreateWithUTF8CString("HostName") }); + values.append({ AdoptWK, WKStringCreateWithJSString(hostName) }); + + keys.append({ AdoptWK, WKStringCreateWithUTF8CString("Value") }); + values.append({ AdoptWK, WKBooleanCreate(value) }); + + Vector<WKStringRef> rawKeys; + Vector<WKTypeRef> rawValues; + rawKeys.resize(keys.size()); + rawValues.resize(values.size()); + + for (size_t i = 0; i < keys.size(); ++i) { + rawKeys[i] = keys[i].get(); + rawValues[i] = values[i].get(); + } + + WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("SetStatisticsPrevalentResource")); + WKRetainPtr<WKDictionaryRef> messageBody(AdoptWK, WKDictionaryCreate(rawKeys.data(), rawValues.data(), rawKeys.size())); + + WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr); +} + +bool TestRunner::isStatisticsPrevalentResource(JSStringRef hostName) +{ + WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("IsStatisticsPrevalentResource")); + WKRetainPtr<WKStringRef> messageBody(AdoptWK, WKStringCreateWithJSString(hostName)); + WKTypeRef returnData = 0; + WKBundlePagePostSynchronousMessageForTesting(InjectedBundle::singleton().page()->page(), messageName.get(), messageBody.get(), &returnData); + return WKBooleanGetValue(static_cast<WKBooleanRef>(returnData)); +} + +void TestRunner::setStatisticsHasHadUserInteraction(JSStringRef hostName, bool value) +{ + Vector<WKRetainPtr<WKStringRef>> keys; + Vector<WKRetainPtr<WKTypeRef>> values; + + keys.append({ AdoptWK, WKStringCreateWithUTF8CString("HostName") }); + values.append({ AdoptWK, WKStringCreateWithJSString(hostName) }); + + keys.append({ AdoptWK, WKStringCreateWithUTF8CString("Value") }); + values.append({ AdoptWK, WKBooleanCreate(value) }); + + Vector<WKStringRef> rawKeys; + Vector<WKTypeRef> rawValues; + rawKeys.resize(keys.size()); + rawValues.resize(values.size()); + + for (size_t i = 0; i < keys.size(); ++i) { + rawKeys[i] = keys[i].get(); + rawValues[i] = values[i].get(); + } + + WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("SetStatisticsHasHadUserInteraction")); + WKRetainPtr<WKDictionaryRef> messageBody(AdoptWK, WKDictionaryCreate(rawKeys.data(), rawValues.data(), rawKeys.size())); + + WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr); +} + +bool TestRunner::isStatisticsHasHadUserInteraction(JSStringRef hostName) +{ + WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("IsStatisticsHasHadUserInteraction")); + WKRetainPtr<WKStringRef> messageBody(AdoptWK, WKStringCreateWithJSString(hostName)); + WKTypeRef returnData = 0; + WKBundlePagePostSynchronousMessageForTesting(InjectedBundle::singleton().page()->page(), messageName.get(), messageBody.get(), &returnData); + return WKBooleanGetValue(static_cast<WKBooleanRef>(returnData)); +} + +void TestRunner::setStatisticsTimeToLiveUserInteraction(double seconds) +{ + WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("SetStatisticsTimeToLiveUserInteraction")); + WKRetainPtr<WKDoubleRef> messageBody(AdoptWK, WKDoubleCreate(seconds)); + WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr); +} + +void TestRunner::installStatisticsDidModifyDataRecordsCallback(JSValueRef callback) +{ + cacheTestRunnerCallback(StatisticsDidModifyDataRecordsCallbackID, callback); +} + +void TestRunner::statisticsDidModifyDataRecordsCallback() +{ + callTestRunnerCallback(StatisticsDidModifyDataRecordsCallbackID); +} + +void TestRunner::statisticsFireDataModificationHandler() +{ + WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("StatisticsFireDataModificationHandler")); + WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), 0, nullptr); +} + +void TestRunner::setStatisticsNotifyPagesWhenDataRecordsWereScanned(bool value) +{ + WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("StatisticsNotifyPagesWhenDataRecordsWereScanned")); + WKRetainPtr<WKBooleanRef> messageBody(AdoptWK, WKBooleanCreate(value)); + WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr); +} + +void TestRunner::setStatisticsShouldClassifyResourcesBeforeDataRecordsRemoval(bool value) +{ + WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("StatisticsShouldClassifyResourcesBeforeDataRecordsRemoval")); + WKRetainPtr<WKBooleanRef> messageBody(AdoptWK, WKBooleanCreate(value)); + WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr); +} + +void TestRunner::setStatisticsMinimumTimeBetweeenDataRecordsRemoval(double seconds) +{ + WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("SetStatisticsMinimumTimeBetweeenDataRecordsRemoval")); + WKRetainPtr<WKDoubleRef> messageBody(AdoptWK, WKDoubleCreate(seconds)); + WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr); +} + +void TestRunner::statisticsResetToConsistentState() +{ + WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("StatisticsResetToConsistentState")); + WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), 0, nullptr); +} + +#if PLATFORM(MAC) +void TestRunner::connectMockGamepad(unsigned index) +{ + WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("ConnectMockGamepad")); + WKRetainPtr<WKTypeRef> messageBody(AdoptWK, WKUInt64Create(index)); + + WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr); +} + +void TestRunner::disconnectMockGamepad(unsigned index) +{ + WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("DisconnectMockGamepad")); + WKRetainPtr<WKTypeRef> messageBody(AdoptWK, WKUInt64Create(index)); + + WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr); +} + +void TestRunner::setMockGamepadDetails(unsigned index, JSStringRef gamepadID, unsigned axisCount, unsigned buttonCount) +{ + Vector<WKRetainPtr<WKStringRef>> keys; + Vector<WKRetainPtr<WKTypeRef>> values; + + keys.append({ AdoptWK, WKStringCreateWithUTF8CString("GamepadID") }); + values.append(toWK(gamepadID)); + + keys.append({ AdoptWK, WKStringCreateWithUTF8CString("GamepadIndex") }); + values.append({ AdoptWK, WKUInt64Create(index) }); + + keys.append({ AdoptWK, WKStringCreateWithUTF8CString("AxisCount") }); + values.append({ AdoptWK, WKUInt64Create(axisCount) }); + + keys.append({ AdoptWK, WKStringCreateWithUTF8CString("ButtonCount") }); + values.append({ AdoptWK, WKUInt64Create(buttonCount) }); + + Vector<WKStringRef> rawKeys; + Vector<WKTypeRef> rawValues; + rawKeys.resize(keys.size()); + rawValues.resize(values.size()); + + for (size_t i = 0; i < keys.size(); ++i) { + rawKeys[i] = keys[i].get(); + rawValues[i] = values[i].get(); + } + + WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("SetMockGamepadDetails")); + WKRetainPtr<WKDictionaryRef> messageBody(AdoptWK, WKDictionaryCreate(rawKeys.data(), rawValues.data(), rawKeys.size())); + + WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr); +} + +void TestRunner::setMockGamepadAxisValue(unsigned index, unsigned axisIndex, double value) +{ + Vector<WKRetainPtr<WKStringRef>> keys; + Vector<WKRetainPtr<WKTypeRef>> values; + + keys.append({ AdoptWK, WKStringCreateWithUTF8CString("GamepadIndex") }); + values.append({ AdoptWK, WKUInt64Create(index) }); + + keys.append({ AdoptWK, WKStringCreateWithUTF8CString("AxisIndex") }); + values.append({ AdoptWK, WKUInt64Create(axisIndex) }); + + keys.append({ AdoptWK, WKStringCreateWithUTF8CString("Value") }); + values.append({ AdoptWK, WKDoubleCreate(value) }); + + Vector<WKStringRef> rawKeys; + Vector<WKTypeRef> rawValues; + rawKeys.resize(keys.size()); + rawValues.resize(values.size()); + + for (size_t i = 0; i < keys.size(); ++i) { + rawKeys[i] = keys[i].get(); + rawValues[i] = values[i].get(); + } + + WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("SetMockGamepadAxisValue")); + WKRetainPtr<WKDictionaryRef> messageBody(AdoptWK, WKDictionaryCreate(rawKeys.data(), rawValues.data(), rawKeys.size())); + + WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr); +} + +void TestRunner::setMockGamepadButtonValue(unsigned index, unsigned buttonIndex, double value) +{ + Vector<WKRetainPtr<WKStringRef>> keys; + Vector<WKRetainPtr<WKTypeRef>> values; + + keys.append({ AdoptWK, WKStringCreateWithUTF8CString("GamepadIndex") }); + values.append({ AdoptWK, WKUInt64Create(index) }); + + keys.append({ AdoptWK, WKStringCreateWithUTF8CString("ButtonIndex") }); + values.append({ AdoptWK, WKUInt64Create(buttonIndex) }); + + keys.append({ AdoptWK, WKStringCreateWithUTF8CString("Value") }); + values.append({ AdoptWK, WKDoubleCreate(value) }); + + Vector<WKStringRef> rawKeys; + Vector<WKTypeRef> rawValues; + rawKeys.resize(keys.size()); + rawValues.resize(values.size()); + + for (size_t i = 0; i < keys.size(); ++i) { + rawKeys[i] = keys[i].get(); + rawValues[i] = values[i].get(); + } + + WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("SetMockGamepadButtonValue")); + WKRetainPtr<WKDictionaryRef> messageBody(AdoptWK, WKDictionaryCreate(rawKeys.data(), rawValues.data(), rawKeys.size())); + + WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr); +} +#else +void TestRunner::connectMockGamepad(unsigned) +{ +} + +void TestRunner::disconnectMockGamepad(unsigned) +{ +} + +void TestRunner::setMockGamepadDetails(unsigned, JSStringRef, unsigned, unsigned) +{ +} + +void TestRunner::setMockGamepadAxisValue(unsigned, unsigned, double) +{ +} + +void TestRunner::setMockGamepadButtonValue(unsigned, unsigned, double) +{ +} +#endif // PLATFORM(MAC) + } // namespace WTR |