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