OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2011 Google Inc. All rights reserved. | 2 * Copyright (C) 2011 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
6 * met: | 6 * met: |
7 * | 7 * |
8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
(...skipping 14 matching lines...) Expand all Loading... |
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
29 */ | 29 */ |
30 | 30 |
31 #include "config.h" | 31 #include "config.h" |
32 #include "web/tests/FrameTestHelpers.h" | 32 #include "web/tests/FrameTestHelpers.h" |
33 | 33 |
34 #include "public/platform/Platform.h" | 34 #include "public/platform/Platform.h" |
| 35 #include "public/platform/WebData.h" |
35 #include "public/platform/WebString.h" | 36 #include "public/platform/WebString.h" |
36 #include "public/platform/WebThread.h" | 37 #include "public/platform/WebThread.h" |
37 #include "public/platform/WebURLRequest.h" | 38 #include "public/platform/WebURLRequest.h" |
38 #include "public/platform/WebURLResponse.h" | 39 #include "public/platform/WebURLResponse.h" |
39 #include "public/platform/WebUnitTestSupport.h" | 40 #include "public/platform/WebUnitTestSupport.h" |
40 #include "public/web/WebSettings.h" | 41 #include "public/web/WebSettings.h" |
41 #include "public/web/WebViewClient.h" | 42 #include "public/web/WebViewClient.h" |
42 #include "web/WebLocalFrameImpl.h" | 43 #include "web/WebLocalFrameImpl.h" |
43 #include "web/tests/URLTestHelpers.h" | 44 #include "web/tests/URLTestHelpers.h" |
44 #include "wtf/StdLibExtras.h" | 45 #include "wtf/StdLibExtras.h" |
45 | 46 |
46 namespace blink { | 47 namespace blink { |
47 namespace FrameTestHelpers { | 48 namespace FrameTestHelpers { |
48 | 49 |
49 namespace { | 50 namespace { |
50 | 51 |
| 52 // The frame test helpers coordinate frame loads in a carefully choreographed |
| 53 // dance. Since the parser is threaded, simply spinning the run loop once is not |
| 54 // enough to ensure completion of a load. Instead, the following pattern is |
| 55 // used to ensure that tests see the final state: |
| 56 // 1. Post a task to trigger a load (LoadTask/LoadHTMLStringTask/ReloadTask). |
| 57 // 2. Enter the run loop. |
| 58 // 3. Posted task triggers the load, and starts pumping pending resource |
| 59 // requests using ServeAsyncRequestsTask. |
| 60 // 4. TestWebFrameClient watches for didStartLoading/didStopLoading calls, |
| 61 // keeping track of how many loads it thinks are in flight. |
| 62 // 5. While ServeAsyncRequestsTask observes TestWebFrameClient to still have |
| 63 // loads in progress, it posts itself back to the run loop. |
| 64 // 6. When ServeAsyncRequestsTask notices there are no more loads in progress, |
| 65 // it exits the run loop. |
| 66 // 7. At this point, all parsing, resource loads, and layout should be finished. |
| 67 TestWebFrameClient* testClientForFrame(WebFrame* frame) |
| 68 { |
| 69 return static_cast<TestWebFrameClient*>(toWebLocalFrameImpl(frame)->client()
); |
| 70 } |
| 71 |
51 class QuitTask : public WebThread::Task { | 72 class QuitTask : public WebThread::Task { |
52 public: | 73 public: |
53 void PostThis(WebCore::Timer<QuitTask>*) | 74 void PostThis(WebCore::Timer<QuitTask>*) |
54 { | 75 { |
55 // We don't just quit here because the SharedTimer may be part-way | 76 // We don't just quit here because the SharedTimer may be part-way |
56 // through the current queue of tasks when runPendingTasks was called, | 77 // through the current queue of tasks when runPendingTasks was called, |
57 // and we can't miss the tasks that were behind it. | 78 // and we can't miss the tasks that were behind it. |
58 // Takes ownership of |this|. | 79 // Takes ownership of |this|. |
59 Platform::current()->currentThread()->postTask(this); | 80 Platform::current()->currentThread()->postTask(this); |
60 } | 81 } |
61 | 82 |
62 virtual void run() | 83 virtual void run() |
63 { | 84 { |
64 Platform::current()->currentThread()->exitRunLoop(); | 85 Platform::current()->currentThread()->exitRunLoop(); |
65 } | 86 } |
66 }; | 87 }; |
67 | 88 |
68 WebFrameClient* defaultWebFrameClient() | 89 class ServeAsyncRequestsTask : public WebThread::Task { |
| 90 public: |
| 91 explicit ServeAsyncRequestsTask(TestWebFrameClient* client) |
| 92 : m_client(client) |
| 93 { |
| 94 } |
| 95 |
| 96 virtual void run() OVERRIDE |
| 97 { |
| 98 Platform::current()->unitTestSupport()->serveAsynchronousMockedRequests(
); |
| 99 if (m_client->isLoading()) |
| 100 Platform::current()->currentThread()->postTask(new ServeAsyncRequest
sTask(m_client)); |
| 101 else |
| 102 Platform::current()->currentThread()->exitRunLoop(); |
| 103 } |
| 104 |
| 105 private: |
| 106 TestWebFrameClient* const m_client; |
| 107 }; |
| 108 |
| 109 void pumpPendingRequests(WebFrame* frame) |
| 110 { |
| 111 Platform::current()->currentThread()->postTask(new ServeAsyncRequestsTask(te
stClientForFrame(frame))); |
| 112 Platform::current()->currentThread()->enterRunLoop(); |
| 113 } |
| 114 |
| 115 class LoadTask : public WebThread::Task { |
| 116 public: |
| 117 LoadTask(WebFrame* frame, const WebURLRequest& request) |
| 118 : m_frame(frame) |
| 119 , m_request(request) |
| 120 { |
| 121 } |
| 122 |
| 123 virtual void run() OVERRIDE |
| 124 { |
| 125 m_frame->loadRequest(m_request); |
| 126 } |
| 127 |
| 128 private: |
| 129 WebFrame* const m_frame; |
| 130 const WebURLRequest m_request; |
| 131 }; |
| 132 |
| 133 class LoadHTMLStringTask : public WebThread::Task { |
| 134 public: |
| 135 LoadHTMLStringTask(WebFrame* frame, const std::string& html, const WebURL& b
aseURL) |
| 136 : m_frame(frame) |
| 137 , m_html(html) |
| 138 , m_baseURL(baseURL) |
| 139 { |
| 140 } |
| 141 |
| 142 virtual void run() OVERRIDE |
| 143 { |
| 144 m_frame->loadHTMLString(WebData(m_html.data(), m_html.size()), m_baseURL
); |
| 145 } |
| 146 |
| 147 private: |
| 148 WebFrame* const m_frame; |
| 149 const std::string m_html; |
| 150 const WebURL m_baseURL; |
| 151 }; |
| 152 |
| 153 class LoadHistoryItemTask : public WebThread::Task { |
| 154 public: |
| 155 LoadHistoryItemTask(WebFrame* frame, const WebHistoryItem& item, WebHistoryL
oadType loadType, WebURLRequest::CachePolicy cachePolicy) |
| 156 : m_frame(frame) |
| 157 , m_item(item) |
| 158 , m_loadType(loadType) |
| 159 , m_cachePolicy(cachePolicy) |
| 160 { |
| 161 } |
| 162 |
| 163 virtual void run() OVERRIDE |
| 164 { |
| 165 m_frame->loadHistoryItem(m_item, m_loadType, m_cachePolicy); |
| 166 } |
| 167 |
| 168 private: |
| 169 WebFrame* const m_frame; |
| 170 const WebHistoryItem m_item; |
| 171 const WebHistoryLoadType m_loadType; |
| 172 const WebURLRequest::CachePolicy m_cachePolicy; |
| 173 }; |
| 174 |
| 175 class ReloadTask : public WebThread::Task { |
| 176 public: |
| 177 ReloadTask(WebFrame* frame, bool ignoreCache) |
| 178 : m_frame(frame) |
| 179 , m_ignoreCache(ignoreCache) |
| 180 { |
| 181 } |
| 182 |
| 183 virtual void run() OVERRIDE |
| 184 { |
| 185 m_frame->reload(m_ignoreCache); |
| 186 } |
| 187 |
| 188 private: |
| 189 WebFrame* const m_frame; |
| 190 const bool m_ignoreCache; |
| 191 }; |
| 192 |
| 193 TestWebFrameClient* defaultWebFrameClient() |
69 { | 194 { |
70 DEFINE_STATIC_LOCAL(TestWebFrameClient, client, ()); | 195 DEFINE_STATIC_LOCAL(TestWebFrameClient, client, ()); |
71 return &client; | 196 return &client; |
72 } | 197 } |
73 | 198 |
74 WebViewClient* defaultWebViewClient() | 199 WebViewClient* defaultWebViewClient() |
75 { | 200 { |
76 DEFINE_STATIC_LOCAL(TestWebViewClient, client, ()); | 201 DEFINE_STATIC_LOCAL(TestWebViewClient, client, ()); |
77 return &client; | 202 return &client; |
78 } | 203 } |
79 | 204 |
80 } // namespace | 205 } // namespace |
81 | 206 |
82 void loadFrame(WebFrame* frame, const std::string& url) | 207 void loadFrame(WebFrame* frame, const std::string& url) |
83 { | 208 { |
84 WebURLRequest urlRequest; | 209 WebURLRequest urlRequest; |
85 urlRequest.initialize(); | 210 urlRequest.initialize(); |
86 urlRequest.setURL(URLTestHelpers::toKURL(url)); | 211 urlRequest.setURL(URLTestHelpers::toKURL(url)); |
87 frame->loadRequest(urlRequest); | 212 |
| 213 Platform::current()->currentThread()->postTask(new LoadTask(frame, urlReques
t)); |
| 214 pumpPendingRequests(frame); |
88 } | 215 } |
89 | 216 |
| 217 void loadHTMLString(WebFrame* frame, const std::string& html, const WebURL& base
URL) |
| 218 { |
| 219 Platform::current()->currentThread()->postTask(new LoadHTMLStringTask(frame,
html, baseURL)); |
| 220 pumpPendingRequests(frame); |
| 221 } |
| 222 |
| 223 void loadHistoryItem(WebFrame* frame, const WebHistoryItem& item, WebHistoryLoad
Type loadType, WebURLRequest::CachePolicy cachePolicy) |
| 224 { |
| 225 Platform::current()->currentThread()->postTask(new LoadHistoryItemTask(frame
, item, loadType, cachePolicy)); |
| 226 pumpPendingRequests(frame); |
| 227 } |
| 228 |
| 229 void reloadFrame(WebFrame* frame) |
| 230 { |
| 231 Platform::current()->currentThread()->postTask(new ReloadTask(frame, false))
; |
| 232 pumpPendingRequests(frame); |
| 233 } |
| 234 |
| 235 void reloadFrameIgnoringCache(WebFrame* frame) |
| 236 { |
| 237 Platform::current()->currentThread()->postTask(new ReloadTask(frame, true)); |
| 238 pumpPendingRequests(frame); |
| 239 } |
| 240 |
| 241 void pumpPendingRequestsDoNotUse(WebFrame* frame) |
| 242 { |
| 243 pumpPendingRequests(frame); |
| 244 } |
| 245 |
| 246 // FIXME: There's a duplicate implementation in UnitTestHelpers.cpp. Remove one. |
90 void runPendingTasks() | 247 void runPendingTasks() |
91 { | 248 { |
92 // Pending tasks include Timers that have been scheduled. | 249 // Pending tasks include Timers that have been scheduled. |
93 WebCore::Timer<QuitTask> quitOnTimeout(new QuitTask, &QuitTask::PostThis); | 250 WebCore::Timer<QuitTask> quitOnTimeout(new QuitTask, &QuitTask::PostThis); |
94 quitOnTimeout.startOneShot(0, FROM_HERE); | 251 quitOnTimeout.startOneShot(0, FROM_HERE); |
95 Platform::current()->currentThread()->enterRunLoop(); | 252 Platform::current()->currentThread()->enterRunLoop(); |
96 } | 253 } |
97 | 254 |
98 WebViewHelper::WebViewHelper() | 255 WebViewHelper::WebViewHelper() |
99 : m_webView(0) | 256 : m_webView(0) |
100 { | 257 { |
101 } | 258 } |
102 | 259 |
103 WebViewHelper::~WebViewHelper() | 260 WebViewHelper::~WebViewHelper() |
104 { | 261 { |
105 reset(); | 262 reset(); |
106 } | 263 } |
107 | 264 |
108 WebViewImpl* WebViewHelper::initialize(bool enableJavascript, WebFrameClient* we
bFrameClient, WebViewClient* webViewClient, void (*updateSettingsFunc)(WebSettin
gs*)) | 265 WebViewImpl* WebViewHelper::initialize(bool enableJavascript, TestWebFrameClient
* webFrameClient, WebViewClient* webViewClient, void (*updateSettingsFunc)(WebSe
ttings*)) |
109 { | 266 { |
110 reset(); | 267 reset(); |
111 | 268 |
112 if (!webFrameClient) | 269 if (!webFrameClient) |
113 webFrameClient = defaultWebFrameClient(); | 270 webFrameClient = defaultWebFrameClient(); |
114 if (!webViewClient) | 271 if (!webViewClient) |
115 webViewClient = defaultWebViewClient(); | 272 webViewClient = defaultWebViewClient(); |
116 m_webView = WebViewImpl::create(webViewClient); | 273 m_webView = WebViewImpl::create(webViewClient); |
117 m_webView->settings()->setJavaScriptEnabled(enableJavascript); | 274 m_webView->settings()->setJavaScriptEnabled(enableJavascript); |
118 if (updateSettingsFunc) { | 275 if (updateSettingsFunc) { |
119 updateSettingsFunc(m_webView->settings()); | 276 updateSettingsFunc(m_webView->settings()); |
120 } else { | 277 } else { |
121 m_webView->settings()->setDeviceSupportsMouse(false); | 278 m_webView->settings()->setDeviceSupportsMouse(false); |
122 m_webView->settings()->setForceCompositingMode(true); | 279 m_webView->settings()->setForceCompositingMode(true); |
123 } | 280 } |
124 | 281 |
125 m_webView->setMainFrame(WebLocalFrameImpl::create(webFrameClient)); | 282 m_webView->setMainFrame(WebLocalFrameImpl::create(webFrameClient)); |
126 | 283 |
127 return m_webView; | 284 return m_webView; |
128 } | 285 } |
129 | 286 |
130 WebViewImpl* WebViewHelper::initializeAndLoad(const std::string& url, bool enabl
eJavascript, WebFrameClient* webFrameClient, WebViewClient* webViewClient, void
(*updateSettingsFunc)(WebSettings*)) | 287 WebViewImpl* WebViewHelper::initializeAndLoad(const std::string& url, bool enabl
eJavascript, TestWebFrameClient* webFrameClient, WebViewClient* webViewClient, v
oid (*updateSettingsFunc)(WebSettings*)) |
131 { | 288 { |
132 initialize(enableJavascript, webFrameClient, webViewClient, updateSettingsFu
nc); | 289 initialize(enableJavascript, webFrameClient, webViewClient, updateSettingsFu
nc); |
133 | 290 |
134 loadFrame(webView()->mainFrame(), url); | 291 loadFrame(webView()->mainFrame(), url); |
135 Platform::current()->unitTestSupport()->serveAsynchronousMockedRequests(); | |
136 | 292 |
137 return webViewImpl(); | 293 return webViewImpl(); |
138 } | 294 } |
139 | 295 |
140 void WebViewHelper::reset() | 296 void WebViewHelper::reset() |
141 { | 297 { |
142 if (m_webView) { | 298 if (m_webView) { |
| 299 ASSERT(!testClientForFrame(m_webView->mainFrame())->isLoading()); |
143 m_webView->close(); | 300 m_webView->close(); |
144 m_webView = 0; | 301 m_webView = 0; |
145 } | 302 } |
146 } | 303 } |
147 | 304 |
| 305 TestWebFrameClient::TestWebFrameClient() : m_loadsInProgress(0) |
| 306 { |
| 307 } |
| 308 |
148 WebFrame* TestWebFrameClient::createChildFrame(WebLocalFrame* parent, const WebS
tring& frameName) | 309 WebFrame* TestWebFrameClient::createChildFrame(WebLocalFrame* parent, const WebS
tring& frameName) |
149 { | 310 { |
150 WebFrame* frame = WebLocalFrame::create(this); | 311 WebFrame* frame = WebLocalFrame::create(this); |
151 parent->appendChild(frame); | 312 parent->appendChild(frame); |
152 return frame; | 313 return frame; |
153 } | 314 } |
154 | 315 |
155 void TestWebFrameClient::frameDetached(WebFrame* frame) | 316 void TestWebFrameClient::frameDetached(WebFrame* frame) |
156 { | 317 { |
157 if (frame->parent()) | 318 if (frame->parent()) |
158 frame->parent()->removeChild(frame); | 319 frame->parent()->removeChild(frame); |
159 frame->close(); | 320 frame->close(); |
160 } | 321 } |
161 | 322 |
| 323 void TestWebFrameClient::didStartLoading(bool) |
| 324 { |
| 325 ++m_loadsInProgress; |
| 326 } |
| 327 |
| 328 void TestWebFrameClient::didStopLoading() |
| 329 { |
| 330 ASSERT(m_loadsInProgress > 0); |
| 331 --m_loadsInProgress; |
| 332 } |
| 333 |
162 void TestWebViewClient::initializeLayerTreeView() | 334 void TestWebViewClient::initializeLayerTreeView() |
163 { | 335 { |
164 m_layerTreeView = adoptPtr(Platform::current()->unitTestSupport()->createLay
erTreeViewForTesting(WebUnitTestSupport::TestViewTypeUnitTest)); | 336 m_layerTreeView = adoptPtr(Platform::current()->unitTestSupport()->createLay
erTreeViewForTesting(WebUnitTestSupport::TestViewTypeUnitTest)); |
165 ASSERT(m_layerTreeView); | 337 ASSERT(m_layerTreeView); |
166 } | 338 } |
167 | 339 |
168 } // namespace FrameTestHelpers | 340 } // namespace FrameTestHelpers |
169 } // namespace blink | 341 } // namespace blink |
OLD | NEW |