2 * Copyright (C) 2010 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23 * THE POSSIBILITY OF SUCH DAMAGE.
26 #include "TestController.h"
28 #include "PlatformWebView.h"
29 #include "StringFunctions.h"
30 #include "TestInvocation.h"
31 #include <WebKit2/WKContextPrivate.h>
32 #include <WebKit2/WKPreferencesPrivate.h>
33 #include <wtf/PassOwnPtr.h>
37 static TestController* controller;
39 TestController& TestController::shared()
45 TestController::TestController(int argc, const char* argv[])
48 , m_printSeparators(false)
49 , m_usingServerMode(false)
51 , m_doneResetting(false)
53 initialize(argc, argv);
59 TestController::~TestController()
63 static void closeOtherPage(WKPageRef page, const void* clientInfo)
66 const PlatformWebView* view = static_cast<const PlatformWebView*>(clientInfo);
70 static WKPageRef createOtherPage(WKPageRef oldPage, const void*)
72 PlatformWebView* view = new PlatformWebView(WKPageGetPageNamespace(oldPage));
73 WKPageRef newPage = view->page();
75 view->resizeTo(800, 600);
77 WKPageUIClient otherPageUIClient = {
91 WKPageSetPageUIClient(newPage, &otherPageUIClient);
97 void TestController::initialize(int argc, const char* argv[])
101 bool printSupportedFeatures = false;
103 for (int i = 1; i < argc; ++i) {
104 std::string argument(argv[i]);
106 if (argument == "--pixel-tests") {
110 if (argument == "--verbose") {
114 if (argument == "--print-supported-features") {
115 printSupportedFeatures = true;
119 // Skip any other arguments that begin with '--'.
120 if (argument.length() >= 2 && argument[0] == '-' && argument[1] == '-')
123 m_paths.push_back(argument);
126 if (printSupportedFeatures) {
127 // FIXME: On Windows, DumpRenderTree uses this to expose whether it supports 3d
128 // transforms and accelerated compositing. When we support those features, we
129 // should match DRT's behavior.
133 m_usingServerMode = (m_paths.size() == 1 && m_paths[0] == "-");
134 if (m_usingServerMode)
135 m_printSeparators = true;
137 m_printSeparators = m_paths.size() > 1;
139 initializeInjectedBundlePath();
140 initializeTestPluginDirectory();
142 m_context.adopt(WKContextCreateWithInjectedBundlePath(injectedBundlePath()));
143 platformInitializeContext();
145 WKContextInjectedBundleClient injectedBundleClient = {
148 didReceiveMessageFromInjectedBundle,
151 WKContextSetInjectedBundleClient(m_context.get(), &injectedBundleClient);
153 _WKContextSetAdditionalPluginsDirectory(m_context.get(), testPluginDirectory());
155 m_pageNamespace.adopt(WKPageNamespaceCreate(m_context.get()));
156 m_mainWebView = adoptPtr(new PlatformWebView(m_pageNamespace.get()));
158 WKPageUIClient pageUIClient = {
172 WKPageSetPageUIClient(m_mainWebView->page(), &pageUIClient);
174 WKPageLoaderClient pageLoaderClient = {
182 didFinishLoadForFrame,
196 WKPageSetPageLoaderClient(m_mainWebView->page(), &pageLoaderClient);
199 void TestController::resetStateToConsistentValues()
203 // FIXME: This function should also ensure that there is only one page open.
206 WKPreferencesRef preferences = WKContextGetPreferences(m_context.get());
207 WKPreferencesSetOfflineWebApplicationCacheEnabled(preferences, true);
208 WKPreferencesSetFontSmoothingLevel(preferences, kWKFontSmoothingLevelNoSubpixelAntiAliasing);
209 WKPreferencesSetXSSAuditorEnabled(preferences, false);
211 static WKStringRef standardFontFamily = WKStringCreateWithUTF8CString("Times");
212 static WKStringRef cursiveFontFamily = WKStringCreateWithUTF8CString("Apple Chancery");
213 static WKStringRef fantasyFontFamily = WKStringCreateWithUTF8CString("Papyrus");
214 static WKStringRef fixedFontFamily = WKStringCreateWithUTF8CString("Courier");
215 static WKStringRef sansSerifFontFamily = WKStringCreateWithUTF8CString("Helvetica");
216 static WKStringRef serifFontFamily = WKStringCreateWithUTF8CString("Times");
218 WKPreferencesSetStandardFontFamily(preferences, standardFontFamily);
219 WKPreferencesSetCursiveFontFamily(preferences, cursiveFontFamily);
220 WKPreferencesSetFantasyFontFamily(preferences, fantasyFontFamily);
221 WKPreferencesSetFixedFontFamily(preferences, fixedFontFamily);
222 WKPreferencesSetSansSerifFontFamily(preferences, sansSerifFontFamily);
223 WKPreferencesSetSerifFontFamily(preferences, serifFontFamily);
225 m_mainWebView->focus();
227 // Reset main page back to about:blank
228 m_doneResetting = false;
230 WKRetainPtr<WKURLRef> url(AdoptWK, createWKURL("about:blank"));
231 WKPageLoadURL(m_mainWebView->page(), url.get());
232 TestController::runUntil(m_doneResetting);
235 void TestController::runTest(const char* test)
237 resetStateToConsistentValues();
239 m_state = RunningTest;
240 m_currentInvocation.set(new TestInvocation(test));
241 m_currentInvocation->invoke();
242 m_currentInvocation.clear();
245 void TestController::runTestingServerLoop()
247 char filenameBuffer[2048];
248 while (fgets(filenameBuffer, sizeof(filenameBuffer), stdin)) {
249 char *newLineCharacter = strchr(filenameBuffer, '\n');
250 if (newLineCharacter)
251 *newLineCharacter = '\0';
253 if (strlen(filenameBuffer) == 0)
256 runTest(filenameBuffer);
260 void TestController::run()
262 if (m_usingServerMode)
263 runTestingServerLoop();
265 for (size_t i = 0; i < m_paths.size(); ++i)
266 runTest(m_paths[i].c_str());
270 // WKContextInjectedBundleClient
272 void TestController::didReceiveMessageFromInjectedBundle(WKContextRef context, WKStringRef messageName, WKTypeRef messageBody, const void* clientInfo)
274 static_cast<TestController*>(const_cast<void*>(clientInfo))->didReceiveMessageFromInjectedBundle(messageName, messageBody);
277 void TestController::didReceiveMessageFromInjectedBundle(WKStringRef messageName, WKTypeRef messageBody)
279 m_currentInvocation->didReceiveMessageFromInjectedBundle(messageName, messageBody);
282 // WKPageLoaderClient
284 void TestController::didFinishLoadForFrame(WKPageRef page, WKFrameRef frame, WKTypeRef, const void* clientInfo)
286 static_cast<TestController*>(const_cast<void*>(clientInfo))->didFinishLoadForFrame(page, frame);
289 void TestController::didFinishLoadForFrame(WKPageRef page, WKFrameRef frame)
291 if (m_state != Resetting)
294 if (!WKFrameIsMainFrame(frame))
297 WKRetainPtr<WKURLRef> wkURL(AdoptWK, WKFrameCopyURL(frame));
298 WKRetainPtr<WKStringRef> wkURLString(AdoptWK, copyURLString(wkURL.get()));
299 if (!WKStringIsEqualToUTF8CString(wkURLString.get(), "about:blank"))
302 m_doneResetting = true;