Add more checks to investigate SupervisedUserPrefStore crash at startup.
[chromium-blink-merge.git] / chrome / browser / devtools / devtools_sanity_browsertest.cc
blobb1edbef9d95c1278c2eee9c6a5f837069ca09a6a
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/stringprintf.h"
13 #include "base/strings/utf_string_conversions.h"
14 #include "base/test/test_timeouts.h"
15 #include "chrome/browser/chrome_notification_types.h"
16 #include "chrome/browser/devtools/browser_list_tabcontents_provider.h"
17 #include "chrome/browser/devtools/devtools_window_testing.h"
18 #include "chrome/browser/extensions/extension_apitest.h"
19 #include "chrome/browser/extensions/extension_browsertest.h"
20 #include "chrome/browser/extensions/extension_service.h"
21 #include "chrome/browser/extensions/unpacked_installer.h"
22 #include "chrome/browser/lifetime/application_lifetime.h"
23 #include "chrome/browser/profiles/profile.h"
24 #include "chrome/browser/ui/browser.h"
25 #include "chrome/browser/ui/browser_commands.h"
26 #include "chrome/browser/ui/browser_iterator.h"
27 #include "chrome/browser/ui/tabs/tab_strip_model.h"
28 #include "chrome/common/chrome_paths.h"
29 #include "chrome/common/chrome_switches.h"
30 #include "chrome/common/url_constants.h"
31 #include "chrome/test/base/in_process_browser_test.h"
32 #include "chrome/test/base/test_switches.h"
33 #include "chrome/test/base/ui_test_utils.h"
34 #include "components/app_modal/javascript_app_modal_dialog.h"
35 #include "components/app_modal/native_app_modal_dialog.h"
36 #include "content/public/browser/child_process_data.h"
37 #include "content/public/browser/content_browser_client.h"
38 #include "content/public/browser/devtools_agent_host.h"
39 #include "content/public/browser/devtools_http_handler.h"
40 #include "content/public/browser/notification_registrar.h"
41 #include "content/public/browser/notification_service.h"
42 #include "content/public/browser/render_view_host.h"
43 #include "content/public/browser/web_contents.h"
44 #include "content/public/browser/worker_service.h"
45 #include "content/public/browser/worker_service_observer.h"
46 #include "content/public/common/content_switches.h"
47 #include "content/public/test/browser_test_utils.h"
48 #include "extensions/browser/extension_registry.h"
49 #include "extensions/browser/extension_system.h"
50 #include "extensions/browser/notification_types.h"
51 #include "extensions/common/switches.h"
52 #include "net/socket/tcp_listen_socket.h"
53 #include "net/test/spawned_test_server/spawned_test_server.h"
55 using app_modal::AppModalDialog;
56 using app_modal::JavaScriptAppModalDialog;
57 using app_modal::NativeAppModalDialog;
58 using content::BrowserThread;
59 using content::DevToolsAgentHost;
60 using content::NavigationController;
61 using content::RenderViewHost;
62 using content::WebContents;
63 using content::WorkerService;
64 using content::WorkerServiceObserver;
66 namespace {
68 const char kDebuggerTestPage[] = "files/devtools/debugger_test_page.html";
69 const char kPauseWhenLoadingDevTools[] =
70 "files/devtools/pause_when_loading_devtools.html";
71 const char kPauseWhenScriptIsRunning[] =
72 "files/devtools/pause_when_script_is_running.html";
73 const char kPageWithContentScript[] =
74 "files/devtools/page_with_content_script.html";
75 const char kNavigateBackTestPage[] =
76 "files/devtools/navigate_back.html";
77 const char kChunkedTestPage[] = "chunked";
78 const char kSlowTestPage[] =
79 "chunked?waitBeforeHeaders=100&waitBetweenChunks=100&chunksNumber=2";
80 const char kSharedWorkerTestPage[] =
81 "files/workers/workers_ui_shared_worker.html";
82 const char kSharedWorkerTestWorker[] =
83 "files/workers/workers_ui_shared_worker.js";
84 const char kReloadSharedWorkerTestPage[] =
85 "files/workers/debug_shared_worker_initialization.html";
86 const char kReloadSharedWorkerTestWorker[] =
87 "files/workers/debug_shared_worker_initialization.js";
89 void RunTestFunction(DevToolsWindow* window, const char* test_name) {
90 std::string result;
92 RenderViewHost* rvh = DevToolsWindowTesting::Get(window)->
93 main_web_contents()->GetRenderViewHost();
94 // At first check that JavaScript part of the front-end is loaded by
95 // checking that global variable uiTests exists(it's created after all js
96 // files have been loaded) and has runTest method.
97 ASSERT_TRUE(
98 content::ExecuteScriptAndExtractString(
99 rvh,
100 "window.domAutomationController.send("
101 " '' + (window.uiTests && (typeof uiTests.runTest)));",
102 &result));
104 ASSERT_EQ("function", result) << "DevTools front-end is broken.";
105 ASSERT_TRUE(content::ExecuteScriptAndExtractString(
106 rvh,
107 base::StringPrintf("uiTests.runTest('%s')", test_name),
108 &result));
109 EXPECT_EQ("[OK]", result);
112 } // namespace
114 class DevToolsSanityTest : public InProcessBrowserTest {
115 public:
116 DevToolsSanityTest() : window_(NULL) {}
118 protected:
119 void RunTest(const std::string& test_name, const std::string& test_page) {
120 OpenDevToolsWindow(test_page, false);
121 RunTestFunction(window_, test_name.c_str());
122 CloseDevToolsWindow();
125 void LoadTestPage(const std::string& test_page) {
126 GURL url = test_server()->GetURL(test_page);
127 ui_test_utils::NavigateToURL(browser(), url);
130 void OpenDevToolsWindow(const std::string& test_page, bool is_docked) {
131 ASSERT_TRUE(test_server()->Start());
132 LoadTestPage(test_page);
134 window_ = DevToolsWindowTesting::OpenDevToolsWindowSync(GetInspectedTab(),
135 is_docked);
138 WebContents* GetInspectedTab() {
139 return browser()->tab_strip_model()->GetWebContentsAt(0);
142 void CloseDevToolsWindow() {
143 DevToolsWindowTesting::CloseDevToolsWindowSync(window_);
146 WebContents* main_web_contents() {
147 return DevToolsWindowTesting::Get(window_)->main_web_contents();
150 WebContents* toolbox_web_contents() {
151 return DevToolsWindowTesting::Get(window_)->toolbox_web_contents();
154 DevToolsWindow* window_;
157 // Used to block until a dev tools window gets beforeunload event.
158 class DevToolsWindowBeforeUnloadObserver
159 : public content::WebContentsObserver {
160 public:
161 explicit DevToolsWindowBeforeUnloadObserver(DevToolsWindow*);
162 void Wait();
163 private:
164 // Invoked when the beforeunload handler fires.
165 void BeforeUnloadFired(const base::TimeTicks& proceed_time) override;
167 bool m_fired;
168 scoped_refptr<content::MessageLoopRunner> message_loop_runner_;
169 DISALLOW_COPY_AND_ASSIGN(DevToolsWindowBeforeUnloadObserver);
172 DevToolsWindowBeforeUnloadObserver::DevToolsWindowBeforeUnloadObserver(
173 DevToolsWindow* devtools_window)
174 : WebContentsObserver(
175 DevToolsWindowTesting::Get(devtools_window)->main_web_contents()),
176 m_fired(false) {
179 void DevToolsWindowBeforeUnloadObserver::Wait() {
180 if (m_fired)
181 return;
182 message_loop_runner_ = new content::MessageLoopRunner;
183 message_loop_runner_->Run();
186 void DevToolsWindowBeforeUnloadObserver::BeforeUnloadFired(
187 const base::TimeTicks& proceed_time) {
188 m_fired = true;
189 if (message_loop_runner_.get())
190 message_loop_runner_->Quit();
193 class DevToolsBeforeUnloadTest: public DevToolsSanityTest {
194 public:
195 void SetUpCommandLine(base::CommandLine* command_line) override {
196 command_line->AppendSwitch(
197 switches::kDisableHangMonitor);
200 void CloseInspectedTab() {
201 browser()->tab_strip_model()->CloseWebContentsAt(0,
202 TabStripModel::CLOSE_NONE);
205 void CloseDevToolsWindowAsync() {
206 DevToolsWindowTesting::CloseDevToolsWindow(window_);
209 void CloseInspectedBrowser() {
210 chrome::CloseWindow(browser());
213 protected:
214 void InjectBeforeUnloadListener(content::WebContents* web_contents) {
215 ASSERT_TRUE(content::ExecuteScript(web_contents->GetRenderViewHost(),
216 "window.addEventListener('beforeunload',"
217 "function(event) { event.returnValue = 'Foo'; });"));
220 void RunBeforeUnloadSanityTest(bool is_docked,
221 base::Callback<void(void)> close_method,
222 bool wait_for_browser_close = true) {
223 OpenDevToolsWindow(kDebuggerTestPage, is_docked);
224 scoped_refptr<content::MessageLoopRunner> runner =
225 new content::MessageLoopRunner;
226 DevToolsWindowTesting::Get(window_)->
227 SetCloseCallback(runner->QuitClosure());
228 InjectBeforeUnloadListener(main_web_contents());
230 DevToolsWindowBeforeUnloadObserver before_unload_observer(window_);
231 close_method.Run();
232 CancelModalDialog();
233 before_unload_observer.Wait();
236 content::WindowedNotificationObserver close_observer(
237 chrome::NOTIFICATION_BROWSER_CLOSED,
238 content::Source<Browser>(browser()));
239 close_method.Run();
240 AcceptModalDialog();
241 if (wait_for_browser_close)
242 close_observer.Wait();
244 runner->Run();
247 DevToolsWindow* OpenDevToolWindowOnWebContents(
248 content::WebContents* contents, bool is_docked) {
249 DevToolsWindow* window =
250 DevToolsWindowTesting::OpenDevToolsWindowSync(contents, is_docked);
251 return window;
254 void OpenDevToolsPopupWindow(DevToolsWindow* devtools_window) {
255 content::WindowedNotificationObserver observer(
256 content::NOTIFICATION_LOAD_STOP,
257 content::NotificationService::AllSources());
258 ASSERT_TRUE(content::ExecuteScript(
259 DevToolsWindowTesting::Get(devtools_window)->
260 main_web_contents()->GetRenderViewHost(),
261 "window.open(\"\", \"\", \"location=0\");"));
262 observer.Wait();
265 void CloseDevToolsPopupWindow(DevToolsWindow* devtools_window) {
266 DevToolsWindowTesting::CloseDevToolsWindowSync(devtools_window);
269 void AcceptModalDialog() {
270 NativeAppModalDialog* native_dialog = GetDialog();
271 native_dialog->AcceptAppModalDialog();
274 void CancelModalDialog() {
275 NativeAppModalDialog* native_dialog = GetDialog();
276 native_dialog->CancelAppModalDialog();
279 NativeAppModalDialog* GetDialog() {
280 AppModalDialog* dialog = ui_test_utils::WaitForAppModalDialog();
281 EXPECT_TRUE(dialog->IsJavaScriptModalDialog());
282 JavaScriptAppModalDialog* js_dialog =
283 static_cast<JavaScriptAppModalDialog*>(dialog);
284 NativeAppModalDialog* native_dialog = js_dialog->native_dialog();
285 EXPECT_TRUE(native_dialog);
286 return native_dialog;
290 class DevToolsUnresponsiveBeforeUnloadTest: public DevToolsBeforeUnloadTest {
291 public:
292 void SetUpCommandLine(base::CommandLine* command_line) override {}
295 void TimeoutCallback(const std::string& timeout_message) {
296 ADD_FAILURE() << timeout_message;
297 base::MessageLoop::current()->Quit();
300 // Base class for DevTools tests that test devtools functionality for
301 // extensions and content scripts.
302 class DevToolsExtensionTest : public DevToolsSanityTest,
303 public content::NotificationObserver {
304 public:
305 DevToolsExtensionTest() : DevToolsSanityTest() {
306 PathService::Get(chrome::DIR_TEST_DATA, &test_extensions_dir_);
307 test_extensions_dir_ = test_extensions_dir_.AppendASCII("devtools");
308 test_extensions_dir_ = test_extensions_dir_.AppendASCII("extensions");
311 protected:
312 // Load an extension from test\data\devtools\extensions\<extension_name>
313 void LoadExtension(const char* extension_name) {
314 base::FilePath path = test_extensions_dir_.AppendASCII(extension_name);
315 ASSERT_TRUE(LoadExtensionFromPath(path)) << "Failed to load extension.";
318 private:
319 bool LoadExtensionFromPath(const base::FilePath& path) {
320 ExtensionService* service = extensions::ExtensionSystem::Get(
321 browser()->profile())->extension_service();
322 extensions::ExtensionRegistry* registry =
323 extensions::ExtensionRegistry::Get(browser()->profile());
324 size_t num_before = registry->enabled_extensions().size();
326 content::NotificationRegistrar registrar;
327 registrar.Add(this,
328 extensions::NOTIFICATION_EXTENSION_LOADED_DEPRECATED,
329 content::NotificationService::AllSources());
330 base::CancelableClosure timeout(
331 base::Bind(&TimeoutCallback, "Extension load timed out."));
332 base::MessageLoop::current()->PostDelayedTask(
333 FROM_HERE, timeout.callback(), TestTimeouts::action_timeout());
334 extensions::UnpackedInstaller::Create(service)->Load(path);
335 content::RunMessageLoop();
336 timeout.Cancel();
338 size_t num_after = registry->enabled_extensions().size();
339 if (num_after != (num_before + 1))
340 return false;
342 return WaitForExtensionViewsToLoad();
345 bool WaitForExtensionViewsToLoad() {
346 // Wait for all the extension render views that exist to finish loading.
347 // NOTE: This assumes that the extension views list is not changing while
348 // this method is running.
350 content::NotificationRegistrar registrar;
351 registrar.Add(this,
352 extensions::NOTIFICATION_EXTENSION_HOST_DID_STOP_LOADING,
353 content::NotificationService::AllSources());
354 base::CancelableClosure timeout(
355 base::Bind(&TimeoutCallback, "Extension host load timed out."));
356 base::MessageLoop::current()->PostDelayedTask(
357 FROM_HERE, timeout.callback(), TestTimeouts::action_timeout());
359 extensions::ProcessManager* manager =
360 extensions::ProcessManager::Get(browser()->profile());
361 extensions::ProcessManager::ViewSet all_views = manager->GetAllViews();
362 for (extensions::ProcessManager::ViewSet::const_iterator iter =
363 all_views.begin();
364 iter != all_views.end();) {
365 if (!(*iter)->IsLoading())
366 ++iter;
367 else
368 content::RunMessageLoop();
371 timeout.Cancel();
372 return true;
375 void Observe(int type,
376 const content::NotificationSource& source,
377 const content::NotificationDetails& details) override {
378 switch (type) {
379 case extensions::NOTIFICATION_EXTENSION_LOADED_DEPRECATED:
380 case extensions::NOTIFICATION_EXTENSION_HOST_DID_STOP_LOADING:
381 base::MessageLoopForUI::current()->Quit();
382 break;
383 default:
384 NOTREACHED();
385 break;
389 base::FilePath test_extensions_dir_;
392 class DevToolsExperimentalExtensionTest : public DevToolsExtensionTest {
393 public:
394 void SetUpCommandLine(base::CommandLine* command_line) override {
395 command_line->AppendSwitch(
396 extensions::switches::kEnableExperimentalExtensionApis);
400 class WorkerDevToolsSanityTest : public InProcessBrowserTest {
401 public:
402 WorkerDevToolsSanityTest() : window_(NULL) {}
404 protected:
405 class WorkerData : public base::RefCountedThreadSafe<WorkerData> {
406 public:
407 WorkerData() : worker_process_id(0), worker_route_id(0) {}
408 int worker_process_id;
409 int worker_route_id;
411 private:
412 friend class base::RefCountedThreadSafe<WorkerData>;
413 ~WorkerData() {}
416 class WorkerCreationObserver : public WorkerServiceObserver {
417 public:
418 explicit WorkerCreationObserver(const std::string& path,
419 WorkerData* worker_data)
420 : path_(path), worker_data_(worker_data) {}
422 private:
423 ~WorkerCreationObserver() override {}
425 void WorkerCreated(const GURL& url,
426 const base::string16& name,
427 int process_id,
428 int route_id) override {
429 if (url.path().rfind(path_) == std::string::npos)
430 return;
431 worker_data_->worker_process_id = process_id;
432 worker_data_->worker_route_id = route_id;
433 WorkerService::GetInstance()->RemoveObserver(this);
434 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
435 base::MessageLoop::QuitClosure());
436 delete this;
438 std::string path_;
439 scoped_refptr<WorkerData> worker_data_;
442 class WorkerTerminationObserver : public WorkerServiceObserver {
443 public:
444 explicit WorkerTerminationObserver(WorkerData* worker_data)
445 : worker_data_(worker_data) {
448 private:
449 ~WorkerTerminationObserver() override {}
451 void WorkerDestroyed(int process_id, int route_id) override {
452 ASSERT_EQ(worker_data_->worker_process_id, process_id);
453 ASSERT_EQ(worker_data_->worker_route_id, route_id);
454 WorkerService::GetInstance()->RemoveObserver(this);
455 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
456 base::MessageLoop::QuitClosure());
457 delete this;
459 scoped_refptr<WorkerData> worker_data_;
462 void RunTest(const char* test_name,
463 const char* test_page,
464 const char* worker_path) {
465 ASSERT_TRUE(test_server()->Start());
466 GURL url = test_server()->GetURL(test_page);
467 ui_test_utils::NavigateToURL(browser(), url);
469 scoped_refptr<WorkerData> worker_data =
470 WaitForFirstSharedWorker(worker_path);
471 OpenDevToolsWindowForSharedWorker(worker_data.get());
472 RunTestFunction(window_, test_name);
473 CloseDevToolsWindow();
476 static void TerminateWorkerOnIOThread(scoped_refptr<WorkerData> worker_data) {
477 if (!WorkerService::GetInstance()->TerminateWorker(
478 worker_data->worker_process_id, worker_data->worker_route_id))
479 FAIL() << "Failed to terminate worker.\n";
480 WorkerService::GetInstance()->AddObserver(
481 new WorkerTerminationObserver(worker_data.get()));
484 static void TerminateWorker(scoped_refptr<WorkerData> worker_data) {
485 BrowserThread::PostTask(
486 BrowserThread::IO, FROM_HERE,
487 base::Bind(&TerminateWorkerOnIOThread, worker_data));
488 content::RunMessageLoop();
491 static void WaitForFirstSharedWorkerOnIOThread(
492 const std::string& path,
493 scoped_refptr<WorkerData> worker_data) {
494 std::vector<WorkerService::WorkerInfo> worker_info =
495 WorkerService::GetInstance()->GetWorkers();
496 for (size_t i = 0; i < worker_info.size(); i++) {
497 if (worker_info[i].url.path().rfind(path) == std::string::npos)
498 continue;
499 worker_data->worker_process_id = worker_info[0].process_id;
500 worker_data->worker_route_id = worker_info[0].route_id;
501 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
502 base::MessageLoop::QuitClosure());
503 return;
506 WorkerService::GetInstance()->AddObserver(
507 new WorkerCreationObserver(path, worker_data.get()));
510 static scoped_refptr<WorkerData> WaitForFirstSharedWorker(const char* path) {
511 scoped_refptr<WorkerData> worker_data(new WorkerData());
512 BrowserThread::PostTask(
513 BrowserThread::IO,
514 FROM_HERE,
515 base::Bind(&WaitForFirstSharedWorkerOnIOThread, path, worker_data));
516 content::RunMessageLoop();
517 return worker_data;
520 void OpenDevToolsWindowForSharedWorker(WorkerData* worker_data) {
521 Profile* profile = browser()->profile();
522 scoped_refptr<DevToolsAgentHost> agent_host(
523 DevToolsAgentHost::GetForWorker(
524 worker_data->worker_process_id,
525 worker_data->worker_route_id));
526 window_ = DevToolsWindowTesting::OpenDevToolsWindowForWorkerSync(
527 profile, agent_host.get());
530 void CloseDevToolsWindow() {
531 DevToolsWindowTesting::CloseDevToolsWindowSync(window_);
534 DevToolsWindow* window_;
537 // Tests that BeforeUnload event gets called on docked devtools if
538 // we try to close them.
539 IN_PROC_BROWSER_TEST_F(DevToolsBeforeUnloadTest, TestDockedDevToolsClose) {
540 RunBeforeUnloadSanityTest(true, base::Bind(
541 &DevToolsBeforeUnloadTest::CloseDevToolsWindowAsync, this), false);
544 // Tests that BeforeUnload event gets called on docked devtools if
545 // we try to close the inspected page.
546 IN_PROC_BROWSER_TEST_F(DevToolsBeforeUnloadTest,
547 TestDockedDevToolsInspectedTabClose) {
548 RunBeforeUnloadSanityTest(true, base::Bind(
549 &DevToolsBeforeUnloadTest::CloseInspectedTab, this));
552 // Tests that BeforeUnload event gets called on docked devtools if
553 // we try to close the inspected browser.
554 IN_PROC_BROWSER_TEST_F(DevToolsBeforeUnloadTest,
555 TestDockedDevToolsInspectedBrowserClose) {
556 RunBeforeUnloadSanityTest(true, base::Bind(
557 &DevToolsBeforeUnloadTest::CloseInspectedBrowser, this));
560 // Tests that BeforeUnload event gets called on undocked devtools if
561 // we try to close them.
562 IN_PROC_BROWSER_TEST_F(DevToolsBeforeUnloadTest, TestUndockedDevToolsClose) {
563 RunBeforeUnloadSanityTest(false, base::Bind(
564 &DevToolsBeforeUnloadTest::CloseDevToolsWindowAsync, this), false);
567 // Tests that BeforeUnload event gets called on undocked devtools if
568 // we try to close the inspected page.
569 IN_PROC_BROWSER_TEST_F(DevToolsBeforeUnloadTest,
570 TestUndockedDevToolsInspectedTabClose) {
571 RunBeforeUnloadSanityTest(false, base::Bind(
572 &DevToolsBeforeUnloadTest::CloseInspectedTab, this));
575 // Tests that BeforeUnload event gets called on undocked devtools if
576 // we try to close the inspected browser.
577 IN_PROC_BROWSER_TEST_F(DevToolsBeforeUnloadTest,
578 TestUndockedDevToolsInspectedBrowserClose) {
579 RunBeforeUnloadSanityTest(false, base::Bind(
580 &DevToolsBeforeUnloadTest::CloseInspectedBrowser, this));
583 // Tests that BeforeUnload event gets called on undocked devtools if
584 // we try to exit application.
585 IN_PROC_BROWSER_TEST_F(DevToolsBeforeUnloadTest,
586 TestUndockedDevToolsApplicationClose) {
587 RunBeforeUnloadSanityTest(false, base::Bind(
588 &chrome::CloseAllBrowsers));
591 // Times out on Win and Linux
592 // @see http://crbug.com/410327
593 #if defined(OS_WIN) || (defined(OS_LINUX) && !defined(OS_CHROMEOS))
594 #define MAYBE_TestUndockedDevToolsUnresponsive DISABLED_TestUndockedDevToolsUnresponsive
595 #else
596 #define MAYBE_TestUndockedDevToolsUnresponsive TestUndockedDevToolsUnresponsive
597 #endif
599 // Tests that inspected tab gets closed if devtools renderer
600 // becomes unresponsive during beforeunload event interception.
601 // @see http://crbug.com/322380
602 IN_PROC_BROWSER_TEST_F(DevToolsUnresponsiveBeforeUnloadTest,
603 MAYBE_TestUndockedDevToolsUnresponsive) {
604 ASSERT_TRUE(test_server()->Start());
605 LoadTestPage(kDebuggerTestPage);
606 DevToolsWindow* devtools_window = OpenDevToolWindowOnWebContents(
607 GetInspectedTab(), false);
609 scoped_refptr<content::MessageLoopRunner> runner =
610 new content::MessageLoopRunner;
611 DevToolsWindowTesting::Get(devtools_window)->SetCloseCallback(
612 runner->QuitClosure());
614 ASSERT_TRUE(content::ExecuteScript(
615 DevToolsWindowTesting::Get(devtools_window)->main_web_contents()->
616 GetRenderViewHost(),
617 "window.addEventListener('beforeunload',"
618 "function(event) { while (true); });"));
619 CloseInspectedTab();
620 runner->Run();
623 // Tests that closing worker inspector window does not cause browser crash
624 // @see http://crbug.com/323031
625 IN_PROC_BROWSER_TEST_F(DevToolsBeforeUnloadTest,
626 TestWorkerWindowClosing) {
627 ASSERT_TRUE(test_server()->Start());
628 LoadTestPage(kDebuggerTestPage);
629 DevToolsWindow* devtools_window = OpenDevToolWindowOnWebContents(
630 GetInspectedTab(), false);
632 OpenDevToolsPopupWindow(devtools_window);
633 CloseDevToolsPopupWindow(devtools_window);
636 // Tests that BeforeUnload event gets called on devtools that are opened
637 // on another devtools.
638 IN_PROC_BROWSER_TEST_F(DevToolsBeforeUnloadTest,
639 TestDevToolsOnDevTools) {
640 ASSERT_TRUE(test_server()->Start());
641 LoadTestPage(kDebuggerTestPage);
643 std::vector<DevToolsWindow*> windows;
644 std::vector<content::WindowedNotificationObserver*> close_observers;
645 content::WebContents* inspected_web_contents = GetInspectedTab();
646 for (int i = 0; i < 3; ++i) {
647 DevToolsWindow* devtools_window = OpenDevToolWindowOnWebContents(
648 inspected_web_contents, i == 0);
649 windows.push_back(devtools_window);
650 content::WindowedNotificationObserver* close_observer =
651 new content::WindowedNotificationObserver(
652 content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
653 content::Source<content::WebContents>(
654 DevToolsWindowTesting::Get(devtools_window)->
655 main_web_contents()));
656 close_observers.push_back(close_observer);
657 inspected_web_contents =
658 DevToolsWindowTesting::Get(devtools_window)->main_web_contents();
661 InjectBeforeUnloadListener(
662 DevToolsWindowTesting::Get(windows[0])->main_web_contents());
663 InjectBeforeUnloadListener(
664 DevToolsWindowTesting::Get(windows[2])->main_web_contents());
665 // Try to close second devtools.
667 content::WindowedNotificationObserver cancel_browser(
668 chrome::NOTIFICATION_BROWSER_CLOSE_CANCELLED,
669 content::NotificationService::AllSources());
670 chrome::CloseWindow(DevToolsWindowTesting::Get(windows[1])->browser());
671 CancelModalDialog();
672 cancel_browser.Wait();
674 // Try to close browser window.
676 content::WindowedNotificationObserver cancel_browser(
677 chrome::NOTIFICATION_BROWSER_CLOSE_CANCELLED,
678 content::NotificationService::AllSources());
679 chrome::CloseWindow(browser());
680 AcceptModalDialog();
681 CancelModalDialog();
682 cancel_browser.Wait();
684 // Try to exit application.
686 content::WindowedNotificationObserver close_observer(
687 chrome::NOTIFICATION_BROWSER_CLOSED,
688 content::Source<Browser>(browser()));
689 chrome::IncrementKeepAliveCount();
690 chrome::CloseAllBrowsers();
691 AcceptModalDialog();
692 AcceptModalDialog();
693 close_observer.Wait();
695 for (size_t i = 0; i < close_observers.size(); ++i) {
696 close_observers[i]->Wait();
697 delete close_observers[i];
701 // Tests scripts panel showing.
702 IN_PROC_BROWSER_TEST_F(DevToolsSanityTest, TestShowScriptsTab) {
703 RunTest("testShowScriptsTab", kDebuggerTestPage);
706 // Tests that scripts tab is populated with inspected scripts even if it
707 // hadn't been shown by the moment inspected paged refreshed.
708 // @see http://crbug.com/26312
709 IN_PROC_BROWSER_TEST_F(
710 DevToolsSanityTest,
711 TestScriptsTabIsPopulatedOnInspectedPageRefresh) {
712 RunTest("testScriptsTabIsPopulatedOnInspectedPageRefresh",
713 kDebuggerTestPage);
716 // Tests that chrome.devtools extension is correctly exposed.
717 IN_PROC_BROWSER_TEST_F(DevToolsExtensionTest,
718 TestDevToolsExtensionAPI) {
719 LoadExtension("devtools_extension");
720 RunTest("waitForTestResultsInConsole", std::string());
723 // Disabled on Windows due to flakiness. http://crbug.com/183649
724 #if defined(OS_WIN)
725 #define MAYBE_TestDevToolsExtensionMessaging DISABLED_TestDevToolsExtensionMessaging
726 #else
727 #define MAYBE_TestDevToolsExtensionMessaging TestDevToolsExtensionMessaging
728 #endif
730 // Tests that chrome.devtools extension can communicate with background page
731 // using extension messaging.
732 IN_PROC_BROWSER_TEST_F(DevToolsExtensionTest,
733 MAYBE_TestDevToolsExtensionMessaging) {
734 LoadExtension("devtools_messaging");
735 RunTest("waitForTestResultsInConsole", std::string());
738 // Tests that chrome.experimental.devtools extension is correctly exposed
739 // when the extension has experimental permission.
740 IN_PROC_BROWSER_TEST_F(DevToolsExperimentalExtensionTest,
741 TestDevToolsExperimentalExtensionAPI) {
742 LoadExtension("devtools_experimental");
743 RunTest("waitForTestResultsInConsole", std::string());
746 // Tests that a content script is in the scripts list.
747 IN_PROC_BROWSER_TEST_F(DevToolsExtensionTest,
748 TestContentScriptIsPresent) {
749 LoadExtension("simple_content_script");
750 RunTest("testContentScriptIsPresent", kPageWithContentScript);
753 // Tests that scripts are not duplicated after Scripts Panel switch.
754 IN_PROC_BROWSER_TEST_F(DevToolsSanityTest,
755 TestNoScriptDuplicatesOnPanelSwitch) {
756 RunTest("testNoScriptDuplicatesOnPanelSwitch", kDebuggerTestPage);
759 // Tests that debugger works correctly if pause event occurs when DevTools
760 // frontend is being loaded.
761 IN_PROC_BROWSER_TEST_F(DevToolsSanityTest,
762 TestPauseWhenLoadingDevTools) {
763 RunTest("testPauseWhenLoadingDevTools", kPauseWhenLoadingDevTools);
766 // Tests that pressing 'Pause' will pause script execution if the script
767 // is already running.
768 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(ARCH_CPU_ARM_FAMILY)
769 // Timing out on linux ARM bot: https://crbug/238453
770 #define MAYBE_TestPauseWhenScriptIsRunning DISABLED_TestPauseWhenScriptIsRunning
771 #else
772 #define MAYBE_TestPauseWhenScriptIsRunning TestPauseWhenScriptIsRunning
773 #endif
774 IN_PROC_BROWSER_TEST_F(DevToolsSanityTest,
775 MAYBE_TestPauseWhenScriptIsRunning) {
776 RunTest("testPauseWhenScriptIsRunning", kPauseWhenScriptIsRunning);
779 // Tests network timing.
780 IN_PROC_BROWSER_TEST_F(DevToolsSanityTest, TestNetworkTiming) {
781 RunTest("testNetworkTiming", kSlowTestPage);
784 // Tests network size.
785 IN_PROC_BROWSER_TEST_F(DevToolsSanityTest, TestNetworkSize) {
786 RunTest("testNetworkSize", kChunkedTestPage);
789 // Tests raw headers text.
790 IN_PROC_BROWSER_TEST_F(DevToolsSanityTest, TestNetworkSyncSize) {
791 RunTest("testNetworkSyncSize", kChunkedTestPage);
794 // Tests raw headers text.
795 IN_PROC_BROWSER_TEST_F(DevToolsSanityTest, TestNetworkRawHeadersText) {
796 RunTest("testNetworkRawHeadersText", kChunkedTestPage);
799 // Tests that console messages are not duplicated on navigation back.
800 #if defined(OS_WIN)
801 // Flaking on windows swarm try runs: crbug.com/409285.
802 #define MAYBE_TestConsoleOnNavigateBack DISABLED_TestConsoleOnNavigateBack
803 #else
804 #define MAYBE_TestConsoleOnNavigateBack TestConsoleOnNavigateBack
805 #endif
806 IN_PROC_BROWSER_TEST_F(DevToolsSanityTest, MAYBE_TestConsoleOnNavigateBack) {
807 RunTest("testConsoleOnNavigateBack", kNavigateBackTestPage);
810 // https://crbug.com/397889
811 IN_PROC_BROWSER_TEST_F(DevToolsSanityTest, DISABLED_TestDeviceEmulation) {
812 RunTest("testDeviceMetricsOverrides", "about:blank");
816 // Tests that external navigation from inspector page is always handled by
817 // DevToolsWindow and results in inspected page navigation.
818 IN_PROC_BROWSER_TEST_F(DevToolsSanityTest, TestDevToolsExternalNavigation) {
819 OpenDevToolsWindow(kDebuggerTestPage, true);
820 GURL url = test_server()->GetURL(kNavigateBackTestPage);
821 ui_test_utils::UrlLoadObserver observer(url,
822 content::NotificationService::AllSources());
823 ASSERT_TRUE(content::ExecuteScript(
824 main_web_contents(),
825 std::string("window.location = \"") + url.spec() + "\""));
826 observer.Wait();
828 ASSERT_TRUE(main_web_contents()->GetURL().
829 SchemeIs(content::kChromeDevToolsScheme));
830 ASSERT_EQ(url, GetInspectedTab()->GetURL());
831 CloseDevToolsWindow();
834 // Tests that toolbox window is loaded when DevTools window is undocked.
835 IN_PROC_BROWSER_TEST_F(DevToolsSanityTest, TestToolboxLoadedUndocked) {
836 OpenDevToolsWindow(kDebuggerTestPage, false);
837 ASSERT_TRUE(toolbox_web_contents());
838 DevToolsWindow* on_self =
839 DevToolsWindowTesting::OpenDevToolsWindowSync(main_web_contents(), false);
840 ASSERT_FALSE(DevToolsWindowTesting::Get(on_self)->toolbox_web_contents());
841 DevToolsWindowTesting::CloseDevToolsWindowSync(on_self);
842 CloseDevToolsWindow();
845 // Tests that toolbox window is not loaded when DevTools window is docked.
846 IN_PROC_BROWSER_TEST_F(DevToolsSanityTest, TestToolboxNotLoadedDocked) {
847 OpenDevToolsWindow(kDebuggerTestPage, true);
848 ASSERT_FALSE(toolbox_web_contents());
849 DevToolsWindow* on_self =
850 DevToolsWindowTesting::OpenDevToolsWindowSync(main_web_contents(), false);
851 ASSERT_FALSE(DevToolsWindowTesting::Get(on_self)->toolbox_web_contents());
852 DevToolsWindowTesting::CloseDevToolsWindowSync(on_self);
853 CloseDevToolsWindow();
856 // Tests that inspector will reattach to inspected page when it is reloaded
857 // after a crash. See http://crbug.com/101952
858 IN_PROC_BROWSER_TEST_F(DevToolsSanityTest, TestReattachAfterCrash) {
859 RunTest("testReattachAfterCrash", std::string());
862 IN_PROC_BROWSER_TEST_F(DevToolsSanityTest, TestPageWithNoJavaScript) {
863 OpenDevToolsWindow("about:blank", false);
864 std::string result;
865 ASSERT_TRUE(
866 content::ExecuteScriptAndExtractString(
867 main_web_contents()->GetRenderViewHost(),
868 "window.domAutomationController.send("
869 " '' + (window.uiTests && (typeof uiTests.runTest)));",
870 &result));
871 ASSERT_EQ("function", result) << "DevTools front-end is broken.";
872 CloseDevToolsWindow();
875 IN_PROC_BROWSER_TEST_F(WorkerDevToolsSanityTest, InspectSharedWorker) {
876 #if defined(OS_WIN) && defined(USE_ASH)
877 // Disable this test in Metro+Ash for now (http://crbug.com/262796).
878 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
879 switches::kAshBrowserTests))
880 return;
881 #endif
883 RunTest("testSharedWorker", kSharedWorkerTestPage, kSharedWorkerTestWorker);
886 // Disabled, crashes under Dr.Memory and ASan, http://crbug.com/432444.
887 IN_PROC_BROWSER_TEST_F(WorkerDevToolsSanityTest,
888 DISABLED_PauseInSharedWorkerInitialization) {
889 ASSERT_TRUE(test_server()->Start());
890 GURL url = test_server()->GetURL(kReloadSharedWorkerTestPage);
891 ui_test_utils::NavigateToURL(browser(), url);
893 scoped_refptr<WorkerData> worker_data =
894 WaitForFirstSharedWorker(kReloadSharedWorkerTestWorker);
895 OpenDevToolsWindowForSharedWorker(worker_data.get());
897 // We should make sure that the worker inspector has loaded before
898 // terminating worker.
899 RunTestFunction(window_, "testPauseInSharedWorkerInitialization1");
901 TerminateWorker(worker_data);
903 // Reload page to restart the worker.
904 ui_test_utils::NavigateToURL(browser(), url);
906 // Wait until worker script is paused on the debugger statement.
907 RunTestFunction(window_, "testPauseInSharedWorkerInitialization2");
908 CloseDevToolsWindow();
911 class DevToolsAgentHostTest : public InProcessBrowserTest {};
913 // Tests DevToolsAgentHost retention by its target.
914 IN_PROC_BROWSER_TEST_F(DevToolsAgentHostTest, TestAgentHostReleased) {
915 ui_test_utils::NavigateToURL(browser(), GURL("about:blank"));
916 WebContents* web_contents = browser()->tab_strip_model()->GetWebContentsAt(0);
917 DevToolsAgentHost* agent_raw =
918 DevToolsAgentHost::GetOrCreateFor(web_contents).get();
919 const std::string agent_id = agent_raw->GetId();
920 ASSERT_EQ(agent_raw, DevToolsAgentHost::GetForId(agent_id).get())
921 << "DevToolsAgentHost cannot be found by id";
922 browser()->tab_strip_model()->
923 CloseWebContentsAt(0, TabStripModel::CLOSE_NONE);
924 ASSERT_FALSE(DevToolsAgentHost::GetForId(agent_id).get())
925 << "DevToolsAgentHost is not released when the tab is closed";
928 class RemoteDebuggingTest: public ExtensionApiTest {
929 void SetUpCommandLine(base::CommandLine* command_line) override {
930 ExtensionApiTest::SetUpCommandLine(command_line);
931 command_line->AppendSwitchASCII(switches::kRemoteDebuggingPort, "9222");
933 // Override the extension root path.
934 PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir_);
935 test_data_dir_ = test_data_dir_.AppendASCII("devtools");
939 // Fails on CrOS. crbug.com/431399
940 #if defined(OS_CHROMEOS)
941 #define MAYBE_RemoteDebugger DISABLED_RemoteDebugger
942 #else
943 #define MAYBE_RemoteDebugger RemoteDebugger
944 #endif
945 IN_PROC_BROWSER_TEST_F(RemoteDebuggingTest, MAYBE_RemoteDebugger) {
946 #if defined(OS_WIN) && defined(USE_ASH)
947 // Disable this test in Metro+Ash for now (http://crbug.com/262796).
948 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
949 switches::kAshBrowserTests))
950 return;
951 #endif
953 ASSERT_TRUE(RunExtensionTest("target_list")) << message_;