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