WebKitTools: Implement the setAllowUniversalAccessFromFileURLs method
[WebKit-https.git] / WebKitTools / DumpRenderTree / qt / LayoutTestControllerQt.cpp
1 /*
2  * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
3  * Copyright (C) 2009 Torch Mobile Inc. http://www.torchmobile.com/
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1.  Redistributions of source code must retain the above copyright
10  *     notice, this list of conditions and the following disclaimer.
11  * 2.  Redistributions in binary form must reproduce the above copyright
12  *     notice, this list of conditions and the following disclaimer in the
13  *     documentation and/or other materials provided with the distribution.
14  * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
15  *     its contributors may be used to endorse or promote products derived
16  *     from this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
19  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
22  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29 #include "config.h"
30 #include "LayoutTestControllerQt.h"
31
32 #include "DumpRenderTree.h"
33 #include "WorkQueue.h"
34 #include "WorkQueueItem.h"
35 #include <QDir>
36
37 extern void qt_dump_editing_callbacks(bool b);
38 extern void qt_dump_resource_load_callbacks(bool b);
39 extern void qt_drt_setJavaScriptProfilingEnabled(QWebFrame*, bool enabled);
40 extern bool qt_drt_pauseAnimation(QWebFrame*, const QString& name, double time, const QString& elementId);
41 extern bool qt_drt_pauseTransitionOfProperty(QWebFrame*, const QString& name, double time, const QString& elementId);
42 extern bool qt_drt_pauseSVGAnimation(QWebFrame*, const QString& animationId, double time, const QString& elementId);
43 extern int qt_drt_numberOfActiveAnimations(QWebFrame*);
44
45 extern void qt_drt_whiteListAccessFromOrigin(const QString& sourceOrigin, const QString& destinationProtocol, const QString& destinationHost, bool allowDestinationSubdomains);
46 extern QString qt_drt_counterValueForElementById(QWebFrame* qFrame, const QString& id);
47
48 LayoutTestController::LayoutTestController(WebCore::DumpRenderTree* drt)
49     : QObject()
50     , m_drt(drt)
51 {
52     reset();
53 }
54
55 void LayoutTestController::reset()
56 {
57     m_isLoading = true;
58     m_textDump = false;
59     m_dumpBackForwardList = false;
60     m_dumpChildrenAsText = false;
61     m_canOpenWindows = false;
62     m_waitForDone = false;
63     m_dumpTitleChanges = false;
64     m_dumpDatabaseCallbacks = false;
65     m_dumpStatusCallbacks = false;
66     m_timeoutTimer.stop();
67     m_topLoadingFrame = 0;
68     m_waitForPolicy = false;
69     m_handleErrorPages = false;
70     qt_dump_editing_callbacks(false);
71     qt_dump_resource_load_callbacks(false);
72 }
73
74 void LayoutTestController::processWork()
75 {
76     // qDebug() << ">>>processWork";
77
78     // if we didn't start a new load, then we finished all the commands, so we're ready to dump state
79     if (WorkQueue::shared()->processWork() && !shouldWaitUntilDone()) {
80         emit done();
81         m_isLoading = false;
82     }
83 }
84
85 // Called on loadFinished on mainFrame.
86 void LayoutTestController::maybeDump(bool success)
87 {
88     Q_ASSERT(sender() == m_topLoadingFrame->page());
89
90     // as the function is called on loadFinished, the test might
91     // already have dumped and thus no longer be active, thus
92     // bail out here.
93     if (!m_isLoading)
94         return;
95
96     m_topLoadingFrame = 0;
97     WorkQueue::shared()->setFrozen(true); // first complete load freezes the queue for the rest of this test
98
99     if (!shouldWaitUntilDone()) {
100         if (WorkQueue::shared()->count())
101             QTimer::singleShot(0, this, SLOT(processWork()));
102         else {
103             if (success)
104                 emit done();
105             m_isLoading = false;
106         }
107     }
108 }
109
110 void LayoutTestController::waitUntilDone()
111 {
112     //qDebug() << ">>>>waitForDone";
113     m_waitForDone = true;
114     m_timeoutTimer.start(15000, this);
115 }
116
117 QString LayoutTestController::counterValueForElementById(const QString& id)
118 {
119     return qt_drt_counterValueForElementById(m_drt->webPage()->mainFrame(), id);
120 }
121
122 void LayoutTestController::keepWebHistory()
123 {
124     // FIXME: implement
125 }
126
127 void LayoutTestController::notifyDone()
128 {
129     qDebug() << ">>>>notifyDone";
130
131     if (!m_timeoutTimer.isActive())
132         return;
133
134     m_timeoutTimer.stop();
135     emit done();
136
137     // FIXME: investigate why always resetting these result in timeouts
138     m_isLoading = false;
139     m_waitForDone = false;
140     m_waitForPolicy = false;
141 }
142
143 int LayoutTestController::windowCount()
144 {
145     return m_drt->windowCount();
146 }
147
148 void LayoutTestController::clearBackForwardList()
149 {
150     m_drt->webPage()->history()->clear();
151 }
152
153 QString LayoutTestController::pathToLocalResource(const QString& url)
154 {
155     // Function introduced in r28690.
156     return QLatin1String("file://") + QUrl(url).toLocalFile();
157 }
158
159 void LayoutTestController::dumpEditingCallbacks()
160 {
161     qDebug() << ">>>dumpEditingCallbacks";
162     qt_dump_editing_callbacks(true);
163 }
164
165 void LayoutTestController::dumpResourceLoadCallbacks()
166 {
167     qt_dump_resource_load_callbacks(true);
168 }
169
170 void LayoutTestController::queueBackNavigation(int howFarBackward)
171 {
172     //qDebug() << ">>>queueBackNavigation" << howFarBackward;
173     WorkQueue::shared()->queue(new BackItem(howFarBackward, m_drt->webPage()));
174 }
175
176 void LayoutTestController::queueForwardNavigation(int howFarForward)
177 {
178     //qDebug() << ">>>queueForwardNavigation" << howFarForward;
179     WorkQueue::shared()->queue(new ForwardItem(howFarForward, m_drt->webPage()));
180 }
181
182 void LayoutTestController::queueLoad(const QString& url, const QString& target)
183 {
184     //qDebug() << ">>>queueLoad" << url << target;
185     QUrl mainResourceUrl = m_drt->webPage()->mainFrame()->url();
186     QString absoluteUrl = mainResourceUrl.resolved(QUrl(url)).toEncoded();
187     WorkQueue::shared()->queue(new LoadItem(absoluteUrl, target, m_drt->webPage()));
188 }
189
190 void LayoutTestController::queueReload()
191 {
192     //qDebug() << ">>>queueReload";
193     WorkQueue::shared()->queue(new ReloadItem(m_drt->webPage()));
194 }
195
196 void LayoutTestController::queueLoadingScript(const QString& script)
197 {
198     //qDebug() << ">>>queueLoadingScript" << script;
199     WorkQueue::shared()->queue(new LoadingScriptItem(script, m_drt->webPage()));
200 }
201
202 void LayoutTestController::queueNonLoadingScript(const QString& script)
203 {
204     //qDebug() << ">>>queueNonLoadingScript" << script;
205     WorkQueue::shared()->queue(new NonLoadingScriptItem(script, m_drt->webPage()));
206 }
207
208 void LayoutTestController::provisionalLoad()
209 {
210     QWebFrame* frame = qobject_cast<QWebFrame*>(sender());
211     if (!m_topLoadingFrame && m_isLoading)
212         m_topLoadingFrame = frame;
213 }
214
215 void LayoutTestController::timerEvent(QTimerEvent *ev)
216 {
217     if (ev->timerId() == m_timeoutTimer.timerId()) {
218         const char* message = "FAIL: Timed out waiting for notifyDone to be called\n";
219         fprintf(stderr, "%s", message);
220         fprintf(stdout, "%s", message);
221         notifyDone();
222     } else
223         QObject::timerEvent(ev);
224 }
225
226 QString LayoutTestController::encodeHostName(const QString& host)
227 {
228     QString encoded = QString::fromLatin1(QUrl::toAce(host + QLatin1String(".no")));
229     encoded.truncate(encoded.length() - 3); // strip .no
230     return encoded;
231 }
232
233 QString LayoutTestController::decodeHostName(const QString& host)
234 {
235     QString decoded = QUrl::fromAce(host.toLatin1() + QByteArray(".no"));
236     decoded.truncate(decoded.length() - 3);
237     return decoded;
238 }
239
240 void LayoutTestController::setAllowUniversalAccessFromFileURLs(bool enabled)
241 {
242     m_drt->webPage()->settings()->setAttribute(QWebSettings::LocalContentCanAccessRemoteUrls, enabled);
243 }
244
245 void LayoutTestController::setJavaScriptProfilingEnabled(bool enable)
246 {
247     m_topLoadingFrame->page()->settings()->setAttribute(QWebSettings::DeveloperExtrasEnabled, true);
248     qt_drt_setJavaScriptProfilingEnabled(m_topLoadingFrame, enable);
249 }
250
251 void LayoutTestController::setFixedContentsSize(int width, int height)
252 {
253     m_topLoadingFrame->page()->setPreferredContentsSize(QSize(width, height));
254 }
255
256 void LayoutTestController::setPrivateBrowsingEnabled(bool enable)
257 {
258     m_drt->webPage()->settings()->setAttribute(QWebSettings::PrivateBrowsingEnabled, enable);
259 }
260
261 void LayoutTestController::setPopupBlockingEnabled(bool enable)
262 {
263     m_drt->webPage()->settings()->setAttribute(QWebSettings::JavascriptCanOpenWindows, !enable);
264 }
265
266 void LayoutTestController::setPOSIXLocale(const QString& locale)
267 {
268     QLocale qlocale(locale);
269     QLocale::setDefault(qlocale);
270
271
272 bool LayoutTestController::pauseAnimationAtTimeOnElementWithId(const QString& animationName,
273                                                                double time,
274                                                                const QString& elementId)
275 {
276     QWebFrame* frame = m_drt->webPage()->mainFrame();
277     Q_ASSERT(frame);
278     return qt_drt_pauseAnimation(frame, animationName, time, elementId);
279 }
280
281 bool LayoutTestController::pauseTransitionAtTimeOnElementWithId(const QString& propertyName,
282                                                                 double time,
283                                                                 const QString& elementId)
284 {
285     QWebFrame* frame = m_drt->webPage()->mainFrame();
286     Q_ASSERT(frame);
287     return qt_drt_pauseTransitionOfProperty(frame, propertyName, time, elementId);
288 }
289
290 bool LayoutTestController::sampleSVGAnimationForElementAtTime(const QString& animationId,
291                                                               double time,
292                                                               const QString& elementId)
293 {
294     QWebFrame* frame = m_drt->webPage()->mainFrame();
295     Q_ASSERT(frame);
296     return qt_drt_pauseSVGAnimation(frame, animationId, time, elementId);
297 }
298
299 unsigned LayoutTestController::numberOfActiveAnimations() const
300 {
301     QWebFrame* frame = m_drt->webPage()->mainFrame();
302     Q_ASSERT(frame);
303     return qt_drt_numberOfActiveAnimations(frame);
304 }
305
306 void LayoutTestController::disableImageLoading()
307 {
308     // FIXME: Implement for testing fix for https://bugs.webkit.org/show_bug.cgi?id=27896
309     // Also need to make sure image loading is re-enabled for each new test.
310 }
311
312 void LayoutTestController::dispatchPendingLoadRequests()
313 {
314     // FIXME: Implement for testing fix for 6727495
315 }
316
317 void LayoutTestController::setDatabaseQuota(int size)
318 {
319     if (!m_topLoadingFrame)
320         return;
321     m_topLoadingFrame->securityOrigin().setDatabaseQuota(size);
322 }
323
324 void LayoutTestController::clearAllDatabases()
325 {
326     QWebDatabase::removeAllDatabases();
327 }
328
329 void LayoutTestController::whiteListAccessFromOrigin(const QString& sourceOrigin, const QString& destinationProtocol, const QString& destinationHost, bool allowDestinationSubdomains)
330 {
331     qt_drt_whiteListAccessFromOrigin(sourceOrigin, destinationProtocol, destinationHost, allowDestinationSubdomains);
332 }
333
334 void LayoutTestController::waitForPolicyDelegate()
335 {
336     m_waitForPolicy = true;
337     waitUntilDone();
338 }
339
340 void LayoutTestController::overridePreference(const QString& name, const QVariant& value)
341 {
342     QWebSettings* settings = m_topLoadingFrame->page()->settings();
343
344     if (name == "WebKitJavaScriptEnabled")
345         settings->setAttribute(QWebSettings::JavascriptEnabled, value.toBool());
346     else if (name == "WebKitTabToLinksPreferenceKey")
347         settings->setAttribute(QWebSettings::LinksIncludedInFocusChain, value.toBool());
348     else if (name == "WebKitOfflineWebApplicationCacheEnabled")
349         settings->setAttribute(QWebSettings::OfflineWebApplicationCacheEnabled, value.toBool());
350     else if (name == "WebKitDefaultFontSize")
351         settings->setFontSize(QWebSettings::DefaultFontSize, value.toInt());
352     else if (name == "WebKitUsesPageCachePreferenceKey")
353         QWebSettings::setMaximumPagesInCache(value.toInt());
354 }