Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / devtools / devtools_sanity_browsertest.cc
blob5ce7a38823a021f84871d656b2211f92406fbe29
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.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/extension_system.h"
22 #include "chrome/browser/extensions/unpacked_installer.h"
23 #include "chrome/browser/lifetime/application_lifetime.h"
24 #include "chrome/browser/profiles/profile.h"
25 #include "chrome/browser/ui/app_modal_dialogs/javascript_app_modal_dialog.h"
26 #include "chrome/browser/ui/app_modal_dialogs/native_app_modal_dialog.h"
27 #include "chrome/browser/ui/browser.h"
28 #include "chrome/browser/ui/browser_commands.h"
29 #include "chrome/browser/ui/browser_iterator.h"
30 #include "chrome/browser/ui/tabs/tab_strip_model.h"
31 #include "chrome/common/chrome_paths.h"
32 #include "chrome/common/chrome_switches.h"
33 #include "chrome/common/pref_names.h"
34 #include "chrome/common/url_constants.h"
35 #include "chrome/test/base/in_process_browser_test.h"
36 #include "chrome/test/base/test_switches.h"
37 #include "chrome/test/base/ui_test_utils.h"
38 #include "content/public/browser/child_process_data.h"
39 #include "content/public/browser/content_browser_client.h"
40 #include "content/public/browser/devtools_agent_host.h"
41 #include "content/public/browser/devtools_client_host.h"
42 #include "content/public/browser/devtools_http_handler.h"
43 #include "content/public/browser/devtools_manager.h"
44 #include "content/public/browser/notification_registrar.h"
45 #include "content/public/browser/notification_service.h"
46 #include "content/public/browser/render_view_host.h"
47 #include "content/public/browser/web_contents.h"
48 #include "content/public/browser/worker_service.h"
49 #include "content/public/browser/worker_service_observer.h"
50 #include "content/public/common/content_switches.h"
51 #include "content/public/test/browser_test_utils.h"
52 #include "extensions/common/switches.h"
53 #include "net/socket/tcp_listen_socket.h"
54 #include "net/test/spawned_test_server/spawned_test_server.h"
56 using content::BrowserThread;
57 using content::DevToolsManager;
58 using content::DevToolsAgentHost;
59 using content::NavigationController;
60 using content::RenderViewHost;
61 using content::WebContents;
62 using content::WorkerService;
63 using content::WorkerServiceObserver;
65 namespace {
67 const char kDebuggerTestPage[] = "files/devtools/debugger_test_page.html";
68 const char kPauseWhenLoadingDevTools[] =
69 "files/devtools/pause_when_loading_devtools.html";
70 const char kPauseWhenScriptIsRunning[] =
71 "files/devtools/pause_when_script_is_running.html";
72 const char kPageWithContentScript[] =
73 "files/devtools/page_with_content_script.html";
74 const char kNavigateBackTestPage[] =
75 "files/devtools/navigate_back.html";
76 const char kChunkedTestPage[] = "chunked";
77 const char kSlowTestPage[] =
78 "chunked?waitBeforeHeaders=100&waitBetweenChunks=100&chunksNumber=2";
79 const char kSharedWorkerTestPage[] =
80 "files/workers/workers_ui_shared_worker.html";
81 const char kReloadSharedWorkerTestPage[] =
82 "files/workers/debug_shared_worker_initialization.html";
84 void RunTestFunction(DevToolsWindow* window, const char* test_name) {
85 std::string result;
87 // At first check that JavaScript part of the front-end is loaded by
88 // checking that global variable uiTests exists(it's created after all js
89 // files have been loaded) and has runTest method.
90 ASSERT_TRUE(
91 content::ExecuteScriptAndExtractString(
92 window->GetRenderViewHost(),
93 "window.domAutomationController.send("
94 " '' + (window.uiTests && (typeof uiTests.runTest)));",
95 &result));
97 if (result == "function") {
98 ASSERT_TRUE(
99 content::ExecuteScriptAndExtractString(
100 window->GetRenderViewHost(),
101 base::StringPrintf("uiTests.runTest('%s')", test_name),
102 &result));
103 EXPECT_EQ("[OK]", result);
104 } else {
105 FAIL() << "DevTools front-end is broken.";
109 } // namespace
111 class DevToolsSanityTest : public InProcessBrowserTest {
112 public:
113 DevToolsSanityTest()
114 : window_(NULL),
115 inspected_rvh_(NULL) {}
117 protected:
118 void RunTest(const std::string& test_name, const std::string& test_page) {
119 OpenDevToolsWindow(test_page, false);
120 RunTestFunction(window_, test_name.c_str());
121 CloseDevToolsWindow();
124 void LoadTestPage(const std::string& test_page) {
125 content::WindowedNotificationObserver load_observer(
126 content::NOTIFICATION_LOAD_STOP,
127 content::NotificationService::AllSources());
128 GURL url = test_server()->GetURL(test_page);
129 ui_test_utils::NavigateToURL(browser(), url);
130 load_observer.Wait();
133 void OpenDevToolsWindow(const std::string& test_page, bool is_docked) {
134 ASSERT_TRUE(test_server()->Start());
135 LoadTestPage(test_page);
137 content::WindowedNotificationObserver observer(
138 content::NOTIFICATION_LOAD_STOP,
139 content::NotificationService::AllSources());
140 inspected_rvh_ = GetInspectedTab()->GetRenderViewHost();
141 window_ =
142 DevToolsWindow::OpenDevToolsWindowForTest(inspected_rvh_, is_docked);
143 observer.Wait();
146 WebContents* GetInspectedTab() {
147 return browser()->tab_strip_model()->GetWebContentsAt(0);
150 void ToggleDevToolsWindow() {
151 content::WindowedNotificationObserver close_observer(
152 content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
153 content::Source<content::WebContents>(window_->web_contents()));
154 DevToolsWindow::ToggleDevToolsWindow(inspected_rvh_, false,
155 DevToolsToggleAction::Toggle());
156 close_observer.Wait();
159 void ToggleDevToolsWindowDontWait() {
160 DevToolsWindow::ToggleDevToolsWindow(inspected_rvh_, false,
161 DevToolsToggleAction::Toggle());
164 void CloseDevToolsWindow() {
165 DevToolsManager* devtools_manager = DevToolsManager::GetInstance();
166 content::WindowedNotificationObserver close_observer(
167 content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
168 content::Source<content::WebContents>(window_->web_contents()));
169 devtools_manager->CloseAllClientHosts();
170 close_observer.Wait();
173 DevToolsWindow* window_;
174 RenderViewHost* inspected_rvh_;
177 // Used to block until a dev tools window gets beforeunload event.
178 class DevToolsWindowBeforeUnloadObserver
179 : public content::WebContentsObserver {
180 public:
181 explicit DevToolsWindowBeforeUnloadObserver(DevToolsWindow*);
182 void Wait();
183 private:
184 // Invoked when the beforeunload handler fires.
185 virtual void BeforeUnloadFired(const base::TimeTicks& proceed_time) OVERRIDE;
187 bool m_fired;
188 scoped_refptr<content::MessageLoopRunner> message_loop_runner_;
189 DISALLOW_COPY_AND_ASSIGN(DevToolsWindowBeforeUnloadObserver);
192 DevToolsWindowBeforeUnloadObserver::DevToolsWindowBeforeUnloadObserver(
193 DevToolsWindow* devtools_window)
194 : WebContentsObserver(devtools_window->web_contents()),
195 m_fired(false) {
198 void DevToolsWindowBeforeUnloadObserver::Wait() {
199 if (m_fired)
200 return;
201 message_loop_runner_ = new content::MessageLoopRunner;
202 message_loop_runner_->Run();
205 void DevToolsWindowBeforeUnloadObserver::BeforeUnloadFired(
206 const base::TimeTicks& proceed_time) {
207 m_fired = true;
208 if (message_loop_runner_.get())
209 message_loop_runner_->Quit();
212 class DevToolsBeforeUnloadTest: public DevToolsSanityTest {
213 public:
214 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
215 command_line->AppendSwitch(
216 switches::kDisableHangMonitor);
219 void CloseInspectedTab() {
220 browser()->tab_strip_model()->CloseWebContentsAt(0,
221 TabStripModel::CLOSE_NONE);
224 void CloseDockedDevTools() {
225 ToggleDevToolsWindowDontWait();
228 void CloseUndockedDevTools() {
229 chrome::CloseWindow(window_->browser());
232 void CloseInspectedBrowser() {
233 chrome::CloseWindow(browser());
235 protected:
236 void InjectBeforeUnloadListener(content::WebContents* web_contents) {
237 ASSERT_TRUE(content::ExecuteScript(web_contents->GetRenderViewHost(),
238 "window.addEventListener('beforeunload',"
239 "function(event) { event.returnValue = 'Foo'; });"));
242 void RunBeforeUnloadSanityTest(bool is_docked,
243 base::Callback<void(void)> close_method,
244 bool wait_for_browser_close = true) {
245 OpenDevToolsWindow(kDebuggerTestPage, is_docked);
246 content::WindowedNotificationObserver devtools_close_observer(
247 content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
248 content::Source<content::WebContents>(window_->web_contents()));
249 InjectBeforeUnloadListener(window_->web_contents());
251 DevToolsWindowBeforeUnloadObserver before_unload_observer(window_);
252 close_method.Run();
253 CancelModalDialog();
254 before_unload_observer.Wait();
257 content::WindowedNotificationObserver close_observer(
258 chrome::NOTIFICATION_BROWSER_CLOSED,
259 content::Source<Browser>(browser()));
260 close_method.Run();
261 AcceptModalDialog();
262 if (wait_for_browser_close)
263 close_observer.Wait();
265 devtools_close_observer.Wait();
268 DevToolsWindow* OpenDevToolWindowOnWebContents(
269 content::WebContents* contents, bool is_docked) {
270 content::WindowedNotificationObserver observer(
271 content::NOTIFICATION_LOAD_STOP,
272 content::NotificationService::AllSources());
273 DevToolsWindow* window = DevToolsWindow::OpenDevToolsWindowForTest(
274 contents->GetRenderViewHost(), is_docked);
275 observer.Wait();
276 return window;
279 void OpenDevToolsPopupWindow(DevToolsWindow* devtools_window) {
280 content::WindowedNotificationObserver observer(
281 content::NOTIFICATION_LOAD_STOP,
282 content::NotificationService::AllSources());
283 ASSERT_TRUE(content::ExecuteScript(
284 devtools_window->web_contents()->GetRenderViewHost(),
285 "window.open(\"\", \"\", \"location=0\");"));
286 observer.Wait();
289 void CloseDevToolsPopupWindow(DevToolsWindow* devtools_window) {
290 Browser* popup_browser = NULL;
291 for (chrome::BrowserIterator it; !it.done(); it.Next()) {
292 if (it->is_devtools()) {
293 content::WebContents* contents =
294 it->tab_strip_model()->GetWebContentsAt(0);
295 if (devtools_window->web_contents() != contents) {
296 popup_browser = *it;
297 break;
301 ASSERT_FALSE(popup_browser == NULL);
302 content::WindowedNotificationObserver close_observer(
303 chrome::NOTIFICATION_BROWSER_CLOSED,
304 content::Source<Browser>(popup_browser));
305 chrome::CloseWindow(popup_browser);
306 close_observer.Wait();
309 void AcceptModalDialog() {
310 NativeAppModalDialog* native_dialog = GetDialog();
311 native_dialog->AcceptAppModalDialog();
314 void CancelModalDialog() {
315 NativeAppModalDialog* native_dialog = GetDialog();
316 native_dialog->CancelAppModalDialog();
319 NativeAppModalDialog* GetDialog() {
320 AppModalDialog* dialog = ui_test_utils::WaitForAppModalDialog();
321 EXPECT_TRUE(dialog->IsJavaScriptModalDialog());
322 JavaScriptAppModalDialog* js_dialog =
323 static_cast<JavaScriptAppModalDialog*>(dialog);
324 NativeAppModalDialog* native_dialog = js_dialog->native_dialog();
325 EXPECT_TRUE(native_dialog);
326 return native_dialog;
330 class DevToolsUnresponsiveBeforeUnloadTest: public DevToolsBeforeUnloadTest {
331 public:
332 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {}
335 void TimeoutCallback(const std::string& timeout_message) {
336 FAIL() << timeout_message;
337 base::MessageLoop::current()->Quit();
340 // Base class for DevTools tests that test devtools functionality for
341 // extensions and content scripts.
342 class DevToolsExtensionTest : public DevToolsSanityTest,
343 public content::NotificationObserver {
344 public:
345 DevToolsExtensionTest() : DevToolsSanityTest() {
346 PathService::Get(chrome::DIR_TEST_DATA, &test_extensions_dir_);
347 test_extensions_dir_ = test_extensions_dir_.AppendASCII("devtools");
348 test_extensions_dir_ = test_extensions_dir_.AppendASCII("extensions");
351 protected:
352 // Load an extension from test\data\devtools\extensions\<extension_name>
353 void LoadExtension(const char* extension_name) {
354 base::FilePath path = test_extensions_dir_.AppendASCII(extension_name);
355 ASSERT_TRUE(LoadExtensionFromPath(path)) << "Failed to load extension.";
358 private:
359 bool LoadExtensionFromPath(const base::FilePath& path) {
360 ExtensionService* service = extensions::ExtensionSystem::Get(
361 browser()->profile())->extension_service();
362 size_t num_before = service->extensions()->size();
364 content::NotificationRegistrar registrar;
365 registrar.Add(this, chrome::NOTIFICATION_EXTENSION_LOADED,
366 content::NotificationService::AllSources());
367 base::CancelableClosure timeout(
368 base::Bind(&TimeoutCallback, "Extension load timed out."));
369 base::MessageLoop::current()->PostDelayedTask(
370 FROM_HERE, timeout.callback(), TestTimeouts::action_timeout());
371 extensions::UnpackedInstaller::Create(service)->Load(path);
372 content::RunMessageLoop();
373 timeout.Cancel();
375 size_t num_after = service->extensions()->size();
376 if (num_after != (num_before + 1))
377 return false;
379 return WaitForExtensionViewsToLoad();
382 bool WaitForExtensionViewsToLoad() {
383 // Wait for all the extension render views that exist to finish loading.
384 // NOTE: This assumes that the extension views list is not changing while
385 // this method is running.
387 content::NotificationRegistrar registrar;
388 registrar.Add(this, chrome::NOTIFICATION_EXTENSION_HOST_DID_STOP_LOADING,
389 content::NotificationService::AllSources());
390 base::CancelableClosure timeout(
391 base::Bind(&TimeoutCallback, "Extension host load timed out."));
392 base::MessageLoop::current()->PostDelayedTask(
393 FROM_HERE, timeout.callback(), TestTimeouts::action_timeout());
395 extensions::ProcessManager* manager =
396 extensions::ExtensionSystem::Get(browser()->profile())->
397 process_manager();
398 extensions::ProcessManager::ViewSet all_views = manager->GetAllViews();
399 for (extensions::ProcessManager::ViewSet::const_iterator iter =
400 all_views.begin();
401 iter != all_views.end();) {
402 if (!(*iter)->IsLoading())
403 ++iter;
404 else
405 content::RunMessageLoop();
408 timeout.Cancel();
409 return true;
412 virtual void Observe(int type,
413 const content::NotificationSource& source,
414 const content::NotificationDetails& details) OVERRIDE {
415 switch (type) {
416 case chrome::NOTIFICATION_EXTENSION_LOADED:
417 case chrome::NOTIFICATION_EXTENSION_HOST_DID_STOP_LOADING:
418 base::MessageLoopForUI::current()->Quit();
419 break;
420 default:
421 NOTREACHED();
422 break;
426 base::FilePath test_extensions_dir_;
429 class DevToolsExperimentalExtensionTest : public DevToolsExtensionTest {
430 public:
431 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
432 command_line->AppendSwitch(
433 extensions::switches::kEnableExperimentalExtensionApis);
437 class WorkerDevToolsSanityTest : public InProcessBrowserTest {
438 public:
439 WorkerDevToolsSanityTest() : window_(NULL) {}
441 protected:
442 class WorkerData : public base::RefCountedThreadSafe<WorkerData> {
443 public:
444 WorkerData() : worker_process_id(0), worker_route_id(0) {}
445 int worker_process_id;
446 int worker_route_id;
448 private:
449 friend class base::RefCountedThreadSafe<WorkerData>;
450 ~WorkerData() {}
453 class WorkerCreationObserver : public WorkerServiceObserver {
454 public:
455 explicit WorkerCreationObserver(WorkerData* worker_data)
456 : worker_data_(worker_data) {
459 private:
460 virtual ~WorkerCreationObserver() {}
462 virtual void WorkerCreated (
463 const GURL& url,
464 const base::string16& name,
465 int process_id,
466 int route_id) OVERRIDE {
467 worker_data_->worker_process_id = process_id;
468 worker_data_->worker_route_id = route_id;
469 WorkerService::GetInstance()->RemoveObserver(this);
470 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
471 base::MessageLoop::QuitClosure());
472 delete this;
474 scoped_refptr<WorkerData> worker_data_;
477 class WorkerTerminationObserver : public WorkerServiceObserver {
478 public:
479 explicit WorkerTerminationObserver(WorkerData* worker_data)
480 : worker_data_(worker_data) {
483 private:
484 virtual ~WorkerTerminationObserver() {}
486 virtual void WorkerDestroyed(int process_id, int route_id) OVERRIDE {
487 ASSERT_EQ(worker_data_->worker_process_id, process_id);
488 ASSERT_EQ(worker_data_->worker_route_id, route_id);
489 WorkerService::GetInstance()->RemoveObserver(this);
490 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
491 base::MessageLoop::QuitClosure());
492 delete this;
494 scoped_refptr<WorkerData> worker_data_;
497 void RunTest(const char* test_name, const char* test_page) {
498 ASSERT_TRUE(test_server()->Start());
499 GURL url = test_server()->GetURL(test_page);
500 ui_test_utils::NavigateToURL(browser(), url);
502 scoped_refptr<WorkerData> worker_data = WaitForFirstSharedWorker();
503 OpenDevToolsWindowForSharedWorker(worker_data.get());
504 RunTestFunction(window_, test_name);
505 CloseDevToolsWindow();
508 static void TerminateWorkerOnIOThread(scoped_refptr<WorkerData> worker_data) {
509 if (WorkerService::GetInstance()->TerminateWorker(
510 worker_data->worker_process_id, worker_data->worker_route_id)) {
511 WorkerService::GetInstance()->AddObserver(
512 new WorkerTerminationObserver(worker_data.get()));
513 return;
515 FAIL() << "Failed to terminate worker.\n";
518 static void TerminateWorker(scoped_refptr<WorkerData> worker_data) {
519 BrowserThread::PostTask(
520 BrowserThread::IO, FROM_HERE,
521 base::Bind(&TerminateWorkerOnIOThread, worker_data));
522 content::RunMessageLoop();
525 static void WaitForFirstSharedWorkerOnIOThread(
526 scoped_refptr<WorkerData> worker_data) {
527 std::vector<WorkerService::WorkerInfo> worker_info =
528 WorkerService::GetInstance()->GetWorkers();
529 if (!worker_info.empty()) {
530 worker_data->worker_process_id = worker_info[0].process_id;
531 worker_data->worker_route_id = worker_info[0].route_id;
532 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
533 base::MessageLoop::QuitClosure());
534 return;
537 WorkerService::GetInstance()->AddObserver(
538 new WorkerCreationObserver(worker_data.get()));
541 static scoped_refptr<WorkerData> WaitForFirstSharedWorker() {
542 scoped_refptr<WorkerData> worker_data(new WorkerData());
543 BrowserThread::PostTask(
544 BrowserThread::IO, FROM_HERE,
545 base::Bind(&WaitForFirstSharedWorkerOnIOThread, worker_data));
546 content::RunMessageLoop();
547 return worker_data;
550 void OpenDevToolsWindowForSharedWorker(WorkerData* worker_data) {
551 Profile* profile = browser()->profile();
552 scoped_refptr<DevToolsAgentHost> agent_host(
553 DevToolsAgentHost::GetForWorker(
554 worker_data->worker_process_id,
555 worker_data->worker_route_id));
556 window_ = DevToolsWindow::OpenDevToolsWindowForWorker(profile, agent_host);
557 RenderViewHost* client_rvh = window_->GetRenderViewHost();
558 WebContents* client_contents = WebContents::FromRenderViewHost(client_rvh);
559 if (client_contents->IsLoading()) {
560 content::WindowedNotificationObserver observer(
561 content::NOTIFICATION_LOAD_STOP,
562 content::Source<NavigationController>(
563 &client_contents->GetController()));
564 observer.Wait();
568 void CloseDevToolsWindow() {
569 Browser* browser = window_->browser();
570 content::WindowedNotificationObserver close_observer(
571 content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
572 content::Source<content::WebContents>(window_->web_contents()));
573 browser->tab_strip_model()->CloseAllTabs();
574 close_observer.Wait();
577 DevToolsWindow* window_;
580 // Tests that BeforeUnload event gets called on docked devtools if
581 // we try to close them.
582 IN_PROC_BROWSER_TEST_F(DevToolsBeforeUnloadTest, TestDockedDevToolsClose) {
583 RunBeforeUnloadSanityTest(true, base::Bind(
584 &DevToolsBeforeUnloadTest::CloseDockedDevTools, this), false);
587 // Tests that BeforeUnload event gets called on docked devtools if
588 // we try to close the inspected page.
589 IN_PROC_BROWSER_TEST_F(DevToolsBeforeUnloadTest,
590 TestDockedDevToolsInspectedTabClose) {
591 RunBeforeUnloadSanityTest(true, base::Bind(
592 &DevToolsBeforeUnloadTest::CloseInspectedTab, this));
595 // Tests that BeforeUnload event gets called on docked devtools if
596 // we try to close the inspected browser.
597 IN_PROC_BROWSER_TEST_F(DevToolsBeforeUnloadTest,
598 TestDockedDevToolsInspectedBrowserClose) {
599 RunBeforeUnloadSanityTest(true, base::Bind(
600 &DevToolsBeforeUnloadTest::CloseInspectedBrowser, this));
603 // Tests that BeforeUnload event gets called on undocked devtools if
604 // we try to close them.
605 IN_PROC_BROWSER_TEST_F(DevToolsBeforeUnloadTest, TestUndockedDevToolsClose) {
606 RunBeforeUnloadSanityTest(false, base::Bind(
607 &DevToolsBeforeUnloadTest::CloseUndockedDevTools, this), false);
610 // Tests that BeforeUnload event gets called on undocked devtools if
611 // we try to close the inspected page.
612 IN_PROC_BROWSER_TEST_F(DevToolsBeforeUnloadTest,
613 TestUndockedDevToolsInspectedTabClose) {
614 RunBeforeUnloadSanityTest(false, base::Bind(
615 &DevToolsBeforeUnloadTest::CloseInspectedTab, this));
618 // Tests that BeforeUnload event gets called on undocked devtools if
619 // we try to close the inspected browser.
620 IN_PROC_BROWSER_TEST_F(DevToolsBeforeUnloadTest,
621 TestUndockedDevToolsInspectedBrowserClose) {
622 RunBeforeUnloadSanityTest(false, base::Bind(
623 &DevToolsBeforeUnloadTest::CloseInspectedBrowser, this));
626 // Tests that BeforeUnload event gets called on undocked devtools if
627 // we try to exit application.
628 IN_PROC_BROWSER_TEST_F(DevToolsBeforeUnloadTest,
629 TestUndockedDevToolsApplicationClose) {
630 RunBeforeUnloadSanityTest(false, base::Bind(
631 &chrome::CloseAllBrowsers));
634 // Tests that inspected tab gets closed if devtools renderer
635 // becomes unresponsive during beforeunload event interception.
636 // @see http://crbug.com/322380
637 IN_PROC_BROWSER_TEST_F(DevToolsUnresponsiveBeforeUnloadTest,
638 TestUndockedDevToolsUnresponsive) {
639 ASSERT_TRUE(test_server()->Start());
640 LoadTestPage(kDebuggerTestPage);
641 DevToolsWindow* devtools_window = OpenDevToolWindowOnWebContents(
642 GetInspectedTab(), false);
643 content::WindowedNotificationObserver devtools_close_observer(
644 content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
645 content::Source<content::WebContents>(
646 devtools_window->web_contents()));
648 ASSERT_TRUE(content::ExecuteScript(
649 devtools_window->web_contents()->GetRenderViewHost(),
650 "window.addEventListener('beforeunload',"
651 "function(event) { while (true); });"));
652 CloseInspectedTab();
653 devtools_close_observer.Wait();
656 // Tests that closing worker inspector window does not cause browser crash
657 // @see http://crbug.com/323031
658 IN_PROC_BROWSER_TEST_F(DevToolsBeforeUnloadTest,
659 TestWorkerWindowClosing) {
660 ASSERT_TRUE(test_server()->Start());
661 LoadTestPage(kDebuggerTestPage);
662 DevToolsWindow* devtools_window = OpenDevToolWindowOnWebContents(
663 GetInspectedTab(), false);
664 content::WindowedNotificationObserver devtools_close_observer(
665 content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
666 content::Source<content::WebContents>(
667 devtools_window->web_contents()));
669 OpenDevToolsPopupWindow(devtools_window);
670 CloseDevToolsPopupWindow(devtools_window);
673 // FLaky on Windows bots: see crbug.com/323847, Linux crbug.com/333554
674 #if defined(OS_WIN) || defined(OS_LINUX)
675 #define MAYBE_TestDevToolsOnDevTools DISABLED_TestDevToolsOnDevTools
676 #else
677 #define MAYBE_TestDevToolsOnDevTools TestDevToolsOnDevTools
678 #endif
679 // Tests that BeforeUnload event gets called on devtools that are opened
680 // on another devtools.
681 IN_PROC_BROWSER_TEST_F(DevToolsBeforeUnloadTest,
682 MAYBE_TestDevToolsOnDevTools) {
683 ASSERT_TRUE(test_server()->Start());
684 LoadTestPage(kDebuggerTestPage);
686 std::vector<DevToolsWindow*> windows;
687 std::vector<content::WindowedNotificationObserver*> close_observers;
688 content::WebContents* inspected_web_contents = GetInspectedTab();
689 for (int i = 0; i < 3; ++i) {
690 DevToolsWindow* devtools_window = OpenDevToolWindowOnWebContents(
691 inspected_web_contents, i == 0);
692 windows.push_back(devtools_window);
693 content::WindowedNotificationObserver* close_observer =
694 new content::WindowedNotificationObserver(
695 content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
696 content::Source<content::WebContents>(
697 devtools_window->web_contents()));
698 close_observers.push_back(close_observer);
699 inspected_web_contents = devtools_window->web_contents();
702 InjectBeforeUnloadListener(windows[0]->web_contents());
703 InjectBeforeUnloadListener(windows[2]->web_contents());
704 // Try to close second devtools.
706 content::WindowedNotificationObserver cancel_browser(
707 chrome::NOTIFICATION_BROWSER_CLOSE_CANCELLED,
708 content::NotificationService::AllSources());
709 chrome::CloseWindow(windows[1]->browser());
710 CancelModalDialog();
711 cancel_browser.Wait();
713 // Try to close browser window.
715 content::WindowedNotificationObserver cancel_browser(
716 chrome::NOTIFICATION_BROWSER_CLOSE_CANCELLED,
717 content::NotificationService::AllSources());
718 chrome::CloseWindow(browser());
719 AcceptModalDialog();
720 CancelModalDialog();
721 cancel_browser.Wait();
723 // Try to exit application.
725 content::WindowedNotificationObserver close_observer(
726 chrome::NOTIFICATION_BROWSER_CLOSED,
727 content::Source<Browser>(browser()));
728 chrome::CloseAllBrowsers();
729 AcceptModalDialog();
730 AcceptModalDialog();
731 close_observer.Wait();
733 for (size_t i = 0; i < close_observers.size(); ++i) {
734 close_observers[i]->Wait();
735 delete close_observers[i];
739 // Tests scripts panel showing.
740 // TODO(pfeldman): figure out flake.
741 IN_PROC_BROWSER_TEST_F(DevToolsSanityTest, DISABLED_TestShowScriptsTab) {
742 RunTest("testShowScriptsTab", kDebuggerTestPage);
745 // Tests that scripts tab is populated with inspected scripts even if it
746 // hadn't been shown by the moment inspected paged refreshed.
747 // @see http://crbug.com/26312
748 IN_PROC_BROWSER_TEST_F(
749 DevToolsSanityTest,
750 TestScriptsTabIsPopulatedOnInspectedPageRefresh) {
751 // Clear inspector settings to ensure that Elements will be
752 // current panel when DevTools window is open.
753 content::BrowserContext* browser_context =
754 GetInspectedTab()->GetBrowserContext();
755 Profile::FromBrowserContext(browser_context)->GetPrefs()->
756 ClearPref(prefs::kWebKitInspectorSettings);
758 RunTest("testScriptsTabIsPopulatedOnInspectedPageRefresh",
759 kDebuggerTestPage);
762 // Tests that chrome.devtools extension is correctly exposed.
763 IN_PROC_BROWSER_TEST_F(DevToolsExtensionTest,
764 TestDevToolsExtensionAPI) {
765 LoadExtension("devtools_extension");
766 RunTest("waitForTestResultsInConsole", std::string());
769 // Disabled on Windows due to flakiness. http://crbug.com/183649
770 #if defined(OS_WIN)
771 #define MAYBE_TestDevToolsExtensionMessaging DISABLED_TestDevToolsExtensionMessaging
772 #else
773 #define MAYBE_TestDevToolsExtensionMessaging TestDevToolsExtensionMessaging
774 #endif
776 // Tests that chrome.devtools extension can communicate with background page
777 // using extension messaging.
778 IN_PROC_BROWSER_TEST_F(DevToolsExtensionTest,
779 MAYBE_TestDevToolsExtensionMessaging) {
780 LoadExtension("devtools_messaging");
781 RunTest("waitForTestResultsInConsole", std::string());
784 // Tests that chrome.experimental.devtools extension is correctly exposed
785 // when the extension has experimental permission.
786 IN_PROC_BROWSER_TEST_F(DevToolsExperimentalExtensionTest,
787 TestDevToolsExperimentalExtensionAPI) {
788 LoadExtension("devtools_experimental");
789 RunTest("waitForTestResultsInConsole", std::string());
792 // Tests that a content script is in the scripts list.
793 // History of flakiness: http://crbug.com/114104, http://crbug.com/315288.
794 IN_PROC_BROWSER_TEST_F(DevToolsExtensionTest,
795 DISABLED_TestContentScriptIsPresent) {
796 LoadExtension("simple_content_script");
797 RunTest("testContentScriptIsPresent", kPageWithContentScript);
800 // Fails quite consistently on Win XP: crbug.com/317725.
801 #if defined(OS_WIN) || defined(OS_MACOSX)
802 #define MAYBE_TestNoScriptDuplicatesOnPanelSwitch \
803 DISABLED_TestNoScriptDuplicatesOnPanelSwitch
804 #else
805 #define MAYBE_TestNoScriptDuplicatesOnPanelSwitch \
806 TestNoScriptDuplicatesOnPanelSwitch
807 #endif
809 // Tests that scripts are not duplicated after Scripts Panel switch.
810 IN_PROC_BROWSER_TEST_F(DevToolsSanityTest,
811 MAYBE_TestNoScriptDuplicatesOnPanelSwitch) {
812 RunTest("testNoScriptDuplicatesOnPanelSwitch", kDebuggerTestPage);
815 // Tests that debugger works correctly if pause event occurs when DevTools
816 // frontend is being loaded.
817 // Disabled because of flakiness on all platforms: crbug.com/329036
818 IN_PROC_BROWSER_TEST_F(DevToolsSanityTest,
819 DISABLED_TestPauseWhenLoadingDevTools) {
820 RunTest("testPauseWhenLoadingDevTools", kPauseWhenLoadingDevTools);
823 // Tests that pressing 'Pause' will pause script execution if the script
824 // is already running.
825 #if defined(OS_WIN)
826 // Timing out on windows tryservers: http://crbug.com/219515
827 #define MAYBE_TestPauseWhenScriptIsRunning DISABLED_TestPauseWhenScriptIsRunning
828 #elif defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(ARCH_CPU_ARM_FAMILY)
829 // Timing out on linux ARM bot: https://crbug/238453
830 #define MAYBE_TestPauseWhenScriptIsRunning DISABLED_TestPauseWhenScriptIsRunning
831 #else
832 #define MAYBE_TestPauseWhenScriptIsRunning TestPauseWhenScriptIsRunning
833 #endif
834 IN_PROC_BROWSER_TEST_F(DevToolsSanityTest,
835 MAYBE_TestPauseWhenScriptIsRunning) {
836 RunTest("testPauseWhenScriptIsRunning", kPauseWhenScriptIsRunning);
839 // Tests network timing.
840 IN_PROC_BROWSER_TEST_F(DevToolsSanityTest, TestNetworkTiming) {
841 RunTest("testNetworkTiming", kSlowTestPage);
844 // Tests network size.
845 IN_PROC_BROWSER_TEST_F(DevToolsSanityTest, TestNetworkSize) {
846 RunTest("testNetworkSize", kChunkedTestPage);
849 // Tests raw headers text.
850 IN_PROC_BROWSER_TEST_F(DevToolsSanityTest, TestNetworkSyncSize) {
851 RunTest("testNetworkSyncSize", kChunkedTestPage);
854 // Tests raw headers text.
855 IN_PROC_BROWSER_TEST_F(DevToolsSanityTest, TestNetworkRawHeadersText) {
856 RunTest("testNetworkRawHeadersText", kChunkedTestPage);
859 // Tests that console messages are not duplicated on navigation back.
860 IN_PROC_BROWSER_TEST_F(DevToolsSanityTest, TestConsoleOnNavigateBack) {
861 RunTest("testConsoleOnNavigateBack", kNavigateBackTestPage);
865 // Tests that external navigation from inspector page is always handled by
866 // DevToolsWindow and results in inspected page navigation.
867 IN_PROC_BROWSER_TEST_F(DevToolsSanityTest, TestDevToolsExternalNavigation) {
868 OpenDevToolsWindow(kDebuggerTestPage, true);
869 GURL url = test_server()->GetURL(kNavigateBackTestPage);
870 content::WindowedNotificationObserver observer(
871 content::NOTIFICATION_LOAD_STOP,
872 content::NotificationService::AllSources());
873 ASSERT_TRUE(content::ExecuteScript(
874 window_->web_contents(),
875 std::string("window.location = \"") + url.spec() + "\""));
876 observer.Wait();
878 ASSERT_TRUE(window_->web_contents()->GetURL().
879 SchemeIs(chrome::kChromeDevToolsScheme));
880 ASSERT_EQ(GetInspectedTab()->GetURL(), url);
881 CloseDevToolsWindow();
884 #if defined(OS_WIN) || defined(OS_MACOSX)
885 // Flakily times out: http://crbug.com/163411
886 #define MAYBE_TestReattachAfterCrash DISABLED_TestReattachAfterCrash
887 #else
888 #define MAYBE_TestReattachAfterCrash TestReattachAfterCrash
889 #endif
890 // Tests that inspector will reattach to inspected page when it is reloaded
891 // after a crash. See http://crbug.com/101952
892 IN_PROC_BROWSER_TEST_F(DevToolsSanityTest, MAYBE_TestReattachAfterCrash) {
893 OpenDevToolsWindow(kDebuggerTestPage, false);
895 content::CrashTab(GetInspectedTab());
896 content::WindowedNotificationObserver observer(
897 content::NOTIFICATION_LOAD_STOP,
898 content::Source<NavigationController>(
899 &browser()->tab_strip_model()->GetActiveWebContents()->
900 GetController()));
901 chrome::Reload(browser(), CURRENT_TAB);
902 observer.Wait();
904 RunTestFunction(window_, "testReattachAfterCrash");
905 CloseDevToolsWindow();
908 IN_PROC_BROWSER_TEST_F(DevToolsSanityTest, TestPageWithNoJavaScript) {
909 OpenDevToolsWindow("about:blank", false);
910 std::string result;
911 ASSERT_TRUE(
912 content::ExecuteScriptAndExtractString(
913 window_->GetRenderViewHost(),
914 "window.domAutomationController.send("
915 " '' + (window.uiTests && (typeof uiTests.runTest)));",
916 &result));
917 ASSERT_EQ("function", result) << "DevTools front-end is broken.";
918 CloseDevToolsWindow();
921 #if defined(OS_MACOSX)
922 #define MAYBE_InspectSharedWorker DISABLED_InspectSharedWorker
923 #else
924 #define MAYBE_InspectSharedWorker InspectSharedWorker
925 #endif
926 // Flakily fails with 25s timeout: http://crbug.com/89845
927 IN_PROC_BROWSER_TEST_F(WorkerDevToolsSanityTest, MAYBE_InspectSharedWorker) {
928 #if defined(OS_WIN) && defined(USE_ASH)
929 // Disable this test in Metro+Ash for now (http://crbug.com/262796).
930 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests))
931 return;
932 #endif
934 RunTest("testSharedWorker", kSharedWorkerTestPage);
937 // http://crbug.com/100538
938 #if defined(OS_MACOSX) || defined(OS_WIN)
939 #define MAYBE_PauseInSharedWorkerInitialization DISABLED_PauseInSharedWorkerInitialization
940 #else
941 #define MAYBE_PauseInSharedWorkerInitialization PauseInSharedWorkerInitialization
942 #endif
944 // http://crbug.com/106114 is masking
945 // MAYBE_PauseInSharedWorkerInitialization into
946 // DISABLED_PauseInSharedWorkerInitialization
947 IN_PROC_BROWSER_TEST_F(WorkerDevToolsSanityTest,
948 MAYBE_PauseInSharedWorkerInitialization) {
949 ASSERT_TRUE(test_server()->Start());
950 GURL url = test_server()->GetURL(kReloadSharedWorkerTestPage);
951 ui_test_utils::NavigateToURL(browser(), url);
953 scoped_refptr<WorkerData> worker_data = WaitForFirstSharedWorker();
954 OpenDevToolsWindowForSharedWorker(worker_data.get());
956 TerminateWorker(worker_data);
958 // Reload page to restart the worker.
959 ui_test_utils::NavigateToURL(browser(), url);
961 // Wait until worker script is paused on the debugger statement.
962 RunTestFunction(window_, "testPauseInSharedWorkerInitialization");
963 CloseDevToolsWindow();
966 class DevToolsAgentHostTest : public InProcessBrowserTest {};
968 // Tests DevToolsAgentHost retention by its target.
969 IN_PROC_BROWSER_TEST_F(DevToolsAgentHostTest, TestAgentHostReleased) {
970 ui_test_utils::NavigateToURL(browser(), GURL("about:blank"));
971 RenderViewHost* rvh = browser()->tab_strip_model()->GetWebContentsAt(0)->
972 GetRenderViewHost();
973 DevToolsAgentHost* agent_raw = DevToolsAgentHost::GetOrCreateFor(rvh).get();
974 const std::string agent_id = agent_raw->GetId();
975 ASSERT_EQ(agent_raw, DevToolsAgentHost::GetForId(agent_id)) <<
976 "DevToolsAgentHost cannot be found by id";
977 browser()->tab_strip_model()->
978 CloseWebContentsAt(0, TabStripModel::CLOSE_NONE);
979 ASSERT_FALSE(DevToolsAgentHost::GetForId(agent_id).get())
980 << "DevToolsAgentHost is not released when the tab is closed";
983 class RemoteDebuggingTest: public ExtensionApiTest {
984 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
985 ExtensionApiTest::SetUpCommandLine(command_line);
986 command_line->AppendSwitchASCII(switches::kRemoteDebuggingPort, "9222");
988 // Override the extension root path.
989 PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir_);
990 test_data_dir_ = test_data_dir_.AppendASCII("devtools");
994 IN_PROC_BROWSER_TEST_F(RemoteDebuggingTest, RemoteDebugger) {
995 #if defined(OS_WIN) && defined(USE_ASH)
996 // Disable this test in Metro+Ash for now (http://crbug.com/262796).
997 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests))
998 return;
999 #endif
1001 ASSERT_TRUE(RunExtensionTest("target_list")) << message_;