diff options
Diffstat (limited to 'Tools/DumpRenderTree/TestRunner.cpp')
-rw-r--r-- | Tools/DumpRenderTree/TestRunner.cpp | 466 |
1 files changed, 294 insertions, 172 deletions
diff --git a/Tools/DumpRenderTree/TestRunner.cpp b/Tools/DumpRenderTree/TestRunner.cpp index 7b249770e..46b8df45e 100644 --- a/Tools/DumpRenderTree/TestRunner.cpp +++ b/Tools/DumpRenderTree/TestRunner.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007, 2008, 2009, 2011, 2012 Apple Inc. All rights reserved. + * Copyright (C) 2007-2016 Apple Inc. All rights reserved. * Copyright (C) 2010 Joone Hur <joone@kldp.org> * * Redistribution and use in source and binary forms, with or without @@ -11,7 +11,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * 3. Neither the name of Apple Inc. ("Apple") nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * @@ -30,36 +30,50 @@ #include "config.h" #include "TestRunner.h" +#include "WebCoreTestSupport.h" #include "WorkQueue.h" #include "WorkQueueItem.h" #include <JavaScriptCore/APICast.h> -#include <JavaScriptCore/JSContextRef.h> +#include <JavaScriptCore/ArrayBufferView.h> +#include <JavaScriptCore/HeapInlines.h> +#include <JavaScriptCore/JSArrayBufferView.h> #include <JavaScriptCore/JSCTestRunnerUtils.h> +#include <JavaScriptCore/JSContextRef.h> #include <JavaScriptCore/JSObjectRef.h> #include <JavaScriptCore/JSRetainPtr.h> +#include <JavaScriptCore/TypedArrayInlines.h> +#include <JavaScriptCore/VMInlines.h> +#include <WebCore/LogInitialization.h> #include <cstring> #include <locale.h> -#include <runtime/ArrayBufferView.h> -#include <runtime/JSArrayBufferView.h> -#include <runtime/TypedArrayInlines.h> #include <stdio.h> #include <wtf/Assertions.h> #include <wtf/CurrentTime.h> +#include <wtf/LoggingAccumulator.h> #include <wtf/MathExtras.h> #include <wtf/RefPtr.h> +#include <wtf/RunLoop.h> #include <wtf/StdLibExtras.h> +#include <wtf/text/WTFString.h> + +#if PLATFORM(IOS) +#include <WebCore/WebCoreThreadRun.h> +#include <wtf/BlockPtr.h> +#endif #if PLATFORM(MAC) && !PLATFORM(IOS) #include <Carbon/Carbon.h> #endif +FILE* testResult = stdout; + const unsigned TestRunner::viewWidth = 800; const unsigned TestRunner::viewHeight = 600; const unsigned TestRunner::w3cSVGViewWidth = 480; const unsigned TestRunner::w3cSVGViewHeight = 360; -TestRunner::TestRunner(const std::string& testPathOrURL, const std::string& expectedPixelHash) +TestRunner::TestRunner(const std::string& testURL, const std::string& expectedPixelHash) : m_disallowIncreaseForApplicationCacheQuota(false) , m_dumpApplicationCacheDelegateCallbacks(false) , m_dumpAsAudio(false) @@ -81,7 +95,6 @@ TestRunner::TestRunner(const std::string& testPathOrURL, const std::string& expe , m_dumpSourceAsWebArchive(false) , m_dumpStatusCallbacks(false) , m_dumpTitleChanges(false) - , m_dumpIconChanges(false) , m_dumpVisitedLinksCallback(false) , m_dumpWillCacheResponse(false) , m_generatePixelResults(true) @@ -101,9 +114,9 @@ TestRunner::TestRunner(const std::string& testPathOrURL, const std::string& expe , m_globalFlag(false) , m_isGeolocationPermissionSet(false) , m_geolocationPermission(false) + , m_rejectsProtectionSpaceAndContinueForAuthenticationChallenges(false) , m_handlesAuthenticationChallenges(false) , m_isPrinting(false) - , m_deferMainResourceDataLoad(true) , m_useDeferredFrameLoading(false) , m_shouldPaintBrokenImage(true) , m_shouldStayOnPageAfterHandlingBeforeUnload(false) @@ -112,15 +125,16 @@ TestRunner::TestRunner(const std::string& testPathOrURL, const std::string& expe , m_hasPendingWebNotificationClick(false) , m_databaseDefaultQuota(-1) , m_databaseMaxQuota(-1) - , m_testPathOrURL(testPathOrURL) + , m_testURL(testURL) , m_expectedPixelHash(expectedPixelHash) , m_titleTextDirection("ltr") + , m_timeout(0) { } -PassRefPtr<TestRunner> TestRunner::create(const std::string& testPathOrURL, const std::string& expectedPixelHash) +Ref<TestRunner> TestRunner::create(const std::string& testURL, const std::string& expectedPixelHash) { - return adoptRef(new TestRunner(testPathOrURL, expectedPixelHash)); + return adoptRef(*new TestRunner(testURL, expectedPixelHash)); } // Static Functions @@ -262,13 +276,6 @@ static JSValueRef dumpTitleChangesCallback(JSContextRef context, JSObjectRef fun return JSValueMakeUndefined(context); } -static JSValueRef dumpIconChangesCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) -{ - TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject)); - controller->setDumpIconChanges(true); - return JSValueMakeUndefined(context); -} - static JSValueRef dumpWillCacheResponseCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) { TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject)); @@ -340,9 +347,12 @@ static JSValueRef setAudioResultCallback(JSContextRef context, JSObjectRef funct return JSValueMakeUndefined(context); // FIXME (123058): Use a JSC API to get buffer contents once such is exposed. - JSC::JSArrayBufferView* jsBufferView = JSC::jsDynamicCast<JSC::JSArrayBufferView*>(toJS(toJS(context), arguments[0])); + JSC::VM& vm = toJS(context)->vm(); + JSC::JSLockHolder lock(vm); + + JSC::JSArrayBufferView* jsBufferView = JSC::jsDynamicCast<JSC::JSArrayBufferView*>(vm, toJS(toJS(context), arguments[0])); ASSERT(jsBufferView); - RefPtr<JSC::ArrayBufferView> bufferView = jsBufferView->impl(); + RefPtr<JSC::ArrayBufferView> bufferView = jsBufferView->unsharedImpl(); const char* buffer = static_cast<const char*>(bufferView->baseAddress()); std::vector<char> audioData(buffer, buffer + bufferView->byteLength()); @@ -466,73 +476,6 @@ static JSValueRef clearAllDatabasesCallback(JSContextRef context, JSObjectRef fu return JSValueMakeUndefined(context); } -static JSValueRef syncLocalStorageCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) -{ - TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject)); - - controller->syncLocalStorage(); - - return JSValueMakeUndefined(context); -} - -static JSValueRef observeStorageTrackerNotificationsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) -{ - TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject)); - - if (argumentCount < 1) - return JSValueMakeUndefined(context); - - unsigned numNotifications = JSValueToNumber(context, arguments[0], exception); - - ASSERT(!*exception); - - controller->observeStorageTrackerNotifications(numNotifications); - - return JSValueMakeUndefined(context); -} - -static JSValueRef deleteAllLocalStorageCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) -{ - TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject)); - controller->deleteAllLocalStorage(); - - return JSValueMakeUndefined(context); -} - -static JSValueRef deleteLocalStorageForOriginCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) -{ - TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject)); - - if (argumentCount < 1) - return JSValueMakeUndefined(context); - - JSRetainPtr<JSStringRef> url(Adopt, JSValueToStringCopy(context, arguments[0], exception)); - ASSERT(!*exception); - - controller->deleteLocalStorageForOrigin(url.get()); - - return JSValueMakeUndefined(context); -} - -static JSValueRef localStorageDiskUsageForOriginCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) -{ - TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject)); - - if (argumentCount < 1) - return JSValueMakeUndefined(context); - - JSRetainPtr<JSStringRef> originURL(Adopt, JSValueToStringCopy(context, arguments[0], exception)); - ASSERT(!*exception); - - return JSValueMakeNumber(context, controller->localStorageDiskUsageForOrigin(originURL.get())); -} - -static JSValueRef originsWithLocalStorageCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) -{ - TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject)); - return controller->originsWithLocalStorage(context); -} - static JSValueRef clearBackForwardListCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) { // Has mac & windows implementation @@ -712,6 +655,12 @@ static JSValueRef numberOfPendingGeolocationPermissionRequestsCallback(JSContext return JSValueMakeNumber(context, controller->numberOfPendingGeolocationPermissionRequests()); } +static JSValueRef isGeolocationProviderActiveCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) +{ + TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject)); + return JSValueMakeBoolean(context, controller->isGeolocationProviderActive()); +} + static JSValueRef queueBackNavigationCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) { // Has mac & windows implementation @@ -977,18 +926,6 @@ static JSValueRef setDatabaseQuotaCallback(JSContextRef context, JSObjectRef fun return JSValueMakeUndefined(context); } -static JSValueRef setDeferMainResourceDataLoadCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) -{ - // Has Mac and Windows implementation - if (argumentCount < 1) - return JSValueMakeUndefined(context); - - TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject)); - controller->setDeferMainResourceDataLoad(JSValueToBoolean(context, arguments[0])); - - return JSValueMakeUndefined(context); -} - static JSValueRef setDefersLoadingCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) { if (argumentCount < 1) @@ -1104,38 +1041,6 @@ static JSValueRef setMockGeolocationPositionUnavailableErrorCallback(JSContextRe return JSValueMakeUndefined(context); } -static JSValueRef addMockSpeechInputResultCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) -{ - if (argumentCount < 3) - return JSValueMakeUndefined(context); - - JSRetainPtr<JSStringRef> result(Adopt, JSValueToStringCopy(context, arguments[0], exception)); - ASSERT(!*exception); - - double confidence = JSValueToNumber(context, arguments[1], exception); - - JSRetainPtr<JSStringRef> language(Adopt, JSValueToStringCopy(context, arguments[2], exception)); - ASSERT(!*exception); - - TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject)); - controller->addMockSpeechInputResult(result.get(), confidence, language.get()); - - return JSValueMakeUndefined(context); -} - -static JSValueRef setMockSpeechInputDumpRectCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) -{ - if (argumentCount < 1) - return JSValueMakeUndefined(context); - - bool dumpRect = JSValueToBoolean(context, arguments[0]); - - TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject)); - controller->setMockSpeechInputDumpRect(dumpRect); - - return JSValueMakeUndefined(context); -} - static JSValueRef setNewWindowsCopyBackForwardListCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) { // Has mac implementation @@ -1160,6 +1065,18 @@ static JSValueRef setGeolocationPermissionCallback(JSContextRef context, JSObjec return JSValueMakeUndefined(context); } +static JSValueRef setRejectsProtectionSpaceAndContinueForAuthenticationChallengesCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) +{ + // Has mac & windows implementation + if (argumentCount < 1) + return JSValueMakeUndefined(context); + + TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject)); + controller->setRejectsProtectionSpaceAndContinueForAuthenticationChallenges(JSValueToBoolean(context, arguments[0])); + + return JSValueMakeUndefined(context); +} + static JSValueRef setHandlesAuthenticationChallengesCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) { // Has mac & windows implementation @@ -1279,6 +1196,15 @@ static JSValueRef setPrintingCallback(JSContextRef context, JSObjectRef function return JSValueMakeUndefined(context); } +static JSValueRef setAllowsAnySSLCertificateCallback(JSContextRef context, JSObjectRef, JSObjectRef, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) +{ + bool allowAnyCertificate = false; + if (argumentCount == 1) + allowAnyCertificate = JSValueToBoolean(context, arguments[0]); + + TestRunner::setAllowsAnySSLCertificate(allowAnyCertificate); + return JSValueMakeUndefined(context); +} static JSValueRef setAllowUniversalAccessFromFileURLsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) { @@ -1304,6 +1230,18 @@ static JSValueRef setAllowFileAccessFromFileURLsCallback(JSContextRef context, J return JSValueMakeUndefined(context); } +static JSValueRef setNeedsStorageAccessFromFileURLsQuirkCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) +{ + // Has mac & windows implementation + if (argumentCount < 1) + return JSValueMakeUndefined(context); + + TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject)); + controller->setNeedsStorageAccessFromFileURLsQuirk(JSValueToBoolean(context, arguments[0])); + + return JSValueMakeUndefined(context); +} + static JSValueRef setTabKeyCyclesThroughElementsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) { // Has mac & windows implementation @@ -1340,19 +1278,6 @@ static JSValueRef setPagePausedCallback(JSContextRef context, JSObjectRef functi } #endif -#if ENABLE(IOS_TEXT_AUTOSIZING) -static JSValueRef setTextAutosizingEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) -{ - if (argumentCount < 1) - return JSValueMakeUndefined(context); - - TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject)); - controller->setTextAutosizingEnabled(JSValueToBoolean(context, arguments[0])); - - return JSValueMakeUndefined(context); -} -#endif - static JSValueRef setUseDashboardCompatibilityModeCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) { // Has mac implementation @@ -1477,6 +1402,22 @@ static JSValueRef setWindowIsKeyCallback(JSContextRef context, JSObjectRef funct return JSValueMakeUndefined(context); } +static JSValueRef setViewSizeCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) +{ + if (argumentCount < 2) + return JSValueMakeUndefined(context); + + double width = JSValueToNumber(context, arguments[0], exception); + ASSERT(!*exception); + double height = JSValueToNumber(context, arguments[1], exception); + ASSERT(!*exception); + + TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject)); + controller->setViewSize(width, height); + + return JSValueMakeUndefined(context); +} + static JSValueRef waitUntilDoneCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) { // Has mac & windows implementation @@ -1579,12 +1520,10 @@ static JSValueRef closeWebInspectorCallback(JSContextRef context, JSObjectRef fu static JSValueRef evaluateInWebInspectorCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) { TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject)); - double callId = JSValueToNumber(context, arguments[0], exception); - ASSERT(!*exception); - JSRetainPtr<JSStringRef> script(Adopt, JSValueToStringCopy(context, arguments[1], exception)); + JSRetainPtr<JSStringRef> script(Adopt, JSValueToStringCopy(context, arguments[0], exception)); ASSERT(!*exception); - controller->evaluateInWebInspector(static_cast<long>(callId), script.get()); + controller->evaluateInWebInspector(script.get()); return JSValueMakeUndefined(context); } @@ -1842,8 +1781,31 @@ static JSValueRef preciseTimeCallback(JSContextRef context, JSObjectRef, JSObjec return JSValueMakeNumber(context, WTF::currentTime()); } +static JSValueRef imageCountInGeneralPasteboardCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) +{ + // Has mac & windows implementation + TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject)); + + return JSValueMakeNumber(context, controller->imageCountInGeneralPasteboard()); +} + +static JSValueRef setSpellCheckerLoggingEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) +{ + if (argumentCount < 1) + return JSValueMakeUndefined(context); + TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject)); + controller->setSpellCheckerLoggingEnabled(JSValueToBoolean(context, arguments[0])); + return JSValueMakeUndefined(context); +} + // Static Values +static JSValueRef getTimeoutCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception) +{ + TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject)); + return JSValueMakeNumber(context, controller->timeout()); +} + static JSValueRef getGlobalFlagCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception) { TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject)); @@ -1884,6 +1846,13 @@ static JSValueRef getTitleTextDirectionCallback(JSContextRef context, JSObjectRe return JSValueMakeString(context, titleDirection.get()); } +static JSValueRef getInspectorTestStubURLCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception) +{ + TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject)); + JSRetainPtr<JSStringRef> url(Adopt, controller->inspectorTestStubURL()); + return JSValueMakeString(context, url.get()); +} + static bool setGlobalFlagCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef value, JSValueRef* exception) { TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject)); @@ -2020,11 +1989,16 @@ static JSValueRef simulateWebNotificationClickCallback(JSContextRef context, JSO return JSValueMakeUndefined(context); } -static JSValueRef numberOfDFGCompiles(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) +static JSValueRef failNextNewCodeBlock(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) { if (argumentCount < 1) return JSValueMakeUndefined(context); + return JSC::failNextNewCodeBlock(context); +} + +static JSValueRef numberOfDFGCompiles(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) +{ return JSC::numberOfDFGCompiles(context, arguments[0]); } @@ -2036,6 +2010,34 @@ static JSValueRef neverInlineFunction(JSContextRef context, JSObjectRef function return JSC::setNeverInline(context, arguments[0]); } +static JSValueRef accummulateLogsForChannel(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) +{ + if (argumentCount < 1) + return JSValueMakeUndefined(context); + + JSRetainPtr<JSStringRef> channel(Adopt, JSValueToStringCopy(context, arguments[0], exception)); + ASSERT(!*exception); + + TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject)); + controller->setAccummulateLogsForChannel(channel.get()); + + return JSValueMakeUndefined(context); +} + +static JSValueRef runUIScriptCallback(JSContextRef context, JSObjectRef, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) +{ + if (argumentCount < 1) + return JSValueMakeUndefined(context); + + JSRetainPtr<JSStringRef> script = argumentCount > 0 ? JSRetainPtr<JSStringRef>(Adopt, JSValueToStringCopy(context, arguments[0], 0)) : JSRetainPtr<JSStringRef>(); + JSValueRef callback = argumentCount > 1 ? arguments[1] : JSValueMakeUndefined(context); + + TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject)); + controller->runUIScript(context, script.get(), callback); + + return JSValueMakeUndefined(context); +} + static void testRunnerObjectFinalize(JSObjectRef object) { TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(object)); @@ -2071,12 +2073,14 @@ JSClassRef TestRunner::getJSClass() JSStaticValue* TestRunner::staticValues() { static JSStaticValue staticValues[] = { + { "timeout", getTimeoutCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "globalFlag", getGlobalFlagCallback, setGlobalFlagCallback, kJSPropertyAttributeNone }, { "webHistoryItemCount", getWebHistoryItemCountCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "secureEventInputIsEnabled", getSecureEventInputIsEnabledCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "titleTextDirection", getTitleTextDirectionCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "databaseDefaultQuota", getDatabaseDefaultQuotaCallback, setDatabaseDefaultQuotaCallback, kJSPropertyAttributeNone }, { "databaseMaxQuota", getDatabaseMaxQuotaCallback, setDatabaseMaxQuotaCallback, kJSPropertyAttributeNone }, + { "inspectorTestStubURL", getInspectorTestStubURLCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { 0, 0, 0, 0 } }; return staticValues; @@ -2122,7 +2126,6 @@ JSStaticFunction* TestRunner::staticFunctions() { "dumpSourceAsWebArchive", dumpSourceAsWebArchiveCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "dumpStatusCallbacks", dumpStatusCallbacksCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "dumpTitleChanges", dumpTitleChangesCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, - { "dumpIconChanges", dumpIconChangesCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "dumpWillCacheResponse", dumpWillCacheResponseCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "encodeHostName", encodeHostNameCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "evaluateInWebInspector", evaluateInWebInspectorCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, @@ -2133,6 +2136,7 @@ JSStaticFunction* TestRunner::staticFunctions() { "originsWithApplicationCache", originsWithApplicationCacheCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "goBack", goBackCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "ignoreLegacyWebNotificationPermissionRequests", ignoreLegacyWebNotificationPermissionRequestsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, + { "isGeolocationProviderActive", isGeolocationProviderActiveCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "isCommandEnabled", isCommandEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "keepWebHistory", keepWebHistoryCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "numberOfPendingGeolocationPermissionRequests", numberOfPendingGeolocationPermissionRequestsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, @@ -2154,6 +2158,8 @@ JSStaticFunction* TestRunner::staticFunctions() { "setAcceptsEditing", setAcceptsEditingCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "setAllowUniversalAccessFromFileURLs", setAllowUniversalAccessFromFileURLsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "setAllowFileAccessFromFileURLs", setAllowFileAccessFromFileURLsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, + { "setNeedsStorageAccessFromFileURLsQuirk", setNeedsStorageAccessFromFileURLsQuirkCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, + { "setAllowsAnySSLCertificate", setAllowsAnySSLCertificateCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "setAlwaysAcceptCookies", setAlwaysAcceptCookiesCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "setAppCacheMaximumSize", setAppCacheMaximumSizeCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "setAudioResult", setAudioResultCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, @@ -2166,11 +2172,11 @@ JSStaticFunction* TestRunner::staticFunctions() { "setCloseRemainingWindowsWhenComplete", setCloseRemainingWindowsWhenCompleteCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "setCustomPolicyDelegate", setCustomPolicyDelegateCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "setDatabaseQuota", setDatabaseQuotaCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, - { "setDeferMainResourceDataLoad", setDeferMainResourceDataLoadCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "setDefersLoading", setDefersLoadingCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "setUseDeferredFrameLoading", setUseDeferredFrameLoadingCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "setDomainRelaxationForbiddenForURLScheme", setDomainRelaxationForbiddenForURLSchemeCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "setGeolocationPermission", setGeolocationPermissionCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, + { "setRejectsProtectionSpaceAndContinueForAuthenticationChallenges", setRejectsProtectionSpaceAndContinueForAuthenticationChallengesCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "setHandlesAuthenticationChallenges", setHandlesAuthenticationChallengesCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "setIconDatabaseEnabled", setIconDatabaseEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "setAutomaticLinkDetectionEnabled", setAutomaticLinkDetectionEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, @@ -2178,8 +2184,6 @@ JSStaticFunction* TestRunner::staticFunctions() { "setMockDeviceOrientation", setMockDeviceOrientationCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "setMockGeolocationPositionUnavailableError", setMockGeolocationPositionUnavailableErrorCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "setMockGeolocationPosition", setMockGeolocationPositionCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, - { "addMockSpeechInputResult", addMockSpeechInputResultCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, - { "setMockSpeechInputDumpRect", setMockSpeechInputDumpRectCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "setNewWindowsCopyBackForwardList", setNewWindowsCopyBackForwardListCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "setPageVisibility", setPageVisibilityCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "setPOSIXLocale", setPOSIXLocaleCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, @@ -2196,9 +2200,6 @@ JSStaticFunction* TestRunner::staticFunctions() { "setTelephoneNumberParsingEnabled", setTelephoneNumberParsingEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "setPagePaused", setPagePausedCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, #endif -#if ENABLE(IOS_TEXT_AUTOSIZING) - { "setTextAutosizingEnabled", setTextAutosizingEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, -#endif { "setUseDashboardCompatibilityMode", setUseDashboardCompatibilityModeCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "setUserStyleSheetEnabled", setUserStyleSheetEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "setUserStyleSheetLocation", setUserStyleSheetLocationCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, @@ -2209,6 +2210,7 @@ JSStaticFunction* TestRunner::staticFunctions() { "setWillSendRequestReturnsNull", setWillSendRequestReturnsNullCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "setWillSendRequestReturnsNullOnRedirect", setWillSendRequestReturnsNullOnRedirectCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "setWindowIsKey", setWindowIsKeyCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, + { "setViewSize", setViewSizeCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "setJavaScriptCanAccessClipboard", setJavaScriptCanAccessClipboardCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "setXSSAuditorEnabled", setXSSAuditorEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "showWebInspector", showWebInspectorCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, @@ -2221,12 +2223,6 @@ JSStaticFunction* TestRunner::staticFunctions() { "addOriginAccessWhitelistEntry", addOriginAccessWhitelistEntryCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "setScrollbarPolicy", setScrollbarPolicyCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "authenticateSession", authenticateSessionCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, - { "deleteAllLocalStorage", deleteAllLocalStorageCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, - { "syncLocalStorage", syncLocalStorageCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, - { "observeStorageTrackerNotifications", observeStorageTrackerNotificationsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, - { "deleteLocalStorageForOrigin", deleteLocalStorageForOriginCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, - { "localStorageDiskUsageForOrigin", localStorageDiskUsageForOriginCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, - { "originsWithLocalStorage", originsWithLocalStorageCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "setShouldPaintBrokenImage", setShouldPaintBrokenImageCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "setTextDirection", setTextDirectionCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "setShouldStayOnPageAfterHandlingBeforeUnload", setShouldStayOnPageAfterHandlingBeforeUnloadCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, @@ -2242,8 +2238,13 @@ JSStaticFunction* TestRunner::staticFunctions() { "denyWebNotificationPermission", denyWebNotificationPermissionCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "removeAllWebNotificationPermissions", removeAllWebNotificationPermissionsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "simulateWebNotificationClick", simulateWebNotificationClickCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, + { "failNextNewCodeBlock", failNextNewCodeBlock, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "numberOfDFGCompiles", numberOfDFGCompiles, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "neverInlineFunction", neverInlineFunction, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, + { "accummulateLogsForChannel", accummulateLogsForChannel, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, + { "runUIScript", runUIScriptCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, + { "imageCountInGeneralPasteboard", imageCountInGeneralPasteboardCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, + { "setSpellCheckerLoggingEnabled", setSpellCheckerLoggingEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { 0, 0, 0 } }; @@ -2252,37 +2253,37 @@ JSStaticFunction* TestRunner::staticFunctions() void TestRunner::queueLoadHTMLString(JSStringRef content, JSStringRef baseURL) { - WorkQueue::shared()->queue(new LoadHTMLStringItem(content, baseURL)); + WorkQueue::singleton().queue(new LoadHTMLStringItem(content, baseURL)); } void TestRunner::queueLoadAlternateHTMLString(JSStringRef content, JSStringRef baseURL, JSStringRef unreachableURL) { - WorkQueue::shared()->queue(new LoadHTMLStringItem(content, baseURL, unreachableURL)); + WorkQueue::singleton().queue(new LoadHTMLStringItem(content, baseURL, unreachableURL)); } void TestRunner::queueBackNavigation(int howFarBack) { - WorkQueue::shared()->queue(new BackItem(howFarBack)); + WorkQueue::singleton().queue(new BackItem(howFarBack)); } void TestRunner::queueForwardNavigation(int howFarForward) { - WorkQueue::shared()->queue(new ForwardItem(howFarForward)); + WorkQueue::singleton().queue(new ForwardItem(howFarForward)); } void TestRunner::queueLoadingScript(JSStringRef script) { - WorkQueue::shared()->queue(new LoadingScriptItem(script)); + WorkQueue::singleton().queue(new LoadingScriptItem(script)); } void TestRunner::queueNonLoadingScript(JSStringRef script) { - WorkQueue::shared()->queue(new NonLoadingScriptItem(script)); + WorkQueue::singleton().queue(new NonLoadingScriptItem(script)); } void TestRunner::queueReload() { - WorkQueue::shared()->queue(new ReloadItem); + WorkQueue::singleton().queue(new ReloadItem); } void TestRunner::ignoreLegacyWebNotificationPermissionRequests() @@ -2293,8 +2294,14 @@ void TestRunner::ignoreLegacyWebNotificationPermissionRequests() void TestRunner::waitToDumpWatchdogTimerFired() { const char* message = "FAIL: Timed out waiting for notifyDone to be called\n"; - fprintf(stderr, "%s", message); - fprintf(stdout, "%s", message); + fprintf(testResult, "%s", message); + + auto accumulatedLogs = getAndResetAccumulatedLogs(); + if (!accumulatedLogs.isEmpty()) { + const char* message = "Logs accumulated during test run:\n"; + fprintf(testResult, "%s%s\n", message, accumulatedLogs.utf8().data()); + } + notifyDone(); } @@ -2325,3 +2332,118 @@ void TestRunner::setShouldPaintBrokenImage(bool shouldPaintBrokenImage) { m_shouldPaintBrokenImage = shouldPaintBrokenImage; } + +void TestRunner::setAccummulateLogsForChannel(JSStringRef channel) +{ + size_t maxLength = JSStringGetMaximumUTF8CStringSize(channel); + auto buffer = std::make_unique<char[]>(maxLength + 1); + JSStringGetUTF8CString(channel, buffer.get(), maxLength + 1); + + WebCoreTestSupport::setLogChannelToAccumulate({ buffer.get() }); +} + +typedef WTF::HashMap<unsigned, JSValueRef> CallbackMap; +static CallbackMap& callbackMap() +{ + static CallbackMap& map = *new CallbackMap; + return map; +} + +void TestRunner::cacheTestRunnerCallback(unsigned index, JSValueRef callback) +{ + if (!callback) + return; + + if (callbackMap().contains(index)) { + fprintf(stderr, "FAIL: Tried to install a second TestRunner callback for the same event (id %d)\n", index); + return; + } + + JSContextRef context = mainFrameJSContext(); + JSValueProtect(context, callback); + callbackMap().add(index, callback); +} + +void TestRunner::callTestRunnerCallback(unsigned index, size_t argumentCount, const JSValueRef arguments[]) +{ + if (!callbackMap().contains(index)) + return; + + JSContextRef context = mainFrameJSContext(); + if (JSObjectRef callback = JSValueToObject(context, callbackMap().take(index), 0)) { + JSObjectCallAsFunction(context, callback, JSContextGetGlobalObject(context), argumentCount, arguments, 0); + JSValueUnprotect(context, callback); + } +} + +void TestRunner::clearTestRunnerCallbacks() +{ + JSContextRef context = mainFrameJSContext(); + + for (auto& iter : callbackMap()) { + if (JSObjectRef callback = JSValueToObject(context, iter.value, 0)) + JSValueUnprotect(context, callback); + } + + callbackMap().clear(); +} + +enum { + FirstUIScriptCallbackID = 100 +}; + +static unsigned nextUIScriptCallbackID() +{ + static unsigned callbackID = FirstUIScriptCallbackID; + return callbackID++; +} + +void TestRunner::runUIScript(JSContextRef context, JSStringRef script, JSValueRef callback) +{ + m_pendingUIScriptInvocationData = nullptr; + + unsigned callbackID = nextUIScriptCallbackID(); + cacheTestRunnerCallback(callbackID, callback); + + if (!m_UIScriptContext) + m_UIScriptContext = std::make_unique<WTR::UIScriptContext>(*this); + + String scriptString(JSStringGetCharactersPtr(script), JSStringGetLength(script)); + m_UIScriptContext->runUIScript(scriptString, callbackID); +} + +void TestRunner::callUIScriptCallback(unsigned callbackID, JSStringRef result) +{ + JSRetainPtr<JSStringRef> protectedResult(result); +#if !PLATFORM(IOS) + RunLoop::main().dispatch([protectedThis = makeRef(*this), callbackID, protectedResult]() mutable { + JSContextRef context = protectedThis->mainFrameJSContext(); + JSValueRef resultValue = JSValueMakeString(context, protectedResult.get()); + protectedThis->callTestRunnerCallback(callbackID, 1, &resultValue); + }); +#else + WebThreadRun( + BlockPtr<void()>::fromCallable([protectedThis = makeRef(*this), callbackID, protectedResult] { + JSContextRef context = protectedThis->mainFrameJSContext(); + JSValueRef resultValue = JSValueMakeString(context, protectedResult.get()); + protectedThis->callTestRunnerCallback(callbackID, 1, &resultValue); + }).get() + ); +#endif +} + +void TestRunner::uiScriptDidComplete(const String& result, unsigned callbackID) +{ + JSRetainPtr<JSStringRef> stringRef(Adopt, JSStringCreateWithUTF8CString(result.utf8().data())); + callUIScriptCallback(callbackID, stringRef.get()); +} + +void TestRunner::setAllowsAnySSLCertificate(bool allowsAnySSLCertificate) +{ + WebCoreTestSupport::setAllowsAnySSLCertificate(allowsAnySSLCertificate); +} + +void TestRunner::cleanup() +{ + clearTestRunnerCallbacks(); +} |