initial import
[vuplus_webkit] / Tools / 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 #include "DumpRenderTreeSupportQt.h"
32
33 #include "DumpRenderTreeQt.h"
34 #include "WorkQueue.h"
35 #include "WorkQueueItemQt.h"
36 #include <QCoreApplication>
37 #include <QDir>
38 #include <QLocale>
39 #include <qwebsettings.h>
40
41 LayoutTestController::LayoutTestController(WebCore::DumpRenderTree* drt)
42     : QObject()
43     , m_drt(drt)
44 {
45     qRegisterMetaType<QWebElement>("QWebElement");
46     reset();
47     DumpRenderTreeSupportQt::dumpNotification(true);
48 }
49
50 void LayoutTestController::reset()
51 {
52     m_hasDumped = false;
53     m_loadFinished = false;
54     m_textDump = false;
55     m_dumpBackForwardList = false;
56     m_dumpChildrenAsText = false;
57     m_dumpChildFrameScrollPositions = false;
58     m_canOpenWindows = false;
59     m_waitForDone = false;
60     m_disallowIncreaseForApplicationCacheQuota = false;
61     m_dumpTitleChanges = false;
62     m_dumpDatabaseCallbacks = false;
63     m_dumpApplicationCacheDelegateCallbacks = false;
64     m_dumpStatusCallbacks = false;
65     m_timeoutTimer.stop();
66     m_topLoadingFrame = 0;
67     m_waitForPolicy = false;
68     m_handleErrorPages = false;
69     m_webHistory = 0;
70     m_globalFlag = false;
71     m_userStyleSheetEnabled = false;
72     m_desktopNotificationAllowedOrigins.clear();
73     m_ignoreDesktopNotification = false;
74     m_isGeolocationPermissionSet = false;
75     m_isPrinting = false;
76     m_geolocationPermission = false;
77
78     DumpRenderTreeSupportQt::dumpEditingCallbacks(false);
79     DumpRenderTreeSupportQt::dumpFrameLoader(false);
80     DumpRenderTreeSupportQt::dumpProgressFinishedCallback(false);
81     DumpRenderTreeSupportQt::dumpUserGestureInFrameLoader(false);
82     DumpRenderTreeSupportQt::dumpResourceLoadCallbacks(false);
83     DumpRenderTreeSupportQt::dumpResourceResponseMIMETypes(false);
84     DumpRenderTreeSupportQt::setDeferMainResourceDataLoad(true);
85     DumpRenderTreeSupportQt::setWillSendRequestReturnsNullOnRedirect(false);
86     DumpRenderTreeSupportQt::setWillSendRequestReturnsNull(false);
87     DumpRenderTreeSupportQt::setWillSendRequestClearHeaders(QStringList());
88     DumpRenderTreeSupportQt::clearScriptWorlds();
89     DumpRenderTreeSupportQt::setCustomPolicyDelegate(false, false);
90     DumpRenderTreeSupportQt::dumpHistoryCallbacks(false);
91     DumpRenderTreeSupportQt::dumpVisitedLinksCallbacks(false);
92     DumpRenderTreeSupportQt::resetGeolocationMock(m_drt->webPage());
93     setIconDatabaseEnabled(false);
94     clearAllDatabases();
95 #if QT_VERSION >= 0x040800
96     // The default state for DRT is to block third-party cookies, mimicing the Mac port
97     setAlwaysAcceptCookies(false);
98 #endif
99     emit hidePage();
100 }
101
102 void LayoutTestController::processWork()
103 {
104     // qDebug() << ">>>processWork";
105
106     // if we didn't start a new load, then we finished all the commands, so we're ready to dump state
107     if (WorkQueue::shared()->processWork() && !shouldWaitUntilDone()) {
108         emit done();
109         m_hasDumped = true;
110     }
111 }
112
113 // Called on loadFinished on WebPage
114 void LayoutTestController::maybeDump(bool /*success*/)
115 {
116
117     // This can happen on any of the http/tests/security/window-events-*.html tests, where the test opens
118     // a new window, calls the unload and load event handlers on the window's page, and then immediately
119     // issues a notifyDone. Needs investigation.
120     if (!m_topLoadingFrame)
121         return;
122
123     // It is possible that we get called by windows created from the main page that have finished
124     // loading, so we don't ASSERT here. At the moment we do not gather results from such windows,
125     // but may need to in future.
126     if (sender() != m_topLoadingFrame->page())
127         return;
128
129     m_loadFinished = true;
130     // as the function is called on loadFinished, the test might
131     // already have dumped and thus no longer be active, thus
132     // bail out here.
133     if (m_hasDumped)
134         return;
135
136     WorkQueue::shared()->setFrozen(true); // first complete load freezes the queue for the rest of this test
137     if (WorkQueue::shared()->count())
138         QTimer::singleShot(0, this, SLOT(processWork()));
139     else if (!shouldWaitUntilDone()) {
140         emit done();
141         m_hasDumped = true;
142     }
143 }
144
145 void LayoutTestController::waitUntilDone()
146 {
147     //qDebug() << ">>>>waitForDone";
148     m_waitForDone = true;
149     m_timeoutTimer.start(30000, this);
150 }
151
152 QString LayoutTestController::counterValueForElementById(const QString& id)
153 {
154     return DumpRenderTreeSupportQt::counterValueForElementById(m_drt->webPage()->mainFrame(), id);
155 }
156
157 void LayoutTestController::setViewModeMediaFeature(const QString& mode)
158 {
159     m_drt->webPage()->setProperty("_q_viewMode", mode);
160 }
161
162 int LayoutTestController::webHistoryItemCount()
163 {
164     if (!m_webHistory)
165         return -1;
166
167     // Subtract one here as our QWebHistory::count() includes the actual page,
168     // which is not considered in the DRT tests.
169     return m_webHistory->count() - 1;
170 }
171
172 void LayoutTestController::keepWebHistory()
173 {
174     m_webHistory = m_drt->webPage()->history();
175 }
176
177 void LayoutTestController::notifyDone()
178 {
179     qDebug() << ">>>>notifyDone";
180
181     if (!m_timeoutTimer.isActive())
182         return;
183
184     m_timeoutTimer.stop();
185     m_waitForDone = false;
186
187     // If the page has not finished loading (i.e. loadFinished() has not been emitted) then
188     // content created by the likes of document.write() JS methods will not be available yet.
189     // When the page has finished loading, maybeDump above will dump the results now that we have
190     // just set shouldWaitUntilDone to false.
191     if (!m_loadFinished)
192         return;
193
194     emit done();
195
196     // FIXME: investigate why always resetting these result in timeouts
197     m_hasDumped = true;
198     m_waitForPolicy = false;
199 }
200
201 int LayoutTestController::windowCount()
202 {
203     return m_drt->windowCount();
204 }
205
206 void LayoutTestController::grantDesktopNotificationPermission(const QString& origin)
207 {
208     QWebFrame* frame = m_drt->webPage()->mainFrame();
209     m_drt->webPage()->setFeaturePermission(frame, QWebPage::Notifications, QWebPage::PermissionGrantedByUser);
210     m_desktopNotificationAllowedOrigins.append(origin);
211 }
212
213 void LayoutTestController::ignoreDesktopNotificationPermissionRequests()
214 {
215     m_ignoreDesktopNotification = true;
216 }
217
218 bool LayoutTestController::checkDesktopNotificationPermission(const QString& origin)
219 {
220     return !m_ignoreDesktopNotification && m_desktopNotificationAllowedOrigins.contains(origin);
221 }
222
223 void LayoutTestController::simulateDesktopNotificationClick(const QString& title)
224 {
225     DumpRenderTreeSupportQt::simulateDesktopNotificationClick(title);
226 }
227
228 void LayoutTestController::display()
229 {
230     emit showPage();
231 }
232
233 void LayoutTestController::displayInvalidatedRegion()
234 {
235     display();
236 }
237
238 void LayoutTestController::clearBackForwardList()
239 {
240     m_drt->webPage()->history()->clear();
241 }
242
243 QString LayoutTestController::pathToLocalResource(const QString& url)
244 {
245     QString localTmpUrl(QLatin1String("file:///tmp/LayoutTests"));
246
247     // Translate a request for /tmp/LayoutTests to the repository LayoutTests directory.
248     // Do not rely on a symlink to be created via the test runner, which will not work on Windows.
249     if (url.startsWith(localTmpUrl)) {
250         // DumpRenderTree lives in WebKit/WebKitBuild/<build_mode>/bin.
251         // Translate from WebKit/WebKitBuild/Release/bin => WebKit/LayoutTests.
252         QFileInfo layoutTestsRoot(QCoreApplication::applicationDirPath() + QLatin1String("/../../../LayoutTests/"));
253         if (layoutTestsRoot.exists())
254             return QLatin1String("file://") + layoutTestsRoot.absolutePath() + url.mid(localTmpUrl.length());
255     }
256
257     return url;
258 }
259
260 void LayoutTestController::dumpConfigurationForViewport(int deviceDPI, int deviceWidth, int deviceHeight, int availableWidth, int availableHeight)
261 {
262     QString res = DumpRenderTreeSupportQt::viewportAsText(m_drt->webPage(), deviceDPI, QSize(deviceWidth, deviceHeight), QSize(availableWidth, availableHeight));
263     fputs(qPrintable(res), stdout);
264 }
265
266 void LayoutTestController::dumpEditingCallbacks()
267 {
268     qDebug() << ">>>dumpEditingCallbacks";
269     DumpRenderTreeSupportQt::dumpEditingCallbacks(true);
270 }
271
272 void LayoutTestController::dumpFrameLoadCallbacks()
273 {
274     DumpRenderTreeSupportQt::dumpFrameLoader(true);
275 }
276
277 void LayoutTestController::dumpProgressFinishedCallback()
278 {
279     DumpRenderTreeSupportQt::dumpProgressFinishedCallback(true);
280 }
281
282 void LayoutTestController::dumpUserGestureInFrameLoadCallbacks()
283 {
284     DumpRenderTreeSupportQt::dumpUserGestureInFrameLoader(true);
285 }
286
287 void LayoutTestController::dumpResourceLoadCallbacks()
288 {
289     DumpRenderTreeSupportQt::dumpResourceLoadCallbacks(true);
290 }
291
292 void LayoutTestController::dumpResourceResponseMIMETypes()
293 {
294     DumpRenderTreeSupportQt::dumpResourceResponseMIMETypes(true);
295 }
296
297 void LayoutTestController::dumpHistoryCallbacks()
298 {
299     DumpRenderTreeSupportQt::dumpHistoryCallbacks(true);
300 }
301
302 void LayoutTestController::setWillSendRequestReturnsNullOnRedirect(bool enabled)
303 {
304     DumpRenderTreeSupportQt::setWillSendRequestReturnsNullOnRedirect(enabled);
305 }
306
307 void LayoutTestController::setWillSendRequestReturnsNull(bool enabled)
308 {
309     DumpRenderTreeSupportQt::setWillSendRequestReturnsNull(enabled);
310 }
311
312 void LayoutTestController::setWillSendRequestClearHeader(const QStringList& headers)
313 {
314     DumpRenderTreeSupportQt::setWillSendRequestClearHeaders(headers);
315 }
316
317 void LayoutTestController::setDeferMainResourceDataLoad(bool defer)
318 {
319     DumpRenderTreeSupportQt::setDeferMainResourceDataLoad(defer);
320 }
321
322 void LayoutTestController::queueBackNavigation(int howFarBackward)
323 {
324     //qDebug() << ">>>queueBackNavigation" << howFarBackward;
325     for (int i = 0; i != howFarBackward; ++i)
326         WorkQueue::shared()->queue(new BackItem(1, m_drt->webPage()));
327 }
328
329 void LayoutTestController::queueForwardNavigation(int howFarForward)
330 {
331     //qDebug() << ">>>queueForwardNavigation" << howFarForward;
332     for (int i = 0; i != howFarForward; ++i)
333         WorkQueue::shared()->queue(new ForwardItem(1, m_drt->webPage()));
334 }
335
336 void LayoutTestController::queueLoad(const QString& url, const QString& target)
337 {
338     //qDebug() << ">>>queueLoad" << url << target;
339     QUrl mainResourceUrl = m_drt->webPage()->mainFrame()->url();
340     QString absoluteUrl = mainResourceUrl.resolved(QUrl(url)).toEncoded();
341     WorkQueue::shared()->queue(new LoadItem(absoluteUrl, target, m_drt->webPage()));
342 }
343
344 void LayoutTestController::queueLoadHTMLString(const QString& content, const QString& baseURL, const QString& failingURL)
345 {
346     if (failingURL.isEmpty())
347         WorkQueue::shared()->queue(new LoadHTMLStringItem(content, baseURL, m_drt->webPage()));
348     else
349         WorkQueue::shared()->queue(new LoadAlternateHTMLStringItem(content, baseURL, failingURL, m_drt->webPage()));
350 }
351
352 void LayoutTestController::queueReload()
353 {
354     //qDebug() << ">>>queueReload";
355     WorkQueue::shared()->queue(new ReloadItem(m_drt->webPage()));
356 }
357
358 void LayoutTestController::queueLoadingScript(const QString& script)
359 {
360     //qDebug() << ">>>queueLoadingScript" << script;
361     WorkQueue::shared()->queue(new LoadingScriptItem(script, m_drt->webPage()));
362 }
363
364 void LayoutTestController::queueNonLoadingScript(const QString& script)
365 {
366     //qDebug() << ">>>queueNonLoadingScript" << script;
367     WorkQueue::shared()->queue(new NonLoadingScriptItem(script, m_drt->webPage()));
368 }
369
370 void LayoutTestController::provisionalLoad()
371 {
372     QWebFrame* frame = qobject_cast<QWebFrame*>(sender());
373     if (!m_topLoadingFrame && !m_hasDumped)
374         m_topLoadingFrame = frame;
375 }
376
377 void LayoutTestController::timerEvent(QTimerEvent *ev)
378 {
379     if (ev->timerId() == m_timeoutTimer.timerId()) {
380         const char* message = "FAIL: Timed out waiting for notifyDone to be called\n";
381         fprintf(stderr, "%s", message);
382         fprintf(stdout, "%s", message);
383         notifyDone();
384     } else
385         QObject::timerEvent(ev);
386 }
387
388 QString LayoutTestController::encodeHostName(const QString& host)
389 {
390     QString encoded = QString::fromLatin1(QUrl::toAce(host + QLatin1String(".no")));
391     encoded.truncate(encoded.length() - 3); // strip .no
392     return encoded;
393 }
394
395 QString LayoutTestController::decodeHostName(const QString& host)
396 {
397     QString decoded = QUrl::fromAce(host.toLatin1() + QByteArray(".no"));
398     decoded.truncate(decoded.length() - 3);
399     return decoded;
400 }
401
402 void LayoutTestController::setMediaType(const QString& type)
403 {
404     DumpRenderTreeSupportQt::setMediaType(m_drt->webPage()->mainFrame(), type);
405 }
406
407 void LayoutTestController::closeWebInspector()
408 {
409     DumpRenderTreeSupportQt::webInspectorClose(m_drt->webPage());
410     m_drt->webPage()->settings()->setAttribute(QWebSettings::DeveloperExtrasEnabled, false);
411 }
412
413 void LayoutTestController::setDeveloperExtrasEnabled(bool enabled)
414 {
415     m_drt->webPage()->settings()->setAttribute(QWebSettings::DeveloperExtrasEnabled, enabled);
416 }
417
418 void LayoutTestController::setAsynchronousSpellCheckingEnabled(bool)
419 {
420     // FIXME: Implement this.
421 }
422
423 void LayoutTestController::showWebInspector()
424 {
425     m_drt->webPage()->settings()->setAttribute(QWebSettings::DeveloperExtrasEnabled, true);
426     DumpRenderTreeSupportQt::webInspectorShow(m_drt->webPage());
427 }
428
429 void LayoutTestController::evaluateInWebInspector(long callId, const QString& script)
430 {
431     DumpRenderTreeSupportQt::webInspectorExecuteScript(m_drt->webPage(), callId, script);
432 }
433
434 void LayoutTestController::setFrameFlatteningEnabled(bool enabled)
435 {
436     DumpRenderTreeSupportQt::setFrameFlatteningEnabled(m_drt->webPage(), enabled);
437 }
438
439 void LayoutTestController::goBack()
440 {
441     DumpRenderTreeSupportQt::goBack(m_drt->webPage());
442 }
443
444 void LayoutTestController::setDefersLoading(bool flag)
445 {
446     DumpRenderTreeSupportQt::setDefersLoading(m_drt->webPage(), flag);
447 }
448
449 void LayoutTestController::setAllowUniversalAccessFromFileURLs(bool enabled)
450 {
451     m_drt->webPage()->settings()->setAttribute(QWebSettings::LocalContentCanAccessRemoteUrls, enabled);
452 }
453
454 void LayoutTestController::setAllowFileAccessFromFileURLs(bool enabled)
455 {
456     m_drt->webPage()->settings()->setAttribute(QWebSettings::LocalContentCanAccessFileUrls, enabled);
457 }
458
459 void LayoutTestController::setAppCacheMaximumSize(unsigned long long quota)
460 {
461     m_drt->webPage()->settings()->setOfflineWebApplicationCacheQuota(quota);
462 }
463
464 void LayoutTestController::setAutofilled(const QWebElement& element, bool isAutofilled)
465 {
466     return DumpRenderTreeSupportQt::setAutofilled(element, isAutofilled);
467 }
468
469 void LayoutTestController::setJavaScriptProfilingEnabled(bool enable)
470 {
471     setDeveloperExtrasEnabled(enable);
472     DumpRenderTreeSupportQt::setJavaScriptProfilingEnabled(m_topLoadingFrame, enable);
473 }
474
475 void LayoutTestController::setValueForUser(const QWebElement& element, const QString& value)
476 {
477     DumpRenderTreeSupportQt::setValueForUser(element, value);
478 }
479
480 void LayoutTestController::setFixedContentsSize(int width, int height)
481 {
482     m_topLoadingFrame->page()->setPreferredContentsSize(QSize(width, height));
483 }
484
485 void LayoutTestController::setPrivateBrowsingEnabled(bool enable)
486 {
487     m_drt->webPage()->settings()->setAttribute(QWebSettings::PrivateBrowsingEnabled, enable);
488 }
489
490 void LayoutTestController::setSpatialNavigationEnabled(bool enable)
491 {
492     m_drt->webPage()->settings()->setAttribute(QWebSettings::SpatialNavigationEnabled, enable);
493 }
494
495 void LayoutTestController::setPopupBlockingEnabled(bool enable)
496 {
497     m_drt->webPage()->settings()->setAttribute(QWebSettings::JavascriptCanOpenWindows, !enable);
498 }
499
500 void LayoutTestController::setPluginsEnabled(bool flag)
501 {
502     // FIXME: Implement
503 }
504
505 void LayoutTestController::setPOSIXLocale(const QString& locale)
506 {
507     QLocale qlocale(locale);
508     QLocale::setDefault(qlocale);
509
510
511 void LayoutTestController::setWindowIsKey(bool isKey)
512 {
513     m_drt->switchFocus(isKey);
514 }
515
516 void LayoutTestController::setMainFrameIsFirstResponder(bool isFirst)
517 {
518     //FIXME: only need this for the moment: https://bugs.webkit.org/show_bug.cgi?id=32990
519 }
520
521 void LayoutTestController::setJavaScriptCanAccessClipboard(bool enable)
522 {
523     m_drt->webPage()->settings()->setAttribute(QWebSettings::JavascriptCanAccessClipboard, enable);
524 }
525
526 void LayoutTestController::setXSSAuditorEnabled(bool enable)
527 {
528     // Set XSSAuditingEnabled globally so that windows created by the test inherit it too.
529     // resetSettings() will call this to reset the page and global setting to false again.
530     // Needed by http/tests/security/xssAuditor/link-opens-new-window.html
531     QWebSettings* globalSettings = QWebSettings::globalSettings();
532     globalSettings->setAttribute(QWebSettings::XSSAuditingEnabled, enable);
533     m_drt->webPage()->settings()->setAttribute(QWebSettings::XSSAuditingEnabled, enable);
534 }
535
536 bool LayoutTestController::pauseAnimationAtTimeOnElementWithId(const QString& animationName,
537                                                                double time,
538                                                                const QString& elementId)
539 {
540     QWebFrame* frame = m_drt->webPage()->mainFrame();
541     Q_ASSERT(frame);
542     return DumpRenderTreeSupportQt::pauseAnimation(frame, animationName, time, elementId);
543 }
544
545 bool LayoutTestController::pauseTransitionAtTimeOnElementWithId(const QString& propertyName,
546                                                                 double time,
547                                                                 const QString& elementId)
548 {
549     QWebFrame* frame = m_drt->webPage()->mainFrame();
550     Q_ASSERT(frame);
551     return DumpRenderTreeSupportQt::pauseTransitionOfProperty(frame, propertyName, time, elementId);
552 }
553
554 bool LayoutTestController::sampleSVGAnimationForElementAtTime(const QString& animationId,
555                                                               double time,
556                                                               const QString& elementId)
557 {
558     QWebFrame* frame = m_drt->webPage()->mainFrame();
559     Q_ASSERT(frame);
560     return DumpRenderTreeSupportQt::pauseSVGAnimation(frame, animationId, time, elementId);
561 }
562
563 unsigned LayoutTestController::numberOfActiveAnimations() const
564 {
565     QWebFrame* frame = m_drt->webPage()->mainFrame();
566     Q_ASSERT(frame);
567     return DumpRenderTreeSupportQt::numberOfActiveAnimations(frame);
568 }
569
570 void LayoutTestController::suspendAnimations() const
571 {
572     QWebFrame* frame = m_drt->webPage()->mainFrame();
573     Q_ASSERT(frame);
574     DumpRenderTreeSupportQt::suspendAnimations(frame);
575 }
576
577 void LayoutTestController::resumeAnimations() const
578 {
579     QWebFrame* frame = m_drt->webPage()->mainFrame();
580     Q_ASSERT(frame);
581     DumpRenderTreeSupportQt::resumeAnimations(frame);
582 }
583
584 void LayoutTestController::disableImageLoading()
585 {
586     m_drt->webPage()->settings()->setAttribute(QWebSettings::AutoLoadImages, false);
587 }
588
589 void LayoutTestController::dispatchPendingLoadRequests()
590 {
591     // FIXME: Implement for testing fix for 6727495
592 }
593
594 void LayoutTestController::clearAllApplicationCaches()
595 {
596     DumpRenderTreeSupportQt::clearAllApplicationCaches();
597 }
598
599 void LayoutTestController::clearApplicationCacheForOrigin(const QString& url)
600 {
601     // FIXME: Implement to support deleting all application caches for an origin.
602 }
603
604 long long LayoutTestController::localStorageDiskUsageForOrigin(const QString& originIdentifier)
605 {
606     // FIXME: Implement to support getting disk usage in bytes for an origin.
607     return 0;
608 }
609
610 void LayoutTestController::setApplicationCacheOriginQuota(unsigned long long quota)
611 {
612     if (!m_topLoadingFrame)
613         return;
614     m_topLoadingFrame->securityOrigin().setApplicationCacheQuota(quota);
615 }
616
617 long long LayoutTestController::applicationCacheDiskUsageForOrigin(const QString& origin)
618 {
619     // FIXME: Implement to support getting disk usage by all application caches for an origin.
620     return 0;
621 }
622
623 QStringList LayoutTestController::originsWithApplicationCache()
624 {
625     // FIXME: Implement to get origins that have application caches.
626     return QStringList();
627 }
628
629 void LayoutTestController::setCacheModel(int model)
630 {
631     // qwebsetting doesn't have matched setting yet :
632     // WEBKIT_CACHE_MODEL_DOCUMENT_VIEWER
633     // WEBKIT_CACHE_MODEL_DOCUMENT_BROWSER
634     // WEBKIT_CACHE_MODEL_WEB_BROWSER
635
636     // FIXME: Implement.
637 }
638
639 void LayoutTestController::setDatabaseQuota(int size)
640 {
641     if (!m_topLoadingFrame)
642         return;
643     m_topLoadingFrame->securityOrigin().setDatabaseQuota(size);
644 }
645
646 void LayoutTestController::clearAllDatabases()
647 {
648     QWebDatabase::removeAllDatabases();
649 }
650
651 void LayoutTestController::addOriginAccessWhitelistEntry(const QString& sourceOrigin, const QString& destinationProtocol, const QString& destinationHost, bool allowDestinationSubdomains)
652 {
653     DumpRenderTreeSupportQt::whiteListAccessFromOrigin(sourceOrigin, destinationProtocol, destinationHost, allowDestinationSubdomains);
654 }
655
656 void LayoutTestController::removeOriginAccessWhitelistEntry(const QString& sourceOrigin, const QString& destinationProtocol, const QString& destinationHost, bool allowDestinationSubdomains)
657 {
658     DumpRenderTreeSupportQt::removeWhiteListAccessFromOrigin(sourceOrigin, destinationProtocol, destinationHost, allowDestinationSubdomains);
659 }
660
661 void LayoutTestController::setCustomPolicyDelegate(bool enabled, bool permissive)
662 {
663     DumpRenderTreeSupportQt::setCustomPolicyDelegate(enabled, permissive);
664 }
665
666 void LayoutTestController::waitForPolicyDelegate()
667 {
668     setCustomPolicyDelegate(true);
669     m_waitForPolicy = true;
670     waitUntilDone();
671 }
672
673 void LayoutTestController::overridePreference(const QString& name, const QVariant& value)
674 {
675     QWebSettings* settings = m_topLoadingFrame->page()->settings();
676
677     if (name == "WebKitJavaScriptEnabled")
678         settings->setAttribute(QWebSettings::JavascriptEnabled, value.toBool());
679     else if (name == "WebKitTabToLinksPreferenceKey")
680         settings->setAttribute(QWebSettings::LinksIncludedInFocusChain, value.toBool());
681     else if (name == "WebKitOfflineWebApplicationCacheEnabled")
682         settings->setAttribute(QWebSettings::OfflineWebApplicationCacheEnabled, value.toBool());
683     else if (name == "WebKitDefaultFontSize")
684         settings->setFontSize(QWebSettings::DefaultFontSize, value.toInt());
685     else if (name == "WebKitUsesPageCachePreferenceKey")
686         QWebSettings::setMaximumPagesInCache(value.toInt());
687     else if (name == "WebKitEnableCaretBrowsing")
688         setCaretBrowsingEnabled(value.toBool());
689     else if (name == "WebKitPluginsEnabled")
690         settings->setAttribute(QWebSettings::PluginsEnabled, value.toBool());
691     else if (name == "WebKitWebGLEnabled")
692         settings->setAttribute(QWebSettings::WebGLEnabled, value.toBool());
693     else if (name == "WebKitHyperlinkAuditingEnabled")
694         settings->setAttribute(QWebSettings::HyperlinkAuditingEnabled, value.toBool());
695     else
696         printf("ERROR: LayoutTestController::overridePreference() does not support the '%s' preference\n",
697             name.toLatin1().data());
698 }
699
700 void LayoutTestController::setUserStyleSheetLocation(const QString& url)
701 {
702     QByteArray urlData = pathToLocalResource(url).toLatin1();
703     m_userStyleSheetLocation = QUrl::fromEncoded(urlData, QUrl::StrictMode);
704
705     if (m_userStyleSheetEnabled)
706         setUserStyleSheetEnabled(true);
707 }
708
709 void LayoutTestController::setCaretBrowsingEnabled(bool value)
710 {
711     DumpRenderTreeSupportQt::setCaretBrowsingEnabled(m_drt->webPage(), value);
712 }
713
714 void LayoutTestController::setAuthorAndUserStylesEnabled(bool value)
715 {
716     DumpRenderTreeSupportQt::setAuthorAndUserStylesEnabled(m_drt->webPage(), value);
717 }
718
719 void LayoutTestController::setUserStyleSheetEnabled(bool enabled)
720 {
721     m_userStyleSheetEnabled = enabled;
722
723     if (enabled)
724         m_drt->webPage()->settings()->setUserStyleSheetUrl(m_userStyleSheetLocation);
725     else
726         m_drt->webPage()->settings()->setUserStyleSheetUrl(QUrl());
727 }
728
729 void LayoutTestController::setDomainRelaxationForbiddenForURLScheme(bool forbidden, const QString& scheme)
730 {
731     DumpRenderTreeSupportQt::setDomainRelaxationForbiddenForURLScheme(forbidden, scheme);
732 }
733
734 int LayoutTestController::workerThreadCount()
735 {
736     return DumpRenderTreeSupportQt::workerThreadCount();
737 }
738
739 int LayoutTestController::pageNumberForElementById(const QString& id, float width, float height)
740 {
741     // If no size specified, webpage viewport size is used
742     if (!width && !height) {
743         width = m_drt->webPage()->viewportSize().width();
744         height = m_drt->webPage()->viewportSize().height();
745     }
746
747     return DumpRenderTreeSupportQt::pageNumberForElementById(m_drt->webPage()->mainFrame(), id, width, height);
748 }
749
750 int LayoutTestController::numberOfPages(float width, float height)
751 {
752     return DumpRenderTreeSupportQt::numberOfPages(m_drt->webPage()->mainFrame(), width, height);
753 }
754
755 bool LayoutTestController::callShouldCloseOnWebView()
756 {
757     return DumpRenderTreeSupportQt::shouldClose(m_drt->webPage()->mainFrame());
758 }
759
760 void LayoutTestController::setScrollbarPolicy(const QString& orientation, const QString& policy)
761 {
762     Qt::Orientation o;
763     Qt::ScrollBarPolicy p;
764
765     if (orientation == "vertical")
766         o = Qt::Vertical;
767     else if (orientation == "horizontal")
768         o = Qt::Horizontal;
769     else
770         return;
771
772     if (policy == "on")
773         p = Qt::ScrollBarAlwaysOn;
774     else if (policy == "auto")
775         p = Qt::ScrollBarAsNeeded;
776     else if (policy == "off")
777         p = Qt::ScrollBarAlwaysOff;
778     else
779         return;
780
781     m_drt->webPage()->mainFrame()->setScrollBarPolicy(o, p);
782 }
783
784 void LayoutTestController::setSmartInsertDeleteEnabled(bool enable)
785 {
786     DumpRenderTreeSupportQt::setSmartInsertDeleteEnabled(m_drt->webPage(), enable);
787 }
788
789 void LayoutTestController::setSelectTrailingWhitespaceEnabled(bool enable)
790 {
791     DumpRenderTreeSupportQt::setSelectTrailingWhitespaceEnabled(m_drt->webPage(), enable);
792 }
793
794 void LayoutTestController::execCommand(const QString& name, const QString& value)
795 {
796     DumpRenderTreeSupportQt::executeCoreCommandByName(m_drt->webPage(), name, value);
797 }
798
799 bool LayoutTestController::isCommandEnabled(const QString& name) const
800 {
801     return DumpRenderTreeSupportQt::isCommandEnabled(m_drt->webPage(), name);
802 }
803
804 bool LayoutTestController::findString(const QString& string, const QStringList& optionArray)
805 {
806     return DumpRenderTreeSupportQt::findString(m_drt->webPage(), string, optionArray);
807 }
808
809 QString LayoutTestController::markerTextForListItem(const QWebElement& listItem)
810 {
811     return DumpRenderTreeSupportQt::markerTextForListItem(listItem);
812 }
813
814 QVariantMap LayoutTestController::computedStyleIncludingVisitedInfo(const QWebElement& element) const
815 {
816     return DumpRenderTreeSupportQt::computedStyleIncludingVisitedInfo(element);
817 }
818
819 bool LayoutTestController::elementDoesAutoCompleteForElementWithId(const QString& elementId)
820 {
821     return DumpRenderTreeSupportQt::elementDoesAutoCompleteForElementWithId(m_drt->webPage()->mainFrame(), elementId);
822 }
823
824 void LayoutTestController::authenticateSession(const QString&, const QString&, const QString&)
825 {
826     // FIXME: If there is a concept per-session (per-process) credential storage, the credentials should be added to it for later use.
827 }
828
829 void LayoutTestController::setIconDatabaseEnabled(bool enable)
830 {
831     if (enable && !m_drt->persistentStoragePath().isEmpty())
832         QWebSettings::setIconDatabasePath(m_drt->persistentStoragePath());
833     else
834         QWebSettings::setIconDatabasePath(QString());
835 }
836
837 void LayoutTestController::setEditingBehavior(const QString& editingBehavior)
838 {
839     DumpRenderTreeSupportQt::setEditingBehavior(m_drt->webPage(), editingBehavior);
840 }
841
842 void LayoutTestController::setMockDeviceOrientation(bool canProvideAlpha, double alpha, bool canProvideBeta, double beta, bool canProvideGamma, double gamma)
843 {
844     DumpRenderTreeSupportQt::setMockDeviceOrientation(canProvideAlpha, alpha, canProvideBeta, beta, canProvideGamma, gamma);
845 }
846
847 void LayoutTestController::setGeolocationPermission(bool allow)
848 {
849     setGeolocationPermissionCommon(allow);
850     QList<WebCore::WebPage*> pages = m_drt->getAllPages();
851     foreach (WebCore::WebPage* page, pages)
852         DumpRenderTreeSupportQt::setMockGeolocationPermission(page, allow);
853 }
854
855 int LayoutTestController::numberOfPendingGeolocationPermissionRequests()
856 {
857     int pendingPermissionCount = 0;
858     QList<WebCore::WebPage*> pages = m_drt->getAllPages();
859     foreach (WebCore::WebPage* page, pages)
860         pendingPermissionCount += DumpRenderTreeSupportQt::numberOfPendingGeolocationPermissionRequests(page);
861
862     return pendingPermissionCount;
863 }
864
865 void LayoutTestController::setGeolocationPermissionCommon(bool allow)
866 {
867      m_isGeolocationPermissionSet = true;
868      m_geolocationPermission = allow;
869 }
870
871 void LayoutTestController::setMockGeolocationError(int code, const QString& message)
872 {
873     QList<WebCore::WebPage*> pages = m_drt->getAllPages();
874     foreach (WebCore::WebPage* page, pages)
875         DumpRenderTreeSupportQt::setMockGeolocationError(page, code, message);
876 }
877
878 void LayoutTestController::setMockGeolocationPosition(double latitude, double longitude, double accuracy)
879 {
880     QList<WebCore::WebPage*> pages = m_drt->getAllPages();
881     foreach (WebCore::WebPage* page, pages)
882         DumpRenderTreeSupportQt::setMockGeolocationPosition(page, latitude, longitude, accuracy);
883 }
884
885 void LayoutTestController::addMockSpeechInputResult(const QString& result, double confidence, const QString& language)
886 {
887     // FIXME: Implement for speech input layout tests.
888     // See https://bugs.webkit.org/show_bug.cgi?id=39485.
889 }
890
891 void LayoutTestController::startSpeechInput(const QString& inputElement)
892 {
893     // FIXME: Implement for speech input layout tests.
894     // See https://bugs.webkit.org/show_bug.cgi?id=39485.
895 }
896
897 void LayoutTestController::evaluateScriptInIsolatedWorld(int worldID, const QString& script)
898 {
899     DumpRenderTreeSupportQt::evaluateScriptInIsolatedWorld(m_drt->webPage()->mainFrame(), worldID, script);
900 }
901
902 bool LayoutTestController::isPageBoxVisible(int pageIndex)
903 {
904     return DumpRenderTreeSupportQt::isPageBoxVisible(m_drt->webPage()->mainFrame(), pageIndex);
905 }
906
907 QString LayoutTestController::pageSizeAndMarginsInPixels(int pageIndex, int width, int height, int marginTop, int marginRight, int marginBottom, int marginLeft)
908 {
909     return DumpRenderTreeSupportQt::pageSizeAndMarginsInPixels(m_drt->webPage()->mainFrame(), pageIndex,
910                                                                width, height, marginTop, marginRight, marginBottom, marginLeft);
911 }
912
913 QString LayoutTestController::pageProperty(const QString& propertyName, int pageNumber)
914 {
915     return DumpRenderTreeSupportQt::pageProperty(m_drt->webPage()->mainFrame(), propertyName, pageNumber);
916 }
917
918 void LayoutTestController::addUserStyleSheet(const QString& sourceCode)
919 {
920     DumpRenderTreeSupportQt::addUserStyleSheet(m_drt->webPage(), sourceCode);
921 }
922
923 void LayoutTestController::removeAllVisitedLinks()
924 {
925     QWebHistory* history = m_drt->webPage()->history();
926     history->clear();
927     DumpRenderTreeSupportQt::dumpVisitedLinksCallbacks(true);
928 }
929
930 bool LayoutTestController::hasSpellingMarker(int, int)
931 {
932     // FIXME: Implement.
933     return false;
934 }
935
936 QVariantList LayoutTestController::nodesFromRect(const QWebElement& document, int x, int y, unsigned top, unsigned right, unsigned bottom, unsigned left, bool ignoreClipping)
937 {
938     return DumpRenderTreeSupportQt::nodesFromRect(document, x, y, top, right, bottom, left, ignoreClipping);
939 }
940
941 void LayoutTestController::addURLToRedirect(const QString& origin, const QString& destination)
942 {
943     DumpRenderTreeSupportQt::addURLToRedirect(origin, destination);
944 }
945
946 void LayoutTestController::setMinimumTimerInterval(double minimumTimerInterval)
947 {
948     DumpRenderTreeSupportQt::setMinimumTimerInterval(m_drt->webPage(), minimumTimerInterval);
949 }
950
951 void LayoutTestController::originsWithLocalStorage()
952 {
953     // FIXME: Implement.
954 }
955
956 void LayoutTestController::deleteAllLocalStorage()
957 {
958     // FIXME: Implement.
959 }
960
961 void LayoutTestController::deleteLocalStorageForOrigin(const QString& originIdentifier)
962 {
963     // FIXME: Implement.
964 }
965
966 void LayoutTestController::observeStorageTrackerNotifications(unsigned number)
967 {
968     // FIXME: Implement.
969 }
970
971 void LayoutTestController::syncLocalStorage()
972 {
973     // FIXME: Implement.
974 }
975
976 QString LayoutTestController::layerTreeAsText()
977 {
978     return DumpRenderTreeSupportQt::layerTreeAsText(m_drt->webPage()->mainFrame());
979 }
980
981 void LayoutTestController::setTextDirection(const QString& directionName)
982 {
983     if (directionName == "auto")
984         m_drt->webPage()->triggerAction(QWebPage::SetTextDirectionDefault);
985     else if (directionName == "rtl")
986         m_drt->webPage()->triggerAction(QWebPage::SetTextDirectionRightToLeft);
987     else if (directionName == "ltr")
988         m_drt->webPage()->triggerAction(QWebPage::SetTextDirectionLeftToRight);
989 }
990
991 #if QT_VERSION >= 0x040800
992 void LayoutTestController::setAlwaysAcceptCookies(bool accept)
993 {
994     QWebSettings* globalSettings = QWebSettings::globalSettings();
995     if (accept)
996         globalSettings->setThirdPartyCookiePolicy(QWebSettings::AlwaysAllowThirdPartyCookies);
997     else {
998         // This matches the Safari third-party cookie blocking policy tested in third-party-cookie-relaxing.html
999         globalSettings->setThirdPartyCookiePolicy(QWebSettings::AllowThirdPartyWithExistingCookies);
1000     }
1001 }
1002
1003 void LayoutTestController::setAlwaysBlockCookies(bool block)
1004 {
1005     QWebSettings* globalSettings = QWebSettings::globalSettings();
1006     if (block)
1007         globalSettings->setThirdPartyCookiePolicy(QWebSettings::AlwaysBlockThirdPartyCookies);
1008     else
1009         globalSettings->setThirdPartyCookiePolicy(QWebSettings::AlwaysAllowThirdPartyCookies);
1010 }
1011 #endif
1012
1013 const unsigned LayoutTestController::maxViewWidth = 800;
1014 const unsigned LayoutTestController::maxViewHeight = 600;