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