Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / third_party / WebKit / Source / web / tests / FrameTestHelpers.cpp
blob1fd60002fc38ec8950ff7837227b839fdf96c5a1
1 /*
2 * Copyright (C) 2011 Google 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 are
6 * met:
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the
13 * distribution.
14 * * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
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.
31 #include "config.h"
32 #include "web/tests/FrameTestHelpers.h"
34 #include "platform/testing/URLTestHelpers.h"
35 #include "platform/testing/UnitTestHelpers.h"
36 #include "public/platform/Platform.h"
37 #include "public/platform/WebData.h"
38 #include "public/platform/WebString.h"
39 #include "public/platform/WebThread.h"
40 #include "public/platform/WebURLRequest.h"
41 #include "public/platform/WebURLResponse.h"
42 #include "public/platform/WebUnitTestSupport.h"
43 #include "public/web/WebRemoteFrame.h"
44 #include "public/web/WebSettings.h"
45 #include "public/web/WebTreeScopeType.h"
46 #include "public/web/WebViewClient.h"
47 #include "web/WebLocalFrameImpl.h"
48 #include "wtf/StdLibExtras.h"
50 namespace blink {
51 namespace FrameTestHelpers {
53 namespace {
55 // The frame test helpers coordinate frame loads in a carefully choreographed
56 // dance. Since the parser is threaded, simply spinning the run loop once is not
57 // enough to ensure completion of a load. Instead, the following pattern is
58 // used to ensure that tests see the final state:
59 // 1. Post a task to trigger a load (LoadTask/LoadHTMLStringTask/ReloadTask).
60 // 2. Enter the run loop.
61 // 3. Posted task triggers the load, and starts pumping pending resource
62 // requests using ServeAsyncRequestsTask.
63 // 4. TestWebFrameClient watches for didStartLoading/didStopLoading calls,
64 // keeping track of how many loads it thinks are in flight.
65 // 5. While ServeAsyncRequestsTask observes TestWebFrameClient to still have
66 // loads in progress, it posts itself back to the run loop.
67 // 6. When ServeAsyncRequestsTask notices there are no more loads in progress,
68 // it exits the run loop.
69 // 7. At this point, all parsing, resource loads, and layout should be finished.
70 TestWebFrameClient* testClientForFrame(WebFrame* frame)
72 return static_cast<TestWebFrameClient*>(toWebLocalFrameImpl(frame)->client());
75 class ServeAsyncRequestsTask : public WebTaskRunner::Task {
76 public:
77 explicit ServeAsyncRequestsTask(TestWebFrameClient* client)
78 : m_client(client)
82 void run() override
84 Platform::current()->unitTestSupport()->serveAsynchronousMockedRequests();
85 if (m_client->isLoading())
86 Platform::current()->currentThread()->taskRunner()->postTask(FROM_HERE, new ServeAsyncRequestsTask(m_client));
87 else
88 Platform::current()->unitTestSupport()->exitRunLoop();
91 private:
92 TestWebFrameClient* const m_client;
95 void pumpPendingRequests(WebFrame* frame)
97 Platform::current()->currentThread()->taskRunner()->postTask(FROM_HERE, new ServeAsyncRequestsTask(testClientForFrame(frame)));
98 Platform::current()->unitTestSupport()->enterRunLoop();
101 class LoadTask : public WebTaskRunner::Task {
102 public:
103 LoadTask(WebFrame* frame, const WebURLRequest& request)
104 : m_frame(frame)
105 , m_request(request)
109 void run() override
111 m_frame->loadRequest(m_request);
114 private:
115 WebFrame* const m_frame;
116 const WebURLRequest m_request;
119 class LoadHTMLStringTask : public WebTaskRunner::Task {
120 public:
121 LoadHTMLStringTask(WebFrame* frame, const std::string& html, const WebURL& baseURL)
122 : m_frame(frame)
123 , m_html(html)
124 , m_baseURL(baseURL)
128 void run() override
130 m_frame->loadHTMLString(WebData(m_html.data(), m_html.size()), m_baseURL);
133 private:
134 WebFrame* const m_frame;
135 const std::string m_html;
136 const WebURL m_baseURL;
139 class LoadHistoryItemTask : public WebTaskRunner::Task {
140 public:
141 LoadHistoryItemTask(WebFrame* frame, const WebHistoryItem& item, WebHistoryLoadType loadType, WebURLRequest::CachePolicy cachePolicy)
142 : m_frame(frame)
143 , m_item(item)
144 , m_loadType(loadType)
145 , m_cachePolicy(cachePolicy)
149 void run() override
151 m_frame->loadHistoryItem(m_item, m_loadType, m_cachePolicy);
154 private:
155 WebFrame* const m_frame;
156 const WebHistoryItem m_item;
157 const WebHistoryLoadType m_loadType;
158 const WebURLRequest::CachePolicy m_cachePolicy;
161 class ReloadTask : public WebTaskRunner::Task {
162 public:
163 ReloadTask(WebFrame* frame, bool ignoreCache)
164 : m_frame(frame)
165 , m_ignoreCache(ignoreCache)
169 void run() override
171 m_frame->reload(m_ignoreCache);
174 private:
175 WebFrame* const m_frame;
176 const bool m_ignoreCache;
179 TestWebFrameClient* defaultWebFrameClient()
181 DEFINE_STATIC_LOCAL(TestWebFrameClient, client, ());
182 return &client;
185 WebViewClient* defaultWebViewClient()
187 DEFINE_STATIC_LOCAL(TestWebViewClient, client, ());
188 return &client;
191 } // namespace
193 void loadFrame(WebFrame* frame, const std::string& url)
195 WebURLRequest urlRequest;
196 urlRequest.initialize();
197 urlRequest.setURL(URLTestHelpers::toKURL(url));
199 Platform::current()->currentThread()->taskRunner()->postTask(FROM_HERE, new LoadTask(frame, urlRequest));
200 pumpPendingRequests(frame);
203 void loadHTMLString(WebFrame* frame, const std::string& html, const WebURL& baseURL)
205 Platform::current()->currentThread()->taskRunner()->postTask(FROM_HERE, new LoadHTMLStringTask(frame, html, baseURL));
206 pumpPendingRequests(frame);
209 void loadHistoryItem(WebFrame* frame, const WebHistoryItem& item, WebHistoryLoadType loadType, WebURLRequest::CachePolicy cachePolicy)
211 Platform::current()->currentThread()->taskRunner()->postTask(FROM_HERE, new LoadHistoryItemTask(frame, item, loadType, cachePolicy));
212 pumpPendingRequests(frame);
215 void reloadFrame(WebFrame* frame)
217 Platform::current()->currentThread()->taskRunner()->postTask(FROM_HERE, new ReloadTask(frame, false));
218 pumpPendingRequests(frame);
221 void reloadFrameIgnoringCache(WebFrame* frame)
223 Platform::current()->currentThread()->taskRunner()->postTask(FROM_HERE, new ReloadTask(frame, true));
224 pumpPendingRequests(frame);
227 void pumpPendingRequestsDoNotUse(WebFrame* frame)
229 pumpPendingRequests(frame);
232 WebViewHelper::WebViewHelper(SettingOverrider* settingOverrider)
233 : m_webView(0)
234 , m_settingOverrider(settingOverrider)
238 WebViewHelper::~WebViewHelper()
240 reset();
243 WebViewImpl* WebViewHelper::initialize(bool enableJavascript, TestWebFrameClient* webFrameClient, WebViewClient* webViewClient, void (*updateSettingsFunc)(WebSettings*))
245 reset();
247 if (!webFrameClient)
248 webFrameClient = defaultWebFrameClient();
249 if (!webViewClient)
250 webViewClient = defaultWebViewClient();
251 m_webView = WebViewImpl::create(webViewClient);
252 m_webView->settings()->setJavaScriptEnabled(enableJavascript);
253 m_webView->settings()->setPluginsEnabled(true);
254 if (updateSettingsFunc)
255 updateSettingsFunc(m_webView->settings());
256 else
257 m_webView->settings()->setDeviceSupportsMouse(false);
258 if (m_settingOverrider)
259 m_settingOverrider->overrideSettings(m_webView->settings());
261 m_webView->setDefaultPageScaleLimits(1, 4);
262 m_webView->setMainFrame(WebLocalFrameImpl::create(WebTreeScopeType::Document, webFrameClient));
264 return m_webView;
267 WebViewImpl* WebViewHelper::initializeAndLoad(const std::string& url, bool enableJavascript, TestWebFrameClient* webFrameClient, WebViewClient* webViewClient, void (*updateSettingsFunc)(WebSettings*))
269 initialize(enableJavascript, webFrameClient, webViewClient, updateSettingsFunc);
271 loadFrame(webView()->mainFrame(), url);
273 return webViewImpl();
276 void WebViewHelper::reset()
278 if (m_webView) {
279 ASSERT(m_webView->mainFrame()->isWebRemoteFrame() || !testClientForFrame(m_webView->mainFrame())->isLoading());
280 m_webView->close();
281 m_webView = 0;
285 TestWebFrameClient::TestWebFrameClient() : m_loadsInProgress(0)
289 WebFrame* TestWebFrameClient::createChildFrame(WebLocalFrame* parent, WebTreeScopeType scope, const WebString& frameName, WebSandboxFlags sandboxFlags)
291 WebFrame* frame = WebLocalFrame::create(scope, this);
292 parent->appendChild(frame);
293 return frame;
296 void TestWebFrameClient::frameDetached(WebFrame* frame, DetachType type)
298 if (type == DetachType::Remove && frame->parent())
299 frame->parent()->removeChild(frame);
300 frame->close();
303 void TestWebFrameClient::didStartLoading(bool)
305 ++m_loadsInProgress;
308 void TestWebFrameClient::didStopLoading()
310 ASSERT(m_loadsInProgress > 0);
311 --m_loadsInProgress;
314 void TestWebFrameClient::waitForLoadToComplete()
316 for (;;) {
317 // We call runPendingTasks multiple times as single call of
318 // runPendingTasks may not be enough.
319 // runPendingTasks only ensures that main thread task queue is empty,
320 // and asynchronous parsing make use of off main thread HTML parser.
321 testing::runPendingTasks();
322 if (!isLoading())
323 break;
325 Platform::current()->yieldCurrentThread();
329 TestWebRemoteFrameClient::TestWebRemoteFrameClient()
330 : m_frame(WebRemoteFrame::create(WebTreeScopeType::Document, this))
334 void TestWebRemoteFrameClient::frameDetached(DetachType type)
336 if (type == DetachType::Remove && m_frame->parent())
337 m_frame->parent()->removeChild(m_frame);
338 m_frame->close();
341 void TestWebViewClient::initializeLayerTreeView()
343 m_layerTreeView = adoptPtr(Platform::current()->unitTestSupport()->createLayerTreeViewForTesting());
344 ASSERT(m_layerTreeView);
347 } // namespace FrameTestHelpers
348 } // namespace blink