Home | History | Annotate | Download | only in runner
      1 /*
      2  * Copyright (C) 2010 Google Inc. All rights reserved.
      3  * Copyright (C) 2010 Pawel Hajdan (phajdan.jr (at) chromium.org)
      4  * Copyright (C) 2012 Apple Inc. All Rights Reserved.
      5  *
      6  * Redistribution and use in source and binary forms, with or without
      7  * modification, are permitted provided that the following conditions are
      8  * met:
      9  *
     10  *     * Redistributions of source code must retain the above copyright
     11  * notice, this list of conditions and the following disclaimer.
     12  *     * Redistributions in binary form must reproduce the above
     13  * copyright notice, this list of conditions and the following disclaimer
     14  * in the documentation and/or other materials provided with the
     15  * distribution.
     16  *     * Neither the name of Google Inc. nor the names of its
     17  * contributors may be used to endorse or promote products derived from
     18  * this software without specific prior written permission.
     19  *
     20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     23  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     24  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     25  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     26  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     30  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     31  */
     32 
     33 #include "TestRunner.h"
     34 
     35 #include "MockWebSpeechInputController.h"
     36 #include "MockWebSpeechRecognizer.h"
     37 #include "NotificationPresenter.h"
     38 #include "TestInterfaces.h"
     39 #include "WebPermissions.h"
     40 #include "public/platform/WebData.h"
     41 #include "public/platform/WebDeviceMotionData.h"
     42 #include "public/platform/WebDeviceOrientationData.h"
     43 #include "public/platform/WebPoint.h"
     44 #include "public/platform/WebURLResponse.h"
     45 #include "public/testing/WebPreferences.h"
     46 #include "public/testing/WebTestDelegate.h"
     47 #include "public/testing/WebTestProxy.h"
     48 #include "public/web/WebBindings.h"
     49 #include "public/web/WebDataSource.h"
     50 #include "public/web/WebDocument.h"
     51 #include "public/web/WebElement.h"
     52 #include "public/web/WebFindOptions.h"
     53 #include "public/web/WebFrame.h"
     54 #include "public/web/WebGeolocationClientMock.h"
     55 #include "public/web/WebInputElement.h"
     56 #include "public/web/WebMIDIClientMock.h"
     57 #include "public/web/WebScriptSource.h"
     58 #include "public/web/WebSecurityPolicy.h"
     59 #include "public/web/WebSerializedScriptValue.h"
     60 #include "public/web/WebSettings.h"
     61 #include "public/web/WebSurroundingText.h"
     62 #include "public/web/WebView.h"
     63 #include "v8/include/v8.h"
     64 #include <limits>
     65 
     66 #if defined(__linux__) || defined(ANDROID)
     67 #include "public/web/linux/WebFontRendering.h"
     68 #endif
     69 
     70 using namespace blink;
     71 using namespace std;
     72 
     73 namespace WebTestRunner {
     74 
     75 namespace {
     76 
     77 class InvokeCallbackTask : public WebMethodTask<TestRunner> {
     78 public:
     79     InvokeCallbackTask(TestRunner* object, WebScopedPtr<CppVariant> callbackArguments)
     80         : WebMethodTask<TestRunner>(object)
     81         , m_callbackArguments(callbackArguments)
     82     {
     83     }
     84 
     85     virtual void runIfValid()
     86     {
     87         CppVariant invokeResult;
     88         m_callbackArguments->invokeDefault(m_callbackArguments.get(), 1, invokeResult);
     89     }
     90 
     91 private:
     92     WebScopedPtr<CppVariant> m_callbackArguments;
     93 };
     94 
     95 }
     96 
     97 TestRunner::WorkQueue::~WorkQueue()
     98 {
     99     reset();
    100 }
    101 
    102 void TestRunner::WorkQueue::processWorkSoon()
    103 {
    104     if (m_controller->topLoadingFrame())
    105         return;
    106 
    107     if (!m_queue.empty()) {
    108         // We delay processing queued work to avoid recursion problems.
    109         m_controller->m_delegate->postTask(new WorkQueueTask(this));
    110     } else if (!m_controller->m_waitUntilDone)
    111         m_controller->m_delegate->testFinished();
    112 }
    113 
    114 void TestRunner::WorkQueue::processWork()
    115 {
    116     // Quit doing work once a load is in progress.
    117     while (!m_queue.empty()) {
    118         bool startedLoad = m_queue.front()->run(m_controller->m_delegate, m_controller->m_webView);
    119         delete m_queue.front();
    120         m_queue.pop_front();
    121         if (startedLoad)
    122             return;
    123     }
    124 
    125     if (!m_controller->m_waitUntilDone && !m_controller->topLoadingFrame())
    126         m_controller->m_delegate->testFinished();
    127 }
    128 
    129 void TestRunner::WorkQueue::reset()
    130 {
    131     m_frozen = false;
    132     while (!m_queue.empty()) {
    133         delete m_queue.front();
    134         m_queue.pop_front();
    135     }
    136 }
    137 
    138 void TestRunner::WorkQueue::addWork(WorkItem* work)
    139 {
    140     if (m_frozen) {
    141         delete work;
    142         return;
    143     }
    144     m_queue.push_back(work);
    145 }
    146 
    147 
    148 TestRunner::TestRunner(TestInterfaces* interfaces)
    149     : m_testIsRunning(false)
    150     , m_closeRemainingWindows(false)
    151     , m_workQueue(this)
    152     , m_testInterfaces(interfaces)
    153     , m_delegate(0)
    154     , m_webView(0)
    155     , m_pageOverlay(0)
    156     , m_webPermissions(new WebPermissions)
    157     , m_notificationPresenter(new NotificationPresenter)
    158 {
    159     // Initialize the map that associates methods of this class with the names
    160     // they will use when called by JavaScript. The actual binding of those
    161     // names to their methods will be done by calling bindToJavaScript() (defined
    162     // by CppBoundClass, the parent to TestRunner).
    163 
    164     // Methods controlling test execution.
    165     bindMethod("notifyDone", &TestRunner::notifyDone);
    166     bindMethod("queueBackNavigation", &TestRunner::queueBackNavigation);
    167     bindMethod("queueForwardNavigation", &TestRunner::queueForwardNavigation);
    168     bindMethod("queueLoadingScript", &TestRunner::queueLoadingScript);
    169     bindMethod("queueLoad", &TestRunner::queueLoad);
    170     bindMethod("queueLoadHTMLString", &TestRunner::queueLoadHTMLString);
    171     bindMethod("queueNonLoadingScript", &TestRunner::queueNonLoadingScript);
    172     bindMethod("queueReload", &TestRunner::queueReload);
    173     bindMethod("setCloseRemainingWindowsWhenComplete", &TestRunner::setCloseRemainingWindowsWhenComplete);
    174     bindMethod("resetTestHelperControllers", &TestRunner::resetTestHelperControllers);
    175     bindMethod("setCustomPolicyDelegate", &TestRunner::setCustomPolicyDelegate);
    176     bindMethod("waitForPolicyDelegate", &TestRunner::waitForPolicyDelegate);
    177     bindMethod("waitUntilDone", &TestRunner::waitUntilDone);
    178     bindMethod("windowCount", &TestRunner::windowCount);
    179     // Methods implemented in terms of chromium's public WebKit API.
    180     bindMethod("setTabKeyCyclesThroughElements", &TestRunner::setTabKeyCyclesThroughElements);
    181     bindMethod("execCommand", &TestRunner::execCommand);
    182     bindMethod("isCommandEnabled", &TestRunner::isCommandEnabled);
    183     bindMethod("callShouldCloseOnWebView", &TestRunner::callShouldCloseOnWebView);
    184     bindMethod("setDomainRelaxationForbiddenForURLScheme", &TestRunner::setDomainRelaxationForbiddenForURLScheme);
    185     bindMethod("evaluateScriptInIsolatedWorldAndReturnValue", &TestRunner::evaluateScriptInIsolatedWorldAndReturnValue);
    186     bindMethod("evaluateScriptInIsolatedWorld", &TestRunner::evaluateScriptInIsolatedWorld);
    187     bindMethod("setIsolatedWorldSecurityOrigin", &TestRunner::setIsolatedWorldSecurityOrigin);
    188     bindMethod("setIsolatedWorldContentSecurityPolicy", &TestRunner::setIsolatedWorldContentSecurityPolicy);
    189     bindMethod("addOriginAccessWhitelistEntry", &TestRunner::addOriginAccessWhitelistEntry);
    190     bindMethod("removeOriginAccessWhitelistEntry", &TestRunner::removeOriginAccessWhitelistEntry);
    191     bindMethod("hasCustomPageSizeStyle", &TestRunner::hasCustomPageSizeStyle);
    192     bindMethod("forceRedSelectionColors", &TestRunner::forceRedSelectionColors);
    193     bindMethod("injectStyleSheet", &TestRunner::injectStyleSheet);
    194     bindMethod("startSpeechInput", &TestRunner::startSpeechInput);
    195     bindMethod("findString", &TestRunner::findString);
    196     bindMethod("setValueForUser", &TestRunner::setValueForUser);
    197     bindMethod("selectionAsMarkup", &TestRunner::selectionAsMarkup);
    198     bindMethod("setTextSubpixelPositioning", &TestRunner::setTextSubpixelPositioning);
    199     bindMethod("setPageVisibility", &TestRunner::setPageVisibility);
    200     bindMethod("setTextDirection", &TestRunner::setTextDirection);
    201     bindMethod("textSurroundingNode", &TestRunner::textSurroundingNode);
    202     bindMethod("useUnfortunateSynchronousResizeMode", &TestRunner::useUnfortunateSynchronousResizeMode);
    203     bindMethod("disableAutoResizeMode", &TestRunner::disableAutoResizeMode);
    204     bindMethod("enableAutoResizeMode", &TestRunner::enableAutoResizeMode);
    205     bindMethod("setMockDeviceMotion", &TestRunner::setMockDeviceMotion);
    206     bindMethod("setMockDeviceOrientation", &TestRunner::setMockDeviceOrientation);
    207     bindMethod("didAcquirePointerLock", &TestRunner::didAcquirePointerLock);
    208     bindMethod("didLosePointerLock", &TestRunner::didLosePointerLock);
    209     bindMethod("didNotAcquirePointerLock", &TestRunner::didNotAcquirePointerLock);
    210     bindMethod("setPointerLockWillRespondAsynchronously", &TestRunner::setPointerLockWillRespondAsynchronously);
    211     bindMethod("setPointerLockWillFailSynchronously", &TestRunner::setPointerLockWillFailSynchronously);
    212 
    213     // The following modify WebPreferences.
    214     bindMethod("setPopupBlockingEnabled", &TestRunner::setPopupBlockingEnabled);
    215     bindMethod("setJavaScriptCanAccessClipboard", &TestRunner::setJavaScriptCanAccessClipboard);
    216     bindMethod("setXSSAuditorEnabled", &TestRunner::setXSSAuditorEnabled);
    217     bindMethod("setAllowUniversalAccessFromFileURLs", &TestRunner::setAllowUniversalAccessFromFileURLs);
    218     bindMethod("setAllowFileAccessFromFileURLs", &TestRunner::setAllowFileAccessFromFileURLs);
    219     bindMethod("overridePreference", &TestRunner::overridePreference);
    220     bindMethod("setPluginsEnabled", &TestRunner::setPluginsEnabled);
    221 
    222     // The following modify the state of the TestRunner.
    223     bindMethod("dumpEditingCallbacks", &TestRunner::dumpEditingCallbacks);
    224     bindMethod("dumpAsText", &TestRunner::dumpAsText);
    225     bindMethod("dumpAsTextWithPixelResults", &TestRunner::dumpAsTextWithPixelResults);
    226     bindMethod("dumpChildFramesAsText", &TestRunner::dumpChildFramesAsText);
    227     bindMethod("dumpChildFrameScrollPositions", &TestRunner::dumpChildFrameScrollPositions);
    228     bindMethod("dumpIconChanges", &TestRunner::dumpIconChanges);
    229     bindMethod("setAudioData", &TestRunner::setAudioData);
    230     bindMethod("dumpFrameLoadCallbacks", &TestRunner::dumpFrameLoadCallbacks);
    231     bindMethod("dumpPingLoaderCallbacks", &TestRunner::dumpPingLoaderCallbacks);
    232     bindMethod("dumpUserGestureInFrameLoadCallbacks", &TestRunner::dumpUserGestureInFrameLoadCallbacks);
    233     bindMethod("dumpTitleChanges", &TestRunner::dumpTitleChanges);
    234     bindMethod("dumpCreateView", &TestRunner::dumpCreateView);
    235     bindMethod("setCanOpenWindows", &TestRunner::setCanOpenWindows);
    236     bindMethod("dumpResourceLoadCallbacks", &TestRunner::dumpResourceLoadCallbacks);
    237     bindMethod("dumpResourceRequestCallbacks", &TestRunner::dumpResourceRequestCallbacks);
    238     bindMethod("dumpResourceResponseMIMETypes", &TestRunner::dumpResourceResponseMIMETypes);
    239     bindMethod("dumpPermissionClientCallbacks", &TestRunner::dumpPermissionClientCallbacks);
    240     bindMethod("setImagesAllowed", &TestRunner::setImagesAllowed);
    241     bindMethod("setScriptsAllowed", &TestRunner::setScriptsAllowed);
    242     bindMethod("setStorageAllowed", &TestRunner::setStorageAllowed);
    243     bindMethod("setPluginsAllowed", &TestRunner::setPluginsAllowed);
    244     bindMethod("setAllowDisplayOfInsecureContent", &TestRunner::setAllowDisplayOfInsecureContent);
    245     bindMethod("setAllowRunningOfInsecureContent", &TestRunner::setAllowRunningOfInsecureContent);
    246     bindMethod("dumpStatusCallbacks", &TestRunner::dumpWindowStatusChanges);
    247     bindMethod("dumpProgressFinishedCallback", &TestRunner::dumpProgressFinishedCallback);
    248     bindMethod("dumpSpellCheckCallbacks", &TestRunner::dumpSpellCheckCallbacks);
    249     bindMethod("dumpBackForwardList", &TestRunner::dumpBackForwardList);
    250     bindMethod("setDeferMainResourceDataLoad", &TestRunner::setDeferMainResourceDataLoad);
    251     bindMethod("dumpSelectionRect", &TestRunner::dumpSelectionRect);
    252     bindMethod("testRepaint", &TestRunner::testRepaint);
    253     bindMethod("repaintSweepHorizontally", &TestRunner::repaintSweepHorizontally);
    254     bindMethod("setPrinting", &TestRunner::setPrinting);
    255     bindMethod("setShouldStayOnPageAfterHandlingBeforeUnload", &TestRunner::setShouldStayOnPageAfterHandlingBeforeUnload);
    256     bindMethod("setWillSendRequestClearHeader", &TestRunner::setWillSendRequestClearHeader);
    257     bindMethod("dumpResourceRequestPriorities", &TestRunner::dumpResourceRequestPriorities);
    258 
    259     // The following methods interact with the WebTestProxy.
    260     // The following methods interact with the WebTestDelegate.
    261     bindMethod("showWebInspector", &TestRunner::showWebInspector);
    262     bindMethod("closeWebInspector", &TestRunner::closeWebInspector);
    263     bindMethod("evaluateInWebInspector", &TestRunner::evaluateInWebInspector);
    264     bindMethod("clearAllDatabases", &TestRunner::clearAllDatabases);
    265     bindMethod("setDatabaseQuota", &TestRunner::setDatabaseQuota);
    266     bindMethod("setAlwaysAcceptCookies", &TestRunner::setAlwaysAcceptCookies);
    267     bindMethod("setWindowIsKey", &TestRunner::setWindowIsKey);
    268     bindMethod("pathToLocalResource", &TestRunner::pathToLocalResource);
    269     bindMethod("setBackingScaleFactor", &TestRunner::setBackingScaleFactor);
    270     bindMethod("setPOSIXLocale", &TestRunner::setPOSIXLocale);
    271     bindMethod("numberOfPendingGeolocationPermissionRequests", &TestRunner:: numberOfPendingGeolocationPermissionRequests);
    272     bindMethod("setGeolocationPermission", &TestRunner::setGeolocationPermission);
    273     bindMethod("setMockGeolocationPositionUnavailableError", &TestRunner::setMockGeolocationPositionUnavailableError);
    274     bindMethod("setMockGeolocationPosition", &TestRunner::setMockGeolocationPosition);
    275     bindMethod("setMIDIAccessorResult", &TestRunner::setMIDIAccessorResult);
    276     bindMethod("setMIDISysExPermission", &TestRunner::setMIDISysExPermission);
    277     bindMethod("grantWebNotificationPermission", &TestRunner::grantWebNotificationPermission);
    278     bindMethod("simulateLegacyWebNotificationClick", &TestRunner::simulateLegacyWebNotificationClick);
    279     bindMethod("cancelAllActiveNotifications", &TestRunner::cancelAllActiveNotifications);
    280     bindMethod("addMockSpeechInputResult", &TestRunner::addMockSpeechInputResult);
    281     bindMethod("setMockSpeechInputDumpRect", &TestRunner::setMockSpeechInputDumpRect);
    282     bindMethod("addMockSpeechRecognitionResult", &TestRunner::addMockSpeechRecognitionResult);
    283     bindMethod("setMockSpeechRecognitionError", &TestRunner::setMockSpeechRecognitionError);
    284     bindMethod("wasMockSpeechRecognitionAborted", &TestRunner::wasMockSpeechRecognitionAborted);
    285     bindMethod("display", &TestRunner::display);
    286     bindMethod("displayInvalidatedRegion", &TestRunner::displayInvalidatedRegion);
    287     bindMethod("isChooserShown", &TestRunner::isChooserShown);
    288 
    289     // The following modify WebPageOverlays.
    290     bindMethod("addWebPageOverlay", &TestRunner::addWebPageOverlay);
    291     bindMethod("removeWebPageOverlay", &TestRunner::removeWebPageOverlay);
    292 
    293     // Properties.
    294     bindProperty("globalFlag", &m_globalFlag);
    295     bindProperty("platformName", &m_platformName);
    296     bindProperty("tooltipText", &m_tooltipText);
    297     bindProperty("disableNotifyDone", &m_disableNotifyDone);
    298 
    299     // webHistoryItemCount is used by tests in LayoutTests\http\tests\history
    300     bindProperty("webHistoryItemCount", &m_webHistoryItemCount);
    301     bindProperty("interceptPostMessage", &m_interceptPostMessage);
    302 
    303     // The following are stubs.
    304     bindMethod("dumpDatabaseCallbacks", &TestRunner::notImplemented);
    305     bindMethod("denyWebNotificationPermission", &TestRunner::notImplemented);
    306     bindMethod("removeAllWebNotificationPermissions", &TestRunner::notImplemented);
    307     bindMethod("simulateWebNotificationClick", &TestRunner::notImplemented);
    308     bindMethod("setIconDatabaseEnabled", &TestRunner::notImplemented);
    309     bindMethod("setScrollbarPolicy", &TestRunner::notImplemented);
    310     bindMethod("clearAllApplicationCaches", &TestRunner::notImplemented);
    311     bindMethod("clearApplicationCacheForOrigin", &TestRunner::notImplemented);
    312     bindMethod("clearBackForwardList", &TestRunner::notImplemented);
    313     bindMethod("keepWebHistory", &TestRunner::notImplemented);
    314     bindMethod("setApplicationCacheOriginQuota", &TestRunner::notImplemented);
    315     bindMethod("setCallCloseOnWebViews", &TestRunner::notImplemented);
    316     bindMethod("setMainFrameIsFirstResponder", &TestRunner::notImplemented);
    317     bindMethod("setUseDashboardCompatibilityMode", &TestRunner::notImplemented);
    318     bindMethod("deleteAllLocalStorage", &TestRunner::notImplemented);
    319     bindMethod("localStorageDiskUsageForOrigin", &TestRunner::notImplemented);
    320     bindMethod("originsWithLocalStorage", &TestRunner::notImplemented);
    321     bindMethod("deleteLocalStorageForOrigin", &TestRunner::notImplemented);
    322     bindMethod("observeStorageTrackerNotifications", &TestRunner::notImplemented);
    323     bindMethod("syncLocalStorage", &TestRunner::notImplemented);
    324     bindMethod("addDisallowedURL", &TestRunner::notImplemented);
    325     bindMethod("applicationCacheDiskUsageForOrigin", &TestRunner::notImplemented);
    326     bindMethod("abortModal", &TestRunner::notImplemented);
    327 
    328     // The fallback method is called when an unknown method is invoked.
    329     bindFallbackMethod(&TestRunner::fallbackMethod);
    330 }
    331 
    332 TestRunner::~TestRunner()
    333 {
    334 }
    335 
    336 void TestRunner::setDelegate(WebTestDelegate* delegate)
    337 {
    338     m_delegate = delegate;
    339     m_webPermissions->setDelegate(delegate);
    340     m_notificationPresenter->setDelegate(delegate);
    341 }
    342 
    343 void TestRunner::setWebView(WebView* webView, WebTestProxyBase* proxy)
    344 {
    345     m_webView = webView;
    346     m_proxy = proxy;
    347 }
    348 
    349 void TestRunner::reset()
    350 {
    351     if (m_webView) {
    352         m_webView->setZoomLevel(0);
    353         m_webView->setTextZoomFactor(1);
    354         m_webView->setTabKeyCyclesThroughElements(true);
    355 #if !defined(__APPLE__) && !defined(WIN32) // Actually, TOOLKIT_GTK
    356         // (Constants copied because we can't depend on the header that defined
    357         // them from this file.)
    358         m_webView->setSelectionColors(0xff1e90ff, 0xff000000, 0xffc8c8c8, 0xff323232);
    359 #endif
    360         m_webView->removeInjectedStyleSheets();
    361         m_webView->setVisibilityState(WebPageVisibilityStateVisible, true);
    362         m_webView->mainFrame()->enableViewSourceMode(false);
    363 
    364         if (m_pageOverlay) {
    365             m_webView->removePageOverlay(m_pageOverlay);
    366             delete m_pageOverlay;
    367             m_pageOverlay = 0;
    368         }
    369     }
    370 
    371     m_topLoadingFrame = 0;
    372     m_waitUntilDone = false;
    373     m_policyDelegateEnabled = false;
    374     m_policyDelegateIsPermissive = false;
    375     m_policyDelegateShouldNotifyDone = false;
    376 
    377     WebSecurityPolicy::resetOriginAccessWhitelists();
    378 #if defined(__linux__) || defined(ANDROID)
    379     WebFontRendering::setSubpixelPositioning(false);
    380 #endif
    381 
    382     if (m_delegate) {
    383         // Reset the default quota for each origin to 5MB
    384         m_delegate->setDatabaseQuota(5 * 1024 * 1024);
    385         m_delegate->setDeviceScaleFactor(1);
    386         m_delegate->setAcceptAllCookies(false);
    387         m_delegate->setLocale("");
    388         m_delegate->useUnfortunateSynchronousResizeMode(false);
    389         m_delegate->disableAutoResizeMode(WebSize());
    390         m_delegate->deleteAllCookies();
    391     }
    392 
    393     m_dumpEditingCallbacks = false;
    394     m_dumpAsText = false;
    395     m_dumpAsMarkup = false;
    396     m_generatePixelResults = true;
    397     m_dumpChildFrameScrollPositions = false;
    398     m_dumpChildFramesAsText = false;
    399     m_dumpIconChanges = false;
    400     m_dumpAsAudio = false;
    401     m_dumpFrameLoadCallbacks = false;
    402     m_dumpPingLoaderCallbacks = false;
    403     m_dumpUserGestureInFrameLoadCallbacks = false;
    404     m_dumpTitleChanges = false;
    405     m_dumpCreateView = false;
    406     m_canOpenWindows = false;
    407     m_dumpResourceLoadCallbacks = false;
    408     m_dumpResourceRequestCallbacks = false;
    409     m_dumpResourceResponseMIMETypes = false;
    410     m_dumpWindowStatusChanges = false;
    411     m_dumpProgressFinishedCallback = false;
    412     m_dumpSpellCheckCallbacks = false;
    413     m_dumpBackForwardList = false;
    414     m_deferMainResourceDataLoad = true;
    415     m_dumpSelectionRect = false;
    416     m_testRepaint = false;
    417     m_sweepHorizontally = false;
    418     m_isPrinting = false;
    419     m_midiAccessorResult = true;
    420     m_shouldStayOnPageAfterHandlingBeforeUnload = false;
    421     m_shouldDumpResourcePriorities = false;
    422 
    423     m_httpHeadersToClear.clear();
    424 
    425     m_globalFlag.set(false);
    426     m_webHistoryItemCount.set(0);
    427     m_interceptPostMessage.set(false);
    428     m_platformName.set("chromium");
    429     m_tooltipText.set("");
    430     m_disableNotifyDone.set(false);
    431 
    432     m_webPermissions->reset();
    433 
    434     m_notificationPresenter->reset();
    435 
    436     m_pointerLocked = false;
    437     m_pointerLockPlannedResult = PointerLockWillSucceed;
    438 
    439     m_taskList.revokeAll();
    440     m_workQueue.reset();
    441 
    442     if (m_closeRemainingWindows && m_delegate)
    443         m_delegate->closeRemainingWindows();
    444     else
    445         m_closeRemainingWindows = true;
    446 }
    447 
    448 
    449 void TestRunner::setTestIsRunning(bool running)
    450 {
    451     m_testIsRunning = running;
    452 }
    453 
    454 bool TestRunner::shouldDumpEditingCallbacks() const
    455 {
    456     return m_dumpEditingCallbacks;
    457 }
    458 
    459 void TestRunner::checkResponseMimeType()
    460 {
    461     // Text output: the test page can request different types of output
    462     // which we handle here.
    463     if (!m_dumpAsText) {
    464         string mimeType = m_webView->mainFrame()->dataSource()->response().mimeType().utf8();
    465         if (mimeType == "text/plain") {
    466             m_dumpAsText = true;
    467             m_generatePixelResults = false;
    468         }
    469     }
    470 }
    471 
    472 bool TestRunner::shouldDumpAsText()
    473 {
    474     checkResponseMimeType();
    475     return m_dumpAsText;
    476 }
    477 
    478 void TestRunner::setShouldDumpAsText(bool value)
    479 {
    480     m_dumpAsText = value;
    481 }
    482 
    483 bool TestRunner::shouldDumpAsMarkup()
    484 {
    485     return m_dumpAsMarkup;
    486 }
    487 
    488 void TestRunner::setShouldDumpAsMarkup(bool value)
    489 {
    490     m_dumpAsMarkup = value;
    491 }
    492 
    493 bool TestRunner::shouldGeneratePixelResults()
    494 {
    495     checkResponseMimeType();
    496     return m_generatePixelResults;
    497 }
    498 
    499 void TestRunner::setShouldGeneratePixelResults(bool value)
    500 {
    501     m_generatePixelResults = value;
    502 }
    503 
    504 bool TestRunner::shouldDumpChildFrameScrollPositions() const
    505 {
    506     return m_dumpChildFrameScrollPositions;
    507 }
    508 
    509 bool TestRunner::shouldDumpChildFramesAsText() const
    510 {
    511     return m_dumpChildFramesAsText;
    512 }
    513 
    514 bool TestRunner::shouldDumpAsAudio() const
    515 {
    516     return m_dumpAsAudio;
    517 }
    518 
    519 const WebArrayBufferView* TestRunner::audioData() const
    520 {
    521     return &m_audioData;
    522 }
    523 
    524 bool TestRunner::shouldDumpFrameLoadCallbacks() const
    525 {
    526     return m_testIsRunning && m_dumpFrameLoadCallbacks;
    527 }
    528 
    529 void TestRunner::setShouldDumpFrameLoadCallbacks(bool value)
    530 {
    531     m_dumpFrameLoadCallbacks = value;
    532 }
    533 
    534 bool TestRunner::shouldDumpPingLoaderCallbacks() const
    535 {
    536     return m_testIsRunning && m_dumpPingLoaderCallbacks;
    537 }
    538 
    539 void TestRunner::setShouldDumpPingLoaderCallbacks(bool value)
    540 {
    541     m_dumpPingLoaderCallbacks = value;
    542 }
    543 
    544 void TestRunner::setShouldEnableViewSource(bool value)
    545 {
    546     m_webView->mainFrame()->enableViewSourceMode(value);
    547 }
    548 
    549 bool TestRunner::shouldDumpUserGestureInFrameLoadCallbacks() const
    550 {
    551     return m_testIsRunning && m_dumpUserGestureInFrameLoadCallbacks;
    552 }
    553 
    554 bool TestRunner::shouldDumpTitleChanges() const
    555 {
    556     return m_dumpTitleChanges;
    557 }
    558 
    559 bool TestRunner::shouldDumpIconChanges() const
    560 {
    561     return m_dumpIconChanges;
    562 }
    563 
    564 bool TestRunner::shouldDumpCreateView() const
    565 {
    566     return m_dumpCreateView;
    567 }
    568 
    569 bool TestRunner::canOpenWindows() const
    570 {
    571     return m_canOpenWindows;
    572 }
    573 
    574 bool TestRunner::shouldDumpResourceLoadCallbacks() const
    575 {
    576     return m_testIsRunning && m_dumpResourceLoadCallbacks;
    577 }
    578 
    579 bool TestRunner::shouldDumpResourceRequestCallbacks() const
    580 {
    581     return m_testIsRunning && m_dumpResourceRequestCallbacks;
    582 }
    583 
    584 bool TestRunner::shouldDumpResourceResponseMIMETypes() const
    585 {
    586     return m_testIsRunning && m_dumpResourceResponseMIMETypes;
    587 }
    588 
    589 WebPermissionClient* TestRunner::webPermissions() const
    590 {
    591     return m_webPermissions.get();
    592 }
    593 
    594 bool TestRunner::shouldDumpStatusCallbacks() const
    595 {
    596     return m_dumpWindowStatusChanges;
    597 }
    598 
    599 bool TestRunner::shouldDumpProgressFinishedCallback() const
    600 {
    601     return m_dumpProgressFinishedCallback;
    602 }
    603 
    604 bool TestRunner::shouldDumpSpellCheckCallbacks() const
    605 {
    606     return m_dumpSpellCheckCallbacks;
    607 }
    608 
    609 bool TestRunner::shouldDumpBackForwardList() const
    610 {
    611     return m_dumpBackForwardList;
    612 }
    613 
    614 bool TestRunner::deferMainResourceDataLoad() const
    615 {
    616     return m_deferMainResourceDataLoad;
    617 }
    618 
    619 bool TestRunner::shouldDumpSelectionRect() const
    620 {
    621     return m_dumpSelectionRect;
    622 }
    623 
    624 bool TestRunner::testRepaint() const
    625 {
    626     return m_testRepaint;
    627 }
    628 
    629 bool TestRunner::sweepHorizontally() const
    630 {
    631     return m_sweepHorizontally;
    632 }
    633 
    634 bool TestRunner::isPrinting() const
    635 {
    636     return m_isPrinting;
    637 }
    638 
    639 bool TestRunner::shouldStayOnPageAfterHandlingBeforeUnload() const
    640 {
    641     return m_shouldStayOnPageAfterHandlingBeforeUnload;
    642 }
    643 
    644 const std::set<std::string>* TestRunner::httpHeadersToClear() const
    645 {
    646     return &m_httpHeadersToClear;
    647 }
    648 
    649 void TestRunner::setTopLoadingFrame(WebFrame* frame, bool clear)
    650 {
    651     if (frame->top()->view() != m_webView)
    652         return;
    653     if (!m_testIsRunning)
    654         return;
    655     if (clear) {
    656         m_topLoadingFrame = 0;
    657         locationChangeDone();
    658     } else if (!m_topLoadingFrame)
    659         m_topLoadingFrame = frame;
    660 }
    661 
    662 WebFrame* TestRunner::topLoadingFrame() const
    663 {
    664     return m_topLoadingFrame;
    665 }
    666 
    667 void TestRunner::policyDelegateDone()
    668 {
    669     BLINK_ASSERT(m_waitUntilDone);
    670     m_delegate->testFinished();
    671     m_waitUntilDone = false;
    672 }
    673 
    674 bool TestRunner::policyDelegateEnabled() const
    675 {
    676     return m_policyDelegateEnabled;
    677 }
    678 
    679 bool TestRunner::policyDelegateIsPermissive() const
    680 {
    681     return m_policyDelegateIsPermissive;
    682 }
    683 
    684 bool TestRunner::policyDelegateShouldNotifyDone() const
    685 {
    686     return m_policyDelegateShouldNotifyDone;
    687 }
    688 
    689 bool TestRunner::shouldInterceptPostMessage() const
    690 {
    691     return m_interceptPostMessage.isBool() && m_interceptPostMessage.toBoolean();
    692 }
    693 
    694 bool TestRunner::shouldDumpResourcePriorities() const
    695 {
    696     return m_shouldDumpResourcePriorities;
    697 }
    698 
    699 WebNotificationPresenter* TestRunner::notificationPresenter() const
    700 {
    701     return m_notificationPresenter.get();
    702 }
    703 
    704 bool TestRunner::requestPointerLock()
    705 {
    706     switch (m_pointerLockPlannedResult) {
    707     case PointerLockWillSucceed:
    708         m_delegate->postDelayedTask(new HostMethodTask(this, &TestRunner::didAcquirePointerLockInternal), 0);
    709         return true;
    710     case PointerLockWillRespondAsync:
    711         BLINK_ASSERT(!m_pointerLocked);
    712         return true;
    713     case PointerLockWillFailSync:
    714         BLINK_ASSERT(!m_pointerLocked);
    715         return false;
    716     default:
    717         BLINK_ASSERT_NOT_REACHED();
    718         return false;
    719     }
    720 }
    721 
    722 void TestRunner::requestPointerUnlock()
    723 {
    724     m_delegate->postDelayedTask(new HostMethodTask(this, &TestRunner::didLosePointerLockInternal), 0);
    725 }
    726 
    727 bool TestRunner::isPointerLocked()
    728 {
    729     return m_pointerLocked;
    730 }
    731 
    732 void TestRunner::setToolTipText(const blink::WebString& text)
    733 {
    734     m_tooltipText.set(text.utf8());
    735 }
    736 
    737 bool TestRunner::midiAccessorResult()
    738 {
    739     return m_midiAccessorResult;
    740 }
    741 
    742 TestRunner::TestPageOverlay::TestPageOverlay(blink::WebView* webView) : m_webView(webView)
    743 {
    744 }
    745 
    746 TestRunner::TestPageOverlay::~TestPageOverlay()
    747 {
    748 }
    749 
    750 void TestRunner::TestPageOverlay::paintPageOverlay(blink::WebCanvas* canvas)
    751 {
    752     SkRect rect = SkRect::MakeWH(m_webView->size().width, m_webView->size().height);
    753     SkPaint paint;
    754     paint.setColor(SK_ColorCYAN);
    755     paint.setStyle(SkPaint::kFill_Style);
    756     canvas->drawRect(rect, paint);
    757 }
    758 
    759 void TestRunner::didAcquirePointerLockInternal()
    760 {
    761     m_pointerLocked = true;
    762     m_webView->didAcquirePointerLock();
    763 
    764     // Reset planned result to default.
    765     m_pointerLockPlannedResult = PointerLockWillSucceed;
    766 }
    767 
    768 void TestRunner::didNotAcquirePointerLockInternal()
    769 {
    770     BLINK_ASSERT(!m_pointerLocked);
    771     m_pointerLocked = false;
    772     m_webView->didNotAcquirePointerLock();
    773 
    774     // Reset planned result to default.
    775     m_pointerLockPlannedResult = PointerLockWillSucceed;
    776 }
    777 
    778 void TestRunner::didLosePointerLockInternal()
    779 {
    780     bool wasLocked = m_pointerLocked;
    781     m_pointerLocked = false;
    782     if (wasLocked)
    783         m_webView->didLosePointerLock();
    784 }
    785 
    786 void TestRunner::showDevTools()
    787 {
    788     m_delegate->showDevTools();
    789 }
    790 
    791 void TestRunner::waitUntilDone(const CppArgumentList&, CppVariant* result)
    792 {
    793     m_waitUntilDone = true;
    794     result->setNull();
    795 }
    796 
    797 void TestRunner::notifyDone(const CppArgumentList&, CppVariant* result)
    798 {
    799     if (m_disableNotifyDone.toBoolean())
    800         return;
    801 
    802     // Test didn't timeout. Kill the timeout timer.
    803     taskList()->revokeAll();
    804 
    805     completeNotifyDone();
    806     result->setNull();
    807 }
    808 
    809 void TestRunner::completeNotifyDone()
    810 {
    811     if (m_waitUntilDone && !topLoadingFrame() && m_workQueue.isEmpty())
    812         m_delegate->testFinished();
    813     m_waitUntilDone = false;
    814 }
    815 
    816 class WorkItemBackForward : public TestRunner::WorkItem {
    817 public:
    818     WorkItemBackForward(int distance) : m_distance(distance) { }
    819     bool run(WebTestDelegate* delegate, WebView*)
    820     {
    821         delegate->goToOffset(m_distance);
    822         return true; // FIXME: Did it really start a navigation?
    823     }
    824 
    825 private:
    826     int m_distance;
    827 };
    828 
    829 void TestRunner::queueBackNavigation(const CppArgumentList& arguments, CppVariant* result)
    830 {
    831     if (arguments.size() > 0 && arguments[0].isNumber())
    832         m_workQueue.addWork(new WorkItemBackForward(-arguments[0].toInt32()));
    833     result->setNull();
    834 }
    835 
    836 void TestRunner::queueForwardNavigation(const CppArgumentList& arguments, CppVariant* result)
    837 {
    838     if (arguments.size() > 0 && arguments[0].isNumber())
    839         m_workQueue.addWork(new WorkItemBackForward(arguments[0].toInt32()));
    840     result->setNull();
    841 }
    842 
    843 class WorkItemReload : public TestRunner::WorkItem {
    844 public:
    845     bool run(WebTestDelegate* delegate, WebView*)
    846     {
    847         delegate->reload();
    848         return true;
    849     }
    850 };
    851 
    852 void TestRunner::queueReload(const CppArgumentList&, CppVariant* result)
    853 {
    854     m_workQueue.addWork(new WorkItemReload);
    855     result->setNull();
    856 }
    857 
    858 class WorkItemLoadingScript : public TestRunner::WorkItem {
    859 public:
    860     WorkItemLoadingScript(const string& script) : m_script(script) { }
    861     bool run(WebTestDelegate*, WebView* webView)
    862     {
    863         webView->mainFrame()->executeScript(WebScriptSource(WebString::fromUTF8(m_script)));
    864         return true; // FIXME: Did it really start a navigation?
    865     }
    866 
    867 private:
    868     string m_script;
    869 };
    870 
    871 class WorkItemNonLoadingScript : public TestRunner::WorkItem {
    872 public:
    873     WorkItemNonLoadingScript(const string& script) : m_script(script) { }
    874     bool run(WebTestDelegate*, WebView* webView)
    875     {
    876         webView->mainFrame()->executeScript(WebScriptSource(WebString::fromUTF8(m_script)));
    877         return false;
    878     }
    879 
    880 private:
    881     string m_script;
    882 };
    883 
    884 void TestRunner::queueLoadingScript(const CppArgumentList& arguments, CppVariant* result)
    885 {
    886     if (arguments.size() > 0 && arguments[0].isString())
    887         m_workQueue.addWork(new WorkItemLoadingScript(arguments[0].toString()));
    888     result->setNull();
    889 }
    890 
    891 void TestRunner::queueNonLoadingScript(const CppArgumentList& arguments, CppVariant* result)
    892 {
    893     if (arguments.size() > 0 && arguments[0].isString())
    894         m_workQueue.addWork(new WorkItemNonLoadingScript(arguments[0].toString()));
    895     result->setNull();
    896 }
    897 
    898 class WorkItemLoad : public TestRunner::WorkItem {
    899 public:
    900     WorkItemLoad(const WebURL& url, const string& target)
    901         : m_url(url)
    902         , m_target(target) { }
    903     bool run(WebTestDelegate* delegate, WebView*)
    904     {
    905         delegate->loadURLForFrame(m_url, m_target);
    906         return true; // FIXME: Did it really start a navigation?
    907     }
    908 
    909 private:
    910     WebURL m_url;
    911     string m_target;
    912 };
    913 
    914 void TestRunner::queueLoad(const CppArgumentList& arguments, CppVariant* result)
    915 {
    916     if (arguments.size() > 0 && arguments[0].isString()) {
    917         // FIXME: Implement WebURL::resolve() and avoid GURL.
    918         GURL currentURL = m_webView->mainFrame()->document().url();
    919         GURL fullURL = currentURL.Resolve(arguments[0].toString());
    920 
    921         string target = "";
    922         if (arguments.size() > 1 && arguments[1].isString())
    923             target = arguments[1].toString();
    924 
    925         m_workQueue.addWork(new WorkItemLoad(fullURL, target));
    926     }
    927     result->setNull();
    928 }
    929 
    930 class WorkItemLoadHTMLString : public TestRunner::WorkItem  {
    931 public:
    932     WorkItemLoadHTMLString(const std::string& html, const WebURL& baseURL)
    933         : m_html(html)
    934         , m_baseURL(baseURL) { }
    935     WorkItemLoadHTMLString(const std::string& html, const WebURL& baseURL, const WebURL& unreachableURL)
    936         : m_html(html)
    937         , m_baseURL(baseURL)
    938         , m_unreachableURL(unreachableURL) { }
    939     bool run(WebTestDelegate*, WebView* webView)
    940     {
    941         webView->mainFrame()->loadHTMLString(
    942             blink::WebData(m_html.data(), m_html.length()), m_baseURL, m_unreachableURL);
    943         return true;
    944     }
    945 
    946 private:
    947     std::string m_html;
    948     WebURL m_baseURL;
    949     WebURL m_unreachableURL;
    950 };
    951 
    952 void TestRunner::queueLoadHTMLString(const CppArgumentList& arguments, CppVariant* result)
    953 {
    954     if (arguments.size() > 0 && arguments[0].isString()) {
    955         string html = arguments[0].toString();
    956         WebURL baseURL(GURL(""));
    957         if (arguments.size() > 1 && arguments[1].isString())
    958             baseURL = WebURL(GURL(arguments[1].toString()));
    959         if (arguments.size() > 2 && arguments[2].isString())
    960             m_workQueue.addWork(new WorkItemLoadHTMLString(html, baseURL, WebURL(GURL(arguments[2].toString()))));
    961         else
    962             m_workQueue.addWork(new WorkItemLoadHTMLString(html, baseURL));
    963     }
    964     result->setNull();
    965 }
    966 
    967 void TestRunner::locationChangeDone()
    968 {
    969     m_webHistoryItemCount.set(m_delegate->navigationEntryCount());
    970 
    971     // No more new work after the first complete load.
    972     m_workQueue.setFrozen(true);
    973 
    974     if (!m_waitUntilDone)
    975         m_workQueue.processWorkSoon();
    976 }
    977 
    978 void TestRunner::windowCount(const CppArgumentList&, CppVariant* result)
    979 {
    980     result->set(static_cast<int>(m_testInterfaces->windowList().size()));
    981 }
    982 
    983 void TestRunner::setCloseRemainingWindowsWhenComplete(const CppArgumentList& arguments, CppVariant* result)
    984 {
    985     if (arguments.size() > 0 && arguments[0].isBool())
    986         m_closeRemainingWindows = arguments[0].value.boolValue;
    987     result->setNull();
    988 }
    989 
    990 void TestRunner::resetTestHelperControllers(const CppArgumentList& arguments, CppVariant* result)
    991 {
    992     m_testInterfaces->resetTestHelperControllers();
    993 
    994     result->setNull();
    995 }
    996 
    997 void TestRunner::setCustomPolicyDelegate(const CppArgumentList& arguments, CppVariant* result)
    998 {
    999     if (arguments.size() > 0 && arguments[0].isBool()) {
   1000         m_policyDelegateEnabled = arguments[0].value.boolValue;
   1001         m_policyDelegateIsPermissive = false;
   1002         if (arguments.size() > 1 && arguments[1].isBool())
   1003             m_policyDelegateIsPermissive = arguments[1].value.boolValue;
   1004     }
   1005     result->setNull();
   1006 }
   1007 
   1008 void TestRunner::waitForPolicyDelegate(const CppArgumentList&, CppVariant* result)
   1009 {
   1010     m_policyDelegateEnabled = true;
   1011     m_policyDelegateShouldNotifyDone = true;
   1012     m_waitUntilDone = true;
   1013     result->setNull();
   1014 }
   1015 
   1016 void TestRunner::dumpPermissionClientCallbacks(const CppArgumentList&, CppVariant* result)
   1017 {
   1018     m_webPermissions->setDumpCallbacks(true);
   1019     result->setNull();
   1020 }
   1021 
   1022 void TestRunner::setImagesAllowed(const CppArgumentList& arguments, CppVariant* result)
   1023 {
   1024     if (arguments.size() > 0 && arguments[0].isBool())
   1025         m_webPermissions->setImagesAllowed(arguments[0].toBoolean());
   1026     result->setNull();
   1027 }
   1028 
   1029 void TestRunner::setScriptsAllowed(const CppArgumentList& arguments, CppVariant* result)
   1030 {
   1031     if (arguments.size() > 0 && arguments[0].isBool())
   1032         m_webPermissions->setScriptsAllowed(arguments[0].toBoolean());
   1033     result->setNull();
   1034 }
   1035 
   1036 void TestRunner::setStorageAllowed(const CppArgumentList& arguments, CppVariant* result)
   1037 {
   1038     if (arguments.size() > 0 && arguments[0].isBool())
   1039         m_webPermissions->setStorageAllowed(arguments[0].toBoolean());
   1040     result->setNull();
   1041 }
   1042 
   1043 void TestRunner::setPluginsAllowed(const CppArgumentList& arguments, CppVariant* result)
   1044 {
   1045     if (arguments.size() > 0 && arguments[0].isBool())
   1046         m_webPermissions->setPluginsAllowed(arguments[0].toBoolean());
   1047     result->setNull();
   1048 }
   1049 
   1050 void TestRunner::setAllowDisplayOfInsecureContent(const CppArgumentList& arguments, CppVariant* result)
   1051 {
   1052     if (arguments.size() > 0 && arguments[0].isBool())
   1053         m_webPermissions->setDisplayingInsecureContentAllowed(arguments[0].toBoolean());
   1054 
   1055     result->setNull();
   1056 }
   1057 
   1058 void TestRunner::setAllowRunningOfInsecureContent(const CppArgumentList& arguments, CppVariant* result)
   1059 {
   1060     if (arguments.size() > 0 && arguments[0].isBool())
   1061         m_webPermissions->setRunningInsecureContentAllowed(arguments[0].value.boolValue);
   1062 
   1063     result->setNull();
   1064 }
   1065 
   1066 void TestRunner::dumpWindowStatusChanges(const CppArgumentList&, CppVariant* result)
   1067 {
   1068     m_dumpWindowStatusChanges = true;
   1069     result->setNull();
   1070 }
   1071 
   1072 void TestRunner::dumpProgressFinishedCallback(const CppArgumentList&, CppVariant* result)
   1073 {
   1074     m_dumpProgressFinishedCallback = true;
   1075     result->setNull();
   1076 }
   1077 
   1078 void TestRunner::dumpSpellCheckCallbacks(const CppArgumentList&, CppVariant* result)
   1079 {
   1080     m_dumpSpellCheckCallbacks = true;
   1081     result->setNull();
   1082 }
   1083 
   1084 void TestRunner::dumpBackForwardList(const CppArgumentList&, CppVariant* result)
   1085 {
   1086     m_dumpBackForwardList = true;
   1087     result->setNull();
   1088 }
   1089 
   1090 void TestRunner::setDeferMainResourceDataLoad(const CppArgumentList& arguments, CppVariant* result)
   1091 {
   1092     if (arguments.size() == 1)
   1093         m_deferMainResourceDataLoad = cppVariantToBool(arguments[0]);
   1094 }
   1095 
   1096 void TestRunner::dumpSelectionRect(const CppArgumentList& arguments, CppVariant* result)
   1097 {
   1098     m_dumpSelectionRect = true;
   1099     result->setNull();
   1100 }
   1101 
   1102 void TestRunner::testRepaint(const CppArgumentList&, CppVariant* result)
   1103 {
   1104     m_testRepaint = true;
   1105     result->setNull();
   1106 }
   1107 
   1108 void TestRunner::repaintSweepHorizontally(const CppArgumentList&, CppVariant* result)
   1109 {
   1110     m_sweepHorizontally = true;
   1111     result->setNull();
   1112 }
   1113 
   1114 void TestRunner::setPrinting(const CppArgumentList& arguments, CppVariant* result)
   1115 {
   1116     m_isPrinting = true;
   1117     result->setNull();
   1118 }
   1119 
   1120 void TestRunner::setShouldStayOnPageAfterHandlingBeforeUnload(const CppArgumentList& arguments, CppVariant* result)
   1121 {
   1122     if (arguments.size() == 1 && arguments[0].isBool())
   1123         m_shouldStayOnPageAfterHandlingBeforeUnload = arguments[0].toBoolean();
   1124 
   1125     result->setNull();
   1126 }
   1127 
   1128 void TestRunner::setWillSendRequestClearHeader(const CppArgumentList& arguments, CppVariant* result)
   1129 {
   1130     if (arguments.size() > 0 && arguments[0].isString()) {
   1131         string header = arguments[0].toString();
   1132         if (!header.empty())
   1133             m_httpHeadersToClear.insert(header);
   1134     }
   1135     result->setNull();
   1136 }
   1137 
   1138 void TestRunner::setTabKeyCyclesThroughElements(const CppArgumentList& arguments, CppVariant* result)
   1139 {
   1140     if (arguments.size() > 0 && arguments[0].isBool())
   1141         m_webView->setTabKeyCyclesThroughElements(arguments[0].toBoolean());
   1142     result->setNull();
   1143 }
   1144 
   1145 void TestRunner::execCommand(const CppArgumentList& arguments, CppVariant* result)
   1146 {
   1147     result->setNull();
   1148     if (arguments.size() <= 0 || !arguments[0].isString())
   1149         return;
   1150 
   1151     std::string command = arguments[0].toString();
   1152     std::string value("");
   1153     // Ignore the second parameter (which is userInterface)
   1154     // since this command emulates a manual action.
   1155     if (arguments.size() >= 3 && arguments[2].isString())
   1156         value = arguments[2].toString();
   1157 
   1158     // Note: webkit's version does not return the boolean, so neither do we.
   1159     m_webView->focusedFrame()->executeCommand(WebString::fromUTF8(command), WebString::fromUTF8(value));
   1160 }
   1161 
   1162 void TestRunner::isCommandEnabled(const CppArgumentList& arguments, CppVariant* result)
   1163 {
   1164     if (arguments.size() <= 0 || !arguments[0].isString()) {
   1165         result->setNull();
   1166         return;
   1167     }
   1168 
   1169     std::string command = arguments[0].toString();
   1170     bool rv = m_webView->focusedFrame()->isCommandEnabled(WebString::fromUTF8(command));
   1171     result->set(rv);
   1172 }
   1173 
   1174 void TestRunner::callShouldCloseOnWebView(const CppArgumentList&, CppVariant* result)
   1175 {
   1176     result->set(m_webView->dispatchBeforeUnloadEvent());
   1177 }
   1178 
   1179 void TestRunner::setDomainRelaxationForbiddenForURLScheme(const CppArgumentList& arguments, CppVariant* result)
   1180 {
   1181     if (arguments.size() != 2 || !arguments[0].isBool() || !arguments[1].isString())
   1182         return;
   1183     m_webView->setDomainRelaxationForbidden(cppVariantToBool(arguments[0]), cppVariantToWebString(arguments[1]));
   1184 }
   1185 
   1186 void TestRunner::evaluateScriptInIsolatedWorldAndReturnValue(const CppArgumentList& arguments, CppVariant* result)
   1187 {
   1188     v8::HandleScope scope(v8::Isolate::GetCurrent());
   1189     WebVector<v8::Local<v8::Value> > values;
   1190     if (arguments.size() >= 2 && arguments[0].isNumber() && arguments[1].isString()) {
   1191         WebScriptSource source(cppVariantToWebString(arguments[1]));
   1192         // This relies on the iframe focusing itself when it loads. This is a bit
   1193         // sketchy, but it seems to be what other tests do.
   1194         m_webView->focusedFrame()->executeScriptInIsolatedWorld(arguments[0].toInt32(), &source, 1, 1, &values);
   1195     }
   1196     result->setNull();
   1197     // Since only one script was added, only one result is expected
   1198     if (values.size() == 1 && !values[0].IsEmpty()) {
   1199         v8::Local<v8::Value> scriptValue = values[0];
   1200         // FIXME: There are many more types that can be handled.
   1201         if (scriptValue->IsString()) {
   1202             v8::String::Utf8Value utf8V8(scriptValue);
   1203             result->set(std::string(*utf8V8));
   1204         } else if (scriptValue->IsBoolean())
   1205             result->set(scriptValue->ToBoolean()->Value());
   1206         else if (scriptValue->IsNumber()) {
   1207             if (scriptValue->IsInt32())
   1208                 result->set(scriptValue->ToInt32()->Value());
   1209             else
   1210                 result->set(scriptValue->ToNumber()->Value());
   1211         } else if (scriptValue->IsNull())
   1212             result->setNull();
   1213     }
   1214 }
   1215 
   1216 void TestRunner::evaluateScriptInIsolatedWorld(const CppArgumentList& arguments, CppVariant* result)
   1217 {
   1218     if (arguments.size() >= 2 && arguments[0].isNumber() && arguments[1].isString()) {
   1219         WebScriptSource source(cppVariantToWebString(arguments[1]));
   1220         // This relies on the iframe focusing itself when it loads. This is a bit
   1221         // sketchy, but it seems to be what other tests do.
   1222         m_webView->focusedFrame()->executeScriptInIsolatedWorld(arguments[0].toInt32(), &source, 1, 1);
   1223     }
   1224     result->setNull();
   1225 }
   1226 
   1227 void TestRunner::setIsolatedWorldSecurityOrigin(const CppArgumentList& arguments, CppVariant* result)
   1228 {
   1229     result->setNull();
   1230 
   1231     if (arguments.size() != 2 || !arguments[0].isNumber() || !(arguments[1].isString() || arguments[1].isNull()))
   1232         return;
   1233 
   1234     WebSecurityOrigin origin;
   1235     if (arguments[1].isString())
   1236         origin = WebSecurityOrigin::createFromString(cppVariantToWebString(arguments[1]));
   1237     m_webView->focusedFrame()->setIsolatedWorldSecurityOrigin(arguments[0].toInt32(), origin);
   1238 }
   1239 
   1240 void TestRunner::setIsolatedWorldContentSecurityPolicy(const CppArgumentList& arguments, CppVariant* result)
   1241 {
   1242     result->setNull();
   1243 
   1244     if (arguments.size() != 2 || !arguments[0].isNumber() || !arguments[1].isString())
   1245         return;
   1246 
   1247     m_webView->focusedFrame()->setIsolatedWorldContentSecurityPolicy(arguments[0].toInt32(), cppVariantToWebString(arguments[1]));
   1248 }
   1249 
   1250 void TestRunner::addOriginAccessWhitelistEntry(const CppArgumentList& arguments, CppVariant* result)
   1251 {
   1252     result->setNull();
   1253 
   1254     if (arguments.size() != 4 || !arguments[0].isString() || !arguments[1].isString()
   1255         || !arguments[2].isString() || !arguments[3].isBool())
   1256         return;
   1257 
   1258     blink::WebURL url(GURL(arguments[0].toString()));
   1259     if (!url.isValid())
   1260         return;
   1261 
   1262     WebSecurityPolicy::addOriginAccessWhitelistEntry(
   1263         url,
   1264         cppVariantToWebString(arguments[1]),
   1265         cppVariantToWebString(arguments[2]),
   1266         arguments[3].toBoolean());
   1267 }
   1268 
   1269 void TestRunner::removeOriginAccessWhitelistEntry(const CppArgumentList& arguments, CppVariant* result)
   1270 {
   1271     result->setNull();
   1272 
   1273     if (arguments.size() != 4 || !arguments[0].isString() || !arguments[1].isString()
   1274         || !arguments[2].isString() || !arguments[3].isBool())
   1275         return;
   1276 
   1277     blink::WebURL url(GURL(arguments[0].toString()));
   1278     if (!url.isValid())
   1279         return;
   1280 
   1281     WebSecurityPolicy::removeOriginAccessWhitelistEntry(
   1282         url,
   1283         cppVariantToWebString(arguments[1]),
   1284         cppVariantToWebString(arguments[2]),
   1285         arguments[3].toBoolean());
   1286 }
   1287 
   1288 void TestRunner::hasCustomPageSizeStyle(const CppArgumentList& arguments, CppVariant* result)
   1289 {
   1290     result->set(false);
   1291     int pageIndex = 0;
   1292     if (arguments.size() > 1)
   1293         return;
   1294     if (arguments.size() == 1)
   1295         pageIndex = cppVariantToInt32(arguments[0]);
   1296     WebFrame* frame = m_webView->mainFrame();
   1297     if (!frame)
   1298         return;
   1299     result->set(frame->hasCustomPageSizeStyle(pageIndex));
   1300 }
   1301 
   1302 void TestRunner::forceRedSelectionColors(const CppArgumentList& arguments, CppVariant* result)
   1303 {
   1304     result->setNull();
   1305     m_webView->setSelectionColors(0xffee0000, 0xff00ee00, 0xff000000, 0xffc0c0c0);
   1306 }
   1307 
   1308 void TestRunner::injectStyleSheet(const CppArgumentList& arguments, CppVariant* result)
   1309 {
   1310     result->setNull();
   1311     if (arguments.size() < 2 || !arguments[0].isString() || !arguments[1].isBool())
   1312         return;
   1313     WebView::injectStyleSheet(
   1314         cppVariantToWebString(arguments[0]), WebVector<WebString>(),
   1315         arguments[1].toBoolean() ? WebView::InjectStyleInAllFrames : WebView::InjectStyleInTopFrameOnly);
   1316 }
   1317 
   1318 void TestRunner::startSpeechInput(const CppArgumentList& arguments, CppVariant* result)
   1319 {
   1320     result->setNull();
   1321     if (arguments.size() != 1)
   1322         return;
   1323 
   1324     WebElement element;
   1325     if (!WebBindings::getElement(arguments[0].value.objectValue, &element))
   1326         return;
   1327 
   1328     WebInputElement* input = toWebInputElement(&element);
   1329     if (!input)
   1330         return;
   1331 
   1332     if (!input->isSpeechInputEnabled())
   1333         return;
   1334 
   1335     input->startSpeechInput();
   1336 }
   1337 
   1338 void TestRunner::findString(const CppArgumentList& arguments, CppVariant* result)
   1339 {
   1340     if (arguments.size() < 1 || !arguments[0].isString())
   1341         return;
   1342 
   1343     WebFindOptions findOptions;
   1344     bool wrapAround = false;
   1345     if (arguments.size() >= 2) {
   1346         vector<string> optionsArray = arguments[1].toStringVector();
   1347         findOptions.matchCase = true;
   1348         findOptions.findNext = true;
   1349 
   1350         for (size_t i = 0; i < optionsArray.size(); ++i) {
   1351             const std::string& option = optionsArray[i];
   1352             if (option == "CaseInsensitive")
   1353                 findOptions.matchCase = false;
   1354             else if (option == "Backwards")
   1355                 findOptions.forward = false;
   1356             else if (option == "StartInSelection")
   1357                 findOptions.findNext = false;
   1358             else if (option == "AtWordStarts")
   1359                 findOptions.wordStart = true;
   1360             else if (option == "TreatMedialCapitalAsWordStart")
   1361                 findOptions.medialCapitalAsWordStart = true;
   1362             else if (option == "WrapAround")
   1363                 wrapAround = true;
   1364         }
   1365     }
   1366 
   1367     WebFrame* frame = m_webView->mainFrame();
   1368     const bool findResult = frame->find(0, cppVariantToWebString(arguments[0]), findOptions, wrapAround, 0);
   1369     frame->stopFinding(false);
   1370     result->set(findResult);
   1371 }
   1372 
   1373 void TestRunner::setValueForUser(const CppArgumentList& arguments, CppVariant* result)
   1374 {
   1375     result->setNull();
   1376     if (arguments.size() != 2)
   1377         return;
   1378 
   1379     WebElement element;
   1380     if (!WebBindings::getElement(arguments[0].value.objectValue, &element))
   1381         return;
   1382 
   1383     WebInputElement* input = toWebInputElement(&element);
   1384     if (!input)
   1385         return;
   1386 
   1387     input->setValue(cppVariantToWebString(arguments[1]), true);
   1388 }
   1389 
   1390 void TestRunner::selectionAsMarkup(const CppArgumentList& arguments, CppVariant* result)
   1391 {
   1392     result->set(m_webView->mainFrame()->selectionAsMarkup().utf8());
   1393 }
   1394 
   1395 void TestRunner::setTextSubpixelPositioning(const CppArgumentList& arguments, CppVariant* result)
   1396 {
   1397 #if defined(__linux__) || defined(ANDROID)
   1398     // Since FontConfig doesn't provide a variable to control subpixel positioning, we'll fall back
   1399     // to setting it globally for all fonts.
   1400     if (arguments.size() > 0 && arguments[0].isBool())
   1401         WebFontRendering::setSubpixelPositioning(arguments[0].value.boolValue);
   1402 #endif
   1403     result->setNull();
   1404 }
   1405 
   1406 void TestRunner::setPageVisibility(const CppArgumentList& arguments, CppVariant* result)
   1407 {
   1408     if (arguments.size() > 0 && arguments[0].isString()) {
   1409         string newVisibility = arguments[0].toString();
   1410         if (newVisibility == "visible")
   1411             m_webView->setVisibilityState(WebPageVisibilityStateVisible, false);
   1412         else if (newVisibility == "hidden")
   1413             m_webView->setVisibilityState(WebPageVisibilityStateHidden, false);
   1414         else if (newVisibility == "prerender")
   1415             m_webView->setVisibilityState(WebPageVisibilityStatePrerender, false);
   1416     }
   1417 }
   1418 
   1419 void TestRunner::setTextDirection(const CppArgumentList& arguments, CppVariant* result)
   1420 {
   1421     result->setNull();
   1422     if (arguments.size() != 1 || !arguments[0].isString())
   1423         return;
   1424 
   1425     // Map a direction name to a WebTextDirection value.
   1426     std::string directionName = arguments[0].toString();
   1427     blink::WebTextDirection direction;
   1428     if (directionName == "auto")
   1429         direction = blink::WebTextDirectionDefault;
   1430     else if (directionName == "rtl")
   1431         direction = blink::WebTextDirectionRightToLeft;
   1432     else if (directionName == "ltr")
   1433         direction = blink::WebTextDirectionLeftToRight;
   1434     else
   1435         return;
   1436 
   1437     m_webView->setTextDirection(direction);
   1438 }
   1439 
   1440 void TestRunner::textSurroundingNode(const CppArgumentList& arguments, CppVariant* result)
   1441 {
   1442     result->setNull();
   1443     if (arguments.size() < 4 || !arguments[0].isObject() || !arguments[1].isNumber() || !arguments[2].isNumber() || !arguments[3].isNumber())
   1444         return;
   1445 
   1446     WebNode node;
   1447     if (!WebBindings::getNode(arguments[0].value.objectValue, &node))
   1448         return;
   1449 
   1450     if (node.isNull() || !node.isTextNode())
   1451         return;
   1452 
   1453     WebPoint point(arguments[1].toInt32(), arguments[2].toInt32());
   1454     unsigned maxLength = arguments[3].toInt32();
   1455 
   1456     WebSurroundingText surroundingText;
   1457     surroundingText.initialize(node, point, maxLength);
   1458     if (surroundingText.isNull())
   1459         return;
   1460 
   1461     result->set(surroundingText.textContent().utf8());
   1462 }
   1463 
   1464 void TestRunner::dumpResourceRequestPriorities(const CppArgumentList& arguments, CppVariant* result)
   1465 {
   1466     m_shouldDumpResourcePriorities = true;
   1467     result->setNull();
   1468 }
   1469 
   1470 void TestRunner::useUnfortunateSynchronousResizeMode(const CppArgumentList& arguments, CppVariant* result)
   1471 {
   1472     result->setNull();
   1473     m_delegate->useUnfortunateSynchronousResizeMode(true);
   1474 }
   1475 
   1476 void TestRunner::enableAutoResizeMode(const CppArgumentList& arguments, CppVariant* result)
   1477 {
   1478     if (arguments.size() != 4) {
   1479         result->set(false);
   1480         return;
   1481     }
   1482     int minWidth = cppVariantToInt32(arguments[0]);
   1483     int minHeight = cppVariantToInt32(arguments[1]);
   1484     blink::WebSize minSize(minWidth, minHeight);
   1485 
   1486     int maxWidth = cppVariantToInt32(arguments[2]);
   1487     int maxHeight = cppVariantToInt32(arguments[3]);
   1488     blink::WebSize maxSize(maxWidth, maxHeight);
   1489 
   1490     m_delegate->enableAutoResizeMode(minSize, maxSize);
   1491     result->set(true);
   1492 }
   1493 
   1494 void TestRunner::disableAutoResizeMode(const CppArgumentList& arguments, CppVariant* result)
   1495 {
   1496     if (arguments.size() !=2) {
   1497         result->set(false);
   1498         return;
   1499     }
   1500     int newWidth = cppVariantToInt32(arguments[0]);
   1501     int newHeight = cppVariantToInt32(arguments[1]);
   1502     blink::WebSize newSize(newWidth, newHeight);
   1503 
   1504     m_delegate->disableAutoResizeMode(newSize);
   1505     result->set(true);
   1506 }
   1507 
   1508 void TestRunner::setMockDeviceMotion(const CppArgumentList& arguments, CppVariant* result)
   1509 {
   1510     result->setNull();
   1511     if (arguments.size() < 19
   1512         || !arguments[0].isBool() || !arguments[1].isNumber() // acceleration.x
   1513         || !arguments[2].isBool() || !arguments[3].isNumber() // acceleration.y
   1514         || !arguments[4].isBool() || !arguments[5].isNumber() // acceleration.z
   1515         || !arguments[6].isBool() || !arguments[7].isNumber() // accelerationIncludingGravity.x
   1516         || !arguments[8].isBool() || !arguments[9].isNumber() // accelerationIncludingGravity.y
   1517         || !arguments[10].isBool() || !arguments[11].isNumber() // accelerationIncludingGravity.z
   1518         || !arguments[12].isBool() || !arguments[13].isNumber() // rotationRate.alpha
   1519         || !arguments[14].isBool() || !arguments[15].isNumber() // rotationRate.beta
   1520         || !arguments[16].isBool() || !arguments[17].isNumber() // rotationRate.gamma
   1521         || !arguments[18].isNumber()) // interval
   1522         return;
   1523 
   1524     WebDeviceMotionData motion;
   1525 
   1526     // acceleration
   1527     motion.hasAccelerationX = arguments[0].toBoolean();
   1528     motion.accelerationX = arguments[1].toDouble();
   1529     motion.hasAccelerationY = arguments[2].toBoolean();
   1530     motion.accelerationY = arguments[3].toDouble();
   1531     motion.hasAccelerationZ = arguments[4].toBoolean();
   1532     motion.accelerationZ = arguments[5].toDouble();
   1533 
   1534     // accelerationIncludingGravity
   1535     motion.hasAccelerationIncludingGravityX = arguments[6].toBoolean();
   1536     motion.accelerationIncludingGravityX = arguments[7].toDouble();
   1537     motion.hasAccelerationIncludingGravityY = arguments[8].toBoolean();
   1538     motion.accelerationIncludingGravityY = arguments[9].toDouble();
   1539     motion.hasAccelerationIncludingGravityZ = arguments[10].toBoolean();
   1540     motion.accelerationIncludingGravityZ = arguments[11].toDouble();
   1541 
   1542     // rotationRate
   1543     motion.hasRotationRateAlpha = arguments[12].toBoolean();
   1544     motion.rotationRateAlpha = arguments[13].toDouble();
   1545     motion.hasRotationRateBeta = arguments[14].toBoolean();
   1546     motion.rotationRateBeta = arguments[15].toDouble();
   1547     motion.hasRotationRateGamma = arguments[16].toBoolean();
   1548     motion.rotationRateGamma = arguments[17].toDouble();
   1549 
   1550     // interval
   1551     motion.interval = arguments[18].toDouble();
   1552 
   1553     m_delegate->setDeviceMotionData(motion);
   1554 }
   1555 
   1556 void TestRunner::setMockDeviceOrientation(const CppArgumentList& arguments, CppVariant* result)
   1557 {
   1558     result->setNull();
   1559     if (arguments.size() < 8
   1560         || !arguments[0].isBool() || !arguments[1].isNumber() // alpha
   1561         || !arguments[2].isBool() || !arguments[3].isNumber() // beta
   1562         || !arguments[4].isBool() || !arguments[5].isNumber() // gamma
   1563         || !arguments[6].isBool() || !arguments[7].isBool()) // absolute
   1564         return;
   1565 
   1566     WebDeviceOrientationData orientation;
   1567 
   1568     // alpha
   1569     orientation.hasAlpha = arguments[0].toBoolean();
   1570     orientation.alpha = arguments[1].toDouble();
   1571 
   1572     // beta
   1573     orientation.hasBeta = arguments[2].toBoolean();
   1574     orientation.beta = arguments[3].toDouble();
   1575 
   1576     // gamma
   1577     orientation.hasGamma = arguments[4].toBoolean();
   1578     orientation.gamma = arguments[5].toDouble();
   1579 
   1580     // absolute
   1581     orientation.hasAbsolute = arguments[6].toBoolean();
   1582     orientation.absolute = arguments[7].toBoolean();
   1583 
   1584     m_delegate->setDeviceOrientationData(orientation);
   1585 }
   1586 
   1587 void TestRunner::setPopupBlockingEnabled(const CppArgumentList& arguments, CppVariant* result)
   1588 {
   1589     if (arguments.size() > 0 && arguments[0].isBool()) {
   1590         bool blockPopups = arguments[0].toBoolean();
   1591         m_delegate->preferences()->javaScriptCanOpenWindowsAutomatically = !blockPopups;
   1592         m_delegate->applyPreferences();
   1593     }
   1594     result->setNull();
   1595 }
   1596 
   1597 void TestRunner::setJavaScriptCanAccessClipboard(const CppArgumentList& arguments, CppVariant* result)
   1598 {
   1599     if (arguments.size() > 0 && arguments[0].isBool()) {
   1600         m_delegate->preferences()->javaScriptCanAccessClipboard = arguments[0].value.boolValue;
   1601         m_delegate->applyPreferences();
   1602     }
   1603     result->setNull();
   1604 }
   1605 
   1606 void TestRunner::setXSSAuditorEnabled(const CppArgumentList& arguments, CppVariant* result)
   1607 {
   1608     if (arguments.size() > 0 && arguments[0].isBool()) {
   1609         m_delegate->preferences()->XSSAuditorEnabled = arguments[0].value.boolValue;
   1610         m_delegate->applyPreferences();
   1611     }
   1612     result->setNull();
   1613 }
   1614 
   1615 void TestRunner::setAllowUniversalAccessFromFileURLs(const CppArgumentList& arguments, CppVariant* result)
   1616 {
   1617     if (arguments.size() > 0 && arguments[0].isBool()) {
   1618         m_delegate->preferences()->allowUniversalAccessFromFileURLs = arguments[0].value.boolValue;
   1619         m_delegate->applyPreferences();
   1620     }
   1621     result->setNull();
   1622 }
   1623 
   1624 void TestRunner::setAllowFileAccessFromFileURLs(const CppArgumentList& arguments, CppVariant* result)
   1625 {
   1626     if (arguments.size() > 0 && arguments[0].isBool()) {
   1627         m_delegate->preferences()->allowFileAccessFromFileURLs = arguments[0].value.boolValue;
   1628         m_delegate->applyPreferences();
   1629     }
   1630     result->setNull();
   1631 }
   1632 
   1633 void TestRunner::overridePreference(const CppArgumentList& arguments, CppVariant* result)
   1634 {
   1635     result->setNull();
   1636     if (arguments.size() != 2 || !arguments[0].isString())
   1637         return;
   1638 
   1639     string key = arguments[0].toString();
   1640     CppVariant value = arguments[1];
   1641     WebPreferences* prefs = m_delegate->preferences();
   1642     if (key == "WebKitDefaultFontSize")
   1643         prefs->defaultFontSize = cppVariantToInt32(value);
   1644     else if (key == "WebKitMinimumFontSize")
   1645         prefs->minimumFontSize = cppVariantToInt32(value);
   1646     else if (key == "WebKitDefaultTextEncodingName")
   1647         prefs->defaultTextEncodingName = cppVariantToWebString(value);
   1648     else if (key == "WebKitJavaScriptEnabled")
   1649         prefs->javaScriptEnabled = cppVariantToBool(value);
   1650     else if (key == "WebKitSupportsMultipleWindows")
   1651         prefs->supportsMultipleWindows = cppVariantToBool(value);
   1652     else if (key == "WebKitDisplayImagesKey")
   1653         prefs->loadsImagesAutomatically = cppVariantToBool(value);
   1654     else if (key == "WebKitPluginsEnabled")
   1655         prefs->pluginsEnabled = cppVariantToBool(value);
   1656     else if (key == "WebKitJavaEnabled")
   1657         prefs->javaEnabled = cppVariantToBool(value);
   1658     else if (key == "WebKitOfflineWebApplicationCacheEnabled")
   1659         prefs->offlineWebApplicationCacheEnabled = cppVariantToBool(value);
   1660     else if (key == "WebKitTabToLinksPreferenceKey")
   1661         prefs->tabsToLinks = cppVariantToBool(value);
   1662     else if (key == "WebKitWebGLEnabled")
   1663         prefs->experimentalWebGLEnabled = cppVariantToBool(value);
   1664     else if (key == "WebKitCSSRegionsEnabled")
   1665         prefs->experimentalCSSRegionsEnabled = cppVariantToBool(value);
   1666     else if (key == "WebKitCSSGridLayoutEnabled")
   1667         prefs->experimentalCSSGridLayoutEnabled = cppVariantToBool(value);
   1668     else if (key == "WebKitHyperlinkAuditingEnabled")
   1669         prefs->hyperlinkAuditingEnabled = cppVariantToBool(value);
   1670     else if (key == "WebKitEnableCaretBrowsing")
   1671         prefs->caretBrowsingEnabled = cppVariantToBool(value);
   1672     else if (key == "WebKitAllowDisplayingInsecureContent")
   1673         prefs->allowDisplayOfInsecureContent = cppVariantToBool(value);
   1674     else if (key == "WebKitAllowRunningInsecureContent")
   1675         prefs->allowRunningOfInsecureContent = cppVariantToBool(value);
   1676     else if (key == "WebKitCSSCustomFilterEnabled")
   1677         prefs->cssCustomFilterEnabled = cppVariantToBool(value);
   1678     else if (key == "WebKitShouldRespectImageOrientation")
   1679         prefs->shouldRespectImageOrientation = cppVariantToBool(value);
   1680     else if (key == "WebKitWebAudioEnabled")
   1681         BLINK_ASSERT(cppVariantToBool(value));
   1682     else {
   1683         string message("Invalid name for preference: ");
   1684         message.append(key);
   1685         printErrorMessage(message);
   1686     }
   1687     m_delegate->applyPreferences();
   1688 }
   1689 
   1690 void TestRunner::setPluginsEnabled(const CppArgumentList& arguments, CppVariant* result)
   1691 {
   1692     if (arguments.size() > 0 && arguments[0].isBool()) {
   1693         m_delegate->preferences()->pluginsEnabled = arguments[0].toBoolean();
   1694         m_delegate->applyPreferences();
   1695     }
   1696     result->setNull();
   1697 }
   1698 
   1699 void TestRunner::showWebInspector(const CppArgumentList&, CppVariant* result)
   1700 {
   1701     showDevTools();
   1702     result->setNull();
   1703 }
   1704 
   1705 void TestRunner::closeWebInspector(const CppArgumentList& args, CppVariant* result)
   1706 {
   1707     m_delegate->closeDevTools();
   1708     result->setNull();
   1709 }
   1710 
   1711 void TestRunner::isChooserShown(const CppArgumentList&, CppVariant* result)
   1712 {
   1713     result->set(m_proxy->isChooserShown());
   1714 }
   1715 
   1716 void TestRunner::evaluateInWebInspector(const CppArgumentList& arguments, CppVariant* result)
   1717 {
   1718     result->setNull();
   1719     if (arguments.size() < 2 || !arguments[0].isNumber() || !arguments[1].isString())
   1720         return;
   1721     m_delegate->evaluateInWebInspector(arguments[0].toInt32(), arguments[1].toString());
   1722 }
   1723 
   1724 void TestRunner::clearAllDatabases(const CppArgumentList& arguments, CppVariant* result)
   1725 {
   1726     result->setNull();
   1727     m_delegate->clearAllDatabases();
   1728 }
   1729 
   1730 void TestRunner::setDatabaseQuota(const CppArgumentList& arguments, CppVariant* result)
   1731 {
   1732     result->setNull();
   1733     if ((arguments.size() >= 1) && arguments[0].isNumber())
   1734         m_delegate->setDatabaseQuota(arguments[0].toInt32());
   1735 }
   1736 
   1737 void TestRunner::setAlwaysAcceptCookies(const CppArgumentList& arguments, CppVariant* result)
   1738 {
   1739     if (arguments.size() > 0)
   1740         m_delegate->setAcceptAllCookies(cppVariantToBool(arguments[0]));
   1741     result->setNull();
   1742 }
   1743 
   1744 void TestRunner::setWindowIsKey(const CppArgumentList& arguments, CppVariant* result)
   1745 {
   1746     if (arguments.size() > 0 && arguments[0].isBool())
   1747         m_delegate->setFocus(m_proxy, arguments[0].value.boolValue);
   1748     result->setNull();
   1749 }
   1750 
   1751 void TestRunner::pathToLocalResource(const CppArgumentList& arguments, CppVariant* result)
   1752 {
   1753     result->setNull();
   1754     if (arguments.size() <= 0 || !arguments[0].isString())
   1755         return;
   1756 
   1757     result->set(m_delegate->pathToLocalResource(arguments[0].toString()));
   1758 }
   1759 
   1760 void TestRunner::setBackingScaleFactor(const CppArgumentList& arguments, CppVariant* result)
   1761 {
   1762     if (arguments.size() < 2 || !arguments[0].isNumber() || !arguments[1].isObject())
   1763         return;
   1764 
   1765     float value = arguments[0].value.doubleValue;
   1766     m_delegate->setDeviceScaleFactor(value);
   1767     m_proxy->discardBackingStore();
   1768 
   1769     WebScopedPtr<CppVariant> callbackArguments(new CppVariant());
   1770     callbackArguments->set(arguments[1]);
   1771     result->setNull();
   1772     m_delegate->postTask(new InvokeCallbackTask(this, callbackArguments));
   1773 }
   1774 
   1775 void TestRunner::setPOSIXLocale(const CppArgumentList& arguments, CppVariant* result)
   1776 {
   1777     result->setNull();
   1778     if (arguments.size() == 1 && arguments[0].isString())
   1779         m_delegate->setLocale(arguments[0].toString());
   1780 }
   1781 
   1782 void TestRunner::numberOfPendingGeolocationPermissionRequests(const CppArgumentList& arguments, CppVariant* result)
   1783 {
   1784     result->set(m_proxy->geolocationClientMock()->numberOfPendingPermissionRequests());
   1785 }
   1786 
   1787 // FIXME: For greater test flexibility, we should be able to set each page's geolocation mock individually.
   1788 // https://bugs.webkit.org/show_bug.cgi?id=52368
   1789 void TestRunner::setGeolocationPermission(const CppArgumentList& arguments, CppVariant* result)
   1790 {
   1791     result->setNull();
   1792     if (arguments.size() < 1 || !arguments[0].isBool())
   1793         return;
   1794     const vector<WebTestProxyBase*>& windowList = m_testInterfaces->windowList();
   1795     for (unsigned i = 0; i < windowList.size(); ++i)
   1796         windowList.at(i)->geolocationClientMock()->setPermission(arguments[0].toBoolean());
   1797 }
   1798 
   1799 void TestRunner::setMockGeolocationPosition(const CppArgumentList& arguments, CppVariant* result)
   1800 {
   1801     result->setNull();
   1802     if (arguments.size() < 3 || !arguments[0].isNumber() || !arguments[1].isNumber() || !arguments[2].isNumber())
   1803         return;
   1804     const vector<WebTestProxyBase*>& windowList = m_testInterfaces->windowList();
   1805     for (unsigned i = 0; i < windowList.size(); ++i)
   1806         windowList.at(i)->geolocationClientMock()->setPosition(arguments[0].toDouble(), arguments[1].toDouble(), arguments[2].toDouble());
   1807 }
   1808 
   1809 void TestRunner::setMockGeolocationPositionUnavailableError(const CppArgumentList& arguments, CppVariant* result)
   1810 {
   1811     result->setNull();
   1812     if (arguments.size() != 1 || !arguments[0].isString())
   1813         return;
   1814     const vector<WebTestProxyBase*>& windowList = m_testInterfaces->windowList();
   1815     for (unsigned i = 0; i < windowList.size(); ++i)
   1816         windowList.at(i)->geolocationClientMock()->setPositionUnavailableError(WebString::fromUTF8(arguments[0].toString()));
   1817 }
   1818 
   1819 void TestRunner::setMIDIAccessorResult(const CppArgumentList& arguments, CppVariant* result)
   1820 {
   1821     result->setNull();
   1822     if (arguments.size() < 1 || !arguments[0].isBool())
   1823         return;
   1824     m_midiAccessorResult = arguments[0].toBoolean();
   1825 }
   1826 
   1827 void TestRunner::setMIDISysExPermission(const CppArgumentList& arguments, CppVariant* result)
   1828 {
   1829     result->setNull();
   1830     if (arguments.size() < 1 || !arguments[0].isBool())
   1831         return;
   1832     const vector<WebTestProxyBase*>& windowList = m_testInterfaces->windowList();
   1833     for (unsigned i = 0; i < windowList.size(); ++i)
   1834         windowList.at(i)->midiClientMock()->setSysExPermission(arguments[0].toBoolean());
   1835 }
   1836 
   1837 void TestRunner::grantWebNotificationPermission(const CppArgumentList& arguments, CppVariant* result)
   1838 {
   1839     if (arguments.size() != 1 || !arguments[0].isString()) {
   1840         result->set(false);
   1841         return;
   1842     }
   1843     m_notificationPresenter->grantPermission(WebString::fromUTF8(arguments[0].toString()));
   1844     result->set(true);
   1845 }
   1846 
   1847 void TestRunner::simulateLegacyWebNotificationClick(const CppArgumentList& arguments, CppVariant* result)
   1848 {
   1849     if (arguments.size() != 1 || !arguments[0].isString()) {
   1850         result->set(false);
   1851         return;
   1852     }
   1853     result->set(m_notificationPresenter->simulateClick(WebString::fromUTF8(arguments[0].toString())));
   1854 }
   1855 
   1856 void TestRunner::cancelAllActiveNotifications(const CppArgumentList& arguments, CppVariant* result)
   1857 {
   1858     m_notificationPresenter->cancelAllActiveNotifications();
   1859     result->set(true);
   1860 }
   1861 
   1862 void TestRunner::addMockSpeechInputResult(const CppArgumentList& arguments, CppVariant* result)
   1863 {
   1864     result->setNull();
   1865     if (arguments.size() < 3 || !arguments[0].isString() || !arguments[1].isNumber() || !arguments[2].isString())
   1866         return;
   1867 
   1868 #if ENABLE_INPUT_SPEECH
   1869     m_proxy->speechInputControllerMock()->addMockRecognitionResult(WebString::fromUTF8(arguments[0].toString()), arguments[1].toDouble(), WebString::fromUTF8(arguments[2].toString()));
   1870 #endif
   1871 }
   1872 
   1873 void TestRunner::setMockSpeechInputDumpRect(const CppArgumentList& arguments, CppVariant* result)
   1874 {
   1875     result->setNull();
   1876     if (arguments.size() < 1 || !arguments[0].isBool())
   1877         return;
   1878 
   1879 #if ENABLE_INPUT_SPEECH
   1880     m_proxy->speechInputControllerMock()->setDumpRect(arguments[0].toBoolean());
   1881 #endif
   1882 }
   1883 
   1884 void TestRunner::addMockSpeechRecognitionResult(const CppArgumentList& arguments, CppVariant* result)
   1885 {
   1886     result->setNull();
   1887     if (arguments.size() < 2 || !arguments[0].isString() || !arguments[1].isNumber())
   1888         return;
   1889 
   1890     m_proxy->speechRecognizerMock()->addMockResult(WebString::fromUTF8(arguments[0].toString()), arguments[1].toDouble());
   1891 }
   1892 
   1893 void TestRunner::setMockSpeechRecognitionError(const CppArgumentList& arguments, CppVariant* result)
   1894 {
   1895     result->setNull();
   1896     if (arguments.size() != 2 || !arguments[0].isString() || !arguments[1].isString())
   1897         return;
   1898 
   1899     m_proxy->speechRecognizerMock()->setError(WebString::fromUTF8(arguments[0].toString()), WebString::fromUTF8(arguments[1].toString()));
   1900 }
   1901 
   1902 void TestRunner::wasMockSpeechRecognitionAborted(const CppArgumentList&, CppVariant* result)
   1903 {
   1904     result->set(m_proxy->speechRecognizerMock()->wasAborted());
   1905 }
   1906 
   1907 void TestRunner::addWebPageOverlay(const CppArgumentList&, CppVariant* result)
   1908 {
   1909     if (m_webView && !m_pageOverlay) {
   1910         m_pageOverlay = new TestPageOverlay(m_webView);
   1911         m_webView->addPageOverlay(m_pageOverlay, 0);
   1912     }
   1913     result->setNull();
   1914 }
   1915 
   1916 void TestRunner::removeWebPageOverlay(const CppArgumentList&, CppVariant* result)
   1917 {
   1918     if (m_webView && m_pageOverlay) {
   1919         m_webView->removePageOverlay(m_pageOverlay);
   1920         delete m_pageOverlay;
   1921         m_pageOverlay = 0;
   1922     }
   1923 
   1924     result->setNull();
   1925 }
   1926 
   1927 void TestRunner::display(const CppArgumentList& arguments, CppVariant* result)
   1928 {
   1929     m_proxy->display();
   1930     result->setNull();
   1931 }
   1932 
   1933 void TestRunner::displayInvalidatedRegion(const CppArgumentList& arguments, CppVariant* result)
   1934 {
   1935     m_proxy->displayInvalidatedRegion();
   1936     result->setNull();
   1937 }
   1938 
   1939 void TestRunner::dumpEditingCallbacks(const CppArgumentList&, CppVariant* result)
   1940 {
   1941     m_dumpEditingCallbacks = true;
   1942     result->setNull();
   1943 }
   1944 
   1945 void TestRunner::dumpAsText(const CppArgumentList&, CppVariant* result)
   1946 {
   1947     m_dumpAsText = true;
   1948     m_generatePixelResults = false;
   1949 
   1950     result->setNull();
   1951 }
   1952 
   1953 void TestRunner::dumpAsTextWithPixelResults(const CppArgumentList&, CppVariant* result)
   1954 {
   1955     m_dumpAsText = true;
   1956     m_generatePixelResults = true;
   1957 
   1958     result->setNull();
   1959 }
   1960 
   1961 void TestRunner::dumpChildFrameScrollPositions(const CppArgumentList&, CppVariant* result)
   1962 {
   1963     m_dumpChildFrameScrollPositions = true;
   1964     result->setNull();
   1965 }
   1966 
   1967 void TestRunner::dumpChildFramesAsText(const CppArgumentList&, CppVariant* result)
   1968 {
   1969     m_dumpChildFramesAsText = true;
   1970     result->setNull();
   1971 }
   1972 
   1973 void TestRunner::dumpIconChanges(const CppArgumentList&, CppVariant* result)
   1974 {
   1975     m_dumpIconChanges = true;
   1976     result->setNull();
   1977 }
   1978 
   1979 void TestRunner::setAudioData(const CppArgumentList& arguments, CppVariant* result)
   1980 {
   1981     result->setNull();
   1982 
   1983     if (arguments.size() < 1 || !arguments[0].isObject())
   1984         return;
   1985 
   1986     // Check that passed-in object is, in fact, an ArrayBufferView.
   1987     NPObject* npobject = NPVARIANT_TO_OBJECT(arguments[0]);
   1988     if (!npobject)
   1989         return;
   1990     if (!WebBindings::getArrayBufferView(npobject, &m_audioData))
   1991         return;
   1992 
   1993     m_dumpAsAudio = true;
   1994 }
   1995 
   1996 void TestRunner::dumpFrameLoadCallbacks(const CppArgumentList&, CppVariant* result)
   1997 {
   1998     m_dumpFrameLoadCallbacks = true;
   1999     result->setNull();
   2000 }
   2001 
   2002 void TestRunner::dumpPingLoaderCallbacks(const CppArgumentList&, CppVariant* result)
   2003 {
   2004     m_dumpPingLoaderCallbacks = true;
   2005     result->setNull();
   2006 }
   2007 
   2008 void TestRunner::dumpUserGestureInFrameLoadCallbacks(const CppArgumentList&, CppVariant* result)
   2009 {
   2010     m_dumpUserGestureInFrameLoadCallbacks = true;
   2011     result->setNull();
   2012 }
   2013 
   2014 void TestRunner::dumpTitleChanges(const CppArgumentList&, CppVariant* result)
   2015 {
   2016     m_dumpTitleChanges = true;
   2017     result->setNull();
   2018 }
   2019 
   2020 void TestRunner::dumpCreateView(const CppArgumentList&, CppVariant* result)
   2021 {
   2022     m_dumpCreateView = true;
   2023     result->setNull();
   2024 }
   2025 
   2026 void TestRunner::setCanOpenWindows(const CppArgumentList&, CppVariant* result)
   2027 {
   2028     m_canOpenWindows = true;
   2029     result->setNull();
   2030 }
   2031 
   2032 void TestRunner::dumpResourceLoadCallbacks(const CppArgumentList&, CppVariant* result)
   2033 {
   2034     m_dumpResourceLoadCallbacks = true;
   2035     result->setNull();
   2036 }
   2037 
   2038 void TestRunner::dumpResourceRequestCallbacks(const CppArgumentList&, CppVariant* result)
   2039 {
   2040     m_dumpResourceRequestCallbacks = true;
   2041     result->setNull();
   2042 }
   2043 
   2044 void TestRunner::dumpResourceResponseMIMETypes(const CppArgumentList&, CppVariant* result)
   2045 {
   2046     m_dumpResourceResponseMIMETypes = true;
   2047     result->setNull();
   2048 }
   2049 
   2050 // Need these conversions because the format of the value for booleans
   2051 // may vary - for example, on mac "1" and "0" are used for boolean.
   2052 bool TestRunner::cppVariantToBool(const CppVariant& value)
   2053 {
   2054     if (value.isBool())
   2055         return value.toBoolean();
   2056     if (value.isNumber())
   2057         return value.toInt32();
   2058     if (value.isString()) {
   2059         string valueString = value.toString();
   2060         if (valueString == "true" || valueString == "1")
   2061             return true;
   2062         if (valueString == "false" || valueString == "0")
   2063             return false;
   2064     }
   2065     printErrorMessage("Invalid value. Expected boolean value.");
   2066     return false;
   2067 }
   2068 
   2069 int32_t TestRunner::cppVariantToInt32(const CppVariant& value)
   2070 {
   2071     if (value.isNumber())
   2072         return value.toInt32();
   2073     if (value.isString()) {
   2074         string stringSource = value.toString();
   2075         const char* source = stringSource.data();
   2076         char* end;
   2077         long number = strtol(source, &end, 10);
   2078         if (end == source + stringSource.length() && number >= numeric_limits<int32_t>::min() && number <= numeric_limits<int32_t>::max())
   2079             return static_cast<int32_t>(number);
   2080     }
   2081     printErrorMessage("Invalid value for preference. Expected integer value.");
   2082     return 0;
   2083 }
   2084 
   2085 WebString TestRunner::cppVariantToWebString(const CppVariant& value)
   2086 {
   2087     if (!value.isString()) {
   2088         printErrorMessage("Invalid value for preference. Expected string value.");
   2089         return WebString();
   2090     }
   2091     return WebString::fromUTF8(value.toString());
   2092 }
   2093 
   2094 void TestRunner::printErrorMessage(const string& text)
   2095 {
   2096     m_delegate->printMessage(string("CONSOLE MESSAGE: ") + text + "\n");
   2097 }
   2098 
   2099 void TestRunner::fallbackMethod(const CppArgumentList&, CppVariant* result)
   2100 {
   2101     printErrorMessage("JavaScript ERROR: unknown method called on TestRunner");
   2102     result->setNull();
   2103 }
   2104 
   2105 void TestRunner::notImplemented(const CppArgumentList&, CppVariant* result)
   2106 {
   2107     result->setNull();
   2108 }
   2109 
   2110 void TestRunner::didAcquirePointerLock(const CppArgumentList&, CppVariant* result)
   2111 {
   2112     didAcquirePointerLockInternal();
   2113     result->setNull();
   2114 }
   2115 
   2116 void TestRunner::didNotAcquirePointerLock(const CppArgumentList&, CppVariant* result)
   2117 {
   2118     didNotAcquirePointerLockInternal();
   2119     result->setNull();
   2120 }
   2121 
   2122 void TestRunner::didLosePointerLock(const CppArgumentList&, CppVariant* result)
   2123 {
   2124     didLosePointerLockInternal();
   2125     result->setNull();
   2126 }
   2127 
   2128 void TestRunner::setPointerLockWillRespondAsynchronously(const CppArgumentList&, CppVariant* result)
   2129 {
   2130     m_pointerLockPlannedResult = PointerLockWillRespondAsync;
   2131     result->setNull();
   2132 }
   2133 
   2134 void TestRunner::setPointerLockWillFailSynchronously(const CppArgumentList&, CppVariant* result)
   2135 {
   2136     m_pointerLockPlannedResult = PointerLockWillFailSync;
   2137     result->setNull();
   2138 }
   2139 
   2140 }
   2141