WebKitTools:
[WebKit-https.git] / WebKitTools / DumpRenderTree / win / LayoutTestControllerWin.cpp
1 /*
2  * Copyright (C) 2006, 2007 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 "DumpRenderTree.h"
30 #include "LayoutTestController.h"
31
32 #include "EditingDelegate.h"
33 #include "PolicyDelegate.h"
34 #include "WorkQueue.h"
35 #include "WorkQueueItem.h"
36 #include <WebCore/COMPtr.h>
37 #include <wtf/Platform.h>
38 #include <wtf/RetainPtr.h>
39 #include <wtf/Vector.h>
40 #include <JavaScriptCore/Assertions.h>
41 #include <JavaScriptCore/JavaScriptCore.h>
42 #include <JavaScriptCore/JSRetainPtr.h>
43 #include <WebKit/IWebHistory.h>
44 #include <WebKit/IWebViewPrivate.h>
45 #include <WebKit/WebKit.h>
46 #include <string>
47 #include <CoreFoundation/CoreFoundation.h>
48
49 using std::string;
50 using std::wstring;
51
52 LayoutTestController::~LayoutTestController()
53 {
54     COMPtr<IWebView> webView;
55     if (FAILED(frame->webView(&webView)))
56         return;
57
58     // reset webview-related states back to default values in preparation for next test
59
60     COMPtr<IWebViewPrivate> viewPrivate;
61     if (SUCCEEDED(webView->QueryInterface(&viewPrivate)))
62         viewPrivate->setTabKeyCyclesThroughElements(TRUE);
63
64     COMPtr<IWebViewEditing> viewEditing;
65     if (FAILED(webView->QueryInterface(&viewEditing)))
66         return;
67     COMPtr<IWebEditingDelegate> delegate;
68     if (FAILED(viewEditing->editingDelegate(&delegate)))
69         return;
70     COMPtr<EditingDelegate> editingDelegate(Query, viewEditing.get());
71     if (editingDelegate)
72         editingDelegate->setAcceptsEditing(TRUE);
73 }
74
75 void LayoutTestController::addDisallowedURL(JSStringRef url)
76 {
77     // FIXME: Implement!
78 }
79
80 void LayoutTestController::clearBackForwardList()
81 {
82     COMPtr<IWebView> webView;
83     if (FAILED(frame->webView(&webView)))
84         return;
85
86     COMPtr<IWebBackForwardList> backForwardList;
87     if (FAILED(webView->backForwardList(&backForwardList)))
88         return;
89
90     COMPtr<IWebHistoryItem> item;
91     if (FAILED(backForwardList->currentItem(&item)))
92         return;
93
94     // We clear the history by setting the back/forward list's capacity to 0
95     // then restoring it back and adding back the current item.
96     int capacity;
97     if (FAILED(backForwardList->capacity(&capacity)))
98         return;
99
100     backForwardList->setCapacity(0);
101     backForwardList->setCapacity(capacity);
102     backForwardList->addItem(item.get());
103     backForwardList->goToItem(item.get());
104 }
105
106 JSStringRef LayoutTestController::copyDecodedHostName(JSStringRef name)
107 {
108     // FIXME: Implement!
109     return 0;
110 }
111
112 JSStringRef LayoutTestController::copyEncodedHostName(JSStringRef name)
113 {
114     // FIXME: Implement!
115     return 0;
116 }
117
118 void LayoutTestController::display()
119 {
120     displayWebView();
121 }
122
123 void LayoutTestController::keepWebHistory()
124 {
125     COMPtr<IWebHistory> history(Create, CLSID_WebHistory);
126     if (!history)
127         return;
128
129     COMPtr<IWebHistory> sharedHistory(Create, CLSID_WebHistory);
130     if (!sharedHistory)
131         return;
132
133     history->setOptionalSharedHistory(sharedHistory.get());
134 }
135
136 void LayoutTestController::notifyDone()
137 {
138     // Same as on mac.  This can be shared.
139     if (m_waitToDump && !topLoadingFrame && !WorkQueue::shared()->count())
140         dump();
141     m_waitToDump = false;
142 }
143
144 void LayoutTestController::queueBackNavigation(int howFarBack)
145 {
146     // Same as on mac.  This can be shared.
147     WorkQueue::shared()->queue(new BackItem(howFarBack));
148 }
149
150 void LayoutTestController::queueForwardNavigation(int howFarForward)
151 {
152     // Same as on mac.  This can be shared.
153     WorkQueue::shared()->queue(new ForwardItem(howFarForward));
154 }
155
156 static wstring jsStringRefToWString(JSStringRef jsStr)
157 {
158     size_t length = JSStringGetLength(jsStr);
159     Vector<WCHAR> buffer(length + 1);
160     memcpy(buffer.data(), JSStringGetCharactersPtr(jsStr), length * sizeof(WCHAR));
161     buffer[length] = '\0';
162
163     return buffer.data();
164 }
165
166 void LayoutTestController::queueLoad(JSStringRef url, JSStringRef target)
167 {
168     COMPtr<IWebDataSource> dataSource;
169     if (FAILED(frame->dataSource(&dataSource)))
170         return;
171
172     COMPtr<IWebURLResponse> response;
173     if (FAILED(dataSource->response(&response)) || !response)
174         return;
175
176     BSTR responseURLBSTR;
177     if (FAILED(response->URL(&responseURLBSTR)))
178         return;
179     wstring responseURL(responseURLBSTR, SysStringLen(responseURLBSTR));
180     SysFreeString(responseURLBSTR);
181
182     // FIXME: We should do real relative URL resolution here.
183     int lastSlash = responseURL.rfind('/');
184     if (lastSlash != -1)
185         responseURL = responseURL.substr(0, lastSlash);
186
187     wstring wURL = jsStringRefToWString(url);
188     wstring wAbosuluteURL = responseURL + TEXT("/") + wURL;
189     JSRetainPtr<JSStringRef> jsAbsoluteURL(Adopt, JSStringCreateWithCharacters(wAbosuluteURL.data(), wAbosuluteURL.length()));
190
191     WorkQueue::shared()->queue(new LoadItem(jsAbsoluteURL.get(), target));
192 }
193
194 void LayoutTestController::queueReload()
195 {
196     WorkQueue::shared()->queue(new ReloadItem);
197 }
198
199 void LayoutTestController::queueScript(JSStringRef script)
200 {
201     WorkQueue::shared()->queue(new ScriptItem(script));
202 }
203
204 void LayoutTestController::setAcceptsEditing(bool acceptsEditing)
205 {
206     COMPtr<IWebView> webView;
207     if (FAILED(frame->webView(&webView)))
208         return;
209
210     COMPtr<IWebViewEditing> viewEditing;
211     if (FAILED(webView->QueryInterface(&viewEditing)))
212         return;
213
214     COMPtr<IWebEditingDelegate> delegate;
215     if (FAILED(viewEditing->editingDelegate(&delegate)))
216         return;
217
218     EditingDelegate* editingDelegate = (EditingDelegate*)(IWebEditingDelegate*)delegate.get();
219     editingDelegate->setAcceptsEditing(acceptsEditing);
220 }
221
222 void LayoutTestController::setCustomPolicyDelegate(bool setDelegate)
223 {
224     COMPtr<IWebView> webView;
225     if (FAILED(frame->webView(&webView)))
226         return;
227
228     if (setDelegate)
229         webView->setPolicyDelegate(policyDelegate);
230     else
231         webView->setPolicyDelegate(NULL);
232 }
233
234 void LayoutTestController::setMainFrameIsFirstResponder(bool flag)
235 {
236     // FIXME: Implement!
237 }
238
239 void LayoutTestController::setPrivateBrowsingEnabled(bool privateBrowsingEnabled)
240 {
241     COMPtr<IWebView> webView;
242     if (FAILED(frame->webView(&webView)))
243         return;
244
245     COMPtr<IWebPreferences> preferences;
246     if (FAILED(webView->preferences(&preferences)))
247         return;
248
249     preferences->setPrivateBrowsingEnabled(privateBrowsingEnabled);
250 }
251
252 void LayoutTestController::setTabKeyCyclesThroughElements(bool shouldCycle)
253 {
254     COMPtr<IWebView> webView;
255     if (FAILED(frame->webView(&webView)))
256         return;
257
258     COMPtr<IWebViewPrivate> viewPrivate;
259     if (FAILED(webView->QueryInterface(&viewPrivate)))
260         return;
261
262     viewPrivate->setTabKeyCyclesThroughElements(shouldCycle ? TRUE : FALSE);
263 }
264
265 void LayoutTestController::setUseDashboardCompatibilityMode(bool flag)
266 {
267     // FIXME: Implement!
268 }
269
270 void LayoutTestController::setUserStyleSheetEnabled(bool flag)
271 {
272     // FIXME: Implement!
273 }
274
275 void LayoutTestController::setUserStyleSheetLocation(JSStringRef path)
276 {
277     // FIXME: Implement!
278 }
279
280 void LayoutTestController::setWindowIsKey(bool flag)
281 {
282     // FIXME: Implement!
283 }
284
285 static const CFTimeInterval waitToDumpWatchdogInterval = 10.0;
286
287 static void waitUntilDoneWatchdogFired(CFRunLoopTimerRef timer, void* info)
288 {
289     const char* message = "FAIL: Timed out waiting for notifyDone to be called\n";
290     fprintf(stderr, message);
291     fprintf(stdout, message);
292     dump();
293 }
294
295 void LayoutTestController::setWaitToDump(bool waitUntilDone)
296 {
297     // Same as on mac.  This can be shared.
298     m_waitToDump = waitUntilDone;
299     if (m_waitToDump && !waitToDumpWatchdog)
300         ::waitToDumpWatchdog = CFRunLoopTimerCreate(0, 0, waitToDumpWatchdogInterval, 0, 0, waitUntilDoneWatchdogFired, NULL);
301 }
302
303 int LayoutTestController::windowCount()
304 {
305     // FIXME: Implement!
306     return 1;
307 }