/* * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) * Copyright (C) 2009 Torch Mobile Inc. http://www.torchmobile.com/ * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "config.h" #include "TestRunnerQt.h" #include "DumpRenderTreeQt.h" #include "DumpRenderTreeSupportQt.h" #include "NotificationPresenterClientQt.h" #include "WorkQueue.h" #include "WorkQueueItemQt.h" #include #include #include #include #include TestRunnerQt::TestRunnerQt(DumpRenderTree* drt) : QObject() , m_drt(drt) , m_shouldTimeout(true) , m_timeout(30000) { reset(); } TestRunner::~TestRunner() { } void TestRunnerQt::reset() { m_hasDumped = false; m_loadFinished = false; m_audioDump = false; m_waitForDone = false; m_timeoutTimer.stop(); m_topLoadingFrame = 0; m_waitForPolicy = false; m_handleErrorPages = false; m_webHistory = 0; m_globalFlag = false; m_userStyleSheetEnabled = false; m_ignoreDesktopNotification = false; m_isGeolocationPermissionSet = false; m_geolocationPermission = false; m_audioData.clear(); m_drt->webPage()->setDevicePixelRatio(1); DumpRenderTreeSupportQt::dumpEditingCallbacks(false); DumpRenderTreeSupportQt::dumpFrameLoader(false); DumpRenderTreeSupportQt::dumpProgressFinishedCallback(false); DumpRenderTreeSupportQt::dumpUserGestureInFrameLoader(false); DumpRenderTreeSupportQt::dumpResourceLoadCallbacks(false); DumpRenderTreeSupportQt::dumpResourceResponseMIMETypes(false); DumpRenderTreeSupportQt::dumpWillCacheResponseCallbacks(false); DumpRenderTreeSupportQt::setDeferMainResourceDataLoad(true); DumpRenderTreeSupportQt::setWillSendRequestReturnsNullOnRedirect(false); DumpRenderTreeSupportQt::setWillSendRequestReturnsNull(false); DumpRenderTreeSupportQt::setWillSendRequestClearHeaders(QStringList()); DumpRenderTreeSupportQt::clearScriptWorlds(); DumpRenderTreeSupportQt::setCustomPolicyDelegate(false, false); DumpRenderTreeSupportQt::dumpHistoryCallbacks(false); DumpRenderTreeSupportQt::dumpVisitedLinksCallbacks(false); DumpRenderTreeSupportQt::resetGeolocationMock(m_drt->pageAdapter()); DumpRenderTreeSupportQt::dumpNotification(false); DumpRenderTreeSupportQt::setShouldUseFontSmoothing(false); setIconDatabaseEnabled(false); clearAllDatabases(); removeAllWebNotificationPermissions(); // The default state for DRT is to block third-party cookies, mimicing the Mac port setAlwaysAcceptCookies(false); emit hidePage(); } void TestRunnerQt::dumpNotifications() { DumpRenderTreeSupportQt::dumpNotification(true); } void TestRunnerQt::processWork() { // qDebug() << ">>>processWork"; // if we didn't start a new load, then we finished all the commands, so we're ready to dump state if (WorkQueue::singleton().processWork() && !shouldWaitUntilDone()) { emit done(); m_hasDumped = true; } } // Called on loadFinished on WebPage void TestRunnerQt::maybeDump(bool /*success*/) { // This can happen on any of the http/tests/security/window-events-*.html tests, where the test opens // a new window, calls the unload and load event handlers on the window's page, and then immediately // issues a notifyDone. Needs investigation. if (!m_topLoadingFrame) return; // It is possible that we get called by windows created from the main page that have finished // loading, so we don't ASSERT here. At the moment we do not gather results from such windows, // but may need to in future. if (sender() != m_topLoadingFrame->page()) return; m_loadFinished = true; // as the function is called on loadFinished, the test might // already have dumped and thus no longer be active, thus // bail out here. if (m_hasDumped) return; WorkQueue::singleton().setFrozen(true); // first complete load freezes the queue for the rest of this test if (WorkQueue::singleton().count()) QTimer::singleShot(0, this, SLOT(processWork())); else if (!shouldWaitUntilDone()) { emit done(); m_hasDumped = true; } } void TestRunnerQt::waitUntilDone() { //qDebug() << ">>>>waitForDone"; m_waitForDone = true; if (!m_shouldTimeout) return; m_timeoutTimer.start(m_timeout, this); } void TestRunnerQt::setViewModeMediaFeature(const QString& mode) { m_drt->webPage()->setProperty("_q_viewMode", mode); } int TestRunnerQt::webHistoryItemCount() { if (!m_webHistory) return -1; // Subtract one here as our QWebHistory::count() includes the actual page, // which is not considered in the DRT tests. return m_webHistory->count() - 1; } void TestRunnerQt::keepWebHistory() { m_webHistory = m_drt->webPage()->history(); } void TestRunnerQt::notifyDone() { qDebug() << ">>>>notifyDone"; if (m_shouldTimeout && !m_timeoutTimer.isActive()) return; m_timeoutTimer.stop(); m_waitForDone = false; // If the page has not finished loading (i.e. loadFinished() has not been emitted) then // content created by the likes of document.write() JS methods will not be available yet. // When the page has finished loading, maybeDump above will dump the results now that we have // just set shouldWaitUntilDone to false. if (!m_loadFinished) return; emit done(); // FIXME: investigate why always resetting these result in timeouts m_hasDumped = true; m_waitForPolicy = false; } int TestRunnerQt::windowCount() { return m_drt->windowCount(); } void TestRunnerQt::grantWebNotificationPermission(const QString& origin) { QWebFrame* frame = m_drt->webPage()->mainFrame(); m_drt->webPage()->setFeaturePermission(frame, QWebPage::Notifications, QWebPage::PermissionGrantedByUser); } void TestRunnerQt::ignoreLegacyWebNotificationPermissionRequests() { m_ignoreDesktopNotification = true; } void TestRunnerQt::denyWebNotificationPermission(const QString& origin) { QWebFrame* frame = m_drt->webPage()->mainFrame(); m_drt->webPage()->setFeaturePermission(frame, QWebPage::Notifications, QWebPage::PermissionDeniedByUser); } void TestRunnerQt::removeAllWebNotificationPermissions() { DumpRenderTreeSupportQt::clearNotificationPermissions(); } void TestRunnerQt::simulateLegacyWebNotificationClick(const QString& title) { DumpRenderTreeSupportQt::simulateDesktopNotificationClick(title); } void TestRunnerQt::display() { DumpRenderTreeSupportQt::setTrackRepaintRects(m_topLoadingFrame->handle(), true); emit showPage(); } void TestRunnerQt::displayInvalidatedRegion() { display(); } void TestRunnerQt::clearBackForwardList() { m_drt->webPage()->history()->clear(); } QString TestRunnerQt::pathToLocalResource(const QString& url) { QString localTmpUrl(QLatin1String("file:///tmp/LayoutTests")); // Translate a request for /tmp/LayoutTests to the repository LayoutTests directory. // Do not rely on a symlink to be created via the test runner, which will not work on Windows. if (url.startsWith(localTmpUrl)) { // DumpRenderTree lives in WebKit/WebKitBuild//bin. // Translate from WebKit/WebKitBuild/Release/bin => WebKit/LayoutTests. QFileInfo layoutTestsRoot(QCoreApplication::applicationDirPath() + QLatin1String("/../../../LayoutTests/")); if (layoutTestsRoot.exists()) return QLatin1String("file://") + layoutTestsRoot.absolutePath() + url.mid(localTmpUrl.length()); } return url; } void TestRunnerQt::dumpEditingCallbacks() { qDebug() << ">>>dumpEditingCallbacks"; DumpRenderTreeSupportQt::dumpEditingCallbacks(true); } void TestRunnerQt::dumpFrameLoadCallbacks() { DumpRenderTreeSupportQt::dumpFrameLoader(true); } void TestRunnerQt::dumpProgressFinishedCallback() { DumpRenderTreeSupportQt::dumpProgressFinishedCallback(true); } void TestRunnerQt::dumpUserGestureInFrameLoadCallbacks() { DumpRenderTreeSupportQt::dumpUserGestureInFrameLoader(true); } void TestRunnerQt::dumpResourceLoadCallbacks() { DumpRenderTreeSupportQt::dumpResourceLoadCallbacks(true); } void TestRunnerQt::dumpResourceResponseMIMETypes() { DumpRenderTreeSupportQt::dumpResourceResponseMIMETypes(true); } void TestRunnerQt::dumpWillCacheResponse() { DumpRenderTreeSupportQt::dumpWillCacheResponseCallbacks(true); } void TestRunnerQt::dumpHistoryCallbacks() { DumpRenderTreeSupportQt::dumpHistoryCallbacks(true); } void TestRunnerQt::setWillSendRequestReturnsNullOnRedirect(bool enabled) { DumpRenderTreeSupportQt::setWillSendRequestReturnsNullOnRedirect(enabled); } void TestRunnerQt::setWillSendRequestReturnsNull(bool enabled) { DumpRenderTreeSupportQt::setWillSendRequestReturnsNull(enabled); } void TestRunnerQt::setWillSendRequestClearHeader(const QStringList& headers) { DumpRenderTreeSupportQt::setWillSendRequestClearHeaders(headers); } void TestRunnerQt::setDeferMainResourceDataLoad(bool defer) { DumpRenderTreeSupportQt::setDeferMainResourceDataLoad(defer); } void TestRunnerQt::queueBackNavigation(int howFarBackward) { //qDebug() << ">>>queueBackNavigation" << howFarBackward; for (int i = 0; i != howFarBackward; ++i) WorkQueue::singleton().queue(new BackItem(1)); } void TestRunnerQt::queueForwardNavigation(int howFarForward) { //qDebug() << ">>>queueForwardNavigation" << howFarForward; for (int i = 0; i != howFarForward; ++i) WorkQueue::singleton().queue(new ForwardItem(1)); } void TestRunnerQt::queueLoadHTMLString(const QString& content, const QString& baseURL, const QString& failingURL) { if (failingURL.isEmpty()) WorkQueue::singleton().queue(new LoadHTMLStringItem(JSStringCreateWithQString(content).get(), JSStringCreateWithQString(baseURL).get())); else WorkQueue::singleton().queue(new LoadAlternateHTMLStringItem(JSStringCreateWithQString(content), JSStringCreateWithQString(baseURL), JSStringCreateWithQString(failingURL))); } void TestRunnerQt::queueReload() { //qDebug() << ">>>queueReload"; WorkQueue::singleton().queue(new ReloadItem()); } void TestRunnerQt::queueLoadingScript(const QString& script) { //qDebug() << ">>>queueLoadingScript" << script; WorkQueue::singleton().queue(new LoadingScriptItem(JSStringCreateWithQString(script).get())); } void TestRunnerQt::queueNonLoadingScript(const QString& script) { //qDebug() << ">>>queueNonLoadingScript" << script; WorkQueue::singleton().queue(new NonLoadingScriptItem(JSStringCreateWithQString(script).get())); } void TestRunnerQt::provisionalLoad() { QWebFrame* frame = qobject_cast(sender()); if (!m_topLoadingFrame && !m_hasDumped) m_topLoadingFrame = frame; } void TestRunnerQt::timerEvent(QTimerEvent *ev) { if (ev->timerId() == m_timeoutTimer.timerId()) { const char* message = "FAIL: Timed out waiting for notifyDone to be called\n"; fprintf(stderr, "%s", message); fprintf(stdout, "%s", message); notifyDone(); } else QObject::timerEvent(ev); } QString TestRunnerQt::encodeHostName(const QString& host) { QString encoded = QString::fromLatin1(QUrl::toAce(host + QLatin1String(".no"))); encoded.truncate(encoded.length() - 3); // strip .no return encoded; } QString TestRunnerQt::decodeHostName(const QString& host) { QString decoded = QUrl::fromAce(host.toLatin1() + QByteArray(".no")); decoded.truncate(decoded.length() - 3); return decoded; } void TestRunnerQt::closeWebInspector() { DumpRenderTreeSupportQt::webInspectorClose(m_drt->pageAdapter()); m_drt->webPage()->settings()->setAttribute(QWebSettings::DeveloperExtrasEnabled, false); } void TestRunnerQt::setDeveloperExtrasEnabled(bool enabled) { m_drt->webPage()->settings()->setAttribute(QWebSettings::DeveloperExtrasEnabled, enabled); } void TestRunnerQt::showWebInspector() { m_drt->webPage()->settings()->setAttribute(QWebSettings::DeveloperExtrasEnabled, true); DumpRenderTreeSupportQt::webInspectorShow(m_drt->pageAdapter()); } void TestRunnerQt::evaluateInWebInspector(const QString& script) { DumpRenderTreeSupportQt::webInspectorExecuteScript(m_drt->pageAdapter(), script); } void TestRunnerQt::setAllowUniversalAccessFromFileURLs(bool enabled) { m_drt->webPage()->settings()->setAttribute(QWebSettings::LocalContentCanAccessRemoteUrls, enabled); } void TestRunnerQt::setAllowFileAccessFromFileURLs(bool enabled) { m_drt->webPage()->settings()->setAttribute(QWebSettings::LocalContentCanAccessFileUrls, enabled); } void TestRunnerQt::setAppCacheMaximumSize(unsigned long long quota) { m_drt->webPage()->settings()->setOfflineWebApplicationCacheQuota(quota); } void TestRunnerQt::setValueForUser(const QWebElement& element, const QString& value) { DumpRenderTreeSupportQt::setValueForUser(element, value); } void TestRunnerQt::setFixedContentsSize(int width, int height) { m_topLoadingFrame->page()->setPreferredContentsSize(QSize(width, height)); } void TestRunnerQt::setPrivateBrowsingEnabled(bool enable) { m_drt->webPage()->settings()->setAttribute(QWebSettings::PrivateBrowsingEnabled, enable); } void TestRunnerQt::setSpatialNavigationEnabled(bool enable) { m_drt->webPage()->settings()->setAttribute(QWebSettings::SpatialNavigationEnabled, enable); } void TestRunnerQt::setPopupBlockingEnabled(bool enable) { m_drt->webPage()->settings()->setAttribute(QWebSettings::JavascriptCanOpenWindows, !enable); } void TestRunnerQt::setPOSIXLocale(const QString& locale) { QLocale qlocale(locale); QLocale::setDefault(qlocale); } void TestRunnerQt::setWindowIsKey(bool isKey) { m_drt->switchFocus(isKey); } void TestRunnerQt::setJavaScriptCanAccessClipboard(bool enable) { m_drt->webPage()->settings()->setAttribute(QWebSettings::JavascriptCanAccessClipboard, enable); } void TestRunnerQt::setXSSAuditorEnabled(bool enable) { // Set XSSAuditingEnabled globally so that windows created by the test inherit it too. // resetSettings() will call this to reset the page and global setting to false again. // Needed by http/tests/security/xssAuditor/link-opens-new-window.html QWebSettings* globalSettings = QWebSettings::globalSettings(); globalSettings->setAttribute(QWebSettings::XSSAuditingEnabled, enable); m_drt->webPage()->settings()->setAttribute(QWebSettings::XSSAuditingEnabled, enable); } void TestRunnerQt::clearAllApplicationCaches() { DumpRenderTreeSupportQt::clearAllApplicationCaches(); } void TestRunnerQt::setApplicationCacheOriginQuota(unsigned long long quota) { if (!m_topLoadingFrame) return; m_topLoadingFrame->securityOrigin().setApplicationCacheQuota(quota); } QStringList TestRunnerQt::originsWithApplicationCache() { // FIXME: Implement to get origins that have application caches. return QStringList(); } void TestRunnerQt::setDatabaseQuota(int size) { if (!m_topLoadingFrame) return; m_topLoadingFrame->securityOrigin().setDatabaseQuota(size); } void TestRunnerQt::clearAllDatabases() { QWebDatabase::removeAllDatabases(); } void TestRunnerQt::addOriginAccessWhitelistEntry(const QString& sourceOrigin, const QString& destinationProtocol, const QString& destinationHost, bool allowDestinationSubdomains) { DumpRenderTreeSupportQt::whiteListAccessFromOrigin(sourceOrigin, destinationProtocol, destinationHost, allowDestinationSubdomains); } void TestRunnerQt::removeOriginAccessWhitelistEntry(const QString& sourceOrigin, const QString& destinationProtocol, const QString& destinationHost, bool allowDestinationSubdomains) { DumpRenderTreeSupportQt::removeWhiteListAccessFromOrigin(sourceOrigin, destinationProtocol, destinationHost, allowDestinationSubdomains); } void TestRunnerQt::setCustomPolicyDelegate(bool enabled, bool permissive) { DumpRenderTreeSupportQt::setCustomPolicyDelegate(enabled, permissive); } void TestRunnerQt::waitForPolicyDelegate() { setCustomPolicyDelegate(true); m_waitForPolicy = true; waitUntilDone(); } void TestRunnerQt::overridePreference(const QString& name, const QVariant& value) { QWebSettings* settings = m_topLoadingFrame->page()->settings(); if (name == "WebKitJavaScriptEnabled") settings->setAttribute(QWebSettings::JavascriptEnabled, value.toBool()); else if (name == "WebKitTabToLinksPreferenceKey") settings->setAttribute(QWebSettings::LinksIncludedInFocusChain, value.toBool()); else if (name == "WebKitOfflineWebApplicationCacheEnabled") settings->setAttribute(QWebSettings::OfflineWebApplicationCacheEnabled, value.toBool()); else if (name == "WebKitDefaultFontSize") settings->setFontSize(QWebSettings::DefaultFontSize, value.toInt()); else if (name == "WebKitUsesPageCachePreferenceKey") QWebSettings::setMaximumPagesInCache(value.toInt()); else if (name == "WebKitEnableCaretBrowsing") setCaretBrowsingEnabled(value.toBool()); else if (name == "WebKitPluginsEnabled") settings->setAttribute(QWebSettings::PluginsEnabled, value.toBool()); else if (name == "WebKitWebGLEnabled") settings->setAttribute(QWebSettings::WebGLEnabled, value.toBool()); else if (name == "WebKitCSSRegionsEnabled") settings->setAttribute(QWebSettings::CSSRegionsEnabled, value.toBool()); else if (name == "WebKitCSSGridLayoutEnabled") settings->setAttribute(QWebSettings::CSSGridLayoutEnabled, value.toBool()); else if (name == "WebKitHyperlinkAuditingEnabled") settings->setAttribute(QWebSettings::HyperlinkAuditingEnabled, value.toBool()); else if (name == "WebKitAcceleratedCompositingEnabled") settings->setAttribute(QWebSettings::AcceleratedCompositingEnabled, value.toBool()); else if (name == "WebKitDisplayImagesKey") settings->setAttribute(QWebSettings::AutoLoadImages, value.toBool()); else if (name == "WebKitWebAudioEnabled") settings->setAttribute(QWebSettings::WebAudioEnabled, value.toBool()); else printf("ERROR: TestRunner::overridePreference() does not support the '%s' preference\n", name.toLatin1().data()); } void TestRunnerQt::setUserStyleSheetLocation(const QString& url) { QByteArray urlData = pathToLocalResource(url).toLatin1(); m_userStyleSheetLocation = QUrl::fromEncoded(urlData, QUrl::StrictMode); if (m_userStyleSheetEnabled) setUserStyleSheetEnabled(true); } void TestRunnerQt::setCaretBrowsingEnabled(bool value) { DumpRenderTreeSupportQt::setCaretBrowsingEnabled(m_drt->pageAdapter(), value); } void TestRunnerQt::setAuthorAndUserStylesEnabled(bool value) { DumpRenderTreeSupportQt::setAuthorAndUserStylesEnabled(m_drt->pageAdapter(), value); } void TestRunnerQt::setUserStyleSheetEnabled(bool enabled) { m_userStyleSheetEnabled = enabled; if (enabled) m_drt->webPage()->settings()->setUserStyleSheetUrl(m_userStyleSheetLocation); else m_drt->webPage()->settings()->setUserStyleSheetUrl(QUrl()); } void TestRunnerQt::setDomainRelaxationForbiddenForURLScheme(bool forbidden, const QString& scheme) { DumpRenderTreeSupportQt::setDomainRelaxationForbiddenForURLScheme(forbidden, scheme); } bool TestRunnerQt::callShouldCloseOnWebView() { return DumpRenderTreeSupportQt::shouldClose(m_drt->mainFrameAdapter()); } void TestRunnerQt::setScrollbarPolicy(const QString& orientation, const QString& policy) { Qt::Orientation o; Qt::ScrollBarPolicy p; if (orientation == "vertical") o = Qt::Vertical; else if (orientation == "horizontal") o = Qt::Horizontal; else return; if (policy == "on") p = Qt::ScrollBarAlwaysOn; else if (policy == "auto") p = Qt::ScrollBarAsNeeded; else if (policy == "off") p = Qt::ScrollBarAlwaysOff; else return; m_drt->webPage()->mainFrame()->setScrollBarPolicy(o, p); } void TestRunnerQt::execCommand(const QString& name, const QString& value) { DumpRenderTreeSupportQt::executeCoreCommandByName(m_drt->pageAdapter(), name, value); } bool TestRunnerQt::isCommandEnabled(const QString& name) const { return DumpRenderTreeSupportQt::isCommandEnabled(m_drt->pageAdapter(), name); } bool TestRunner::findString(JSContextRef context, JSStringRef string, JSObjectRef optionsArray) { JSRetainPtr lengthPropertyName(Adopt, JSStringCreateWithUTF8CString("length")); JSValueRef lengthValue = JSObjectGetProperty(context, optionsArray, lengthPropertyName.get(), 0); if (!JSValueIsNumber(context, lengthValue)) return false; QWebPage::FindFlags findFlags = QWebPage::FindCaseSensitively; int length = static_cast(JSValueToNumber(context, lengthValue, 0)); for (int i = 0; i < length; ++i) { JSValueRef value = JSObjectGetPropertyAtIndex(context, optionsArray, i, 0); if (!JSValueIsString(context, value)) continue; JSRetainPtr optionName(Adopt, JSValueToStringCopy(context, value, 0)); if (JSStringIsEqualToUTF8CString(optionName.get(), "CaseInsensitive")) findFlags &= ~QWebPage::FindCaseSensitively; else if (JSStringIsEqualToUTF8CString(optionName.get(), "AtWordStarts")) findFlags |= QWebPage::FindAtWordBeginningsOnly; else if (JSStringIsEqualToUTF8CString(optionName.get(), "TreatMedialCapitalAsWordStart")) findFlags |= QWebPage::TreatMedialCapitalAsWordBeginning; else if (JSStringIsEqualToUTF8CString(optionName.get(), "Backwards")) findFlags |= QWebPage::FindBackward; else if (JSStringIsEqualToUTF8CString(optionName.get(), "WrapAround")) findFlags |= QWebPage::FindWrapsAroundDocument; else if (JSStringIsEqualToUTF8CString(optionName.get(), "StartInSelection")) findFlags |= QWebPage::FindBeginsInSelection; } DumpRenderTree* drt = DumpRenderTree::instance(); return drt->webPage()->findText(JSStringCopyQString(string), findFlags); } void TestRunnerQt::setIconDatabaseEnabled(bool enable) { if (enable && !m_drt->persistentStoragePath().isEmpty()) QWebSettings::setIconDatabasePath(m_drt->persistentStoragePath()); else QWebSettings::setIconDatabasePath(QString()); } void TestRunnerQt::setMockDeviceOrientation(bool canProvideAlpha, double alpha, bool canProvideBeta, double beta, bool canProvideGamma, double gamma) { QList pages = m_drt->getAllPages(); foreach (WebPage* page, pages) DumpRenderTreeSupportQt::setMockDeviceOrientation(page->handle(), canProvideAlpha, alpha, canProvideBeta, beta, canProvideGamma, gamma); } void TestRunnerQt::setGeolocationPermission(bool allow) { setGeolocationPermissionCommon(allow); QList pages = m_drt->getAllPages(); foreach (WebPage* page, pages) DumpRenderTreeSupportQt::setMockGeolocationPermission(page->handle(), allow); } int TestRunnerQt::numberOfPendingGeolocationPermissionRequests() { int pendingPermissionCount = 0; QList pages = m_drt->getAllPages(); foreach (WebPage* page, pages) pendingPermissionCount += DumpRenderTreeSupportQt::numberOfPendingGeolocationPermissionRequests(page->handle()); return pendingPermissionCount; } void TestRunnerQt::setGeolocationPermissionCommon(bool allow) { m_isGeolocationPermissionSet = true; m_geolocationPermission = allow; } void TestRunnerQt::setMockGeolocationPositionUnavailableError(const QString& message) { QList pages = m_drt->getAllPages(); foreach (WebPage* page, pages) DumpRenderTreeSupportQt::setMockGeolocationPositionUnavailableError(page->handle(), message); } void TestRunnerQt::setMockGeolocationPosition(double latitude, double longitude, double accuracy) { QList pages = m_drt->getAllPages(); foreach (WebPage* page, pages) DumpRenderTreeSupportQt::setMockGeolocationPosition(page->handle(), latitude, longitude, accuracy); } void TestRunnerQt::removeAllVisitedLinks() { QWebHistory* history = m_drt->webPage()->history(); history->clear(); DumpRenderTreeSupportQt::dumpVisitedLinksCallbacks(true); } void TestRunnerQt::addURLToRedirect(const QString& origin, const QString& destination) { DumpRenderTreeSupportQt::addURLToRedirect(origin, destination); } void TestRunnerQt::setAlwaysAcceptCookies(bool accept) { QWebSettings* globalSettings = QWebSettings::globalSettings(); if (accept) globalSettings->setThirdPartyCookiePolicy(QWebSettings::AlwaysAllowThirdPartyCookies); else { // This matches the Safari third-party cookie blocking policy tested in third-party-cookie-relaxing.html globalSettings->setThirdPartyCookiePolicy(QWebSettings::AllowThirdPartyWithExistingCookies); } } void TestRunnerQt::setAlwaysBlockCookies(bool block) { QWebSettings* globalSettings = QWebSettings::globalSettings(); if (block) globalSettings->setThirdPartyCookiePolicy(QWebSettings::AlwaysBlockThirdPartyCookies); else globalSettings->setThirdPartyCookiePolicy(QWebSettings::AlwaysAllowThirdPartyCookies); } void TestRunnerQt::setAudioResult(const QByteArray& audioData) { m_audioData = audioData; m_audioDump = true; } // --- JSC C API stubs void TestRunner::addDisallowedURL(JSStringRef url) { } void TestRunner::queueLoad(JSStringRef url, JSStringRef target) { DumpRenderTree* drt = DumpRenderTree::instance(); QUrl mainResourceUrl = drt->webPage()->mainFrame()->url(); QString absoluteUrl = mainResourceUrl.resolved(QUrl(JSStringCopyQString(url))).toEncoded(); WorkQueue::singleton().queue(new LoadItem(JSStringCreateWithQString(absoluteUrl).get(), target)); } void TestRunner::removeAllVisitedLinks() { } void TestRunner::setAcceptsEditing(bool) { } void TestRunner::simulateLegacyWebNotificationClick(JSStringRef title) { } void TestRunner::setWindowIsKey(bool) { } void TestRunner::setAlwaysAcceptCookies(bool) { } void TestRunner::addOriginAccessWhitelistEntry(JSStringRef sourceOrigin, JSStringRef destinationProtocol, JSStringRef destinationHost, bool allowDestinationSubdomains) { } void TestRunner::setWebViewEditable(bool) { } void TestRunner::clearAllApplicationCaches() { } void TestRunner::setTextDirection(JSStringRef directionName) { QWebPage* webPage = DumpRenderTree::instance()->webPage(); if (JSStringIsEqualToUTF8CString(directionName, "auto")) webPage->triggerAction(QWebPage::SetTextDirectionDefault); else if (JSStringIsEqualToUTF8CString(directionName, "rtl")) webPage->triggerAction(QWebPage::SetTextDirectionRightToLeft); else if (JSStringIsEqualToUTF8CString(directionName, "ltr")) webPage->triggerAction(QWebPage::SetTextDirectionLeftToRight); } void TestRunner::notifyDone() { } int TestRunner::numberOfPendingGeolocationPermissionRequests() { return 0; } bool TestRunner::isGeolocationProviderActive() { return false; } void TestRunner::overridePreference(JSStringRef key, JSStringRef value) { } JSStringRef TestRunner::pathToLocalResource(JSContextRef, JSStringRef url) { return JSStringCreateWithUTF8CString(0); // ### Take impl from WTR } void TestRunner::removeAllWebNotificationPermissions() { } void TestRunner::simulateWebNotificationClick(JSValueRef notification) { } void TestRunner::closeIdleLocalStorageDatabases() { } void TestRunner::focusWebView() { } void TestRunner::setBackingScaleFactor(double scale) { DumpRenderTree::instance()->webPage()->setDevicePixelRatio(scale); } void TestRunner::removeChromeInputField() { } void TestRunner::addChromeInputField() { } int TestRunner::windowCount() { return 0; } void TestRunner::setWaitToDump(bool) { } void TestRunner::waitForPolicyDelegate() { } size_t TestRunner::webHistoryItemCount() { return 0; } void TestRunner::showWebInspector() { } void TestRunner::closeWebInspector() { } void TestRunner::evaluateInWebInspector(JSStringRef script) { } void TestRunner::setSerializeHTTPLoads(bool) { } void TestRunner::apiTestNewWindowDataLoadBaseURL(JSStringRef utf8Data, JSStringRef baseURL) { } void TestRunner::setCustomPolicyDelegate(bool setDelegate, bool permissive) { } void TestRunner::setDatabaseQuota(unsigned long long quota) { } void TestRunner::setDomainRelaxationForbiddenForURLScheme(bool forbidden, JSStringRef scheme) { } void TestRunner::resetPageVisibility() { DumpRenderTreeSupportQt::resetPageVisibility(DumpRenderTree::instance()->pageAdapter()); } void TestRunner::setPageVisibility(const char* visibility) { QLatin1String newVisibility = QLatin1String(visibility); if (newVisibility == QStringLiteral("visible")) DumpRenderTree::instance()->webPage()->setVisibilityState(QWebPage::VisibilityStateVisible); else if (newVisibility == QStringLiteral("hidden")) DumpRenderTree::instance()->webPage()->setVisibilityState(QWebPage::VisibilityStateHidden); else if (newVisibility == QStringLiteral("prerender")) DumpRenderTree::instance()->webPage()->setVisibilityState(QWebPage::VisibilityStatePrerender); else if (newVisibility == QStringLiteral("unloaded")) DumpRenderTree::instance()->webPage()->setVisibilityState(QWebPage::VisibilityStateUnloaded); } void TestRunner::keepWebHistory() { } void TestRunner::goBack() { DumpRenderTreeSupportQt::goBack(DumpRenderTree::instance()->pageAdapter()); } JSValueRef TestRunner::originsWithApplicationCache(JSContextRef context) { return JSValueMakeNull(context); } long long TestRunner::applicationCacheDiskUsageForOrigin(JSStringRef name) { return 0; } void TestRunner::display() { } void TestRunner::dispatchPendingLoadRequests() { } void TestRunner::clearPersistentUserStyleSheet() { } bool TestRunner::callShouldCloseOnWebView() { return false; } JSStringRef TestRunner::copyDecodedHostName(JSStringRef name) { return JSStringCreateWithUTF8CString(0); } void TestRunner::clearBackForwardList() { } void TestRunner::clearAllDatabases() { } void TestRunner::clearApplicationCacheForOrigin(JSStringRef name) { } void TestRunner::apiTestGoToCurrentBackForwardItem() { } void TestRunner::authenticateSession(JSStringRef url, JSStringRef username, JSStringRef password) { } void TestRunner::abortModal() { } void TestRunner::setStorageDatabaseIdleInterval(double) { } void TestRunner::setXSSAuditorEnabled(bool flag) { } void TestRunner::setSpatialNavigationEnabled(bool) { } void TestRunner::setScrollbarPolicy(JSStringRef orientation, JSStringRef policy) { } void TestRunner::setJavaScriptCanAccessClipboard(bool flag) { } void TestRunner::setAutomaticLinkDetectionEnabled(bool flag) { } void TestRunner::setUserStyleSheetEnabled(bool flag) { } void TestRunner::setUserStyleSheetLocation(JSStringRef path) { } void TestRunner::setUseDashboardCompatibilityMode(bool flag) { } void TestRunner::setTabKeyCyclesThroughElements(bool) { } void TestRunner::setPrivateBrowsingEnabled(bool) { } void TestRunner::setPluginsEnabled(bool) { } void TestRunner::setPopupBlockingEnabled(bool) { } void TestRunner::setPersistentUserStyleSheetLocation(JSStringRef path) { } 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) { } void TestRunner::setMockGeolocationPositionUnavailableError(JSStringRef message) { } void TestRunner::setMockDeviceOrientation(bool canProvideAlpha, double alpha, bool canProvideBeta, double beta, bool canProvideGamma, double gamma) { } void TestRunner::setMainFrameIsFirstResponder(bool flag) { } void TestRunner::setIconDatabaseEnabled(bool) { } void TestRunner::setGeolocationPermission(bool allow) { } void TestRunner::setDefersLoading(bool flag) { DumpRenderTreeSupportQt::setDefersLoading(DumpRenderTree::instance()->pageAdapter(), flag); } void TestRunner::setCacheModel(int) { } void TestRunner::setAuthorAndUserStylesEnabled(bool) { } void TestRunner::setAllowFileAccessFromFileURLs(bool) { } void TestRunner::setAppCacheMaximumSize(unsigned long long quota) { } void TestRunner::setAllowUniversalAccessFromFileURLs(bool) { } void TestRunner::denyWebNotificationPermission(JSStringRef origin) { } void TestRunner::grantWebNotificationPermission(JSStringRef origin) { } void TestRunner::setValueForUser(JSContextRef, JSValueRef nodeObject, JSStringRef value) { } void TestRunner::setViewModeMediaFeature(JSStringRef) { } void TestRunner::removeOriginAccessWhitelistEntry(JSStringRef sourceOrigin, JSStringRef destinationProtocol, JSStringRef destinationHost, bool allowDestinationSubdomains) { } void TestRunner::addUserScript(JSStringRef source, bool runAtStart, bool allFrames) { } bool TestRunner::isCommandEnabled(JSStringRef name) { return false; } void TestRunner::evaluateScriptInIsolatedWorld(unsigned worldID, JSObjectRef globalObject, JSStringRef script) { DumpRenderTreeSupportQt::evaluateScriptInIsolatedWorld(DumpRenderTree::instance()->mainFrameAdapter(), worldID, JSStringCopyQString(script)); } void TestRunner::evaluateScriptInIsolatedWorldAndReturnValue(unsigned worldID, JSObjectRef globalObject, JSStringRef script) { } JSStringRef TestRunner::copyEncodedHostName(JSStringRef name) { return JSStringCreateWithUTF8CString(0); } void TestRunner::addUserStyleSheet(JSStringRef source, bool allFrames) { DumpRenderTreeSupportQt::addUserStyleSheet(DumpRenderTree::instance()->pageAdapter(), JSStringCopyQString(source)); } void TestRunner::execCommand(JSStringRef name, JSStringRef value) { } JSStringRef TestRunner::inspectorTestStubURL() { return JSStringCreateWithUTF8CString("qrc:/webkit/inspector/UserInterface/TestStub.html"); }