Need a method to close all idle localstorage databases immediately.
[WebKit-https.git] / Tools / DumpRenderTree / win / TestRunnerWin.cpp
1 /*
2  * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2012 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  * 1.  Redistributions of source code must retain the above copyright
9  *     notice, this list of conditions and the following disclaimer.
10  * 2.  Redistributions in binary form must reproduce the above copyright
11  *     notice, this list of conditions and the following disclaimer in the
12  *     documentation and/or other materials provided with the distribution.
13  * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
14  *     its contributors may be used to endorse or promote products derived
15  *     from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
18  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28
29 #include "config.h"
30 #include "TestRunner.h"
31
32 #include "DumpRenderTree.h"
33 #include "EditingDelegate.h"
34 #include "PolicyDelegate.h"
35 #include "WorkQueue.h"
36 #include "WorkQueueItem.h"
37 #include <CoreFoundation/CoreFoundation.h>
38 #include <JavaScriptCore/JSRetainPtr.h>
39 #include <JavaScriptCore/JSStringRefBSTR.h>
40 #include <JavaScriptCore/JavaScriptCore.h>
41 #include <WebCore/COMPtr.h>
42 #include <WebKit/WebKit.h>
43 #include <WebKit/WebKitCOMAPI.h>
44 #include <comutil.h>
45 #include <shlguid.h>
46 #include <shlwapi.h>
47 #include <shobjidl.h>
48 #include <string>
49 #include <wtf/Assertions.h>
50 #include <wtf/Platform.h>
51 #include <wtf/RetainPtr.h>
52 #include <wtf/Vector.h>
53
54 using std::string;
55 using std::wstring;
56
57 static bool resolveCygwinPath(const wstring& cygwinPath, wstring& windowsPath);
58
59 TestRunner::~TestRunner()
60 {
61     COMPtr<IWebView> webView;
62     if (FAILED(frame->webView(&webView)))
63         return;
64
65     // reset webview-related states back to default values in preparation for next test
66
67     COMPtr<IWebViewPrivate> viewPrivate;
68     if (SUCCEEDED(webView->QueryInterface(&viewPrivate)))
69         viewPrivate->setTabKeyCyclesThroughElements(TRUE);
70
71     COMPtr<IWebViewEditing> viewEditing;
72     if (FAILED(webView->QueryInterface(&viewEditing)))
73         return;
74     COMPtr<IWebEditingDelegate> delegate;
75     if (FAILED(viewEditing->editingDelegate(&delegate)))
76         return;
77     COMPtr<EditingDelegate> editingDelegate(Query, viewEditing.get());
78     if (editingDelegate)
79         editingDelegate->setAcceptsEditing(TRUE);
80 }
81
82 void TestRunner::addDisallowedURL(JSStringRef url)
83 {
84     // FIXME: Implement!
85 }
86
87 void TestRunner::clearBackForwardList()
88 {
89     COMPtr<IWebView> webView;
90     if (FAILED(frame->webView(&webView)))
91         return;
92
93     COMPtr<IWebBackForwardList> backForwardList;
94     if (FAILED(webView->backForwardList(&backForwardList)))
95         return;
96
97     COMPtr<IWebHistoryItem> item;
98     if (FAILED(backForwardList->currentItem(&item)))
99         return;
100
101     // We clear the history by setting the back/forward list's capacity to 0
102     // then restoring it back and adding back the current item.
103     int capacity;
104     if (FAILED(backForwardList->capacity(&capacity)))
105         return;
106
107     backForwardList->setCapacity(0);
108     backForwardList->setCapacity(capacity);
109     backForwardList->addItem(item.get());
110     backForwardList->goToItem(item.get());
111 }
112
113 bool TestRunner::callShouldCloseOnWebView()
114 {
115     COMPtr<IWebView> webView;
116     if (FAILED(frame->webView(&webView)))
117         return false;
118
119     COMPtr<IWebViewPrivate> viewPrivate;
120     if (FAILED(webView->QueryInterface(&viewPrivate)))
121         return false;
122
123     BOOL result;
124     viewPrivate->shouldClose(&result);
125     return result;
126 }
127
128 JSStringRef TestRunner::copyDecodedHostName(JSStringRef name)
129 {
130     // FIXME: Implement!
131     return 0;
132 }
133
134 JSStringRef TestRunner::copyEncodedHostName(JSStringRef name)
135 {
136     // FIXME: Implement!
137     return 0;
138 }
139
140 void TestRunner::disableImageLoading()
141 {
142     COMPtr<IWebView> webView;
143     if (FAILED(frame->webView(&webView)))
144         return;
145     
146     COMPtr<IWebPreferences> preferences;
147     if (FAILED(webView->preferences(&preferences)))
148         return;
149     
150     preferences->setLoadsImagesAutomatically(FALSE);
151 }
152
153 void TestRunner::dispatchPendingLoadRequests()
154 {
155     // FIXME: Implement for testing fix for 6727495
156 }
157
158 void TestRunner::display()
159 {
160     displayWebView();
161 }
162
163 void TestRunner::keepWebHistory()
164 {
165     COMPtr<IWebHistory> history;
166     if (FAILED(WebKitCreateInstance(CLSID_WebHistory, 0, __uuidof(history), reinterpret_cast<void**>(&history))))
167         return;
168
169     COMPtr<IWebHistory> sharedHistory;
170     if (FAILED(WebKitCreateInstance(CLSID_WebHistory, 0, __uuidof(sharedHistory), reinterpret_cast<void**>(&sharedHistory))))
171         return;
172
173     history->setOptionalSharedHistory(sharedHistory.get());
174 }
175
176 JSValueRef TestRunner::computedStyleIncludingVisitedInfo(JSContextRef context, JSValueRef value)
177 {
178     // FIXME: Implement this.
179     return JSValueMakeUndefined(context);
180 }
181
182 JSRetainPtr<JSStringRef> TestRunner::markerTextForListItem(JSContextRef context, JSValueRef nodeObject) const
183 {
184     COMPtr<IWebView> webView;
185     if (FAILED(frame->webView(&webView)))
186         return 0;
187
188     COMPtr<IWebViewPrivate> webViewPrivate(Query, webView);
189     if (!webViewPrivate)
190         return 0;
191
192     COMPtr<IDOMElement> element;
193     if (FAILED(webViewPrivate->elementFromJS(context, nodeObject, &element)))
194         return 0;
195
196     COMPtr<IDOMElementPrivate> elementPrivate(Query, element);
197     if (!elementPrivate)
198         return 0;
199
200     BSTR textBSTR = 0;
201     if (FAILED(elementPrivate->markerTextForListItem(&textBSTR)))
202         return 0;
203
204     JSRetainPtr<JSStringRef> markerText(Adopt, JSStringCreateWithBSTR(textBSTR));
205     SysFreeString(textBSTR);
206     return markerText;
207 }
208
209 void TestRunner::waitForPolicyDelegate()
210 {
211     COMPtr<IWebView> webView;
212     if (FAILED(frame->webView(&webView)))
213         return;
214
215     setWaitToDump(true);
216     policyDelegate->setControllerToNotifyDone(this);
217     webView->setPolicyDelegate(policyDelegate);
218 }
219
220 size_t TestRunner::webHistoryItemCount()
221 {
222     COMPtr<IWebHistory> history;
223     if (FAILED(WebKitCreateInstance(CLSID_WebHistory, 0, __uuidof(history), reinterpret_cast<void**>(&history))))
224         return 0;
225
226     COMPtr<IWebHistory> sharedHistory;
227     if (FAILED(history->optionalSharedHistory(&sharedHistory)) || !sharedHistory)
228         return 0;
229
230     COMPtr<IWebHistoryPrivate> sharedHistoryPrivate;
231     if (FAILED(sharedHistory->QueryInterface(&sharedHistoryPrivate)))
232         return 0;
233
234     int count;
235     if (FAILED(sharedHistoryPrivate->allItems(&count, 0)))
236         return 0;
237
238     return count;
239 }
240
241 unsigned TestRunner::workerThreadCount() const
242 {
243     COMPtr<IWebWorkersPrivate> workers;
244     if (FAILED(WebKitCreateInstance(CLSID_WebWorkersPrivate, 0, __uuidof(workers), reinterpret_cast<void**>(&workers))))
245         return 0;
246     unsigned count;
247     if (FAILED(workers->workerThreadCount(&count)))
248         return 0;
249     return count;
250 }
251
252 JSRetainPtr<JSStringRef> TestRunner::platformName() const
253 {
254     JSRetainPtr<JSStringRef> platformName(Adopt, JSStringCreateWithUTF8CString("win"));
255     return platformName;
256 }
257
258 void TestRunner::notifyDone()
259 {
260     // Same as on mac.  This can be shared.
261     if (m_waitToDump && !topLoadingFrame && !WorkQueue::shared()->count())
262         dump();
263     m_waitToDump = false;
264 }
265
266 JSStringRef TestRunner::pathToLocalResource(JSContextRef context, JSStringRef url)
267 {
268     wstring input(JSStringGetCharactersPtr(url), JSStringGetLength(url));
269
270     wstring localPath;
271     if (!resolveCygwinPath(input, localPath)) {
272         printf("ERROR: Failed to resolve Cygwin path %S\n", input.c_str());
273         return 0;
274     }
275
276     return JSStringCreateWithCharacters(localPath.c_str(), localPath.length());
277 }
278
279 static wstring jsStringRefToWString(JSStringRef jsStr)
280 {
281     size_t length = JSStringGetLength(jsStr);
282     Vector<WCHAR> buffer(length + 1);
283     memcpy(buffer.data(), JSStringGetCharactersPtr(jsStr), length * sizeof(WCHAR));
284     buffer[length] = '\0';
285
286     return buffer.data();
287 }
288
289 void TestRunner::queueLoad(JSStringRef url, JSStringRef target)
290 {
291     COMPtr<IWebDataSource> dataSource;
292     if (FAILED(frame->dataSource(&dataSource)))
293         return;
294
295     COMPtr<IWebURLResponse> response;
296     if (FAILED(dataSource->response(&response)) || !response)
297         return;
298
299     BSTR responseURLBSTR;
300     if (FAILED(response->URL(&responseURLBSTR)))
301         return;
302     wstring responseURL(responseURLBSTR, SysStringLen(responseURLBSTR));
303     SysFreeString(responseURLBSTR);
304
305     // FIXME: We should do real relative URL resolution here.
306     int lastSlash = responseURL.rfind('/');
307     if (lastSlash != -1)
308         responseURL = responseURL.substr(0, lastSlash);
309
310     wstring wURL = jsStringRefToWString(url);
311     wstring wAbsoluteURL = responseURL + TEXT("/") + wURL;
312     JSRetainPtr<JSStringRef> jsAbsoluteURL(Adopt, JSStringCreateWithCharacters(wAbsoluteURL.data(), wAbsoluteURL.length()));
313
314     WorkQueue::shared()->queue(new LoadItem(jsAbsoluteURL.get(), target));
315 }
316
317 void TestRunner::setAcceptsEditing(bool acceptsEditing)
318 {
319     COMPtr<IWebView> webView;
320     if (FAILED(frame->webView(&webView)))
321         return;
322
323     COMPtr<IWebViewEditing> viewEditing;
324     if (FAILED(webView->QueryInterface(&viewEditing)))
325         return;
326
327     COMPtr<IWebEditingDelegate> delegate;
328     if (FAILED(viewEditing->editingDelegate(&delegate)))
329         return;
330
331     EditingDelegate* editingDelegate = (EditingDelegate*)(IWebEditingDelegate*)delegate.get();
332     editingDelegate->setAcceptsEditing(acceptsEditing);
333 }
334
335 void TestRunner::setAlwaysAcceptCookies(bool alwaysAcceptCookies)
336 {
337     if (alwaysAcceptCookies == m_alwaysAcceptCookies)
338         return;
339
340     if (!::setAlwaysAcceptCookies(alwaysAcceptCookies))
341         return;
342     m_alwaysAcceptCookies = alwaysAcceptCookies;
343 }
344
345 void TestRunner::setAuthorAndUserStylesEnabled(bool flag)
346 {
347     COMPtr<IWebView> webView;
348     if (FAILED(frame->webView(&webView)))
349         return;
350
351     COMPtr<IWebPreferences> preferences;
352     if (FAILED(webView->preferences(&preferences)))
353         return;
354
355     COMPtr<IWebPreferencesPrivate> prefsPrivate(Query, preferences);
356     if (!prefsPrivate)
357         return;
358
359     prefsPrivate->setAuthorAndUserStylesEnabled(flag);
360 }
361
362 void TestRunner::setAutofilled(JSContextRef context, JSValueRef nodeObject, bool autofilled)
363 {
364     COMPtr<IWebView> webView;
365     if (FAILED(frame->webView(&webView)))
366         return;
367
368     COMPtr<IWebViewPrivate> webViewPrivate(Query, webView);
369     if (!webViewPrivate)
370         return;
371
372     COMPtr<IDOMElement> element;
373     if (FAILED(webViewPrivate->elementFromJS(context, nodeObject, &element)))
374         return;
375
376     COMPtr<IFormsAutoFillTransition> autofillElement(Query, element);
377     if (!autofillElement)
378         return;
379
380     autofillElement->setAutofilled(autofilled);
381 }
382
383 void TestRunner::setCustomPolicyDelegate(bool setDelegate, bool permissive)
384 {
385     COMPtr<IWebView> webView;
386     if (FAILED(frame->webView(&webView)))
387         return;
388
389     if (setDelegate) {
390         policyDelegate->setPermissive(permissive);
391         webView->setPolicyDelegate(policyDelegate);
392     } else
393         webView->setPolicyDelegate(0);
394 }
395
396 void TestRunner::setMockDeviceOrientation(bool canProvideAlpha, double alpha, bool canProvideBeta, double beta, bool canProvideGamma, double gamma)
397 {
398     // FIXME: Implement for DeviceOrientation layout tests.
399     // See https://bugs.webkit.org/show_bug.cgi?id=30335.
400 }
401
402 void TestRunner::setMockGeolocationPosition(double latitude, double longitude, double accuracy, bool providesAltitude, double altitude, bool providesAltitudeAccuracy, double altitudeAccuracy, bool providesHeading, double heading, bool providesSpeed, double speed)
403 {
404     // FIXME: Implement for Geolocation layout tests.
405     // See https://bugs.webkit.org/show_bug.cgi?id=28264.
406 }
407
408 void TestRunner::setMockGeolocationPositionUnavailableError(JSStringRef message)
409 {
410     // FIXME: Implement for Geolocation layout tests.
411     // See https://bugs.webkit.org/show_bug.cgi?id=28264.
412 }
413
414 void TestRunner::setGeolocationPermission(bool allow)
415 {
416     // FIXME: Implement for Geolocation layout tests.
417     setGeolocationPermissionCommon(allow);
418 }
419
420 int TestRunner::numberOfPendingGeolocationPermissionRequests()
421 {
422     // FIXME: Implement for Geolocation layout tests.
423     return -1;
424 }
425
426 void TestRunner::addMockSpeechInputResult(JSStringRef result, double confidence, JSStringRef language)
427 {
428     // FIXME: Implement for speech input layout tests.
429     // See https://bugs.webkit.org/show_bug.cgi?id=39485.
430 }
431
432 void TestRunner::setMockSpeechInputDumpRect(bool flag)
433 {
434     // FIXME: Implement for speech input layout tests.
435     // See https://bugs.webkit.org/show_bug.cgi?id=39485.
436 }
437
438 void TestRunner::startSpeechInput(JSContextRef inputElement)
439 {
440     // FIXME: Implement for speech input layout tests.
441     // See https://bugs.webkit.org/show_bug.cgi?id=39485.
442 }
443
444 void TestRunner::setIconDatabaseEnabled(bool iconDatabaseEnabled)
445 {
446     // See also <rdar://problem/6480108>
447     COMPtr<IWebIconDatabase> iconDatabase;
448     COMPtr<IWebIconDatabase> tmpIconDatabase;
449     if (FAILED(WebKitCreateInstance(CLSID_WebIconDatabase, 0, IID_IWebIconDatabase, (void**)&tmpIconDatabase)))
450         return;
451     if (FAILED(tmpIconDatabase->sharedIconDatabase(&iconDatabase)))
452         return;
453
454     iconDatabase->setEnabled(iconDatabaseEnabled);
455 }
456
457 void TestRunner::setMainFrameIsFirstResponder(bool flag)
458 {
459     // FIXME: Implement!
460 }
461
462 void TestRunner::setPrivateBrowsingEnabled(bool privateBrowsingEnabled)
463 {
464     COMPtr<IWebView> webView;
465     if (FAILED(frame->webView(&webView)))
466         return;
467
468     COMPtr<IWebPreferences> preferences;
469     if (FAILED(webView->preferences(&preferences)))
470         return;
471
472     preferences->setPrivateBrowsingEnabled(privateBrowsingEnabled);
473 }
474
475 void TestRunner::setXSSAuditorEnabled(bool enabled)
476 {
477     COMPtr<IWebView> webView;
478     if (FAILED(frame->webView(&webView)))
479         return;
480
481     COMPtr<IWebPreferences> preferences;
482     if (FAILED(webView->preferences(&preferences)))
483         return;
484
485     COMPtr<IWebPreferencesPrivate> prefsPrivate(Query, preferences);
486     if (!prefsPrivate)
487         return;
488
489     prefsPrivate->setXSSAuditorEnabled(enabled);
490 }
491
492 void TestRunner::setFrameFlatteningEnabled(bool enabled)
493 {
494     COMPtr<IWebView> webView;
495     if (FAILED(frame->webView(&webView)))
496         return;
497
498     COMPtr<IWebPreferences> preferences;
499     if (FAILED(webView->preferences(&preferences)))
500         return;
501
502     COMPtr<IWebPreferencesPrivate> prefsPrivate(Query, preferences);
503     if (!prefsPrivate)
504         return;
505
506     prefsPrivate->setFrameFlatteningEnabled(enabled);
507 }
508
509 void TestRunner::setSpatialNavigationEnabled(bool enabled)
510 {
511     // FIXME: Implement for SpatialNavigation layout tests.
512 }
513
514 void TestRunner::setAllowUniversalAccessFromFileURLs(bool enabled)
515 {
516     COMPtr<IWebView> webView;
517     if (FAILED(frame->webView(&webView)))
518         return;
519
520     COMPtr<IWebPreferences> preferences;
521     if (FAILED(webView->preferences(&preferences)))
522         return;
523
524     COMPtr<IWebPreferencesPrivate> prefsPrivate(Query, preferences);
525     if (!prefsPrivate)
526         return;
527
528     prefsPrivate->setAllowUniversalAccessFromFileURLs(enabled);
529 }
530
531 void TestRunner::setAllowFileAccessFromFileURLs(bool enabled)
532 {
533     COMPtr<IWebView> webView;
534     if (FAILED(frame->webView(&webView)))
535         return;
536
537     COMPtr<IWebPreferences> preferences;
538     if (FAILED(webView->preferences(&preferences)))
539         return;
540
541     COMPtr<IWebPreferencesPrivate> prefsPrivate(Query, preferences);
542     if (!prefsPrivate)
543         return;
544
545     prefsPrivate->setAllowFileAccessFromFileURLs(enabled);
546 }
547
548 void TestRunner::setPopupBlockingEnabled(bool enabled)
549 {
550     COMPtr<IWebView> webView;
551     if (FAILED(frame->webView(&webView)))
552         return;
553
554     COMPtr<IWebPreferences> preferences;
555     if (FAILED(webView->preferences(&preferences)))
556         return;
557
558     preferences->setJavaScriptCanOpenWindowsAutomatically(!enabled);
559 }
560
561 void TestRunner::setPluginsEnabled(bool flag)
562 {
563     // FIXME: Implement
564 }
565
566 void TestRunner::setJavaScriptCanAccessClipboard(bool enabled)
567 {
568     COMPtr<IWebView> webView;
569     if (FAILED(frame->webView(&webView)))
570         return;
571
572     COMPtr<IWebPreferences> preferences;
573     if (FAILED(webView->preferences(&preferences)))
574         return;
575
576     COMPtr<IWebPreferencesPrivate> prefsPrivate(Query, preferences);
577     if (!prefsPrivate)
578         return;
579
580     prefsPrivate->setJavaScriptCanAccessClipboard(enabled);
581 }
582
583 void TestRunner::setTabKeyCyclesThroughElements(bool shouldCycle)
584 {
585     COMPtr<IWebView> webView;
586     if (FAILED(frame->webView(&webView)))
587         return;
588
589     COMPtr<IWebViewPrivate> viewPrivate;
590     if (FAILED(webView->QueryInterface(&viewPrivate)))
591         return;
592
593     viewPrivate->setTabKeyCyclesThroughElements(shouldCycle ? TRUE : FALSE);
594 }
595
596 void TestRunner::setUseDashboardCompatibilityMode(bool flag)
597 {
598     // FIXME: Implement!
599 }
600
601 void TestRunner::setUserStyleSheetEnabled(bool flag)
602 {
603     COMPtr<IWebView> webView;
604     if (FAILED(frame->webView(&webView)))
605         return;
606
607     COMPtr<IWebPreferences> preferences;
608     if (FAILED(webView->preferences(&preferences)))
609         return;
610
611     preferences->setUserStyleSheetEnabled(flag);
612 }
613
614 bool appendComponentToPath(wstring& path, const wstring& component)
615 {
616     WCHAR buffer[MAX_PATH];
617
618     if (path.size() + 1 > MAX_PATH)
619         return false;
620
621     memcpy(buffer, path.data(), path.size() * sizeof(WCHAR));
622     buffer[path.size()] = '\0';
623
624     if (!PathAppendW(buffer, component.c_str()))
625         return false;
626
627     path = wstring(buffer);
628     return true;
629 }
630
631 static bool followShortcuts(wstring& path)
632 {
633     if (PathFileExists(path.c_str()))
634         return true;
635
636     // Do we have a shortcut?
637     wstring linkPath = path;
638     linkPath.append(TEXT(".lnk"));
639     if (!PathFileExists(linkPath.c_str()))
640        return true;
641
642     // We have a shortcut, find its target.
643     COMPtr<IShellLink> shortcut(Create, CLSID_ShellLink);
644     if (!shortcut)
645        return false;
646     COMPtr<IPersistFile> persistFile(Query, shortcut);
647     if (!shortcut)
648         return false;
649     if (FAILED(persistFile->Load(linkPath.c_str(), STGM_READ)))
650         return false;
651     if (FAILED(shortcut->Resolve(0, 0)))
652         return false;
653     WCHAR targetPath[MAX_PATH];
654     DWORD targetPathLen = _countof(targetPath);
655     if (FAILED(shortcut->GetPath(targetPath, targetPathLen, 0, 0)))
656         return false;
657     if (!PathFileExists(targetPath))
658         return false;
659     // Use the target path as the result path instead.
660     path = wstring(targetPath);
661
662     return true;
663 }
664
665 static bool resolveCygwinPath(const wstring& cygwinPath, wstring& windowsPath)
666 {
667     wstring fileProtocol = L"file://";
668     bool isFileProtocol = cygwinPath.find(fileProtocol) != string::npos;
669     if (cygwinPath[isFileProtocol ? 7 : 0] != '/') // ensure path is absolute
670         return false;
671
672     // Get the Root path.
673     WCHAR rootPath[MAX_PATH];
674     DWORD rootPathSize = _countof(rootPath);
675     DWORD keyType;
676     DWORD result = ::SHGetValueW(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Cygnus Solutions\\Cygwin\\mounts v2\\/"), TEXT("native"), &keyType, &rootPath, &rootPathSize);
677
678     if (result != ERROR_SUCCESS || keyType != REG_SZ) {
679         // Cygwin 1.7 doesn't store Cygwin's root as a mount point anymore, because mount points are now stored in /etc/fstab.
680         // However, /etc/fstab doesn't contain any information about where / is located as a Windows path, so we need to use Cygwin's
681         // new registry key that has the root.
682         result = ::SHGetValueW(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Cygwin\\setup"), TEXT("rootdir"), &keyType, &rootPath, &rootPathSize);
683         if (result != ERROR_SUCCESS || keyType != REG_SZ)
684             return false;
685     }
686
687     windowsPath = wstring(rootPath, rootPathSize);
688
689     int oldPos = isFileProtocol ? 8 : 1;
690     while (1) {
691         int newPos = cygwinPath.find('/', oldPos);
692
693         if (newPos == -1) {
694             wstring pathComponent = cygwinPath.substr(oldPos);
695
696             if (!appendComponentToPath(windowsPath, pathComponent))
697                return false;
698
699             if (!followShortcuts(windowsPath))
700                 return false;
701
702             break;
703         }
704
705         wstring pathComponent = cygwinPath.substr(oldPos, newPos - oldPos);
706         if (!appendComponentToPath(windowsPath, pathComponent))
707             return false;
708
709         if (!followShortcuts(windowsPath))
710             return false;
711
712         oldPos = newPos + 1;
713     }
714
715     if (isFileProtocol)
716         windowsPath = fileProtocol + windowsPath;
717
718     return true;
719 }
720
721 void TestRunner::setUserStyleSheetLocation(JSStringRef jsURL)
722 {
723     COMPtr<IWebView> webView;
724     if (FAILED(frame->webView(&webView)))
725         return;
726
727     COMPtr<IWebPreferences> preferences;
728     if (FAILED(webView->preferences(&preferences)))
729         return;
730
731     RetainPtr<CFStringRef> urlString(AdoptCF, JSStringCopyCFString(0, jsURL));
732     RetainPtr<CFURLRef> url(AdoptCF, CFURLCreateWithString(0, urlString.get(), 0));
733     if (!url)
734         return;
735
736     // Now copy the file system path, POSIX style.
737     RetainPtr<CFStringRef> pathCF(AdoptCF, CFURLCopyFileSystemPath(url.get(), kCFURLPOSIXPathStyle));
738     if (!pathCF)
739         return;
740
741     wstring path = cfStringRefToWString(pathCF.get());
742
743     wstring resultPath;
744     if (!resolveCygwinPath(path, resultPath))
745         return;
746
747     // The path has been resolved, now convert it back to a CFURL.
748     int result = WideCharToMultiByte(CP_UTF8, 0, resultPath.c_str(), resultPath.size() + 1, 0, 0, 0, 0);
749     Vector<char> utf8Vector(result);
750     result = WideCharToMultiByte(CP_UTF8, 0, resultPath.c_str(), resultPath.size() + 1, utf8Vector.data(), result, 0, 0);
751     if (!result)
752         return;
753
754     url = CFURLCreateFromFileSystemRepresentation(0, (const UInt8*)utf8Vector.data(), utf8Vector.size() - 1, false);
755     if (!url)
756         return;
757
758     resultPath = cfStringRefToWString(CFURLGetString(url.get()));
759
760     BSTR resultPathBSTR = SysAllocStringLen(resultPath.data(), resultPath.size());
761     preferences->setUserStyleSheetLocation(resultPathBSTR);
762     SysFreeString(resultPathBSTR);
763 }
764
765 void TestRunner::setValueForUser(JSContextRef context, JSValueRef element, JSStringRef value)
766 {
767     COMPtr<IWebView> webView;
768     if (FAILED(frame->webView(&webView)))
769         return;
770
771     COMPtr<IWebViewPrivate> webViewPrivate(Query, webView);
772     if (!webViewPrivate)
773         return;
774
775     COMPtr<IDOMElement> domElement;
776     if (FAILED(webViewPrivate->elementFromJS(context, element, &domElement)))
777         return;
778
779     COMPtr<IDOMHTMLInputElement> domInputElement;
780     if (FAILED(domElement->QueryInterface(IID_IDOMHTMLInputElement, reinterpret_cast<void**>(&domInputElement))))
781         return;
782
783     _bstr_t valueBSTR(JSStringCopyBSTR(value), false);
784
785     domInputElement->setValueForUser(valueBSTR);
786 }
787
788 void TestRunner::setViewModeMediaFeature(JSStringRef mode)
789 {
790     // FIXME: implement
791 }
792
793 void TestRunner::setPersistentUserStyleSheetLocation(JSStringRef jsURL)
794 {
795     RetainPtr<CFStringRef> urlString(AdoptCF, JSStringCopyCFString(0, jsURL));
796     ::setPersistentUserStyleSheetLocation(urlString.get());
797 }
798
799 void TestRunner::clearPersistentUserStyleSheet()
800 {
801     ::setPersistentUserStyleSheetLocation(0);
802 }
803
804 void TestRunner::setWindowIsKey(bool flag)
805 {
806     COMPtr<IWebView> webView;
807     if (FAILED(frame->webView(&webView)))
808         return;
809
810     COMPtr<IWebViewPrivate> viewPrivate;
811     if (FAILED(webView->QueryInterface(&viewPrivate)))
812         return;
813
814     HWND webViewWindow;
815     if (FAILED(viewPrivate->viewWindow((OLE_HANDLE*)&webViewWindow)))
816         return;
817
818     ::SendMessage(webViewWindow, flag ? WM_SETFOCUS : WM_KILLFOCUS, (WPARAM)::GetDesktopWindow(), 0);
819 }
820
821 void TestRunner::setSmartInsertDeleteEnabled(bool flag)
822 {
823     COMPtr<IWebView> webView;
824     if (FAILED(frame->webView(&webView)))
825         return;
826
827     COMPtr<IWebViewEditing> viewEditing;
828     if (FAILED(webView->QueryInterface(&viewEditing)))
829         return;
830
831     viewEditing->setSmartInsertDeleteEnabled(flag ? TRUE : FALSE);
832 }
833
834 void TestRunner::setSelectTrailingWhitespaceEnabled(bool flag)
835 {
836     COMPtr<IWebView> webView;
837     if (FAILED(frame->webView(&webView)))
838         return;
839
840     COMPtr<IWebViewEditing> viewEditing;
841     if (FAILED(webView->QueryInterface(&viewEditing)))
842         return;
843
844     viewEditing->setSelectTrailingWhitespaceEnabled(flag ? TRUE : FALSE);
845 }
846
847 static const CFTimeInterval waitToDumpWatchdogInterval = 30.0;
848
849 static void CALLBACK waitUntilDoneWatchdogFired(HWND, UINT, UINT_PTR, DWORD)
850 {
851     gTestRunner->waitToDumpWatchdogTimerFired();
852 }
853
854 void TestRunner::setWaitToDump(bool waitUntilDone)
855 {
856     m_waitToDump = waitUntilDone;
857     if (m_waitToDump && !waitToDumpWatchdog)
858         waitToDumpWatchdog = SetTimer(0, 0, waitToDumpWatchdogInterval * 1000, waitUntilDoneWatchdogFired);
859 }
860
861 int TestRunner::windowCount()
862 {
863     return openWindows().size();
864 }
865
866 bool TestRunner::elementDoesAutoCompleteForElementWithId(JSStringRef id)
867 {
868     COMPtr<IDOMDocument> document;
869     if (FAILED(frame->DOMDocument(&document)))
870         return false;
871
872     wstring idWstring = jsStringRefToWString(id);
873     BSTR idBSTR = SysAllocStringLen((OLECHAR*)idWstring.c_str(), idWstring.length());
874     COMPtr<IDOMElement> element;
875     HRESULT result = document->getElementById(idBSTR, &element);
876     SysFreeString(idBSTR);
877
878     if (FAILED(result))
879         return false;
880
881     COMPtr<IWebFramePrivate> framePrivate(Query, frame);
882     if (!framePrivate)
883         return false;
884
885     BOOL autoCompletes;
886     if (FAILED(framePrivate->elementDoesAutoComplete(element.get(), &autoCompletes)))
887         return false;
888
889     return autoCompletes;
890 }
891
892 void TestRunner::execCommand(JSStringRef name, JSStringRef value)
893 {
894     wstring wName = jsStringRefToWString(name);
895     wstring wValue = jsStringRefToWString(value);
896
897     COMPtr<IWebView> webView;
898     if (FAILED(frame->webView(&webView)))
899         return;
900
901     COMPtr<IWebViewPrivate> viewPrivate;
902     if (FAILED(webView->QueryInterface(&viewPrivate)))
903         return;
904
905     BSTR nameBSTR = SysAllocStringLen((OLECHAR*)wName.c_str(), wName.length());
906     BSTR valueBSTR = SysAllocStringLen((OLECHAR*)wValue.c_str(), wValue.length());
907     viewPrivate->executeCoreCommandByName(nameBSTR, valueBSTR);
908
909     SysFreeString(nameBSTR);
910     SysFreeString(valueBSTR);
911 }
912
913 bool TestRunner::findString(JSContextRef /* context */, JSStringRef /* target */, JSObjectRef /* optionsArray */)
914 {
915     // FIXME: Implement
916     return false;
917 }
918
919 void TestRunner::setCacheModel(int)
920 {
921     // FIXME: Implement
922 }
923
924 bool TestRunner::isCommandEnabled(JSStringRef /*name*/)
925 {
926     printf("ERROR: TestRunner::isCommandEnabled() not implemented\n");
927     return false;
928 }
929
930 void TestRunner::clearAllApplicationCaches()
931 {
932     // FIXME: Implement to support application cache quotas.
933 }
934
935 void TestRunner::clearApplicationCacheForOrigin(JSStringRef origin)
936 {
937     // FIXME: Implement to support deleting all application cache for an origin.
938 }
939
940 void TestRunner::setApplicationCacheOriginQuota(unsigned long long quota)
941 {
942     // FIXME: Implement to support application cache quotas.
943 }
944
945 JSValueRef TestRunner::originsWithApplicationCache(JSContextRef context)
946 {
947     // FIXME: Implement to get origins that have application caches.
948     return JSValueMakeUndefined(context);
949 }
950
951 long long TestRunner::applicationCacheDiskUsageForOrigin(JSStringRef name)
952 {
953     // FIXME: Implement to get disk usage by all application caches for an origin.
954     return 0;
955 }
956
957 void TestRunner::clearAllDatabases()
958 {
959     COMPtr<IWebDatabaseManager> databaseManager;
960     COMPtr<IWebDatabaseManager> tmpDatabaseManager;
961     if (FAILED(WebKitCreateInstance(CLSID_WebDatabaseManager, 0, IID_IWebDatabaseManager, (void**)&tmpDatabaseManager)))
962         return;
963     if (FAILED(tmpDatabaseManager->sharedWebDatabaseManager(&databaseManager)))
964         return;
965
966     databaseManager->deleteAllDatabases();
967 }
968
969 void TestRunner::overridePreference(JSStringRef key, JSStringRef value)
970 {
971     COMPtr<IWebView> webView;
972     if (FAILED(frame->webView(&webView)))
973         return;
974
975     COMPtr<IWebPreferences> preferences;
976     if (FAILED(webView->preferences(&preferences)))
977         return;
978
979     COMPtr<IWebPreferencesPrivate> prefsPrivate(Query, preferences);
980     if (!prefsPrivate)
981         return;
982
983     BSTR keyBSTR = JSStringCopyBSTR(key);
984     BSTR valueBSTR = JSStringCopyBSTR(value);
985     prefsPrivate->setPreferenceForTest(keyBSTR, valueBSTR);
986     SysFreeString(keyBSTR);
987     SysFreeString(valueBSTR);
988 }
989
990 void TestRunner::setDatabaseQuota(unsigned long long quota)
991 {
992     COMPtr<IWebDatabaseManager> databaseManager;
993     COMPtr<IWebDatabaseManager> tmpDatabaseManager;
994
995     if (FAILED(WebKitCreateInstance(CLSID_WebDatabaseManager, 0, IID_IWebDatabaseManager, (void**)&tmpDatabaseManager)))
996         return;
997     if (FAILED(tmpDatabaseManager->sharedWebDatabaseManager(&databaseManager)))
998         return;
999
1000     databaseManager->setQuota(TEXT("file:///"), quota);
1001 }
1002
1003 void TestRunner::goBack()
1004 {
1005     // FIXME: implement to enable loader/navigation-while-deferring-loads.html
1006 }
1007
1008 void TestRunner::setDefersLoading(bool)
1009 {
1010     // FIXME: implement to enable loader/navigation-while-deferring-loads.html
1011 }
1012
1013 void TestRunner::setDomainRelaxationForbiddenForURLScheme(bool forbidden, JSStringRef scheme)
1014 {
1015     COMPtr<IWebViewPrivate> webView;
1016     if (FAILED(WebKitCreateInstance(__uuidof(WebView), 0, __uuidof(webView), reinterpret_cast<void**>(&webView))))
1017         return;
1018
1019     BSTR schemeBSTR = JSStringCopyBSTR(scheme);
1020     webView->setDomainRelaxationForbiddenForURLScheme(forbidden, schemeBSTR);
1021     SysFreeString(schemeBSTR);
1022 }
1023
1024 void TestRunner::setAppCacheMaximumSize(unsigned long long size)
1025 {
1026     printf("ERROR: TestRunner::setAppCacheMaximumSize() not implemented\n");
1027 }
1028
1029 bool TestRunner::pauseAnimationAtTimeOnElementWithId(JSStringRef animationName, double time, JSStringRef elementId)
1030 {
1031     COMPtr<IDOMDocument> document;
1032     if (FAILED(frame->DOMDocument(&document)))
1033         return false;
1034
1035     BSTR idBSTR = JSStringCopyBSTR(elementId);
1036     COMPtr<IDOMElement> element;
1037     HRESULT hr = document->getElementById(idBSTR, &element);
1038     SysFreeString(idBSTR);
1039     if (FAILED(hr))
1040         return false;
1041
1042     COMPtr<IWebFramePrivate> framePrivate(Query, frame);
1043     if (!framePrivate)
1044         return false;
1045
1046     BSTR nameBSTR = JSStringCopyBSTR(animationName);
1047     BOOL wasRunning = FALSE;
1048     hr = framePrivate->pauseAnimation(nameBSTR, element.get(), time, &wasRunning);
1049     SysFreeString(nameBSTR);
1050
1051     return SUCCEEDED(hr) && wasRunning;
1052 }
1053
1054 bool TestRunner::pauseTransitionAtTimeOnElementWithId(JSStringRef propertyName, double time, JSStringRef elementId)
1055 {
1056     COMPtr<IDOMDocument> document;
1057     if (FAILED(frame->DOMDocument(&document)))
1058         return false;
1059
1060     BSTR idBSTR = JSStringCopyBSTR(elementId);
1061     COMPtr<IDOMElement> element;
1062     HRESULT hr = document->getElementById(idBSTR, &element);
1063     SysFreeString(idBSTR);
1064     if (FAILED(hr))
1065         return false;
1066
1067     COMPtr<IWebFramePrivate> framePrivate(Query, frame);
1068     if (!framePrivate)
1069         return false;
1070
1071     BSTR nameBSTR = JSStringCopyBSTR(propertyName);
1072     BOOL wasRunning = FALSE;
1073     hr = framePrivate->pauseTransition(nameBSTR, element.get(), time, &wasRunning);
1074     SysFreeString(nameBSTR);
1075
1076     return SUCCEEDED(hr) && wasRunning;
1077 }
1078
1079 unsigned TestRunner::numberOfActiveAnimations() const
1080 {
1081     COMPtr<IWebFramePrivate> framePrivate(Query, frame);
1082     if (!framePrivate)
1083         return 0;
1084
1085     UINT number = 0;
1086     if (FAILED(framePrivate->numberOfActiveAnimations(&number)))
1087         return 0;
1088
1089     return number;
1090 }
1091
1092 static _bstr_t bstrT(JSStringRef jsString)
1093 {
1094     // The false parameter tells the _bstr_t constructor to adopt the BSTR we pass it.
1095     return _bstr_t(JSStringCopyBSTR(jsString), false);
1096 }
1097
1098 void TestRunner::addOriginAccessWhitelistEntry(JSStringRef sourceOrigin, JSStringRef destinationProtocol, JSStringRef destinationHost, bool allowDestinationSubdomains)
1099 {
1100     COMPtr<IWebViewPrivate> webView;
1101     if (FAILED(WebKitCreateInstance(__uuidof(WebView), 0, __uuidof(webView), reinterpret_cast<void**>(&webView))))
1102         return;
1103
1104     webView->addOriginAccessWhitelistEntry(bstrT(sourceOrigin).GetBSTR(), bstrT(destinationProtocol).GetBSTR(), bstrT(destinationHost).GetBSTR(), allowDestinationSubdomains);
1105 }
1106
1107 void TestRunner::removeOriginAccessWhitelistEntry(JSStringRef sourceOrigin, JSStringRef destinationProtocol, JSStringRef destinationHost, bool allowDestinationSubdomains)
1108 {
1109     COMPtr<IWebViewPrivate> webView;
1110     if (FAILED(WebKitCreateInstance(__uuidof(WebView), 0, __uuidof(webView), reinterpret_cast<void**>(&webView))))
1111         return;
1112
1113     webView->removeOriginAccessWhitelistEntry(bstrT(sourceOrigin).GetBSTR(), bstrT(destinationProtocol).GetBSTR(), bstrT(destinationHost).GetBSTR(), allowDestinationSubdomains);
1114 }
1115
1116 void TestRunner::setScrollbarPolicy(JSStringRef orientation, JSStringRef policy)
1117 {
1118     // FIXME: implement
1119 }
1120
1121 void TestRunner::addUserScript(JSStringRef source, bool runAtStart, bool allFrames)
1122 {
1123     COMPtr<IWebViewPrivate> webView;
1124     if (FAILED(WebKitCreateInstance(__uuidof(WebView), 0, __uuidof(webView), reinterpret_cast<void**>(&webView))))
1125         return;
1126
1127     COMPtr<IWebScriptWorld> world;
1128     if (FAILED(WebKitCreateInstance(__uuidof(WebScriptWorld), 0, __uuidof(world), reinterpret_cast<void**>(&world))))
1129         return;
1130
1131     webView->addUserScriptToGroup(_bstr_t(L"org.webkit.DumpRenderTree").GetBSTR(), world.get(), bstrT(source).GetBSTR(), 0, 0, 0, 0, 0, runAtStart ? WebInjectAtDocumentStart : WebInjectAtDocumentEnd);
1132 }
1133
1134
1135 void TestRunner::addUserStyleSheet(JSStringRef source, bool allFrames)
1136 {
1137     COMPtr<IWebViewPrivate> webView;
1138     if (FAILED(WebKitCreateInstance(__uuidof(WebView), 0, __uuidof(webView), reinterpret_cast<void**>(&webView))))
1139         return;
1140
1141     COMPtr<IWebScriptWorld> world;
1142     if (FAILED(WebKitCreateInstance(__uuidof(WebScriptWorld), 0, __uuidof(world), reinterpret_cast<void**>(&world))))
1143         return;
1144
1145     webView->addUserStyleSheetToGroup(_bstr_t(L"org.webkit.DumpRenderTree").GetBSTR(), world.get(), bstrT(source).GetBSTR(), 0, 0, 0, 0, 0);
1146 }
1147
1148 void TestRunner::setDeveloperExtrasEnabled(bool enabled)
1149 {
1150     COMPtr<IWebView> webView;
1151     if (FAILED(frame->webView(&webView)))
1152         return;
1153
1154     COMPtr<IWebPreferences> preferences;
1155     if (FAILED(webView->preferences(&preferences)))
1156         return;
1157
1158     COMPtr<IWebPreferencesPrivate> prefsPrivate(Query, preferences);
1159     if (!prefsPrivate)
1160         return;
1161
1162     prefsPrivate->setDeveloperExtrasEnabled(enabled);
1163 }
1164
1165 void TestRunner::setAsynchronousSpellCheckingEnabled(bool)
1166 {
1167     // FIXME: Implement this.
1168 }
1169
1170 void TestRunner::showWebInspector()
1171 {
1172     COMPtr<IWebView> webView;
1173     if (FAILED(frame->webView(&webView)))
1174         return;
1175
1176     COMPtr<IWebViewPrivate> viewPrivate(Query, webView);
1177     if (!viewPrivate)
1178         return;
1179
1180     COMPtr<IWebInspector> inspector;
1181     if (SUCCEEDED(viewPrivate->inspector(&inspector)))
1182         inspector->show();
1183 }
1184
1185 void TestRunner::closeWebInspector()
1186 {
1187     COMPtr<IWebView> webView;
1188     if (FAILED(frame->webView(&webView)))
1189         return;
1190
1191     COMPtr<IWebViewPrivate> viewPrivate(Query, webView);
1192     if (!viewPrivate)
1193         return;
1194
1195     COMPtr<IWebInspector> inspector;
1196     if (FAILED(viewPrivate->inspector(&inspector)))
1197         return;
1198
1199     inspector->close();
1200 }
1201
1202 void TestRunner::evaluateInWebInspector(long callId, JSStringRef script)
1203 {
1204     COMPtr<IWebView> webView;
1205     if (FAILED(frame->webView(&webView)))
1206         return;
1207
1208     COMPtr<IWebViewPrivate> viewPrivate(Query, webView);
1209     if (!viewPrivate)
1210         return;
1211
1212     COMPtr<IWebInspector> inspector;
1213     if (FAILED(viewPrivate->inspector(&inspector)))
1214         return;
1215
1216     COMPtr<IWebInspectorPrivate> inspectorPrivate(Query, inspector);
1217     if (!inspectorPrivate)
1218         return;
1219
1220     inspectorPrivate->evaluateInFrontend(callId, bstrT(script).GetBSTR());
1221 }
1222
1223 typedef HashMap<unsigned, COMPtr<IWebScriptWorld> > WorldMap;
1224 static WorldMap& worldMap()
1225 {
1226     static WorldMap& map = *new WorldMap;
1227     return map;
1228 }
1229
1230 unsigned worldIDForWorld(IWebScriptWorld* world)
1231 {
1232     WorldMap::const_iterator end = worldMap().end();
1233     for (WorldMap::const_iterator it = worldMap().begin(); it != end; ++it) {
1234         if (it->value == world)
1235             return it->key;
1236     }
1237
1238     return 0;
1239 }
1240
1241 void TestRunner::evaluateScriptInIsolatedWorldAndReturnValue(unsigned worldID, JSObjectRef globalObject, JSStringRef script)
1242 {
1243     // FIXME: Implement this.
1244 }
1245
1246 void TestRunner::evaluateScriptInIsolatedWorld(unsigned worldID, JSObjectRef globalObject, JSStringRef script)
1247 {
1248     COMPtr<IWebFramePrivate> framePrivate(Query, frame);
1249     if (!framePrivate)
1250         return;
1251
1252     // A worldID of 0 always corresponds to a new world. Any other worldID corresponds to a world
1253     // that is created once and cached forever.
1254     COMPtr<IWebScriptWorld> world;
1255     if (!worldID) {
1256         if (FAILED(WebKitCreateInstance(__uuidof(WebScriptWorld), 0, __uuidof(world), reinterpret_cast<void**>(&world))))
1257             return;
1258     } else {
1259         COMPtr<IWebScriptWorld>& worldSlot = worldMap().add(worldID, 0).iterator->value;
1260         if (!worldSlot && FAILED(WebKitCreateInstance(__uuidof(WebScriptWorld), 0, __uuidof(worldSlot), reinterpret_cast<void**>(&worldSlot))))
1261             return;
1262         world = worldSlot;
1263     }
1264
1265     BSTR result;
1266     if (FAILED(framePrivate->stringByEvaluatingJavaScriptInScriptWorld(world.get(), globalObject, bstrT(script).GetBSTR(), &result)))
1267         return;
1268     SysFreeString(result);
1269 }
1270
1271 void TestRunner::removeAllVisitedLinks()
1272 {
1273     COMPtr<IWebHistory> history;
1274     if (FAILED(WebKitCreateInstance(CLSID_WebHistory, 0, __uuidof(history), reinterpret_cast<void**>(&history))))
1275         return;
1276
1277     COMPtr<IWebHistory> sharedHistory;
1278     if (FAILED(history->optionalSharedHistory(&sharedHistory)) || !sharedHistory)
1279         return;
1280
1281     COMPtr<IWebHistoryPrivate> sharedHistoryPrivate;
1282     if (FAILED(sharedHistory->QueryInterface(&sharedHistoryPrivate)))
1283         return;
1284
1285     sharedHistoryPrivate->removeAllVisitedLinks();
1286 }
1287
1288 void TestRunner::apiTestNewWindowDataLoadBaseURL(JSStringRef utf8Data, JSStringRef baseURL)
1289 {
1290
1291 }
1292
1293 void TestRunner::apiTestGoToCurrentBackForwardItem()
1294 {
1295     COMPtr<IWebView> webView;
1296     if (FAILED(frame->webView(&webView)))
1297         return;
1298
1299     COMPtr<IWebBackForwardList> backForwardList;
1300     if (FAILED(webView->backForwardList(&backForwardList)))
1301         return;
1302
1303     COMPtr<IWebHistoryItem> item;
1304     if (FAILED(backForwardList->currentItem(&item)))
1305         return;
1306
1307     BOOL success;
1308     webView->goToBackForwardItem(item.get(), &success);
1309 }
1310
1311 void TestRunner::setWebViewEditable(bool)
1312 {
1313 }
1314
1315 void TestRunner::authenticateSession(JSStringRef, JSStringRef, JSStringRef)
1316 {
1317 }
1318
1319 void TestRunner::abortModal()
1320 {
1321 }
1322
1323 void TestRunner::setSerializeHTTPLoads(bool)
1324 {
1325     // FIXME: Implement.
1326 }
1327
1328 void TestRunner::syncLocalStorage()
1329 {
1330     // FIXME: Implement.
1331 }
1332
1333 void TestRunner::observeStorageTrackerNotifications(unsigned number)
1334 {
1335     // FIXME: Implement.
1336 }
1337
1338 void TestRunner::deleteAllLocalStorage()
1339 {
1340     // FIXME: Implement.
1341 }
1342
1343 JSValueRef TestRunner::originsWithLocalStorage(JSContextRef context)
1344 {
1345     // FIXME: Implement.
1346     return JSValueMakeUndefined(context);
1347 }
1348
1349 long long TestRunner::localStorageDiskUsageForOrigin(JSStringRef originIdentifier)
1350 {
1351     // FIXME: Implement to support getting local storage disk usage for an origin.
1352     return 0;
1353 }
1354
1355 void TestRunner::deleteLocalStorageForOrigin(JSStringRef URL)
1356 {
1357     // FIXME: Implement.
1358 }
1359
1360 void TestRunner::setMinimumTimerInterval(double minimumTimerInterval)
1361 {
1362     COMPtr<IWebView> webView;
1363     if (FAILED(frame->webView(&webView)))
1364         return;
1365
1366     COMPtr<IWebViewPrivate> viewPrivate(Query, webView);
1367     if (!viewPrivate)
1368         return;
1369
1370     viewPrivate->setMinimumTimerInterval(minimumTimerInterval);
1371 }
1372
1373 void TestRunner::setTextDirection(JSStringRef direction)
1374 {
1375     COMPtr<IWebFramePrivate> framePrivate(Query, frame);
1376     if (!framePrivate)
1377         return;
1378
1379     framePrivate->setTextDirection(bstrT(direction).GetBSTR());
1380 }
1381
1382 void TestRunner::addChromeInputField()
1383 {
1384 }
1385
1386 void TestRunner::removeChromeInputField()
1387 {
1388 }
1389
1390 void TestRunner::focusWebView()
1391 {
1392 }
1393
1394 void TestRunner::setBackingScaleFactor(double)
1395 {
1396 }
1397
1398 void TestRunner::grantWebNotificationPermission(JSStringRef origin)
1399 {
1400 }
1401
1402 void TestRunner::denyWebNotificationPermission(JSStringRef jsOrigin)
1403 {
1404 }
1405
1406 void TestRunner::removeAllWebNotificationPermissions()
1407 {
1408 }
1409
1410 void TestRunner::simulateWebNotificationClick(JSValueRef jsNotification)
1411 {
1412 }
1413
1414 void TestRunner::simulateLegacyWebNotificationClick(JSStringRef title)
1415 {
1416     // FIXME: Implement.
1417 }
1418
1419 void TestRunner::resetPageVisibility()
1420 {
1421     // FIXME: Implement this.
1422 }
1423
1424 void TestRunner::setPageVisibility(const char*)
1425 {
1426     // FIXME: Implement this.
1427 }
1428
1429 void TestRunner::setAutomaticLinkDetectionEnabled(bool)
1430 {
1431     // FIXME: Implement this.
1432 }
1433
1434 void TestRunner::sendWebIntentResponse(JSStringRef)
1435 {
1436     // FIXME: Implement this.
1437 }
1438
1439 void TestRunner::deliverWebIntent(JSStringRef, JSStringRef, JSStringRef)
1440 {
1441     // FIXME: Implement this.
1442 }
1443
1444 void TestRunner::setStorageDatabaseIdleInterval(double)
1445 {
1446     // FIXME: Implement this.
1447 }
1448
1449 void TestRunner::closeIdleLocalStorageDatabases()
1450 {
1451     // FIXME: Implement this.
1452 }