Convert raw pointers to scoped_ptr in net module.
[chromium-blink-merge.git] / content / shell / renderer / layout_test / blink_test_runner.cc
bloba69c2fff5bf3290e0601b357b3ffc56f378d3a63
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "content/shell/renderer/layout_test/blink_test_runner.h"
7 #include <algorithm>
8 #include <clocale>
9 #include <cmath>
11 #include "base/base64.h"
12 #include "base/command_line.h"
13 #include "base/compiler_specific.h"
14 #include "base/debug/debugger.h"
15 #include "base/files/file_path.h"
16 #include "base/md5.h"
17 #include "base/memory/scoped_ptr.h"
18 #include "base/message_loop/message_loop.h"
19 #include "base/strings/string_util.h"
20 #include "base/strings/stringprintf.h"
21 #include "base/strings/sys_string_conversions.h"
22 #include "base/strings/utf_string_conversions.h"
23 #include "base/time/time.h"
24 #include "content/public/common/content_switches.h"
25 #include "content/public/common/url_constants.h"
26 #include "content/public/common/web_preferences.h"
27 #include "content/public/renderer/render_frame.h"
28 #include "content/public/renderer/render_view.h"
29 #include "content/public/renderer/render_view_visitor.h"
30 #include "content/public/renderer/renderer_gamepad_provider.h"
31 #include "content/public/test/layouttest_support.h"
32 #include "content/shell/common/layout_test/layout_test_messages.h"
33 #include "content/shell/common/shell_messages.h"
34 #include "content/shell/common/shell_switches.h"
35 #include "content/shell/renderer/layout_test/blink_test_helpers.h"
36 #include "content/shell/renderer/layout_test/gc_controller.h"
37 #include "content/shell/renderer/layout_test/layout_test_render_process_observer.h"
38 #include "content/shell/renderer/layout_test/leak_detector.h"
39 #include "content/shell/renderer/test_runner/app_banner_client.h"
40 #include "content/shell/renderer/test_runner/gamepad_controller.h"
41 #include "content/shell/renderer/test_runner/mock_screen_orientation_client.h"
42 #include "content/shell/renderer/test_runner/test_interfaces.h"
43 #include "content/shell/renderer/test_runner/web_task.h"
44 #include "content/shell/renderer/test_runner/web_test_interfaces.h"
45 #include "content/shell/renderer/test_runner/web_test_proxy.h"
46 #include "content/shell/renderer/test_runner/web_test_runner.h"
47 #include "net/base/filename_util.h"
48 #include "net/base/net_errors.h"
49 #include "skia/ext/platform_canvas.h"
50 #include "third_party/WebKit/public/platform/Platform.h"
51 #include "third_party/WebKit/public/platform/WebCString.h"
52 #include "third_party/WebKit/public/platform/WebPoint.h"
53 #include "third_party/WebKit/public/platform/WebRect.h"
54 #include "third_party/WebKit/public/platform/WebSize.h"
55 #include "third_party/WebKit/public/platform/WebString.h"
56 #include "third_party/WebKit/public/platform/WebThread.h"
57 #include "third_party/WebKit/public/platform/WebTraceLocation.h"
58 #include "third_party/WebKit/public/platform/WebURL.h"
59 #include "third_party/WebKit/public/platform/WebURLError.h"
60 #include "third_party/WebKit/public/platform/WebURLRequest.h"
61 #include "third_party/WebKit/public/platform/WebURLResponse.h"
62 #include "third_party/WebKit/public/platform/modules/app_banner/WebAppBannerPromptReply.h"
63 #include "third_party/WebKit/public/web/WebArrayBufferView.h"
64 #include "third_party/WebKit/public/web/WebContextMenuData.h"
65 #include "third_party/WebKit/public/web/WebDataSource.h"
66 #include "third_party/WebKit/public/web/WebDevToolsAgent.h"
67 #include "third_party/WebKit/public/web/WebDocument.h"
68 #include "third_party/WebKit/public/web/WebElement.h"
69 #include "third_party/WebKit/public/web/WebHistoryItem.h"
70 #include "third_party/WebKit/public/web/WebKit.h"
71 #include "third_party/WebKit/public/web/WebLeakDetector.h"
72 #include "third_party/WebKit/public/web/WebLocalFrame.h"
73 #include "third_party/WebKit/public/web/WebScriptSource.h"
74 #include "third_party/WebKit/public/web/WebTestingSupport.h"
75 #include "third_party/WebKit/public/web/WebView.h"
76 #include "ui/gfx/geometry/rect.h"
78 using blink::Platform;
79 using blink::WebArrayBufferView;
80 using blink::WebContextMenuData;
81 using blink::WebDevToolsAgent;
82 using blink::WebDeviceMotionData;
83 using blink::WebDeviceOrientationData;
84 using blink::WebElement;
85 using blink::WebLocalFrame;
86 using blink::WebHistoryItem;
87 using blink::WebLocalFrame;
88 using blink::WebPoint;
89 using blink::WebRect;
90 using blink::WebScriptSource;
91 using blink::WebSize;
92 using blink::WebString;
93 using blink::WebURL;
94 using blink::WebURLError;
95 using blink::WebURLRequest;
96 using blink::WebScreenOrientationType;
97 using blink::WebTestingSupport;
98 using blink::WebTraceLocation;
99 using blink::WebThread;
100 using blink::WebVector;
101 using blink::WebView;
103 namespace content {
105 namespace {
107 class InvokeTaskHelper : public WebThread::Task {
108 public:
109 InvokeTaskHelper(scoped_ptr<WebTask> task) : task_(task.Pass()) {}
111 // WebThread::Task implementation:
112 void run() override { task_->run(); }
114 private:
115 scoped_ptr<WebTask> task_;
118 class SyncNavigationStateVisitor : public RenderViewVisitor {
119 public:
120 SyncNavigationStateVisitor() {}
121 ~SyncNavigationStateVisitor() override {}
123 bool Visit(RenderView* render_view) override {
124 SyncNavigationState(render_view);
125 return true;
127 private:
128 DISALLOW_COPY_AND_ASSIGN(SyncNavigationStateVisitor);
131 class ProxyToRenderViewVisitor : public RenderViewVisitor {
132 public:
133 explicit ProxyToRenderViewVisitor(WebTestProxyBase* proxy)
134 : proxy_(proxy),
135 render_view_(NULL) {
137 ~ProxyToRenderViewVisitor() override {}
139 RenderView* render_view() const { return render_view_; }
141 bool Visit(RenderView* render_view) override {
142 BlinkTestRunner* test_runner = BlinkTestRunner::Get(render_view);
143 if (!test_runner) {
144 NOTREACHED();
145 return true;
147 if (test_runner->proxy() == proxy_) {
148 render_view_ = render_view;
149 return false;
151 return true;
154 private:
155 WebTestProxyBase* proxy_;
156 RenderView* render_view_;
158 DISALLOW_COPY_AND_ASSIGN(ProxyToRenderViewVisitor);
161 class NavigateAwayVisitor : public RenderViewVisitor {
162 public:
163 explicit NavigateAwayVisitor(RenderView* main_render_view)
164 : main_render_view_(main_render_view) {}
165 ~NavigateAwayVisitor() override {}
167 bool Visit(RenderView* render_view) override {
168 if (render_view == main_render_view_)
169 return true;
170 render_view->GetWebView()->mainFrame()->loadRequest(
171 WebURLRequest(GURL(url::kAboutBlankURL)));
172 return true;
175 private:
176 RenderView* main_render_view_;
178 DISALLOW_COPY_AND_ASSIGN(NavigateAwayVisitor);
181 class UseSynchronousResizeModeVisitor : public RenderViewVisitor {
182 public:
183 explicit UseSynchronousResizeModeVisitor(bool enable) : enable_(enable) {}
184 ~UseSynchronousResizeModeVisitor() override {}
186 bool Visit(RenderView* render_view) override {
187 UseSynchronousResizeMode(render_view, enable_);
188 return true;
191 private:
192 bool enable_;
195 class MockGamepadProvider : public RendererGamepadProvider {
196 public:
197 explicit MockGamepadProvider(GamepadController* controller)
198 : RendererGamepadProvider(nullptr), controller_(controller) {}
199 ~MockGamepadProvider() override {
200 StopIfObserving();
203 // RendererGamepadProvider implementation.
204 void SampleGamepads(blink::WebGamepads& gamepads) override {
205 controller_->SampleGamepads(gamepads);
207 void Start(blink::WebPlatformEventListener* listener) override {
208 controller_->SetListener(static_cast<blink::WebGamepadListener*>(listener));
209 RendererGamepadProvider::Start(listener);
211 void SendStartMessage() override {}
212 void SendStopMessage() override {}
214 private:
215 scoped_ptr<GamepadController> controller_;
217 DISALLOW_COPY_AND_ASSIGN(MockGamepadProvider);
220 } // namespace
222 BlinkTestRunner::BlinkTestRunner(RenderView* render_view)
223 : RenderViewObserver(render_view),
224 RenderViewObserverTracker<BlinkTestRunner>(render_view),
225 proxy_(NULL),
226 focused_view_(NULL),
227 is_main_window_(false),
228 focus_on_next_commit_(false),
229 leak_detector_(new LeakDetector(this)) {
232 BlinkTestRunner::~BlinkTestRunner() {
235 // WebTestDelegate -----------------------------------------------------------
237 void BlinkTestRunner::ClearEditCommand() {
238 render_view()->ClearEditCommands();
241 void BlinkTestRunner::SetEditCommand(const std::string& name,
242 const std::string& value) {
243 render_view()->SetEditCommandForNextKeyEvent(name, value);
246 void BlinkTestRunner::SetGamepadProvider(
247 GamepadController* controller) {
248 scoped_ptr<MockGamepadProvider> provider(new MockGamepadProvider(controller));
249 SetMockGamepadProvider(provider.Pass());
252 void BlinkTestRunner::SetDeviceLightData(const double data) {
253 SetMockDeviceLightData(data);
256 void BlinkTestRunner::SetDeviceMotionData(const WebDeviceMotionData& data) {
257 SetMockDeviceMotionData(data);
260 void BlinkTestRunner::SetDeviceOrientationData(
261 const WebDeviceOrientationData& data) {
262 SetMockDeviceOrientationData(data);
265 void BlinkTestRunner::SetScreenOrientation(
266 const WebScreenOrientationType& orientation) {
267 MockScreenOrientationClient* mock_client =
268 proxy()->GetScreenOrientationClientMock();
269 mock_client->UpdateDeviceOrientation(
270 render_view()->GetWebView()->mainFrame()->toWebLocalFrame(), orientation);
273 void BlinkTestRunner::ResetScreenOrientation() {
274 MockScreenOrientationClient* mock_client =
275 proxy()->GetScreenOrientationClientMock();
276 mock_client->ResetData();
279 void BlinkTestRunner::DidChangeBatteryStatus(
280 const blink::WebBatteryStatus& status) {
281 MockBatteryStatusChanged(status);
284 void BlinkTestRunner::PrintMessage(const std::string& message) {
285 Send(new ShellViewHostMsg_PrintMessage(routing_id(), message));
288 void BlinkTestRunner::PostTask(WebTask* task) {
289 Platform::current()->currentThread()->postTask(
290 WebTraceLocation(__FUNCTION__, __FILE__),
291 new InvokeTaskHelper(make_scoped_ptr(task)));
294 void BlinkTestRunner::PostDelayedTask(WebTask* task, long long ms) {
295 Platform::current()->currentThread()->postDelayedTask(
296 WebTraceLocation(__FUNCTION__, __FILE__),
297 new InvokeTaskHelper(make_scoped_ptr(task)), ms);
300 WebString BlinkTestRunner::RegisterIsolatedFileSystem(
301 const blink::WebVector<blink::WebString>& absolute_filenames) {
302 std::vector<base::FilePath> files;
303 for (size_t i = 0; i < absolute_filenames.size(); ++i)
304 files.push_back(base::FilePath::FromUTF16Unsafe(absolute_filenames[i]));
305 std::string filesystem_id;
306 Send(new LayoutTestHostMsg_RegisterIsolatedFileSystem(
307 routing_id(), files, &filesystem_id));
308 return WebString::fromUTF8(filesystem_id);
311 long long BlinkTestRunner::GetCurrentTimeInMillisecond() {
312 return base::TimeDelta(base::Time::Now() -
313 base::Time::UnixEpoch()).ToInternalValue() /
314 base::Time::kMicrosecondsPerMillisecond;
317 WebString BlinkTestRunner::GetAbsoluteWebStringFromUTF8Path(
318 const std::string& utf8_path) {
319 base::FilePath path = base::FilePath::FromUTF8Unsafe(utf8_path);
320 if (!path.IsAbsolute()) {
321 GURL base_url =
322 net::FilePathToFileURL(test_config_.current_working_directory.Append(
323 FILE_PATH_LITERAL("foo")));
324 net::FileURLToFilePath(base_url.Resolve(utf8_path), &path);
326 return path.AsUTF16Unsafe();
329 WebURL BlinkTestRunner::LocalFileToDataURL(const WebURL& file_url) {
330 base::FilePath local_path;
331 if (!net::FileURLToFilePath(file_url, &local_path))
332 return WebURL();
334 std::string contents;
335 Send(new LayoutTestHostMsg_ReadFileToString(
336 routing_id(), local_path, &contents));
338 std::string contents_base64;
339 base::Base64Encode(contents, &contents_base64);
341 const char data_url_prefix[] = "data:text/css:charset=utf-8;base64,";
342 return WebURL(GURL(data_url_prefix + contents_base64));
345 WebURL BlinkTestRunner::RewriteLayoutTestsURL(const std::string& utf8_url) {
346 const char kPrefix[] = "file:///tmp/LayoutTests/";
347 const int kPrefixLen = arraysize(kPrefix) - 1;
349 if (utf8_url.compare(0, kPrefixLen, kPrefix, kPrefixLen))
350 return WebURL(GURL(utf8_url));
352 base::FilePath replace_path =
353 LayoutTestRenderProcessObserver::GetInstance()->webkit_source_dir()
354 .Append(FILE_PATH_LITERAL("LayoutTests/"));
355 #if defined(OS_WIN)
356 std::string utf8_path = base::WideToUTF8(replace_path.value());
357 #else
358 std::string utf8_path =
359 base::WideToUTF8(base::SysNativeMBToWide(replace_path.value()));
360 #endif
361 std::string new_url =
362 std::string("file://") + utf8_path + utf8_url.substr(kPrefixLen);
363 return WebURL(GURL(new_url));
366 TestPreferences* BlinkTestRunner::Preferences() {
367 return &prefs_;
370 void BlinkTestRunner::ApplyPreferences() {
371 WebPreferences prefs = render_view()->GetWebkitPreferences();
372 ExportLayoutTestSpecificPreferences(prefs_, &prefs);
373 render_view()->SetWebkitPreferences(prefs);
374 Send(new ShellViewHostMsg_OverridePreferences(routing_id(), prefs));
377 std::string BlinkTestRunner::makeURLErrorDescription(const WebURLError& error) {
378 std::string domain = error.domain.utf8();
379 int code = error.reason;
381 if (domain == net::kErrorDomain) {
382 domain = "NSURLErrorDomain";
383 switch (error.reason) {
384 case net::ERR_ABORTED:
385 code = -999; // NSURLErrorCancelled
386 break;
387 case net::ERR_UNSAFE_PORT:
388 // Our unsafe port checking happens at the network stack level, but we
389 // make this translation here to match the behavior of stock WebKit.
390 domain = "WebKitErrorDomain";
391 code = 103;
392 break;
393 case net::ERR_ADDRESS_INVALID:
394 case net::ERR_ADDRESS_UNREACHABLE:
395 case net::ERR_NETWORK_ACCESS_DENIED:
396 code = -1004; // NSURLErrorCannotConnectToHost
397 break;
399 } else {
400 DLOG(WARNING) << "Unknown error domain";
403 return base::StringPrintf("<NSError domain %s, code %d, failing URL \"%s\">",
404 domain.c_str(), code, error.unreachableURL.spec().data());
407 void BlinkTestRunner::UseUnfortunateSynchronousResizeMode(bool enable) {
408 UseSynchronousResizeModeVisitor visitor(enable);
409 RenderView::ForEach(&visitor);
412 void BlinkTestRunner::EnableAutoResizeMode(const WebSize& min_size,
413 const WebSize& max_size) {
414 content::EnableAutoResizeMode(render_view(), min_size, max_size);
417 void BlinkTestRunner::DisableAutoResizeMode(const WebSize& new_size) {
418 content::DisableAutoResizeMode(render_view(), new_size);
419 if (!new_size.isEmpty())
420 ForceResizeRenderView(render_view(), new_size);
423 void BlinkTestRunner::ClearDevToolsLocalStorage() {
424 Send(new ShellViewHostMsg_ClearDevToolsLocalStorage(routing_id()));
427 void BlinkTestRunner::ShowDevTools(const std::string& settings,
428 const std::string& frontend_url) {
429 Send(new ShellViewHostMsg_ShowDevTools(
430 routing_id(), settings, frontend_url));
433 void BlinkTestRunner::CloseDevTools() {
434 Send(new ShellViewHostMsg_CloseDevTools(routing_id()));
435 WebDevToolsAgent* agent =
436 render_view()->GetMainRenderFrame()->GetWebFrame()->devToolsAgent();
437 if (agent)
438 agent->detach();
441 void BlinkTestRunner::EvaluateInWebInspector(long call_id,
442 const std::string& script) {
443 WebDevToolsAgent* agent =
444 render_view()->GetMainRenderFrame()->GetWebFrame()->devToolsAgent();
445 if (agent)
446 agent->evaluateInWebInspector(call_id, WebString::fromUTF8(script));
449 void BlinkTestRunner::ClearAllDatabases() {
450 Send(new LayoutTestHostMsg_ClearAllDatabases(routing_id()));
453 void BlinkTestRunner::SetDatabaseQuota(int quota) {
454 Send(new LayoutTestHostMsg_SetDatabaseQuota(routing_id(), quota));
457 void BlinkTestRunner::SimulateWebNotificationClick(const std::string& title) {
458 Send(new LayoutTestHostMsg_SimulateWebNotificationClick(routing_id(), title));
461 void BlinkTestRunner::SetDeviceScaleFactor(float factor) {
462 content::SetDeviceScaleFactor(render_view(), factor);
465 void BlinkTestRunner::SetDeviceColorProfile(const std::string& name) {
466 content::SetDeviceColorProfile(render_view(), name);
469 void BlinkTestRunner::SetBluetoothMockDataSet(const std::string& name) {
470 Send(new LayoutTestHostMsg_SetBluetoothAdapter(name));
473 void BlinkTestRunner::SetGeofencingMockProvider(bool service_available) {
474 content::SetGeofencingMockProvider(service_available);
477 void BlinkTestRunner::ClearGeofencingMockProvider() {
478 content::ClearGeofencingMockProvider();
481 void BlinkTestRunner::SetGeofencingMockPosition(double latitude,
482 double longitude) {
483 content::SetGeofencingMockPosition(latitude, longitude);
486 void BlinkTestRunner::SetFocus(WebTestProxyBase* proxy, bool focus) {
487 ProxyToRenderViewVisitor visitor(proxy);
488 RenderView::ForEach(&visitor);
489 if (!visitor.render_view()) {
490 NOTREACHED();
491 return;
494 // Check whether the focused view was closed meanwhile.
495 if (!BlinkTestRunner::Get(focused_view_))
496 focused_view_ = NULL;
498 if (focus) {
499 if (focused_view_ != visitor.render_view()) {
500 if (focused_view_)
501 SetFocusAndActivate(focused_view_, false);
502 SetFocusAndActivate(visitor.render_view(), true);
503 focused_view_ = visitor.render_view();
505 } else {
506 if (focused_view_ == visitor.render_view()) {
507 SetFocusAndActivate(visitor.render_view(), false);
508 focused_view_ = NULL;
513 void BlinkTestRunner::SetAcceptAllCookies(bool accept) {
514 Send(new LayoutTestHostMsg_AcceptAllCookies(routing_id(), accept));
517 std::string BlinkTestRunner::PathToLocalResource(const std::string& resource) {
518 #if defined(OS_WIN)
519 if (resource.find("/tmp/") == 0) {
520 // We want a temp file.
521 GURL base_url = net::FilePathToFileURL(test_config_.temp_path);
522 return base_url.Resolve(resource.substr(strlen("/tmp/"))).spec();
524 #endif
526 // Some layout tests use file://// which we resolve as a UNC path. Normalize
527 // them to just file:///.
528 std::string result = resource;
529 while (base::StringToLowerASCII(result).find("file:////") == 0) {
530 result = result.substr(0, strlen("file:///")) +
531 result.substr(strlen("file:////"));
533 return RewriteLayoutTestsURL(result).spec();
536 void BlinkTestRunner::SetLocale(const std::string& locale) {
537 setlocale(LC_ALL, locale.c_str());
540 void BlinkTestRunner::TestFinished() {
541 if (!is_main_window_) {
542 Send(new ShellViewHostMsg_TestFinishedInSecondaryWindow(routing_id()));
543 return;
545 WebTestInterfaces* interfaces =
546 LayoutTestRenderProcessObserver::GetInstance()->test_interfaces();
547 interfaces->SetTestIsRunning(false);
548 if (interfaces->TestRunner()->ShouldDumpBackForwardList()) {
549 SyncNavigationStateVisitor visitor;
550 RenderView::ForEach(&visitor);
551 Send(new ShellViewHostMsg_CaptureSessionHistory(routing_id()));
552 } else {
553 CaptureDump();
557 void BlinkTestRunner::CloseRemainingWindows() {
558 NavigateAwayVisitor visitor(render_view());
559 RenderView::ForEach(&visitor);
560 Send(new ShellViewHostMsg_CloseRemainingWindows(routing_id()));
563 void BlinkTestRunner::DeleteAllCookies() {
564 Send(new LayoutTestHostMsg_DeleteAllCookies(routing_id()));
567 int BlinkTestRunner::NavigationEntryCount() {
568 return GetLocalSessionHistoryLength(render_view());
571 void BlinkTestRunner::GoToOffset(int offset) {
572 Send(new ShellViewHostMsg_GoToOffset(routing_id(), offset));
575 void BlinkTestRunner::Reload() {
576 Send(new ShellViewHostMsg_Reload(routing_id()));
579 void BlinkTestRunner::LoadURLForFrame(const WebURL& url,
580 const std::string& frame_name) {
581 Send(new ShellViewHostMsg_LoadURLForFrame(
582 routing_id(), url, frame_name));
585 bool BlinkTestRunner::AllowExternalPages() {
586 return test_config_.allow_external_pages;
589 std::string BlinkTestRunner::DumpHistoryForWindow(WebTestProxyBase* proxy) {
590 size_t pos = 0;
591 std::vector<int>::iterator id;
592 for (id = routing_ids_.begin(); id != routing_ids_.end(); ++id, ++pos) {
593 RenderView* render_view = RenderView::FromRoutingID(*id);
594 if (!render_view) {
595 NOTREACHED();
596 continue;
598 if (BlinkTestRunner::Get(render_view)->proxy() == proxy)
599 break;
602 if (id == routing_ids_.end()) {
603 NOTREACHED();
604 return std::string();
606 return DumpBackForwardList(session_histories_[pos],
607 current_entry_indexes_[pos]);
610 void BlinkTestRunner::FetchManifest(
611 blink::WebView* view,
612 const GURL& url,
613 const base::Callback<void(const blink::WebURLResponse& response,
614 const std::string& data)>& callback) {
615 ::content::FetchManifest(view, url, callback);
618 void BlinkTestRunner::SetPermission(const std::string& name,
619 const std::string& value,
620 const GURL& origin,
621 const GURL& embedding_origin) {
622 content::PermissionStatus status;
623 if (value == "granted")
624 status = PERMISSION_STATUS_GRANTED;
625 else if (value == "prompt")
626 status = PERMISSION_STATUS_ASK;
627 else if (value == "denied")
628 status = PERMISSION_STATUS_DENIED;
629 else {
630 NOTREACHED();
631 status = PERMISSION_STATUS_DENIED;
634 Send(new LayoutTestHostMsg_SetPermission(
635 routing_id(), name, status, origin, embedding_origin));
638 void BlinkTestRunner::ResetPermissions() {
639 Send(new LayoutTestHostMsg_ResetPermissions(routing_id()));
642 scoped_refptr<cc::TextureLayer> BlinkTestRunner::CreateTextureLayerForMailbox(
643 cc::TextureLayerClient* client) {
644 return ::content::CreateTextureLayerForMailbox(client);
647 blink::WebLayer* BlinkTestRunner::InstantiateWebLayer(
648 scoped_refptr<cc::TextureLayer> layer) {
649 return ::content::InstantiateWebLayer(layer);
652 cc::SharedBitmapManager* BlinkTestRunner::GetSharedBitmapManager() {
653 return RenderThread::Get()->GetSharedBitmapManager();
656 void BlinkTestRunner::DispatchBeforeInstallPromptEvent(
657 int request_id,
658 const std::vector<std::string>& event_platforms,
659 const base::Callback<void(bool)>& callback) {
660 // Send the event to the frame.
661 blink::WebAppBannerPromptReply reply;
662 std::vector<blink::WebString> blink_web_strings;
663 for (const auto& platform : event_platforms)
664 blink_web_strings.push_back(blink::WebString::fromUTF8(platform));
665 blink::WebVector<blink::WebString> blink_event_platforms(blink_web_strings);
667 WebLocalFrame* main_frame =
668 render_view()->GetWebView()->mainFrame()->toWebLocalFrame();
669 main_frame->willShowInstallBannerPrompt(request_id, blink_event_platforms,
670 &reply);
672 callback.Run(reply == blink::WebAppBannerPromptReply::Cancel);
675 void BlinkTestRunner::ResolveBeforeInstallPromptPromise(
676 int request_id, const std::string& platform) {
677 WebTestInterfaces* interfaces =
678 LayoutTestRenderProcessObserver::GetInstance()->test_interfaces();
679 interfaces->GetTestInterfaces()->GetAppBannerClient()->ResolvePromise(
680 request_id, platform);
683 // RenderViewObserver --------------------------------------------------------
685 void BlinkTestRunner::DidClearWindowObject(WebLocalFrame* frame) {
686 WebTestingSupport::injectInternalsObject(frame);
687 LayoutTestRenderProcessObserver::GetInstance()->test_interfaces()->BindTo(
688 frame);
689 GCController::Install(frame);
692 bool BlinkTestRunner::OnMessageReceived(const IPC::Message& message) {
693 bool handled = true;
694 IPC_BEGIN_MESSAGE_MAP(BlinkTestRunner, message)
695 IPC_MESSAGE_HANDLER(ShellViewMsg_SetTestConfiguration,
696 OnSetTestConfiguration)
697 IPC_MESSAGE_HANDLER(ShellViewMsg_SessionHistory, OnSessionHistory)
698 IPC_MESSAGE_HANDLER(ShellViewMsg_Reset, OnReset)
699 IPC_MESSAGE_HANDLER(ShellViewMsg_NotifyDone, OnNotifyDone)
700 IPC_MESSAGE_HANDLER(ShellViewMsg_TryLeakDetection, OnTryLeakDetection)
701 IPC_MESSAGE_UNHANDLED(handled = false)
702 IPC_END_MESSAGE_MAP()
704 return handled;
707 void BlinkTestRunner::Navigate(const GURL& url) {
708 focus_on_next_commit_ = true;
709 if (!is_main_window_ &&
710 LayoutTestRenderProcessObserver::GetInstance()->main_test_runner() ==
711 this) {
712 WebTestInterfaces* interfaces =
713 LayoutTestRenderProcessObserver::GetInstance()->test_interfaces();
714 interfaces->SetTestIsRunning(true);
715 interfaces->ConfigureForTestWithURL(GURL(), false);
716 ForceResizeRenderView(render_view(), WebSize(800, 600));
720 void BlinkTestRunner::DidCommitProvisionalLoad(WebLocalFrame* frame,
721 bool is_new_navigation) {
722 if (!focus_on_next_commit_)
723 return;
724 focus_on_next_commit_ = false;
725 render_view()->GetWebView()->setFocusedFrame(frame);
728 void BlinkTestRunner::DidFailProvisionalLoad(WebLocalFrame* frame,
729 const WebURLError& error) {
730 focus_on_next_commit_ = false;
733 // Public methods - -----------------------------------------------------------
735 void BlinkTestRunner::Reset() {
736 // The proxy_ is always non-NULL, it is set right after construction.
737 proxy_->set_widget(render_view()->GetWebView());
738 proxy_->Reset();
739 prefs_.Reset();
740 routing_ids_.clear();
741 session_histories_.clear();
742 current_entry_indexes_.clear();
744 render_view()->ClearEditCommands();
745 if (render_view()->GetWebView()->mainFrame()->isWebLocalFrame())
746 render_view()->GetWebView()->mainFrame()->setName(WebString());
747 render_view()->GetWebView()->mainFrame()->clearOpener();
749 // Resetting the internals object also overrides the WebPreferences, so we
750 // have to sync them to WebKit again.
751 if (render_view()->GetWebView()->mainFrame()->isWebLocalFrame()) {
752 WebTestingSupport::resetInternalsObject(
753 render_view()->GetWebView()->mainFrame()->toWebLocalFrame());
754 render_view()->SetWebkitPreferences(render_view()->GetWebkitPreferences());
758 // Private methods -----------------------------------------------------------
760 void BlinkTestRunner::CaptureDump() {
761 WebTestInterfaces* interfaces =
762 LayoutTestRenderProcessObserver::GetInstance()->test_interfaces();
763 TRACE_EVENT0("shell", "BlinkTestRunner::CaptureDump");
765 if (interfaces->TestRunner()->ShouldDumpAsAudio()) {
766 std::vector<unsigned char> vector_data;
767 interfaces->TestRunner()->GetAudioData(&vector_data);
768 Send(new ShellViewHostMsg_AudioDump(routing_id(), vector_data));
769 } else {
770 Send(new ShellViewHostMsg_TextDump(routing_id(),
771 proxy()->CaptureTree(false)));
773 if (test_config_.enable_pixel_dumping &&
774 interfaces->TestRunner()->ShouldGeneratePixelResults()) {
775 CHECK(render_view()->GetWebView()->isAcceleratedCompositingActive());
776 proxy()->CapturePixelsAsync(base::Bind(
777 &BlinkTestRunner::CaptureDumpPixels, base::Unretained(this)));
778 return;
782 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
783 switches::kEnableSlimmingPaint)) {
784 // Force a layout/paint by the end of the test to ensure test coverage of
785 // incremental painting in slimming paint mode.
786 proxy()->LayoutAndPaintAsyncThen(base::Bind(
787 &BlinkTestRunner::CaptureDumpComplete, base::Unretained(this)));
788 return;
791 CaptureDumpComplete();
794 void BlinkTestRunner::CaptureDumpPixels(const SkBitmap& snapshot) {
795 DCHECK_NE(0, snapshot.info().width());
796 DCHECK_NE(0, snapshot.info().height());
798 SkAutoLockPixels snapshot_lock(snapshot);
799 // The snapshot arrives from the GPU process via shared memory. Because MSan
800 // can't track initializedness across processes, we must assure it that the
801 // pixels are in fact initialized.
802 MSAN_UNPOISON(snapshot.getPixels(), snapshot.getSize());
803 base::MD5Digest digest;
804 base::MD5Sum(snapshot.getPixels(), snapshot.getSize(), &digest);
805 std::string actual_pixel_hash = base::MD5DigestToBase16(digest);
807 if (actual_pixel_hash == test_config_.expected_pixel_hash) {
808 SkBitmap empty_image;
809 Send(new ShellViewHostMsg_ImageDump(
810 routing_id(), actual_pixel_hash, empty_image));
811 } else {
812 Send(new ShellViewHostMsg_ImageDump(
813 routing_id(), actual_pixel_hash, snapshot));
816 CaptureDumpComplete();
819 void BlinkTestRunner::CaptureDumpComplete() {
820 render_view()->GetWebView()->mainFrame()->stopLoading();
822 base::MessageLoop::current()->PostTask(
823 FROM_HERE, base::Bind(base::IgnoreResult(&BlinkTestRunner::Send),
824 base::Unretained(this),
825 new ShellViewHostMsg_TestFinished(routing_id())));
828 void BlinkTestRunner::OnSetTestConfiguration(
829 const ShellTestConfiguration& params) {
830 test_config_ = params;
831 is_main_window_ = true;
833 ForceResizeRenderView(
834 render_view(),
835 WebSize(params.initial_size.width(), params.initial_size.height()));
836 SetFocus(proxy_, true);
838 WebTestInterfaces* interfaces =
839 LayoutTestRenderProcessObserver::GetInstance()->test_interfaces();
840 interfaces->SetTestIsRunning(true);
841 interfaces->ConfigureForTestWithURL(params.test_url,
842 params.enable_pixel_dumping);
845 void BlinkTestRunner::OnSessionHistory(
846 const std::vector<int>& routing_ids,
847 const std::vector<std::vector<PageState>>& session_histories,
848 const std::vector<unsigned>& current_entry_indexes) {
849 routing_ids_ = routing_ids;
850 session_histories_ = session_histories;
851 current_entry_indexes_ = current_entry_indexes;
852 CaptureDump();
855 void BlinkTestRunner::OnReset() {
856 LayoutTestRenderProcessObserver::GetInstance()->test_interfaces()->ResetAll();
857 Reset();
858 // Navigating to about:blank will make sure that no new loads are initiated
859 // by the renderer.
860 render_view()->GetWebView()->mainFrame()->loadRequest(
861 WebURLRequest(GURL(url::kAboutBlankURL)));
862 Send(new ShellViewHostMsg_ResetDone(routing_id()));
865 void BlinkTestRunner::OnNotifyDone() {
866 render_view()->GetWebView()->mainFrame()->executeScript(
867 WebScriptSource(WebString::fromUTF8("testRunner.notifyDone();")));
870 void BlinkTestRunner::OnTryLeakDetection() {
871 WebLocalFrame* main_frame =
872 render_view()->GetWebView()->mainFrame()->toWebLocalFrame();
873 DCHECK_EQ(GURL(url::kAboutBlankURL), GURL(main_frame->document().url()));
874 DCHECK(!main_frame->isLoading());
876 leak_detector_->TryLeakDetection(main_frame);
879 void BlinkTestRunner::ReportLeakDetectionResult(
880 const LeakDetectionResult& report) {
881 Send(new ShellViewHostMsg_LeakDetectionDone(routing_id(), report));
884 } // namespace content