Make castv2 performance test work.
[chromium-blink-merge.git] / chrome / browser / devtools / devtools_sanity_browsertest.cc
blobdb9eb50e335b54768a9204409fc60383b512f18d
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 "base/bind.h"
6 #include "base/cancelable_callback.h"
7 #include "base/command_line.h"
8 #include "base/compiler_specific.h"
9 #include "base/memory/ref_counted.h"
10 #include "base/path_service.h"
11 #include "base/prefs/pref_service.h"
12 #include "base/strings/string_number_conversions.h"
13 #include "base/strings/stringprintf.h"
14 #include "base/strings/utf_string_conversions.h"
15 #include "base/test/test_timeouts.h"
16 #include "chrome/browser/chrome_notification_types.h"
17 #include "chrome/browser/devtools/browser_list_tabcontents_provider.h"
18 #include "chrome/browser/devtools/device/self_device_provider.h"
19 #include "chrome/browser/devtools/devtools_window_testing.h"
20 #include "chrome/browser/extensions/extension_apitest.h"
21 #include "chrome/browser/extensions/extension_browsertest.h"
22 #include "chrome/browser/extensions/extension_service.h"
23 #include "chrome/browser/extensions/unpacked_installer.h"
24 #include "chrome/browser/lifetime/application_lifetime.h"
25 #include "chrome/browser/profiles/profile.h"
26 #include "chrome/browser/ui/browser.h"
27 #include "chrome/browser/ui/browser_commands.h"
28 #include "chrome/browser/ui/browser_iterator.h"
29 #include "chrome/browser/ui/tabs/tab_strip_model.h"
30 #include "chrome/common/chrome_paths.h"
31 #include "chrome/common/chrome_switches.h"
32 #include "chrome/common/pref_names.h"
33 #include "chrome/common/url_constants.h"
34 #include "chrome/test/base/in_process_browser_test.h"
35 #include "chrome/test/base/test_switches.h"
36 #include "chrome/test/base/ui_test_utils.h"
37 #include "components/app_modal/javascript_app_modal_dialog.h"
38 #include "components/app_modal/native_app_modal_dialog.h"
39 #include "content/public/browser/child_process_data.h"
40 #include "content/public/browser/content_browser_client.h"
41 #include "content/public/browser/devtools_agent_host.h"
42 #include "content/public/browser/devtools_http_handler.h"
43 #include "content/public/browser/notification_registrar.h"
44 #include "content/public/browser/notification_service.h"
45 #include "content/public/browser/render_view_host.h"
46 #include "content/public/browser/web_contents.h"
47 #include "content/public/browser/worker_service.h"
48 #include "content/public/browser/worker_service_observer.h"
49 #include "content/public/common/content_switches.h"
50 #include "content/public/test/browser_test_utils.h"
51 #include "extensions/browser/extension_registry.h"
52 #include "extensions/browser/extension_system.h"
53 #include "extensions/browser/notification_types.h"
54 #include "extensions/common/switches.h"
55 #include "net/socket/tcp_listen_socket.h"
56 #include "net/test/spawned_test_server/spawned_test_server.h"
58 using app_modal::AppModalDialog;
59 using app_modal::JavaScriptAppModalDialog;
60 using app_modal::NativeAppModalDialog;
61 using content::BrowserThread;
62 using content::DevToolsAgentHost;
63 using content::NavigationController;
64 using content::RenderViewHost;
65 using content::WebContents;
66 using content::WorkerService;
67 using content::WorkerServiceObserver;
69 namespace {
71 const char kDebuggerTestPage[] = "files/devtools/debugger_test_page.html";
72 const char kPauseWhenLoadingDevTools[] =
73 "files/devtools/pause_when_loading_devtools.html";
74 const char kPauseWhenScriptIsRunning[] =
75 "files/devtools/pause_when_script_is_running.html";
76 const char kPageWithContentScript[] =
77 "files/devtools/page_with_content_script.html";
78 const char kNavigateBackTestPage[] =
79 "files/devtools/navigate_back.html";
80 const char kChunkedTestPage[] = "chunked";
81 const char kSlowTestPage[] =
82 "chunked?waitBeforeHeaders=100&waitBetweenChunks=100&chunksNumber=2";
83 const char kSharedWorkerTestPage[] =
84 "files/workers/workers_ui_shared_worker.html";
85 const char kSharedWorkerTestWorker[] =
86 "files/workers/workers_ui_shared_worker.js";
87 const char kReloadSharedWorkerTestPage[] =
88 "files/workers/debug_shared_worker_initialization.html";
89 const char kReloadSharedWorkerTestWorker[] =
90 "files/workers/debug_shared_worker_initialization.js";
92 const int kRemoteDebuggingPort = 9225;
94 void RunTestFunction(DevToolsWindow* window, const char* test_name) {
95 std::string result;
97 RenderViewHost* rvh = DevToolsWindowTesting::Get(window)->
98 main_web_contents()->GetRenderViewHost();
99 // At first check that JavaScript part of the front-end is loaded by
100 // checking that global variable uiTests exists(it's created after all js
101 // files have been loaded) and has runTest method.
102 ASSERT_TRUE(
103 content::ExecuteScriptAndExtractString(
104 rvh,
105 "window.domAutomationController.send("
106 " '' + (window.uiTests && (typeof uiTests.runTest)));",
107 &result));
109 ASSERT_EQ("function", result) << "DevTools front-end is broken.";
110 ASSERT_TRUE(content::ExecuteScriptAndExtractString(
111 rvh,
112 base::StringPrintf("uiTests.runTest('%s')", test_name),
113 &result));
114 EXPECT_EQ("[OK]", result);
117 } // namespace
119 class DevToolsSanityTest : public InProcessBrowserTest {
120 public:
121 DevToolsSanityTest() : window_(NULL) {}
123 protected:
124 void RunTest(const std::string& test_name, const std::string& test_page) {
125 OpenDevToolsWindow(test_page, false);
126 RunTestFunction(window_, test_name.c_str());
127 CloseDevToolsWindow();
130 void LoadTestPage(const std::string& test_page) {
131 GURL url = test_server()->GetURL(test_page);
132 ui_test_utils::NavigateToURL(browser(), url);
135 void OpenDevToolsWindow(const std::string& test_page, bool is_docked) {
136 ASSERT_TRUE(test_server()->Start());
137 LoadTestPage(test_page);
139 window_ = DevToolsWindowTesting::OpenDevToolsWindowSync(GetInspectedTab(),
140 is_docked);
143 WebContents* GetInspectedTab() {
144 return browser()->tab_strip_model()->GetWebContentsAt(0);
147 void CloseDevToolsWindow() {
148 DevToolsWindowTesting::CloseDevToolsWindowSync(window_);
151 WebContents* main_web_contents() {
152 return DevToolsWindowTesting::Get(window_)->main_web_contents();
155 WebContents* toolbox_web_contents() {
156 return DevToolsWindowTesting::Get(window_)->toolbox_web_contents();
159 DevToolsWindow* window_;
162 // Used to block until a dev tools window gets beforeunload event.
163 class DevToolsWindowBeforeUnloadObserver
164 : public content::WebContentsObserver {
165 public:
166 explicit DevToolsWindowBeforeUnloadObserver(DevToolsWindow*);
167 void Wait();
168 private:
169 // Invoked when the beforeunload handler fires.
170 void BeforeUnloadFired(const base::TimeTicks& proceed_time) override;
172 bool m_fired;
173 scoped_refptr<content::MessageLoopRunner> message_loop_runner_;
174 DISALLOW_COPY_AND_ASSIGN(DevToolsWindowBeforeUnloadObserver);
177 DevToolsWindowBeforeUnloadObserver::DevToolsWindowBeforeUnloadObserver(
178 DevToolsWindow* devtools_window)
179 : WebContentsObserver(
180 DevToolsWindowTesting::Get(devtools_window)->main_web_contents()),
181 m_fired(false) {
184 void DevToolsWindowBeforeUnloadObserver::Wait() {
185 if (m_fired)
186 return;
187 message_loop_runner_ = new content::MessageLoopRunner;
188 message_loop_runner_->Run();
191 void DevToolsWindowBeforeUnloadObserver::BeforeUnloadFired(
192 const base::TimeTicks& proceed_time) {
193 m_fired = true;
194 if (message_loop_runner_.get())
195 message_loop_runner_->Quit();
198 class DevToolsBeforeUnloadTest: public DevToolsSanityTest {
199 public:
200 void SetUpCommandLine(base::CommandLine* command_line) override {
201 command_line->AppendSwitch(
202 switches::kDisableHangMonitor);
205 void CloseInspectedTab() {
206 browser()->tab_strip_model()->CloseWebContentsAt(0,
207 TabStripModel::CLOSE_NONE);
210 void CloseDevToolsWindowAsync() {
211 DevToolsWindowTesting::CloseDevToolsWindow(window_);
214 void CloseInspectedBrowser() {
215 chrome::CloseWindow(browser());
218 protected:
219 void InjectBeforeUnloadListener(content::WebContents* web_contents) {
220 ASSERT_TRUE(content::ExecuteScript(web_contents->GetRenderViewHost(),
221 "window.addEventListener('beforeunload',"
222 "function(event) { event.returnValue = 'Foo'; });"));
225 void RunBeforeUnloadSanityTest(bool is_docked,
226 base::Callback<void(void)> close_method,
227 bool wait_for_browser_close = true) {
228 OpenDevToolsWindow(kDebuggerTestPage, is_docked);
229 scoped_refptr<content::MessageLoopRunner> runner =
230 new content::MessageLoopRunner;
231 DevToolsWindowTesting::Get(window_)->
232 SetCloseCallback(runner->QuitClosure());
233 InjectBeforeUnloadListener(main_web_contents());
235 DevToolsWindowBeforeUnloadObserver before_unload_observer(window_);
236 close_method.Run();
237 CancelModalDialog();
238 before_unload_observer.Wait();
241 content::WindowedNotificationObserver close_observer(
242 chrome::NOTIFICATION_BROWSER_CLOSED,
243 content::Source<Browser>(browser()));
244 close_method.Run();
245 AcceptModalDialog();
246 if (wait_for_browser_close)
247 close_observer.Wait();
249 runner->Run();
252 DevToolsWindow* OpenDevToolWindowOnWebContents(
253 content::WebContents* contents, bool is_docked) {
254 DevToolsWindow* window =
255 DevToolsWindowTesting::OpenDevToolsWindowSync(contents, is_docked);
256 return window;
259 void OpenDevToolsPopupWindow(DevToolsWindow* devtools_window) {
260 content::WindowedNotificationObserver observer(
261 content::NOTIFICATION_LOAD_STOP,
262 content::NotificationService::AllSources());
263 ASSERT_TRUE(content::ExecuteScript(
264 DevToolsWindowTesting::Get(devtools_window)->
265 main_web_contents()->GetRenderViewHost(),
266 "window.open(\"\", \"\", \"location=0\");"));
267 observer.Wait();
270 void CloseDevToolsPopupWindow(DevToolsWindow* devtools_window) {
271 DevToolsWindowTesting::CloseDevToolsWindowSync(devtools_window);
274 void AcceptModalDialog() {
275 NativeAppModalDialog* native_dialog = GetDialog();
276 native_dialog->AcceptAppModalDialog();
279 void CancelModalDialog() {
280 NativeAppModalDialog* native_dialog = GetDialog();
281 native_dialog->CancelAppModalDialog();
284 NativeAppModalDialog* GetDialog() {
285 AppModalDialog* dialog = ui_test_utils::WaitForAppModalDialog();
286 EXPECT_TRUE(dialog->IsJavaScriptModalDialog());
287 JavaScriptAppModalDialog* js_dialog =
288 static_cast<JavaScriptAppModalDialog*>(dialog);
289 NativeAppModalDialog* native_dialog = js_dialog->native_dialog();
290 EXPECT_TRUE(native_dialog);
291 return native_dialog;
295 class DevToolsUnresponsiveBeforeUnloadTest: public DevToolsBeforeUnloadTest {
296 public:
297 void SetUpCommandLine(base::CommandLine* command_line) override {}
300 void TimeoutCallback(const std::string& timeout_message) {
301 ADD_FAILURE() << timeout_message;
302 base::MessageLoop::current()->Quit();
305 // Base class for DevTools tests that test devtools functionality for
306 // extensions and content scripts.
307 class DevToolsExtensionTest : public DevToolsSanityTest,
308 public content::NotificationObserver {
309 public:
310 DevToolsExtensionTest() : DevToolsSanityTest() {
311 PathService::Get(chrome::DIR_TEST_DATA, &test_extensions_dir_);
312 test_extensions_dir_ = test_extensions_dir_.AppendASCII("devtools");
313 test_extensions_dir_ = test_extensions_dir_.AppendASCII("extensions");
316 protected:
317 // Load an extension from test\data\devtools\extensions\<extension_name>
318 void LoadExtension(const char* extension_name) {
319 base::FilePath path = test_extensions_dir_.AppendASCII(extension_name);
320 ASSERT_TRUE(LoadExtensionFromPath(path)) << "Failed to load extension.";
323 private:
324 bool LoadExtensionFromPath(const base::FilePath& path) {
325 ExtensionService* service = extensions::ExtensionSystem::Get(
326 browser()->profile())->extension_service();
327 extensions::ExtensionRegistry* registry =
328 extensions::ExtensionRegistry::Get(browser()->profile());
329 size_t num_before = registry->enabled_extensions().size();
331 content::NotificationRegistrar registrar;
332 registrar.Add(this,
333 extensions::NOTIFICATION_EXTENSION_LOADED_DEPRECATED,
334 content::NotificationService::AllSources());
335 base::CancelableClosure timeout(
336 base::Bind(&TimeoutCallback, "Extension load timed out."));
337 base::MessageLoop::current()->PostDelayedTask(
338 FROM_HERE, timeout.callback(), TestTimeouts::action_timeout());
339 extensions::UnpackedInstaller::Create(service)->Load(path);
340 content::RunMessageLoop();
341 timeout.Cancel();
343 size_t num_after = registry->enabled_extensions().size();
344 if (num_after != (num_before + 1))
345 return false;
347 return WaitForExtensionViewsToLoad();
350 bool WaitForExtensionViewsToLoad() {
351 // Wait for all the extension render views that exist to finish loading.
352 // NOTE: This assumes that the extension views list is not changing while
353 // this method is running.
355 content::NotificationRegistrar registrar;
356 registrar.Add(this,
357 extensions::NOTIFICATION_EXTENSION_HOST_DID_STOP_FIRST_LOAD,
358 content::NotificationService::AllSources());
359 base::CancelableClosure timeout(
360 base::Bind(&TimeoutCallback, "Extension host load timed out."));
361 base::MessageLoop::current()->PostDelayedTask(
362 FROM_HERE, timeout.callback(), TestTimeouts::action_timeout());
364 extensions::ProcessManager* manager =
365 extensions::ProcessManager::Get(browser()->profile());
366 extensions::ProcessManager::FrameSet all_frames = manager->GetAllFrames();
367 for (extensions::ProcessManager::FrameSet::const_iterator iter =
368 all_frames.begin();
369 iter != all_frames.end();) {
370 if (!content::WebContents::FromRenderFrameHost(*iter)->IsLoading())
371 ++iter;
372 else
373 content::RunMessageLoop();
376 timeout.Cancel();
377 return true;
380 void Observe(int type,
381 const content::NotificationSource& source,
382 const content::NotificationDetails& details) override {
383 switch (type) {
384 case extensions::NOTIFICATION_EXTENSION_LOADED_DEPRECATED:
385 case extensions::NOTIFICATION_EXTENSION_HOST_DID_STOP_FIRST_LOAD:
386 base::MessageLoopForUI::current()->Quit();
387 break;
388 default:
389 NOTREACHED();
390 break;
394 base::FilePath test_extensions_dir_;
397 class DevToolsExperimentalExtensionTest : public DevToolsExtensionTest {
398 public:
399 void SetUpCommandLine(base::CommandLine* command_line) override {
400 command_line->AppendSwitch(
401 extensions::switches::kEnableExperimentalExtensionApis);
405 class WorkerDevToolsSanityTest : public InProcessBrowserTest {
406 public:
407 WorkerDevToolsSanityTest() : window_(NULL) {}
409 protected:
410 class WorkerData : public base::RefCountedThreadSafe<WorkerData> {
411 public:
412 WorkerData() : worker_process_id(0), worker_route_id(0) {}
413 int worker_process_id;
414 int worker_route_id;
416 private:
417 friend class base::RefCountedThreadSafe<WorkerData>;
418 ~WorkerData() {}
421 class WorkerCreationObserver : public WorkerServiceObserver {
422 public:
423 explicit WorkerCreationObserver(const std::string& path,
424 WorkerData* worker_data)
425 : path_(path), worker_data_(worker_data) {}
427 private:
428 ~WorkerCreationObserver() override {}
430 void WorkerCreated(const GURL& url,
431 const base::string16& name,
432 int process_id,
433 int route_id) override {
434 if (url.path().rfind(path_) == std::string::npos)
435 return;
436 worker_data_->worker_process_id = process_id;
437 worker_data_->worker_route_id = route_id;
438 WorkerService::GetInstance()->RemoveObserver(this);
439 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
440 base::MessageLoop::QuitClosure());
441 delete this;
443 std::string path_;
444 scoped_refptr<WorkerData> worker_data_;
447 class WorkerTerminationObserver : public WorkerServiceObserver {
448 public:
449 explicit WorkerTerminationObserver(WorkerData* worker_data)
450 : worker_data_(worker_data) {
453 private:
454 ~WorkerTerminationObserver() override {}
456 void WorkerDestroyed(int process_id, int route_id) override {
457 ASSERT_EQ(worker_data_->worker_process_id, process_id);
458 ASSERT_EQ(worker_data_->worker_route_id, route_id);
459 WorkerService::GetInstance()->RemoveObserver(this);
460 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
461 base::MessageLoop::QuitClosure());
462 delete this;
464 scoped_refptr<WorkerData> worker_data_;
467 void RunTest(const char* test_name,
468 const char* test_page,
469 const char* worker_path) {
470 ASSERT_TRUE(test_server()->Start());
471 GURL url = test_server()->GetURL(test_page);
472 ui_test_utils::NavigateToURL(browser(), url);
474 scoped_refptr<WorkerData> worker_data =
475 WaitForFirstSharedWorker(worker_path);
476 OpenDevToolsWindowForSharedWorker(worker_data.get());
477 RunTestFunction(window_, test_name);
478 CloseDevToolsWindow();
481 static void TerminateWorkerOnIOThread(scoped_refptr<WorkerData> worker_data) {
482 if (!WorkerService::GetInstance()->TerminateWorker(
483 worker_data->worker_process_id, worker_data->worker_route_id))
484 FAIL() << "Failed to terminate worker.\n";
485 WorkerService::GetInstance()->AddObserver(
486 new WorkerTerminationObserver(worker_data.get()));
489 static void TerminateWorker(scoped_refptr<WorkerData> worker_data) {
490 BrowserThread::PostTask(
491 BrowserThread::IO, FROM_HERE,
492 base::Bind(&TerminateWorkerOnIOThread, worker_data));
493 content::RunMessageLoop();
496 static void WaitForFirstSharedWorkerOnIOThread(
497 const std::string& path,
498 scoped_refptr<WorkerData> worker_data) {
499 std::vector<WorkerService::WorkerInfo> worker_info =
500 WorkerService::GetInstance()->GetWorkers();
501 for (size_t i = 0; i < worker_info.size(); i++) {
502 if (worker_info[i].url.path().rfind(path) == std::string::npos)
503 continue;
504 worker_data->worker_process_id = worker_info[0].process_id;
505 worker_data->worker_route_id = worker_info[0].route_id;
506 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
507 base::MessageLoop::QuitClosure());
508 return;
511 WorkerService::GetInstance()->AddObserver(
512 new WorkerCreationObserver(path, worker_data.get()));
515 static scoped_refptr<WorkerData> WaitForFirstSharedWorker(const char* path) {
516 scoped_refptr<WorkerData> worker_data(new WorkerData());
517 BrowserThread::PostTask(
518 BrowserThread::IO,
519 FROM_HERE,
520 base::Bind(&WaitForFirstSharedWorkerOnIOThread, path, worker_data));
521 content::RunMessageLoop();
522 return worker_data;
525 void OpenDevToolsWindowForSharedWorker(WorkerData* worker_data) {
526 Profile* profile = browser()->profile();
527 scoped_refptr<DevToolsAgentHost> agent_host(
528 DevToolsAgentHost::GetForWorker(
529 worker_data->worker_process_id,
530 worker_data->worker_route_id));
531 window_ = DevToolsWindowTesting::OpenDevToolsWindowForWorkerSync(
532 profile, agent_host.get());
535 void CloseDevToolsWindow() {
536 DevToolsWindowTesting::CloseDevToolsWindowSync(window_);
539 DevToolsWindow* window_;
542 // Tests that BeforeUnload event gets called on docked devtools if
543 // we try to close them.
544 IN_PROC_BROWSER_TEST_F(DevToolsBeforeUnloadTest, TestDockedDevToolsClose) {
545 RunBeforeUnloadSanityTest(true, base::Bind(
546 &DevToolsBeforeUnloadTest::CloseDevToolsWindowAsync, this), false);
549 // Tests that BeforeUnload event gets called on docked devtools if
550 // we try to close the inspected page.
551 IN_PROC_BROWSER_TEST_F(DevToolsBeforeUnloadTest,
552 TestDockedDevToolsInspectedTabClose) {
553 RunBeforeUnloadSanityTest(true, base::Bind(
554 &DevToolsBeforeUnloadTest::CloseInspectedTab, this));
557 // Tests that BeforeUnload event gets called on docked devtools if
558 // we try to close the inspected browser.
559 IN_PROC_BROWSER_TEST_F(DevToolsBeforeUnloadTest,
560 TestDockedDevToolsInspectedBrowserClose) {
561 RunBeforeUnloadSanityTest(true, base::Bind(
562 &DevToolsBeforeUnloadTest::CloseInspectedBrowser, this));
565 // Tests that BeforeUnload event gets called on undocked devtools if
566 // we try to close them.
567 IN_PROC_BROWSER_TEST_F(DevToolsBeforeUnloadTest, TestUndockedDevToolsClose) {
568 RunBeforeUnloadSanityTest(false, base::Bind(
569 &DevToolsBeforeUnloadTest::CloseDevToolsWindowAsync, this), false);
572 // Tests that BeforeUnload event gets called on undocked devtools if
573 // we try to close the inspected page.
574 IN_PROC_BROWSER_TEST_F(DevToolsBeforeUnloadTest,
575 TestUndockedDevToolsInspectedTabClose) {
576 RunBeforeUnloadSanityTest(false, base::Bind(
577 &DevToolsBeforeUnloadTest::CloseInspectedTab, this));
580 // Tests that BeforeUnload event gets called on undocked devtools if
581 // we try to close the inspected browser.
582 IN_PROC_BROWSER_TEST_F(DevToolsBeforeUnloadTest,
583 TestUndockedDevToolsInspectedBrowserClose) {
584 RunBeforeUnloadSanityTest(false, base::Bind(
585 &DevToolsBeforeUnloadTest::CloseInspectedBrowser, this));
588 // Tests that BeforeUnload event gets called on undocked devtools if
589 // we try to exit application.
590 IN_PROC_BROWSER_TEST_F(DevToolsBeforeUnloadTest,
591 TestUndockedDevToolsApplicationClose) {
592 RunBeforeUnloadSanityTest(false, base::Bind(
593 &chrome::CloseAllBrowsers));
596 // Times out on Win and Linux
597 // @see http://crbug.com/410327
598 #if defined(OS_WIN) || (defined(OS_LINUX) && !defined(OS_CHROMEOS))
599 #define MAYBE_TestUndockedDevToolsUnresponsive DISABLED_TestUndockedDevToolsUnresponsive
600 #else
601 #define MAYBE_TestUndockedDevToolsUnresponsive TestUndockedDevToolsUnresponsive
602 #endif
604 // Tests that inspected tab gets closed if devtools renderer
605 // becomes unresponsive during beforeunload event interception.
606 // @see http://crbug.com/322380
607 IN_PROC_BROWSER_TEST_F(DevToolsUnresponsiveBeforeUnloadTest,
608 MAYBE_TestUndockedDevToolsUnresponsive) {
609 ASSERT_TRUE(test_server()->Start());
610 LoadTestPage(kDebuggerTestPage);
611 DevToolsWindow* devtools_window = OpenDevToolWindowOnWebContents(
612 GetInspectedTab(), false);
614 scoped_refptr<content::MessageLoopRunner> runner =
615 new content::MessageLoopRunner;
616 DevToolsWindowTesting::Get(devtools_window)->SetCloseCallback(
617 runner->QuitClosure());
619 ASSERT_TRUE(content::ExecuteScript(
620 DevToolsWindowTesting::Get(devtools_window)->main_web_contents()->
621 GetRenderViewHost(),
622 "window.addEventListener('beforeunload',"
623 "function(event) { while (true); });"));
624 CloseInspectedTab();
625 runner->Run();
628 // Tests that closing worker inspector window does not cause browser crash
629 // @see http://crbug.com/323031
630 IN_PROC_BROWSER_TEST_F(DevToolsBeforeUnloadTest,
631 TestWorkerWindowClosing) {
632 ASSERT_TRUE(test_server()->Start());
633 LoadTestPage(kDebuggerTestPage);
634 DevToolsWindow* devtools_window = OpenDevToolWindowOnWebContents(
635 GetInspectedTab(), false);
637 OpenDevToolsPopupWindow(devtools_window);
638 CloseDevToolsPopupWindow(devtools_window);
641 // Tests that BeforeUnload event gets called on devtools that are opened
642 // on another devtools.
643 IN_PROC_BROWSER_TEST_F(DevToolsBeforeUnloadTest,
644 TestDevToolsOnDevTools) {
645 ASSERT_TRUE(test_server()->Start());
646 LoadTestPage(kDebuggerTestPage);
648 std::vector<DevToolsWindow*> windows;
649 std::vector<content::WindowedNotificationObserver*> close_observers;
650 content::WebContents* inspected_web_contents = GetInspectedTab();
651 for (int i = 0; i < 3; ++i) {
652 DevToolsWindow* devtools_window = OpenDevToolWindowOnWebContents(
653 inspected_web_contents, i == 0);
654 windows.push_back(devtools_window);
655 content::WindowedNotificationObserver* close_observer =
656 new content::WindowedNotificationObserver(
657 content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
658 content::Source<content::WebContents>(
659 DevToolsWindowTesting::Get(devtools_window)->
660 main_web_contents()));
661 close_observers.push_back(close_observer);
662 inspected_web_contents =
663 DevToolsWindowTesting::Get(devtools_window)->main_web_contents();
666 InjectBeforeUnloadListener(
667 DevToolsWindowTesting::Get(windows[0])->main_web_contents());
668 InjectBeforeUnloadListener(
669 DevToolsWindowTesting::Get(windows[2])->main_web_contents());
670 // Try to close second devtools.
672 content::WindowedNotificationObserver cancel_browser(
673 chrome::NOTIFICATION_BROWSER_CLOSE_CANCELLED,
674 content::NotificationService::AllSources());
675 chrome::CloseWindow(DevToolsWindowTesting::Get(windows[1])->browser());
676 CancelModalDialog();
677 cancel_browser.Wait();
679 // Try to close browser window.
681 content::WindowedNotificationObserver cancel_browser(
682 chrome::NOTIFICATION_BROWSER_CLOSE_CANCELLED,
683 content::NotificationService::AllSources());
684 chrome::CloseWindow(browser());
685 AcceptModalDialog();
686 CancelModalDialog();
687 cancel_browser.Wait();
689 // Try to exit application.
691 content::WindowedNotificationObserver close_observer(
692 chrome::NOTIFICATION_BROWSER_CLOSED,
693 content::Source<Browser>(browser()));
694 chrome::IncrementKeepAliveCount();
695 chrome::CloseAllBrowsers();
696 AcceptModalDialog();
697 AcceptModalDialog();
698 close_observer.Wait();
700 for (size_t i = 0; i < close_observers.size(); ++i) {
701 close_observers[i]->Wait();
702 delete close_observers[i];
706 // Tests scripts panel showing.
707 IN_PROC_BROWSER_TEST_F(DevToolsSanityTest, TestShowScriptsTab) {
708 RunTest("testShowScriptsTab", kDebuggerTestPage);
711 // Tests that scripts tab is populated with inspected scripts even if it
712 // hadn't been shown by the moment inspected paged refreshed.
713 // @see http://crbug.com/26312
714 IN_PROC_BROWSER_TEST_F(
715 DevToolsSanityTest,
716 TestScriptsTabIsPopulatedOnInspectedPageRefresh) {
717 RunTest("testScriptsTabIsPopulatedOnInspectedPageRefresh",
718 kDebuggerTestPage);
721 // Tests that chrome.devtools extension is correctly exposed.
722 IN_PROC_BROWSER_TEST_F(DevToolsExtensionTest,
723 TestDevToolsExtensionAPI) {
724 LoadExtension("devtools_extension");
725 RunTest("waitForTestResultsInConsole", std::string());
728 // Disabled on Windows due to flakiness. http://crbug.com/183649
729 #if defined(OS_WIN)
730 #define MAYBE_TestDevToolsExtensionMessaging DISABLED_TestDevToolsExtensionMessaging
731 #else
732 #define MAYBE_TestDevToolsExtensionMessaging TestDevToolsExtensionMessaging
733 #endif
735 // Tests that chrome.devtools extension can communicate with background page
736 // using extension messaging.
737 IN_PROC_BROWSER_TEST_F(DevToolsExtensionTest,
738 MAYBE_TestDevToolsExtensionMessaging) {
739 LoadExtension("devtools_messaging");
740 RunTest("waitForTestResultsInConsole", std::string());
743 // Tests that chrome.experimental.devtools extension is correctly exposed
744 // when the extension has experimental permission.
745 IN_PROC_BROWSER_TEST_F(DevToolsExperimentalExtensionTest,
746 TestDevToolsExperimentalExtensionAPI) {
747 LoadExtension("devtools_experimental");
748 RunTest("waitForTestResultsInConsole", std::string());
751 // Tests that a content script is in the scripts list.
752 IN_PROC_BROWSER_TEST_F(DevToolsExtensionTest,
753 TestContentScriptIsPresent) {
754 LoadExtension("simple_content_script");
755 RunTest("testContentScriptIsPresent", kPageWithContentScript);
758 // Tests that scripts are not duplicated after Scripts Panel switch.
759 IN_PROC_BROWSER_TEST_F(DevToolsSanityTest,
760 TestNoScriptDuplicatesOnPanelSwitch) {
761 RunTest("testNoScriptDuplicatesOnPanelSwitch", kDebuggerTestPage);
764 // Tests that debugger works correctly if pause event occurs when DevTools
765 // frontend is being loaded.
766 IN_PROC_BROWSER_TEST_F(DevToolsSanityTest,
767 TestPauseWhenLoadingDevTools) {
768 RunTest("testPauseWhenLoadingDevTools", kPauseWhenLoadingDevTools);
771 // Tests that pressing 'Pause' will pause script execution if the script
772 // is already running.
773 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(ARCH_CPU_ARM_FAMILY)
774 // Timing out on linux ARM bot: https://crbug/238453
775 #define MAYBE_TestPauseWhenScriptIsRunning DISABLED_TestPauseWhenScriptIsRunning
776 #else
777 #define MAYBE_TestPauseWhenScriptIsRunning TestPauseWhenScriptIsRunning
778 #endif
779 IN_PROC_BROWSER_TEST_F(DevToolsSanityTest,
780 MAYBE_TestPauseWhenScriptIsRunning) {
781 RunTest("testPauseWhenScriptIsRunning", kPauseWhenScriptIsRunning);
784 // Tests network timing.
785 IN_PROC_BROWSER_TEST_F(DevToolsSanityTest, TestNetworkTiming) {
786 RunTest("testNetworkTiming", kSlowTestPage);
789 // Tests network size.
790 IN_PROC_BROWSER_TEST_F(DevToolsSanityTest, TestNetworkSize) {
791 RunTest("testNetworkSize", kChunkedTestPage);
794 // Tests raw headers text.
795 IN_PROC_BROWSER_TEST_F(DevToolsSanityTest, TestNetworkSyncSize) {
796 RunTest("testNetworkSyncSize", kChunkedTestPage);
799 // Tests raw headers text.
800 IN_PROC_BROWSER_TEST_F(DevToolsSanityTest, TestNetworkRawHeadersText) {
801 RunTest("testNetworkRawHeadersText", kChunkedTestPage);
804 // Tests that console messages are not duplicated on navigation back.
805 #if defined(OS_WIN)
806 // Flaking on windows swarm try runs: crbug.com/409285.
807 #define MAYBE_TestConsoleOnNavigateBack DISABLED_TestConsoleOnNavigateBack
808 #else
809 #define MAYBE_TestConsoleOnNavigateBack TestConsoleOnNavigateBack
810 #endif
811 IN_PROC_BROWSER_TEST_F(DevToolsSanityTest, MAYBE_TestConsoleOnNavigateBack) {
812 RunTest("testConsoleOnNavigateBack", kNavigateBackTestPage);
815 // https://crbug.com/397889
816 IN_PROC_BROWSER_TEST_F(DevToolsSanityTest, DISABLED_TestDeviceEmulation) {
817 RunTest("testDeviceMetricsOverrides", "about:blank");
820 // Tests that external navigation from inspector page is always handled by
821 // DevToolsWindow and results in inspected page navigation.
822 IN_PROC_BROWSER_TEST_F(DevToolsSanityTest, TestDevToolsExternalNavigation) {
823 OpenDevToolsWindow(kDebuggerTestPage, true);
824 GURL url = test_server()->GetURL(kNavigateBackTestPage);
825 ui_test_utils::UrlLoadObserver observer(url,
826 content::NotificationService::AllSources());
827 ASSERT_TRUE(content::ExecuteScript(
828 main_web_contents(),
829 std::string("window.location = \"") + url.spec() + "\""));
830 observer.Wait();
832 ASSERT_TRUE(main_web_contents()->GetURL().
833 SchemeIs(content::kChromeDevToolsScheme));
834 ASSERT_EQ(url, GetInspectedTab()->GetURL());
835 CloseDevToolsWindow();
838 // Tests that toolbox window is loaded when DevTools window is undocked.
839 IN_PROC_BROWSER_TEST_F(DevToolsSanityTest, TestToolboxLoadedUndocked) {
840 OpenDevToolsWindow(kDebuggerTestPage, false);
841 ASSERT_TRUE(toolbox_web_contents());
842 DevToolsWindow* on_self =
843 DevToolsWindowTesting::OpenDevToolsWindowSync(main_web_contents(), false);
844 ASSERT_FALSE(DevToolsWindowTesting::Get(on_self)->toolbox_web_contents());
845 DevToolsWindowTesting::CloseDevToolsWindowSync(on_self);
846 CloseDevToolsWindow();
849 // Tests that toolbox window is not loaded when DevTools window is docked.
850 IN_PROC_BROWSER_TEST_F(DevToolsSanityTest, TestToolboxNotLoadedDocked) {
851 OpenDevToolsWindow(kDebuggerTestPage, true);
852 ASSERT_FALSE(toolbox_web_contents());
853 DevToolsWindow* on_self =
854 DevToolsWindowTesting::OpenDevToolsWindowSync(main_web_contents(), false);
855 ASSERT_FALSE(DevToolsWindowTesting::Get(on_self)->toolbox_web_contents());
856 DevToolsWindowTesting::CloseDevToolsWindowSync(on_self);
857 CloseDevToolsWindow();
860 // Tests that inspector will reattach to inspected page when it is reloaded
861 // after a crash. See http://crbug.com/101952
862 // Disabled. it doesn't check anything right now: http://crbug.com/461790
863 IN_PROC_BROWSER_TEST_F(DevToolsSanityTest, DISABLED_TestReattachAfterCrash) {
864 RunTest("testReattachAfterCrash", std::string());
867 IN_PROC_BROWSER_TEST_F(DevToolsSanityTest, TestPageWithNoJavaScript) {
868 OpenDevToolsWindow("about:blank", false);
869 std::string result;
870 ASSERT_TRUE(
871 content::ExecuteScriptAndExtractString(
872 main_web_contents()->GetRenderViewHost(),
873 "window.domAutomationController.send("
874 " '' + (window.uiTests && (typeof uiTests.runTest)));",
875 &result));
876 ASSERT_EQ("function", result) << "DevTools front-end is broken.";
877 CloseDevToolsWindow();
880 IN_PROC_BROWSER_TEST_F(WorkerDevToolsSanityTest, InspectSharedWorker) {
881 #if defined(OS_WIN) && defined(USE_ASH)
882 // Disable this test in Metro+Ash for now (http://crbug.com/262796).
883 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
884 switches::kAshBrowserTests))
885 return;
886 #endif
888 RunTest("testSharedWorker", kSharedWorkerTestPage, kSharedWorkerTestWorker);
891 // Disabled, crashes under Dr.Memory and ASan, http://crbug.com/432444.
892 IN_PROC_BROWSER_TEST_F(WorkerDevToolsSanityTest,
893 DISABLED_PauseInSharedWorkerInitialization) {
894 ASSERT_TRUE(test_server()->Start());
895 GURL url = test_server()->GetURL(kReloadSharedWorkerTestPage);
896 ui_test_utils::NavigateToURL(browser(), url);
898 scoped_refptr<WorkerData> worker_data =
899 WaitForFirstSharedWorker(kReloadSharedWorkerTestWorker);
900 OpenDevToolsWindowForSharedWorker(worker_data.get());
902 // We should make sure that the worker inspector has loaded before
903 // terminating worker.
904 RunTestFunction(window_, "testPauseInSharedWorkerInitialization1");
906 TerminateWorker(worker_data);
908 // Reload page to restart the worker.
909 ui_test_utils::NavigateToURL(browser(), url);
911 // Wait until worker script is paused on the debugger statement.
912 RunTestFunction(window_, "testPauseInSharedWorkerInitialization2");
913 CloseDevToolsWindow();
916 class DevToolsAgentHostTest : public InProcessBrowserTest {};
918 // Tests DevToolsAgentHost retention by its target.
919 IN_PROC_BROWSER_TEST_F(DevToolsAgentHostTest, TestAgentHostReleased) {
920 ui_test_utils::NavigateToURL(browser(), GURL("about:blank"));
921 WebContents* web_contents = browser()->tab_strip_model()->GetWebContentsAt(0);
922 DevToolsAgentHost* agent_raw =
923 DevToolsAgentHost::GetOrCreateFor(web_contents).get();
924 const std::string agent_id = agent_raw->GetId();
925 ASSERT_EQ(agent_raw, DevToolsAgentHost::GetForId(agent_id).get())
926 << "DevToolsAgentHost cannot be found by id";
927 browser()->tab_strip_model()->
928 CloseWebContentsAt(0, TabStripModel::CLOSE_NONE);
929 ASSERT_FALSE(DevToolsAgentHost::GetForId(agent_id).get())
930 << "DevToolsAgentHost is not released when the tab is closed";
933 class RemoteDebuggingTest : public ExtensionApiTest {
934 void SetUpCommandLine(base::CommandLine* command_line) override {
935 ExtensionApiTest::SetUpCommandLine(command_line);
936 command_line->AppendSwitchASCII(switches::kRemoteDebuggingPort, "9222");
938 // Override the extension root path.
939 PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir_);
940 test_data_dir_ = test_data_dir_.AppendASCII("devtools");
944 // Fails on CrOS. crbug.com/431399
945 #if defined(OS_CHROMEOS)
946 #define MAYBE_RemoteDebugger DISABLED_RemoteDebugger
947 #else
948 #define MAYBE_RemoteDebugger RemoteDebugger
949 #endif
950 IN_PROC_BROWSER_TEST_F(RemoteDebuggingTest, MAYBE_RemoteDebugger) {
951 #if defined(OS_WIN) && defined(USE_ASH)
952 // Disable this test in Metro+Ash for now (http://crbug.com/262796).
953 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
954 switches::kAshBrowserTests))
955 return;
956 #endif
958 ASSERT_TRUE(RunExtensionTest("target_list")) << message_;
961 using DevToolsPolicyTest = InProcessBrowserTest;
962 IN_PROC_BROWSER_TEST_F(DevToolsPolicyTest, PolicyTrue) {
963 browser()->profile()->GetPrefs()->SetBoolean(prefs::kDevToolsDisabled, true);
964 ui_test_utils::NavigateToURL(browser(), GURL("about:blank"));
965 content::WebContents* web_contents =
966 browser()->tab_strip_model()->GetWebContentsAt(0);
967 scoped_refptr<content::DevToolsAgentHost> agent(
968 content::DevToolsAgentHost::GetOrCreateFor(web_contents));
969 DevToolsWindow::OpenDevToolsWindow(web_contents);
970 DevToolsWindow* window = DevToolsWindow::FindDevToolsWindow(agent.get());
971 ASSERT_FALSE(window);
974 class RemoteWebSocketTest : public DevToolsSanityTest {
975 void SetUpCommandLine(base::CommandLine* command_line) override {
976 DevToolsSanityTest::SetUpCommandLine(command_line);
977 command_line->AppendSwitchASCII(switches::kRemoteDebuggingPort,
978 base::IntToString(kRemoteDebuggingPort));
982 IN_PROC_BROWSER_TEST_F(RemoteWebSocketTest, TestWebSocket) {
983 AndroidDeviceManager::DeviceProviders device_providers;
984 device_providers.push_back(new SelfAsDeviceProvider(kRemoteDebuggingPort));
985 DevToolsAndroidBridge::Factory::GetForProfile(browser()->profile())->
986 set_device_providers_for_test(device_providers);
987 RunTest("testRemoteWebSocket", "about:blank");