PSON: Make WebKitTestRunner work with process swap on navigation turned on
authorrniwa@webkit.org <rniwa@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 2 May 2018 04:05:41 +0000 (04:05 +0000)
committerrniwa@webkit.org <rniwa@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 2 May 2018 04:05:41 +0000 (04:05 +0000)
https://bugs.webkit.org/show_bug.cgi?id=185111

Reviewed by Chris Dumez.

Add the basic support for running layout tests with process-swap-on-navigation turned on.

First, move m_whatToDump, m_dumpPixels, m_waitToDump, and m_dumpFrameLoadCallbacks from WebContent process
to UI process so that calls to waitUntilDone, dumpAsText, etc... persist across process swaps.

In addition, initialize the injected bundle inside a new WebContent process when the first page is created.
This instantiates objects such as TestRunner, GCController, etc... in the new process. The initialization
can't be done in InjectedBundle::beginTesting because some steps in InjectedBundle::initialize require
the current PageGroup and Page objects. We avoid clearing databases and app cache in this case.

* WebKitTestRunner/InjectedBundle/InjectedBundle.cpp:
(WTR::InjectedBundle::didCreatePage): Send "Initialization" message to UI process. This message returns
all the dictionary values usually present in "BeginTest" message from UI process as well as "ResumeTesting"
boolean which is set when this process was created as a result of a process swap on navgation. Invoke
beginTesting with BegingTestingMode::Resume when this boolean is set.
(WTR::InjectedBundle::didReceiveMessageToPage):
(WTR::InjectedBundle::beginTesting): Don't clear database, app cache, etc... when initializing an injected
bundle after a process swap on navigation.
* WebKitTestRunner/InjectedBundle/InjectedBundle.h:
* WebKitTestRunner/InjectedBundle/InjectedBundlePage.cpp:
(WTR::InjectedBundlePage::dump):
(WTR::InjectedBundlePage::frameDidChangeLocation):
* WebKitTestRunner/InjectedBundle/TestRunner.cpp:
(WTR::TestRunner::TestRunner):
(WTR::TestRunner::shouldDumpPixels const): Added.
(WTR::TestRunner::setDumpPixels): Added.
(WTR::TestRunner::dumpAsText):
(WTR::TestRunner::whatToDump const): Added.
(WTR::TestRunner::setWhatToDump): Added.
(WTR::TestRunner::waitUntilDone):
(WTR::TestRunner::setWaitUntilDone): Added.
(WTR::TestRunner::shouldWaitUntilDone): Added.
(WTR::TestRunner::notifyDone):
(WTR::TestRunner::forceImmediateCompletion):
(WTR::TestRunner::setShouldDumpFrameLoadCallbacks): Added.
(WTR::TestRunner::shouldDumpFrameLoadCallbacks): Added.
(WTR::TestRunner::setAudioResult):
* WebKitTestRunner/InjectedBundle/TestRunner.h:
(WTR::TestRunner::dumpChildFramesAsText):
(WTR::TestRunner::dumpDOMAsWebArchive):
(WTR::TestRunner::setShouldDumpFrameLoadCallbacks): Moved to cpp.
(WTR::TestRunner::whatToDump const): Moved to cpp.
(WTR::TestRunner::shouldDumpMainFrameScrollPosition const):
(WTR::TestRunner::shouldDumpPixels const): Moved to cpp.
(WTR::TestRunner::shouldDumpFrameLoadCallbacks const): Moved to cpp.
(WTR::TestRunner::waitToDump const): Renamed to shouldWaitUntilDone and moved to cpp.
* WebKitTestRunner/TestInvocation.cpp:
(WTR::TestInvocation::TestInvocation): Initialize m_dumpFrameLoadCallbacks here.
(WTR::TestInvocation::shouldLogFrameLoadDelegates const): Deleted.
(WTR::TestInvocation::createTestSettingsDictionary): Extracted from invoke().
(WTR::TestInvocation::invoke): Sets m_startedTesting to true immediately afte sending "BeginTest" message.
m_startedTesting is later used in didReceiveSynchronousMessageFromInjectedBundle to detect whether a given
"Initialization" message is sent from a regular WebContent process (m_startedTesting is false) or the one
started as a result of a process swap on navigation (m_startedTesting is true).
(WTR::TestInvocation::didReceiveSynchronousMessageFromInjectedBundle): Added a bunch of new messgaes to
support initializing the injected bundle in a process swapped after navigation and set/get messages for
the states which must persist across process swaps within a test.
* WebKitTestRunner/TestInvocation.h:
* WebKitTestRunner/WebKitTestRunner.xcodeproj/project.pbxproj:
* Tools/WebKitTestRunner/WhatToDump.h:
(WTR::WhatToDump): Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@231222 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Tools/ChangeLog
Tools/WebKitTestRunner/InjectedBundle/InjectedBundle.cpp
Tools/WebKitTestRunner/InjectedBundle/InjectedBundle.h
Tools/WebKitTestRunner/InjectedBundle/InjectedBundlePage.cpp
Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp
Tools/WebKitTestRunner/InjectedBundle/TestRunner.h
Tools/WebKitTestRunner/TestInvocation.cpp
Tools/WebKitTestRunner/TestInvocation.h
Tools/WebKitTestRunner/WebKitTestRunner.xcodeproj/project.pbxproj
Tools/WebKitTestRunner/WhatToDump.h [new file with mode: 0644]

index 55e127a..4851101 100644 (file)
@@ -1,3 +1,72 @@
+2018-05-01  Ryosuke Niwa  <rniwa@webkit.org>
+
+        PSON: Make WebKitTestRunner work with process swap on navigation turned on
+        https://bugs.webkit.org/show_bug.cgi?id=185111
+
+        Reviewed by Chris Dumez.
+
+        Add the basic support for running layout tests with process-swap-on-navigation turned on.
+
+        First, move m_whatToDump, m_dumpPixels, m_waitToDump, and m_dumpFrameLoadCallbacks from WebContent process
+        to UI process so that calls to waitUntilDone, dumpAsText, etc... persist across process swaps.
+
+        In addition, initialize the injected bundle inside a new WebContent process when the first page is created.
+        This instantiates objects such as TestRunner, GCController, etc... in the new process. The initialization
+        can't be done in InjectedBundle::beginTesting because some steps in InjectedBundle::initialize require
+        the current PageGroup and Page objects. We avoid clearing databases and app cache in this case.
+
+        * WebKitTestRunner/InjectedBundle/InjectedBundle.cpp:
+        (WTR::InjectedBundle::didCreatePage): Send "Initialization" message to UI process. This message returns
+        all the dictionary values usually present in "BeginTest" message from UI process as well as "ResumeTesting"
+        boolean which is set when this process was created as a result of a process swap on navgation. Invoke
+        beginTesting with BegingTestingMode::Resume when this boolean is set.
+        (WTR::InjectedBundle::didReceiveMessageToPage):
+        (WTR::InjectedBundle::beginTesting): Don't clear database, app cache, etc... when initializing an injected
+        bundle after a process swap on navigation.
+        * WebKitTestRunner/InjectedBundle/InjectedBundle.h:
+        * WebKitTestRunner/InjectedBundle/InjectedBundlePage.cpp:
+        (WTR::InjectedBundlePage::dump):
+        (WTR::InjectedBundlePage::frameDidChangeLocation):
+        * WebKitTestRunner/InjectedBundle/TestRunner.cpp:
+        (WTR::TestRunner::TestRunner):
+        (WTR::TestRunner::shouldDumpPixels const): Added.
+        (WTR::TestRunner::setDumpPixels): Added.
+        (WTR::TestRunner::dumpAsText):
+        (WTR::TestRunner::whatToDump const): Added.
+        (WTR::TestRunner::setWhatToDump): Added.
+        (WTR::TestRunner::waitUntilDone):
+        (WTR::TestRunner::setWaitUntilDone): Added.
+        (WTR::TestRunner::shouldWaitUntilDone): Added.
+        (WTR::TestRunner::notifyDone):
+        (WTR::TestRunner::forceImmediateCompletion):
+        (WTR::TestRunner::setShouldDumpFrameLoadCallbacks): Added.
+        (WTR::TestRunner::shouldDumpFrameLoadCallbacks): Added.
+        (WTR::TestRunner::setAudioResult):
+        * WebKitTestRunner/InjectedBundle/TestRunner.h:
+        (WTR::TestRunner::dumpChildFramesAsText):
+        (WTR::TestRunner::dumpDOMAsWebArchive):
+        (WTR::TestRunner::setShouldDumpFrameLoadCallbacks): Moved to cpp.
+        (WTR::TestRunner::whatToDump const): Moved to cpp.
+        (WTR::TestRunner::shouldDumpMainFrameScrollPosition const):
+        (WTR::TestRunner::shouldDumpPixels const): Moved to cpp.
+        (WTR::TestRunner::shouldDumpFrameLoadCallbacks const): Moved to cpp.
+        (WTR::TestRunner::waitToDump const): Renamed to shouldWaitUntilDone and moved to cpp.
+        * WebKitTestRunner/TestInvocation.cpp:
+        (WTR::TestInvocation::TestInvocation): Initialize m_dumpFrameLoadCallbacks here.
+        (WTR::TestInvocation::shouldLogFrameLoadDelegates const): Deleted.
+        (WTR::TestInvocation::createTestSettingsDictionary): Extracted from invoke().
+        (WTR::TestInvocation::invoke): Sets m_startedTesting to true immediately afte sending "BeginTest" message.
+        m_startedTesting is later used in didReceiveSynchronousMessageFromInjectedBundle to detect whether a given
+        "Initialization" message is sent from a regular WebContent process (m_startedTesting is false) or the one
+        started as a result of a process swap on navigation (m_startedTesting is true).
+        (WTR::TestInvocation::didReceiveSynchronousMessageFromInjectedBundle): Added a bunch of new messgaes to
+        support initializing the injected bundle in a process swapped after navigation and set/get messages for
+        the states which must persist across process swaps within a test.
+        * WebKitTestRunner/TestInvocation.h:
+        * WebKitTestRunner/WebKitTestRunner.xcodeproj/project.pbxproj:
+        * Tools/WebKitTestRunner/WhatToDump.h:
+        (WTR::WhatToDump): Added.
+
 2018-05-01  Leo Balter  <leonardo.balter@gmail.com>
 
         Auto save the results for Test262
index 6eb3540..da162cb 100644 (file)
@@ -120,9 +120,25 @@ void InjectedBundle::initialize(WKBundleRef bundle, WKTypeRef initializationUser
 
 void InjectedBundle::didCreatePage(WKBundlePageRef page)
 {
+    bool isMainPage = m_pages.isEmpty();
     m_pages.append(std::make_unique<InjectedBundlePage>(page));
 
     setUpInjectedBundleClients(page);
+
+    if (!isMainPage)
+        return;
+
+    WKRetainPtr<WKStringRef> messsageName(AdoptWK, WKStringCreateWithUTF8CString("Initialization"));
+    WKTypeRef result = 0;
+    WKBundlePostSynchronousMessage(m_bundle, messsageName.get(), 0, &result);
+    ASSERT(WKGetTypeID(result) == WKDictionaryGetTypeID());
+    WKDictionaryRef initializationDictionary = static_cast<WKDictionaryRef>(result);
+
+    WKRetainPtr<WKStringRef> resumeTestingKey(AdoptWK, WKStringCreateWithUTF8CString("ResumeTesting"));
+    WKTypeRef resumeTestingValue = WKDictionaryGetItemForKey(initializationDictionary, resumeTestingKey.get());
+    ASSERT(WKGetTypeID(resumeTestingValue) == WKBooleanGetTypeID());
+    if (WKBooleanGetValue(static_cast<WKBooleanRef>(resumeTestingValue)))
+        beginTesting(initializationDictionary, BegingTestingMode::Resume);
 }
 
 void InjectedBundle::willDestroyPage(WKBundlePageRef page)
@@ -197,7 +213,7 @@ void InjectedBundle::didReceiveMessageToPage(WKBundlePageRef page, WKStringRef m
         WKRetainPtr<WKStringRef> ackMessageBody(AdoptWK, WKStringCreateWithUTF8CString("BeginTest"));
         WKBundlePagePostMessage(page, ackMessageName.get(), ackMessageBody.get());
 
-        beginTesting(messageBodyDictionary);
+        beginTesting(messageBodyDictionary, BegingTestingMode::New);
         return;
     }
 
@@ -332,7 +348,7 @@ void InjectedBundle::didReceiveMessageToPage(WKBundlePageRef page, WKStringRef m
     }
 
     if (WKStringIsEqualToUTF8CString(messageName, "WorkQueueProcessedCallback")) {
-        if (!topLoadingFrame() && !m_testRunner->waitToDump())
+        if (!topLoadingFrame() && !m_testRunner->shouldWaitUntilDone())
             InjectedBundle::page()->dump();
         return;
     }
@@ -379,7 +395,7 @@ bool InjectedBundle::booleanForKey(WKDictionaryRef dictionary, const char* key)
     return WKBooleanGetValue(static_cast<WKBooleanRef>(value));
 }
 
-void InjectedBundle::beginTesting(WKDictionaryRef settings)
+void InjectedBundle::beginTesting(WKDictionaryRef settings, BegingTestingMode testingMode)
 {
     m_state = Testing;
 
@@ -413,7 +429,6 @@ void InjectedBundle::beginTesting(WKDictionaryRef settings)
 
     m_testRunner->setPluginsEnabled(true);
 
-    m_testRunner->setShouldDumpFrameLoadCallbacks(booleanForKey(settings, "DumpFrameLoadDelegates"));
     m_testRunner->setUserStyleSheetEnabled(false);
     m_testRunner->setXSSAuditorEnabled(false);
 
@@ -435,6 +450,9 @@ void InjectedBundle::beginTesting(WKDictionaryRef settings)
 
     page()->prepare();
 
+    if (testingMode != BegingTestingMode::New)
+        return;
+
     WKBundleClearAllDatabases(m_bundle);
     WKBundlePageClearApplicationCache(page()->page());
     WKBundleResetOriginAccessWhitelists(m_bundle);
index f5eef39..7307b6c 100644 (file)
@@ -161,7 +161,8 @@ private:
     void platformInitialize(WKTypeRef initializationUserData);
     void resetLocalSettings();
 
-    void beginTesting(WKDictionaryRef initialSettings);
+    enum class BegingTestingMode { New, Resume };
+    void beginTesting(WKDictionaryRef initialSettings, BegingTestingMode);
 
     bool booleanForKey(WKDictionaryRef, const char* key);
 
index bb3946c..a8e0e11 100644 (file)
@@ -890,22 +890,22 @@ void InjectedBundlePage::dump()
     StringBuilder stringBuilder;
 
     switch (injectedBundle.testRunner()->whatToDump()) {
-    case TestRunner::RenderTree: {
+    case WhatToDump::RenderTree: {
         if (injectedBundle.testRunner()->isPrinting())
             stringBuilder.append(toWTFString(adoptWK(WKBundlePageCopyRenderTreeExternalRepresentationForPrinting(m_page)).get()));
         else
             stringBuilder.append(toWTFString(adoptWK(WKBundlePageCopyRenderTreeExternalRepresentation(m_page)).get()));
         break;
     }
-    case TestRunner::MainFrameText:
+    case WhatToDump::MainFrameText:
         dumpFrameText(WKBundlePageGetMainFrame(m_page), stringBuilder);
         break;
-    case TestRunner::AllFramesText:
+    case WhatToDump::AllFramesText:
         dumpAllFramesText(stringBuilder);
         break;
-    case TestRunner::Audio:
+    case WhatToDump::Audio:
         break;
-    case TestRunner::DOMAsWebArchive:
+    case WhatToDump::DOMAsWebArchive:
         dumpDOMAsWebArchive(frame, stringBuilder);
         break;
     }
@@ -2031,7 +2031,7 @@ void InjectedBundlePage::frameDidChangeLocation(WKBundleFrameRef frame)
 
     injectedBundle.setTopLoadingFrame(nullptr);
 
-    if (injectedBundle.testRunner()->waitToDump())
+    if (injectedBundle.testRunner()->shouldWaitUntilDone())
         return;
 
     if (injectedBundle.shouldProcessWorkQueue()) {
index e62eb93..db8f2ff 100644 (file)
@@ -62,18 +62,15 @@ Ref<TestRunner> TestRunner::create()
 }
 
 TestRunner::TestRunner()
-    : m_whatToDump(RenderTree)
-    , m_shouldDumpAllFrameScrollPositions(false)
+    : m_shouldDumpAllFrameScrollPositions(false)
     , m_shouldDumpBackForwardListsForAllWindows(false)
     , m_shouldAllowEditing(true)
     , m_shouldCloseExtraWindows(false)
     , m_dumpEditingCallbacks(false)
     , m_dumpStatusCallbacks(false)
     , m_dumpTitleChanges(false)
-    , m_dumpPixels(true)
     , m_dumpSelectionRect(false)
     , m_dumpFullScreenCallbacks(false)
-    , m_dumpFrameLoadCallbacks(false)
     , m_dumpProgressFinishedCallback(false)
     , m_dumpResourceLoadCallbacks(false)
     , m_dumpResourceResponseMIMETypes(false)
@@ -81,7 +78,6 @@ TestRunner::TestRunner()
     , m_dumpApplicationCacheDelegateCallbacks(false)
     , m_dumpDatabaseCallbacks(false)
     , m_disallowIncreaseForApplicationCacheQuota(false)
-    , m_waitToDump(false)
     , m_testRepaint(false)
     , m_testRepaintSweepHorizontally(false)
     , m_isPrinting(false)
@@ -127,11 +123,44 @@ void TestRunner::displayAndTrackRepaints()
     WKBundlePageResetTrackedRepaints(page);
 }
 
+bool TestRunner::shouldDumpPixels() const
+{
+    WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("GetDumpPixels"));
+    WKTypeRef result = 0;
+    WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), 0, &result);
+    ASSERT(WKGetTypeID(result) == WKBooleanGetTypeID());
+    return WKBooleanGetValue(static_cast<WKBooleanRef>(result));
+}
+
+void TestRunner::setDumpPixels(bool dumpPixels)
+{
+    WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("SetDumpPixels"));
+    WKRetainPtr<WKBooleanRef> messageBody(AdoptWK, WKBooleanCreate(dumpPixels));
+    WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr);
+}
+
 void TestRunner::dumpAsText(bool dumpPixels)
 {
-    if (m_whatToDump < MainFrameText)
-        m_whatToDump = MainFrameText;
-    m_dumpPixels = dumpPixels;
+    if (whatToDump() < WhatToDump::MainFrameText)
+        setWhatToDump(WhatToDump::MainFrameText);
+    setDumpPixels(dumpPixels);
+}
+    
+WhatToDump TestRunner::whatToDump() const
+{
+    WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("GetWhatToDump"));
+    WKTypeRef result = 0;
+    WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), 0, &result);
+    ASSERT(WKGetTypeID(result) == WKUInt64GetTypeID());
+    auto uint64value = WKUInt64GetValue(static_cast<WKUInt64Ref>(result));
+    return static_cast<WhatToDump>(uint64value);
+}
+
+void TestRunner::setWhatToDump(WhatToDump whatToDump)
+{
+    WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("SetWhatToDump"));
+    WKRetainPtr<WKUInt64Ref> messageBody(AdoptWK, WKUInt64Create(static_cast<uint64_t>(whatToDump)));
+    WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr);
 }
 
 void TestRunner::setCustomPolicyDelegate(bool enabled, bool permissive)
@@ -156,11 +185,28 @@ void TestRunner::waitUntilDownloadFinished()
 
 void TestRunner::waitUntilDone()
 {
-    m_waitToDump = true;
+    setWaitUntilDone(true);
+    // FIXME: Watchdog timer should be moved to UI process in order to take the elapsed time in anotehr process into account.
     if (InjectedBundle::singleton().useWaitToDumpWatchdogTimer())
         initializeWaitToDumpWatchdogTimerIfNeeded();
 }
 
+void TestRunner::setWaitUntilDone(bool value)
+{
+    WKRetainPtr<WKStringRef> messsageName(AdoptWK, WKStringCreateWithUTF8CString("SetWaitUntilDone"));
+    WKRetainPtr<WKBooleanRef> messageBody(AdoptWK, WKBooleanCreate(value));
+    WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messsageName.get(), messageBody.get(), nullptr);
+}
+
+bool TestRunner::shouldWaitUntilDone() const
+{
+    WKRetainPtr<WKStringRef> messsageName(AdoptWK, WKStringCreateWithUTF8CString("GetWaitUntilDone"));
+    WKTypeRef result = 0;
+    WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messsageName.get(), 0, &result);
+    ASSERT(WKGetTypeID(result) == WKBooleanGetTypeID());
+    return WKBooleanGetValue(static_cast<WKBooleanRef>(result));
+}
+
 void TestRunner::waitToDumpWatchdogTimerFired()
 {
     invalidateWaitToDumpWatchdogTimer();
@@ -180,14 +226,14 @@ void TestRunner::notifyDone()
     if (!injectedBundle.isTestRunning())
         return;
 
-    if (m_waitToDump && !injectedBundle.topLoadingFrame())
+    if (shouldWaitUntilDone() && !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;
+    setWaitUntilDone(false);
 }
 
 void TestRunner::forceImmediateCompletion()
@@ -196,10 +242,26 @@ void TestRunner::forceImmediateCompletion()
     if (!injectedBundle.isTestRunning())
         return;
 
-    if (m_waitToDump && injectedBundle.page())
+    if (shouldWaitUntilDone() && injectedBundle.page())
         injectedBundle.page()->dump();
 
-    m_waitToDump = false;
+    setWaitUntilDone(false);
+}
+
+void TestRunner::setShouldDumpFrameLoadCallbacks(bool value)
+{
+    WKRetainPtr<WKStringRef> messsageName(AdoptWK, WKStringCreateWithUTF8CString("SetDumpFrameLoadCallbacks"));
+    WKRetainPtr<WKBooleanRef> messageBody(AdoptWK, WKBooleanCreate(value));
+    WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messsageName.get(), messageBody.get(), nullptr);
+}
+
+bool TestRunner::shouldDumpFrameLoadCallbacks()
+{
+    WKRetainPtr<WKStringRef> messsageName(AdoptWK, WKStringCreateWithUTF8CString("GetDumpFrameLoadCallbacks"));
+    WKTypeRef result = 0;
+    WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messsageName.get(), 0, &result);
+    ASSERT(WKGetTypeID(result) == WKBooleanGetTypeID());
+    return WKBooleanGetValue(static_cast<WKBooleanRef>(result));
 }
 
 unsigned TestRunner::imageCountInGeneralPasteboard() const
@@ -527,8 +589,8 @@ void TestRunner::setAudioResult(JSContextRef context, JSValueRef data)
     // FIXME (123058): Use a JSC API to get buffer contents once such is exposed.
     WKRetainPtr<WKDataRef> audioData(AdoptWK, WKBundleCreateWKDataFromUInt8Array(injectedBundle.bundle(), context, data));
     injectedBundle.setAudioResult(audioData.get());
-    m_whatToDump = Audio;
-    m_dumpPixels = false;
+    setWhatToDump(WhatToDump::Audio);
+    setDumpPixels(false);
 }
 
 unsigned TestRunner::windowCount()
index 85bfbcf..bb6ab44 100644 (file)
@@ -27,6 +27,7 @@
 
 #include "JSWrappable.h"
 #include "StringFunctions.h"
+#include "WhatToDump.h"
 #include <JavaScriptCore/JSRetainPtr.h>
 #include <WebKit/WKBundleScriptWorld.h>
 #include <WebKit/WKRetainPtr.h>
@@ -65,7 +66,7 @@ public:
     void setTestURL(WKURLRef url) { m_testURL = url; }
     void dumpAsText(bool dumpPixels);
     void waitForPolicyDelegate();
-    void dumpChildFramesAsText() { m_whatToDump = AllFramesText; }
+    void dumpChildFramesAsText() { setWhatToDump(WhatToDump::AllFramesText); }
     void waitUntilDownloadFinished();
     void waitUntilDone();
     void notifyDone();
@@ -87,10 +88,10 @@ public:
     void dumpWillCacheResponse() { m_dumpWillCacheResponse = true; }
     void dumpApplicationCacheDelegateCallbacks() { m_dumpApplicationCacheDelegateCallbacks = true; }
     void dumpDatabaseCallbacks() { m_dumpDatabaseCallbacks = true; }
-    void dumpDOMAsWebArchive() { m_whatToDump = DOMAsWebArchive; }
+    void dumpDOMAsWebArchive() { setWhatToDump(WhatToDump::DOMAsWebArchive); }
     void dumpPolicyDelegateCallbacks() { m_dumpPolicyCallbacks = true; }
 
-    void setShouldDumpFrameLoadCallbacks(bool value) { m_dumpFrameLoadCallbacks = value; }
+    void setShouldDumpFrameLoadCallbacks(bool value);
     void setShouldDumpProgressFinishedCallback(bool value) { m_dumpProgressFinishedCallback = value; }
 
     // Special options.
@@ -192,18 +193,18 @@ public:
     void setBlockAllPlugins(bool);
     void setPluginSupportedMode(JSStringRef);
 
-    enum WhatToDump { RenderTree, MainFrameText, AllFramesText, Audio, DOMAsWebArchive };
-    WhatToDump whatToDump() const { return m_whatToDump; }
+    WhatToDump whatToDump() const;
+    void setWhatToDump(WhatToDump);
 
     bool shouldDumpAllFrameScrollPositions() const { return m_shouldDumpAllFrameScrollPositions; }
     bool shouldDumpBackForwardListsForAllWindows() const { return m_shouldDumpBackForwardListsForAllWindows; }
     bool shouldDumpEditingCallbacks() const { return m_dumpEditingCallbacks; }
-    bool shouldDumpMainFrameScrollPosition() const { return m_whatToDump == RenderTree; }
+    bool shouldDumpMainFrameScrollPosition() const { return whatToDump() == WhatToDump::RenderTree; }
     bool shouldDumpStatusCallbacks() const { return m_dumpStatusCallbacks; }
     bool shouldDumpTitleChanges() const { return m_dumpTitleChanges; }
-    bool shouldDumpPixels() const { return m_dumpPixels; }
+    bool shouldDumpPixels() const;
     bool shouldDumpFullScreenCallbacks() const { return m_dumpFullScreenCallbacks; }
-    bool shouldDumpFrameLoadCallbacks() const { return m_dumpFrameLoadCallbacks; }
+    bool shouldDumpFrameLoadCallbacks();
     bool shouldDumpProgressFinishedCallback() const { return m_dumpProgressFinishedCallback; }
     bool shouldDumpResourceLoadCallbacks() const { return m_dumpResourceLoadCallbacks; }
     bool shouldDumpResourceResponseMIMETypes() const { return m_dumpResourceResponseMIMETypes; }
@@ -219,7 +220,7 @@ public:
     bool didReceiveServerRedirectForProvisionalNavigation() const;
     void clearDidReceiveServerRedirectForProvisionalNavigation();
 
-    bool waitToDump() const { return m_waitToDump; }
+    bool shouldWaitUntilDone() const;
     void waitToDumpWatchdogTimerFired();
     void invalidateWaitToDumpWatchdogTimer();
 
@@ -449,9 +450,11 @@ private:
     void platformInitialize();
     void initializeWaitToDumpWatchdogTimerIfNeeded();
 
+    void setDumpPixels(bool);
+    void setWaitUntilDone(bool);
+
     WKRetainPtr<WKURLRef> m_testURL; // Set by InjectedBundlePage once provisional load starts.
 
-    WhatToDump m_whatToDump;
     bool m_shouldDumpAllFrameScrollPositions;
     bool m_shouldDumpBackForwardListsForAllWindows;
 
@@ -464,7 +467,6 @@ private:
     bool m_dumpPixels;
     bool m_dumpSelectionRect;
     bool m_dumpFullScreenCallbacks;
-    bool m_dumpFrameLoadCallbacks;
     bool m_dumpProgressFinishedCallback;
     bool m_dumpResourceLoadCallbacks;
     bool m_dumpResourceResponseMIMETypes;
@@ -473,7 +475,6 @@ private:
     bool m_dumpDatabaseCallbacks;
     bool m_dumpPolicyCallbacks { false };
     bool m_disallowIncreaseForApplicationCacheQuota;
-    bool m_waitToDump; // True if waitUntilDone() has been called, but notifyDone() has not yet been called.
     bool m_testRepaint;
     bool m_testRepaintSweepHorizontally;
     bool m_isPrinting;
index cd5db0a..f199f7e 100644 (file)
@@ -74,6 +74,9 @@ TestInvocation::TestInvocation(WKURLRef url, const TestOptions& options)
     WKStringGetUTF8CString(urlString.get(), urlVector.data(), stringLength + 1);
 
     m_urlString = String(urlVector.data(), stringLength);
+
+    // FIXME: Avoid mutating the setting via a test directory like this.
+    m_dumpFrameLoadCallbacks = urlContains("loading/");
 }
 
 TestInvocation::~TestInvocation()
@@ -112,37 +115,15 @@ double TestInvocation::shortTimeout() const
     return m_timeout / 1000. / 4;
 }
 
-bool TestInvocation::shouldLogFrameLoadDelegates() const
-{
-    return urlContains("loading/");
-}
-
 bool TestInvocation::shouldLogHistoryClientCallbacks() const
 {
     return urlContains("globalhistory/");
 }
 
-void TestInvocation::invoke()
+WKRetainPtr<WKMutableDictionaryRef> TestInvocation::createTestSettingsDictionary()
 {
-    TestController::singleton().configureViewForTest(*this);
-
-    WKPageSetAddsVisitedLinks(TestController::singleton().mainWebView()->page(), false);
-
-    m_textOutput.clear();
-
-    TestController::singleton().setShouldLogHistoryClientCallbacks(shouldLogHistoryClientCallbacks());
-
-    WKCookieManagerSetHTTPCookieAcceptPolicy(WKContextGetCookieManager(TestController::singleton().context()), kWKHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain);
-
-    // FIXME: We should clear out visited links here.
-
-    WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("BeginTest"));
     WKRetainPtr<WKMutableDictionaryRef> beginTestMessageBody = adoptWK(WKMutableDictionaryCreate());
 
-    WKRetainPtr<WKStringRef> dumpFrameLoadDelegatesKey = adoptWK(WKStringCreateWithUTF8CString("DumpFrameLoadDelegates"));
-    WKRetainPtr<WKBooleanRef> dumpFrameLoadDelegatesValue = adoptWK(WKBooleanCreate(shouldLogFrameLoadDelegates()));
-    WKDictionarySetItem(beginTestMessageBody.get(), dumpFrameLoadDelegatesKey.get(), dumpFrameLoadDelegatesValue.get());
-
     WKRetainPtr<WKStringRef> useFlexibleViewportKey = adoptWK(WKStringCreateWithUTF8CString("UseFlexibleViewport"));
     WKRetainPtr<WKBooleanRef> useFlexibleViewportValue = adoptWK(WKBooleanCreate(options().useFlexibleViewport));
     WKDictionarySetItem(beginTestMessageBody.get(), useFlexibleViewportKey.get(), useFlexibleViewportValue.get());
@@ -162,9 +143,30 @@ void TestInvocation::invoke()
     WKRetainPtr<WKStringRef> dumpJSConsoleLogInStdErrKey = adoptWK(WKStringCreateWithUTF8CString("DumpJSConsoleLogInStdErr"));
     WKRetainPtr<WKBooleanRef> dumpJSConsoleLogInStdErrValue = adoptWK(WKBooleanCreate(m_dumpJSConsoleLogInStdErr));
     WKDictionarySetItem(beginTestMessageBody.get(), dumpJSConsoleLogInStdErrKey.get(), dumpJSConsoleLogInStdErrValue.get());
+    
+    return beginTestMessageBody;
+}
 
+void TestInvocation::invoke()
+{
+    TestController::singleton().configureViewForTest(*this);
+
+    WKPageSetAddsVisitedLinks(TestController::singleton().mainWebView()->page(), false);
+
+    m_textOutput.clear();
+
+    TestController::singleton().setShouldLogHistoryClientCallbacks(shouldLogHistoryClientCallbacks());
+
+    WKCookieManagerSetHTTPCookieAcceptPolicy(WKContextGetCookieManager(TestController::singleton().context()), kWKHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain);
+
+    // FIXME: We should clear out visited links here.
+
+    WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("BeginTest"));
+    auto beginTestMessageBody = createTestSettingsDictionary();
     WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), beginTestMessageBody.get());
 
+    m_startedTesting = true;
+
     bool shouldOpenExternalURLs = false;
 
     TestController::singleton().runUntil(m_gotInitialResponse, TestController::noTimeout);
@@ -769,6 +771,46 @@ void TestInvocation::didReceiveMessageFromInjectedBundle(WKStringRef messageName
 
 WKRetainPtr<WKTypeRef> TestInvocation::didReceiveSynchronousMessageFromInjectedBundle(WKStringRef messageName, WKTypeRef messageBody)
 {
+    if (WKStringIsEqualToUTF8CString(messageName, "Initialization")) {
+        auto settings = createTestSettingsDictionary();
+        WKRetainPtr<WKStringRef> resumeTestingKey = adoptWK(WKStringCreateWithUTF8CString("ResumeTesting"));
+        WKRetainPtr<WKBooleanRef> resumeTestingValue = adoptWK(WKBooleanCreate(m_startedTesting));
+        WKDictionarySetItem(settings.get(), resumeTestingKey.get(), resumeTestingValue.get());
+        return settings;
+    }
+
+    if (WKStringIsEqualToUTF8CString(messageName, "SetDumpPixels")) {
+        ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
+        m_dumpPixels = WKBooleanGetValue(static_cast<WKBooleanRef>(messageBody));
+        return nullptr;
+    }
+    if (WKStringIsEqualToUTF8CString(messageName, "GetDumpPixels"))
+        return WKRetainPtr<WKTypeRef>(AdoptWK, WKBooleanCreate(m_dumpPixels));
+
+    if (WKStringIsEqualToUTF8CString(messageName, "SetWhatToDump")) {
+        ASSERT(WKGetTypeID(messageBody) == WKUInt64GetTypeID());
+        m_whatToDump = static_cast<WhatToDump>(WKUInt64GetValue(static_cast<WKUInt64Ref>(messageBody)));
+        return nullptr;
+    }
+    if (WKStringIsEqualToUTF8CString(messageName, "GetWhatToDump"))
+        return WKRetainPtr<WKTypeRef>(AdoptWK, WKUInt64Create(static_cast<uint64_t>(m_whatToDump)));
+
+    if (WKStringIsEqualToUTF8CString(messageName, "SetWaitUntilDone")) {
+        ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
+        m_waitUntilDone = static_cast<unsigned char>(WKBooleanGetValue(static_cast<WKBooleanRef>(messageBody)));
+        return nullptr;
+    }
+    if (WKStringIsEqualToUTF8CString(messageName, "GetWaitUntilDone"))
+        return WKRetainPtr<WKTypeRef>(AdoptWK, WKBooleanCreate(m_waitUntilDone));
+
+    if (WKStringIsEqualToUTF8CString(messageName, "SetDumpFrameLoadCallbacks")) {
+        ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
+        m_dumpFrameLoadCallbacks = static_cast<unsigned char>(WKBooleanGetValue(static_cast<WKBooleanRef>(messageBody)));
+        return nullptr;
+    }
+    if (WKStringIsEqualToUTF8CString(messageName, "GetDumpFrameLoadCallbacks"))
+        return WKRetainPtr<WKTypeRef>(AdoptWK, WKBooleanCreate(m_dumpFrameLoadCallbacks));
+
     if (WKStringIsEqualToUTF8CString(messageName, "SetWindowIsKey")) {
         ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
         WKBooleanRef isKeyValue = static_cast<WKBooleanRef>(messageBody);
index 555f7cb..940b324 100644 (file)
@@ -29,6 +29,7 @@
 #include "JSWrappable.h"
 #include "TestOptions.h"
 #include "UIScriptContext.h"
+#include "WhatToDump.h"
 #include <WebKit/WKRetainPtr.h>
 #include <string>
 #include <wtf/Noncopyable.h>
@@ -77,6 +78,8 @@ public:
     void didRemoveAllSessionCredentials();
     
 private:
+    WKRetainPtr<WKMutableDictionaryRef> createTestSettingsDictionary();
+
     void dumpResults();
     static void dump(const char* textToStdout, const char* textToStderr = 0, bool seenError = false);
     enum class SnapshotResultType { WebView, WebContents };
@@ -93,7 +96,6 @@ private:
     };
     static void runUISideScriptAfterUpdateCallback(WKErrorRef, void* context);
 
-    bool shouldLogFrameLoadDelegates() const;
     bool shouldLogHistoryClientCallbacks() const;
 
     void runUISideScript(WKStringRef, unsigned callbackID);
@@ -111,13 +113,17 @@ private:
     bool m_dumpJSConsoleLogInStdErr { false };
 
     // Invocation state
+    bool m_startedTesting { false };
     bool m_gotInitialResponse { false };
     bool m_gotFinalMessage { false };
     bool m_gotRepaint { false };
     bool m_error { false };
 
+    bool m_waitUntilDone { false };
+    bool m_dumpFrameLoadCallbacks { false };
     bool m_dumpPixels { false };
     bool m_pixelResultIsPending { false };
+    WhatToDump m_whatToDump { WhatToDump::RenderTree };
 
     StringBuilder m_textOutput;
     WKRetainPtr<WKDataRef> m_audioResult;
index e176b0d..8bba10d 100644 (file)
                841CC00E181185BF0042E9B6 /* Options.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Options.h; sourceTree = "<group>"; };
                8DD76FA10486AA7600D96B5E /* WebKitTestRunner */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = WebKitTestRunner; sourceTree = BUILT_PRODUCTS_DIR; };
                9B0D132E2036D346008FC8FB /* WebKitTestRunnerApp-iOS.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = "WebKitTestRunnerApp-iOS.entitlements"; sourceTree = "<group>"; };
+               9B36A270209453A0003E0651 /* WhatToDump.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WhatToDump.h; sourceTree = "<group>"; };
                A18510271B9ADE4800744AEB /* libWebKitTestRunner.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libWebKitTestRunner.a; sourceTree = BUILT_PRODUCTS_DIR; };
                A18510381B9ADF2200744AEB /* WebKitTestRunner.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = WebKitTestRunner.xcconfig; sourceTree = "<group>"; };
                A18510391B9ADFF800744AEB /* WebKitTestRunnerApp.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = WebKitTestRunnerApp.xcconfig; sourceTree = "<group>"; };
                        children = (
                                378D442213346D00006A777B /* config.h */,
                                BC99A4841208901A007E9F08 /* StringFunctions.h */,
+                               9B36A270209453A0003E0651 /* WhatToDump.h */,
                        );
                        name = Shared;
                        sourceTree = "<group>";
diff --git a/Tools/WebKitTestRunner/WhatToDump.h b/Tools/WebKitTestRunner/WhatToDump.h
new file mode 100644 (file)
index 0000000..ef0daa1
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * 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
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+namespace WTR {
+
+enum class WhatToDump : unsigned char { RenderTree, MainFrameText, AllFramesText, Audio, DOMAsWebArchive };
+
+}