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