2010-07-12 Maciej Stachowiak <mjs@apple.com>
[WebKit-https.git] / WebKitTools / WebKitTestRunner / TestInvocation.cpp
1 /*
2  * Copyright (C) 2010 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 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.
12  *
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.
24  */
25
26 #include "TestInvocation.h"
27
28 #include "PlatformWebView.h"
29 #include "TestController.h"
30 #include <WebKit2/WKContextPrivate.h>
31 #include <WebKit2/WKRetainPtr.h>
32 #include <WebKit2/WKStringCF.h>
33 #include <WebKit2/WKURLCF.h>
34 #include <wtf/PassOwnPtr.h>
35 #include <wtf/RetainPtr.h>
36 #include <wtf/Vector.h>
37
38 using namespace WebKit;
39
40 namespace WTR {
41
42 static WKURLRef createWKURL(const char* pathOrURL)
43 {
44     RetainPtr<CFStringRef> pathOrURLCFString(AdoptCF, CFStringCreateWithCString(0, pathOrURL, kCFStringEncodingUTF8));
45     RetainPtr<CFURLRef> cfURL;
46     if (CFStringHasPrefix(pathOrURLCFString.get(), CFSTR("http://")) || CFStringHasPrefix(pathOrURLCFString.get(), CFSTR("https://")))
47         cfURL.adoptCF(CFURLCreateWithString(0, pathOrURLCFString.get(), 0));
48     else
49         cfURL.adoptCF(CFURLCreateWithFileSystemPath(0, pathOrURLCFString.get(), kCFURLPOSIXPathStyle, false));
50     return WKURLCreateWithCFURL(cfURL.get());
51 }
52
53 static PassOwnPtr<Vector<char> > WKStringToUTF8(WKStringRef wkStringRef)
54 {
55     RetainPtr<CFStringRef> cfString(AdoptCF, WKStringCopyCFString(0, wkStringRef));
56     CFIndex bufferLength = CFStringGetMaximumSizeForEncoding(CFStringGetLength(cfString.get()), kCFStringEncodingUTF8) + 1;
57     OwnPtr<Vector<char> > buffer(new Vector<char>(bufferLength));
58     if (!CFStringGetCString(cfString.get(), buffer->data(), bufferLength, kCFStringEncodingUTF8)) {
59         buffer->shrink(1);
60         (*buffer)[0] = 0;
61     } else
62         buffer->shrink(strlen(buffer->data()) + 1);
63     return buffer.release();
64 }
65
66 TestInvocation::TestInvocation(const char* pathOrURL)
67     : m_url(AdoptWK, createWKURL(pathOrURL))
68     , m_pathOrURL(fastStrDup(pathOrURL))
69     , m_gotInitialResponse(false)
70     , m_gotFinalMessage(false)
71     , m_error(false)
72 {
73 }
74
75 TestInvocation::~TestInvocation()
76 {
77     fastFree(m_pathOrURL);
78 }
79
80 static const unsigned w3cSVGWidth = 480;
81 static const unsigned w3cSVGHeight = 360;
82 static const unsigned normalWidth = 800;
83 static const unsigned normalHeight = 600;
84
85 static void sizeWebViewForCurrentTest(char* pathOrURL)
86 {
87     bool isSVGW3CTest = strstr(pathOrURL, "svg/W3C-SVG-1.1");
88
89     if (isSVGW3CTest)
90         TestController::shared().mainWebView()->resizeTo(w3cSVGWidth, w3cSVGHeight);
91     else
92         TestController::shared().mainWebView()->resizeTo(normalWidth, normalHeight);
93 }
94
95 void TestInvocation::invoke()
96 {
97     sizeWebViewForCurrentTest(m_pathOrURL);
98     WKRetainPtr<WKStringRef> message(AdoptWK, WKStringCreateWithCFString(CFSTR("BeginTest")));
99     WKContextPostMessageToInjectedBundle(TestController::shared().context(), message.get());
100
101     runUntil(m_gotInitialResponse);
102     if (m_error) {
103         dump("FAIL\n");
104         return;
105     }
106
107     WKPageLoadURL(TestController::shared().mainWebView()->page(), m_url.get());
108
109     runUntil(m_gotFinalMessage);
110     if (m_error) {
111         dump("FAIL\n");
112         return;
113     }
114 }
115
116 void TestInvocation::dump(const char* stringToDump)
117 {
118     printf("Content-Type: text/plain\n");
119     printf("%s", stringToDump);
120
121     fputs("#EOF\n", stdout);
122     fputs("#EOF\n", stdout);
123     fputs("#EOF\n", stderr);
124
125     fflush(stdout);
126     fflush(stderr);
127 }
128
129 void TestInvocation::didRecieveMessageFromInjectedBundle(WKStringRef message)
130 {
131     RetainPtr<CFStringRef> cfMessage(AdoptCF, WKStringCopyCFString(0, message));
132     
133     if (CFEqual(cfMessage.get(), CFSTR("Error"))) {
134         // Set all states to true to stop spinning the runloop.
135         m_gotInitialResponse = true;
136         m_gotFinalMessage = true;
137         m_error = true;
138         return;
139     }
140
141     if (CFEqual(cfMessage.get(), CFSTR("BeginTestAck"))) {
142         m_gotInitialResponse = true;
143         return;
144     }
145
146     OwnPtr<Vector<char> > utf8Message = WKStringToUTF8(message);
147
148     dump(utf8Message->data());
149     m_gotFinalMessage = true;
150 }
151
152 } // namespace WTR