NaCl: Update revision in DEPS, r12770 -> r12773
[chromium-blink-merge.git] / chrome / browser / devtools / devtools_sanity_browsertest.cc
blob60817209b29fe3a51630a13484b5df2ea475299f
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/unpacked_installer.h"
22 #include "chrome/browser/lifetime/application_lifetime.h"
23 #include "chrome/browser/profiles/profile.h"
24 #include "chrome/browser/ui/app_modal_dialogs/javascript_app_modal_dialog.h"
25 #include "chrome/browser/ui/app_modal_dialogs/native_app_modal_dialog.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 "content/public/browser/child_process_data.h"
38 #include "content/public/browser/content_browser_client.h"
39 #include "content/public/browser/devtools_agent_host.h"
40 #include "content/public/browser/devtools_client_host.h"
41 #include "content/public/browser/devtools_http_handler.h"
42 #include "content/public/browser/devtools_manager.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_system.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 GURL url = test_server()->GetURL(test_page);
126 ui_test_utils::NavigateToURL(browser(), url);
129 void OpenDevToolsWindow(const std::string& test_page, bool is_docked) {
130 ASSERT_TRUE(test_server()->Start());
131 LoadTestPage(test_page);
133 inspected_rvh_ = GetInspectedTab()->GetRenderViewHost();
134 window_ =
135 DevToolsWindow::OpenDevToolsWindowForTest(inspected_rvh_, is_docked);
136 ui_test_utils::WaitUntilDevToolsWindowLoaded(window_);
139 WebContents* GetInspectedTab() {
140 return browser()->tab_strip_model()->GetWebContentsAt(0);
143 void ToggleDevToolsWindow() {
144 content::WindowedNotificationObserver close_observer(
145 content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
146 content::Source<content::WebContents>(window_->web_contents()));
147 DevToolsWindow::ToggleDevToolsWindow(inspected_rvh_, false,
148 DevToolsToggleAction::Toggle());
149 close_observer.Wait();
152 void ToggleDevToolsWindowDontWait() {
153 DevToolsWindow::ToggleDevToolsWindow(inspected_rvh_, false,
154 DevToolsToggleAction::Toggle());
157 void CloseDevToolsWindow() {
158 DevToolsManager* devtools_manager = DevToolsManager::GetInstance();
159 content::WindowedNotificationObserver close_observer(
160 content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
161 content::Source<content::WebContents>(window_->web_contents()));
162 devtools_manager->CloseAllClientHosts();
163 close_observer.Wait();
166 DevToolsWindow* window_;
167 RenderViewHost* inspected_rvh_;
170 // Used to block until a dev tools window gets beforeunload event.
171 class DevToolsWindowBeforeUnloadObserver
172 : public content::WebContentsObserver {
173 public:
174 explicit DevToolsWindowBeforeUnloadObserver(DevToolsWindow*);
175 void Wait();
176 private:
177 // Invoked when the beforeunload handler fires.
178 virtual void BeforeUnloadFired(const base::TimeTicks& proceed_time) OVERRIDE;
180 bool m_fired;
181 scoped_refptr<content::MessageLoopRunner> message_loop_runner_;
182 DISALLOW_COPY_AND_ASSIGN(DevToolsWindowBeforeUnloadObserver);
185 DevToolsWindowBeforeUnloadObserver::DevToolsWindowBeforeUnloadObserver(
186 DevToolsWindow* devtools_window)
187 : WebContentsObserver(devtools_window->web_contents()),
188 m_fired(false) {
191 void DevToolsWindowBeforeUnloadObserver::Wait() {
192 if (m_fired)
193 return;
194 message_loop_runner_ = new content::MessageLoopRunner;
195 message_loop_runner_->Run();
198 void DevToolsWindowBeforeUnloadObserver::BeforeUnloadFired(
199 const base::TimeTicks& proceed_time) {
200 m_fired = true;
201 if (message_loop_runner_.get())
202 message_loop_runner_->Quit();
205 class DevToolsBeforeUnloadTest: public DevToolsSanityTest {
206 public:
207 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
208 command_line->AppendSwitch(
209 switches::kDisableHangMonitor);
212 void CloseInspectedTab() {
213 browser()->tab_strip_model()->CloseWebContentsAt(0,
214 TabStripModel::CLOSE_NONE);
217 void CloseDockedDevTools() {
218 ToggleDevToolsWindowDontWait();
221 void CloseUndockedDevTools() {
222 chrome::CloseWindow(window_->browser());
225 void CloseInspectedBrowser() {
226 chrome::CloseWindow(browser());
228 protected:
229 void InjectBeforeUnloadListener(content::WebContents* web_contents) {
230 ASSERT_TRUE(content::ExecuteScript(web_contents->GetRenderViewHost(),
231 "window.addEventListener('beforeunload',"
232 "function(event) { event.returnValue = 'Foo'; });"));
235 void RunBeforeUnloadSanityTest(bool is_docked,
236 base::Callback<void(void)> close_method,
237 bool wait_for_browser_close = true) {
238 OpenDevToolsWindow(kDebuggerTestPage, is_docked);
239 content::WindowedNotificationObserver devtools_close_observer(
240 content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
241 content::Source<content::WebContents>(window_->web_contents()));
242 InjectBeforeUnloadListener(window_->web_contents());
244 DevToolsWindowBeforeUnloadObserver before_unload_observer(window_);
245 close_method.Run();
246 CancelModalDialog();
247 before_unload_observer.Wait();
250 content::WindowedNotificationObserver close_observer(
251 chrome::NOTIFICATION_BROWSER_CLOSED,
252 content::Source<Browser>(browser()));
253 close_method.Run();
254 AcceptModalDialog();
255 if (wait_for_browser_close)
256 close_observer.Wait();
258 devtools_close_observer.Wait();
261 DevToolsWindow* OpenDevToolWindowOnWebContents(
262 content::WebContents* contents, bool is_docked) {
263 DevToolsWindow* window = DevToolsWindow::OpenDevToolsWindowForTest(
264 contents->GetRenderViewHost(), is_docked);
265 ui_test_utils::WaitUntilDevToolsWindowLoaded(window);
266 return window;
269 void OpenDevToolsPopupWindow(DevToolsWindow* devtools_window) {
270 content::WindowedNotificationObserver observer(
271 content::NOTIFICATION_LOAD_STOP,
272 content::NotificationService::AllSources());
273 ASSERT_TRUE(content::ExecuteScript(
274 devtools_window->web_contents()->GetRenderViewHost(),
275 "window.open(\"\", \"\", \"location=0\");"));
276 observer.Wait();
279 void CloseDevToolsPopupWindow(DevToolsWindow* devtools_window) {
280 Browser* popup_browser = NULL;
281 for (chrome::BrowserIterator it; !it.done(); it.Next()) {
282 if (it->is_devtools()) {
283 content::WebContents* contents =
284 it->tab_strip_model()->GetWebContentsAt(0);
285 if (devtools_window->web_contents() != contents) {
286 popup_browser = *it;
287 break;
291 ASSERT_FALSE(popup_browser == NULL);
292 content::WindowedNotificationObserver close_observer(
293 chrome::NOTIFICATION_BROWSER_CLOSED,
294 content::Source<Browser>(popup_browser));
295 chrome::CloseWindow(popup_browser);
296 close_observer.Wait();
299 void AcceptModalDialog() {
300 NativeAppModalDialog* native_dialog = GetDialog();
301 native_dialog->AcceptAppModalDialog();
304 void CancelModalDialog() {
305 NativeAppModalDialog* native_dialog = GetDialog();
306 native_dialog->CancelAppModalDialog();
309 NativeAppModalDialog* GetDialog() {
310 AppModalDialog* dialog = ui_test_utils::WaitForAppModalDialog();
311 EXPECT_TRUE(dialog->IsJavaScriptModalDialog());
312 JavaScriptAppModalDialog* js_dialog =
313 static_cast<JavaScriptAppModalDialog*>(dialog);
314 NativeAppModalDialog* native_dialog = js_dialog->native_dialog();
315 EXPECT_TRUE(native_dialog);
316 return native_dialog;
320 class DevToolsUnresponsiveBeforeUnloadTest: public DevToolsBeforeUnloadTest {
321 public:
322 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {}
325 void TimeoutCallback(const std::string& timeout_message) {
326 FAIL() << timeout_message;
327 base::MessageLoop::current()->Quit();
330 // Base class for DevTools tests that test devtools functionality for
331 // extensions and content scripts.
332 class DevToolsExtensionTest : public DevToolsSanityTest,
333 public content::NotificationObserver {
334 public:
335 DevToolsExtensionTest() : DevToolsSanityTest() {
336 PathService::Get(chrome::DIR_TEST_DATA, &test_extensions_dir_);
337 test_extensions_dir_ = test_extensions_dir_.AppendASCII("devtools");
338 test_extensions_dir_ = test_extensions_dir_.AppendASCII("extensions");
341 protected:
342 // Load an extension from test\data\devtools\extensions\<extension_name>
343 void LoadExtension(const char* extension_name) {
344 base::FilePath path = test_extensions_dir_.AppendASCII(extension_name);
345 ASSERT_TRUE(LoadExtensionFromPath(path)) << "Failed to load extension.";
348 private:
349 bool LoadExtensionFromPath(const base::FilePath& path) {
350 ExtensionService* service = extensions::ExtensionSystem::Get(
351 browser()->profile())->extension_service();
352 size_t num_before = service->extensions()->size();
354 content::NotificationRegistrar registrar;
355 registrar.Add(this, chrome::NOTIFICATION_EXTENSION_LOADED,
356 content::NotificationService::AllSources());
357 base::CancelableClosure timeout(
358 base::Bind(&TimeoutCallback, "Extension load timed out."));
359 base::MessageLoop::current()->PostDelayedTask(
360 FROM_HERE, timeout.callback(), TestTimeouts::action_timeout());
361 extensions::UnpackedInstaller::Create(service)->Load(path);
362 content::RunMessageLoop();
363 timeout.Cancel();
365 size_t num_after = service->extensions()->size();
366 if (num_after != (num_before + 1))
367 return false;
369 return WaitForExtensionViewsToLoad();
372 bool WaitForExtensionViewsToLoad() {
373 // Wait for all the extension render views that exist to finish loading.
374 // NOTE: This assumes that the extension views list is not changing while
375 // this method is running.
377 content::NotificationRegistrar registrar;
378 registrar.Add(this, chrome::NOTIFICATION_EXTENSION_HOST_DID_STOP_LOADING,
379 content::NotificationService::AllSources());
380 base::CancelableClosure timeout(
381 base::Bind(&TimeoutCallback, "Extension host load timed out."));
382 base::MessageLoop::current()->PostDelayedTask(
383 FROM_HERE, timeout.callback(), TestTimeouts::action_timeout());
385 extensions::ProcessManager* manager =
386 extensions::ExtensionSystem::Get(browser()->profile())->
387 process_manager();
388 extensions::ProcessManager::ViewSet all_views = manager->GetAllViews();
389 for (extensions::ProcessManager::ViewSet::const_iterator iter =
390 all_views.begin();
391 iter != all_views.end();) {
392 if (!(*iter)->IsLoading())
393 ++iter;
394 else
395 content::RunMessageLoop();
398 timeout.Cancel();
399 return true;
402 virtual void Observe(int type,
403 const content::NotificationSource& source,
404 const content::NotificationDetails& details) OVERRIDE {
405 switch (type) {
406 case chrome::NOTIFICATION_EXTENSION_LOADED:
407 case chrome::NOTIFICATION_EXTENSION_HOST_DID_STOP_LOADING:
408 base::MessageLoopForUI::current()->Quit();
409 break;
410 default:
411 NOTREACHED();
412 break;
416 base::FilePath test_extensions_dir_;
419 class DevToolsExperimentalExtensionTest : public DevToolsExtensionTest {
420 public:
421 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
422 command_line->AppendSwitch(
423 extensions::switches::kEnableExperimentalExtensionApis);
427 class WorkerDevToolsSanityTest : public InProcessBrowserTest {
428 public:
429 WorkerDevToolsSanityTest() : window_(NULL) {}
431 protected:
432 class WorkerData : public base::RefCountedThreadSafe<WorkerData> {
433 public:
434 WorkerData() : worker_process_id(0), worker_route_id(0) {}
435 int worker_process_id;
436 int worker_route_id;
438 private:
439 friend class base::RefCountedThreadSafe<WorkerData>;
440 ~WorkerData() {}
443 class WorkerCreationObserver : public WorkerServiceObserver {
444 public:
445 explicit WorkerCreationObserver(WorkerData* worker_data)
446 : worker_data_(worker_data) {
449 private:
450 virtual ~WorkerCreationObserver() {}
452 virtual void WorkerCreated (
453 const GURL& url,
454 const base::string16& name,
455 int process_id,
456 int route_id) OVERRIDE {
457 worker_data_->worker_process_id = process_id;
458 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 class WorkerTerminationObserver : public WorkerServiceObserver {
468 public:
469 explicit WorkerTerminationObserver(WorkerData* worker_data)
470 : worker_data_(worker_data) {
473 private:
474 virtual ~WorkerTerminationObserver() {}
476 virtual void WorkerDestroyed(int process_id, int route_id) OVERRIDE {
477 ASSERT_EQ(worker_data_->worker_process_id, process_id);
478 ASSERT_EQ(worker_data_->worker_route_id, route_id);
479 WorkerService::GetInstance()->RemoveObserver(this);
480 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
481 base::MessageLoop::QuitClosure());
482 delete this;
484 scoped_refptr<WorkerData> worker_data_;
487 void RunTest(const char* test_name, const char* test_page) {
488 ASSERT_TRUE(test_server()->Start());
489 GURL url = test_server()->GetURL(test_page);
490 ui_test_utils::NavigateToURL(browser(), url);
492 scoped_refptr<WorkerData> worker_data = WaitForFirstSharedWorker();
493 OpenDevToolsWindowForSharedWorker(worker_data.get());
494 RunTestFunction(window_, test_name);
495 CloseDevToolsWindow();
498 static void TerminateWorkerOnIOThread(scoped_refptr<WorkerData> worker_data) {
499 if (WorkerService::GetInstance()->TerminateWorker(
500 worker_data->worker_process_id, worker_data->worker_route_id)) {
501 WorkerService::GetInstance()->AddObserver(
502 new WorkerTerminationObserver(worker_data.get()));
503 return;
505 FAIL() << "Failed to terminate worker.\n";
508 static void TerminateWorker(scoped_refptr<WorkerData> worker_data) {
509 BrowserThread::PostTask(
510 BrowserThread::IO, FROM_HERE,
511 base::Bind(&TerminateWorkerOnIOThread, worker_data));
512 content::RunMessageLoop();
515 static void WaitForFirstSharedWorkerOnIOThread(
516 scoped_refptr<WorkerData> worker_data) {
517 std::vector<WorkerService::WorkerInfo> worker_info =
518 WorkerService::GetInstance()->GetWorkers();
519 if (!worker_info.empty()) {
520 worker_data->worker_process_id = worker_info[0].process_id;
521 worker_data->worker_route_id = worker_info[0].route_id;
522 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
523 base::MessageLoop::QuitClosure());
524 return;
527 WorkerService::GetInstance()->AddObserver(
528 new WorkerCreationObserver(worker_data.get()));
531 static scoped_refptr<WorkerData> WaitForFirstSharedWorker() {
532 scoped_refptr<WorkerData> worker_data(new WorkerData());
533 BrowserThread::PostTask(
534 BrowserThread::IO, FROM_HERE,
535 base::Bind(&WaitForFirstSharedWorkerOnIOThread, worker_data));
536 content::RunMessageLoop();
537 return worker_data;
540 void OpenDevToolsWindowForSharedWorker(WorkerData* worker_data) {
541 Profile* profile = browser()->profile();
542 scoped_refptr<DevToolsAgentHost> agent_host(
543 DevToolsAgentHost::GetForWorker(
544 worker_data->worker_process_id,
545 worker_data->worker_route_id));
546 window_ = DevToolsWindow::OpenDevToolsWindowForWorker(profile, agent_host);
547 RenderViewHost* client_rvh = window_->GetRenderViewHost();
548 WebContents* client_contents = WebContents::FromRenderViewHost(client_rvh);
549 content::WaitForLoadStop(client_contents);
552 void CloseDevToolsWindow() {
553 Browser* browser = window_->browser();
554 content::WindowedNotificationObserver close_observer(
555 content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
556 content::Source<content::WebContents>(window_->web_contents()));
557 browser->tab_strip_model()->CloseAllTabs();
558 close_observer.Wait();
561 DevToolsWindow* window_;
564 // Tests that BeforeUnload event gets called on docked devtools if
565 // we try to close them.
566 IN_PROC_BROWSER_TEST_F(DevToolsBeforeUnloadTest, TestDockedDevToolsClose) {
567 RunBeforeUnloadSanityTest(true, base::Bind(
568 &DevToolsBeforeUnloadTest::CloseDockedDevTools, this), false);
571 // Tests that BeforeUnload event gets called on docked devtools if
572 // we try to close the inspected page.
573 IN_PROC_BROWSER_TEST_F(DevToolsBeforeUnloadTest,
574 TestDockedDevToolsInspectedTabClose) {
575 RunBeforeUnloadSanityTest(true, base::Bind(
576 &DevToolsBeforeUnloadTest::CloseInspectedTab, this));
579 // Tests that BeforeUnload event gets called on docked devtools if
580 // we try to close the inspected browser.
581 IN_PROC_BROWSER_TEST_F(DevToolsBeforeUnloadTest,
582 TestDockedDevToolsInspectedBrowserClose) {
583 RunBeforeUnloadSanityTest(true, base::Bind(
584 &DevToolsBeforeUnloadTest::CloseInspectedBrowser, this));
587 // Tests that BeforeUnload event gets called on undocked devtools if
588 // we try to close them.
589 IN_PROC_BROWSER_TEST_F(DevToolsBeforeUnloadTest, TestUndockedDevToolsClose) {
590 RunBeforeUnloadSanityTest(false, base::Bind(
591 &DevToolsBeforeUnloadTest::CloseUndockedDevTools, this), false);
594 // Tests that BeforeUnload event gets called on undocked devtools if
595 // we try to close the inspected page.
596 IN_PROC_BROWSER_TEST_F(DevToolsBeforeUnloadTest,
597 TestUndockedDevToolsInspectedTabClose) {
598 RunBeforeUnloadSanityTest(false, base::Bind(
599 &DevToolsBeforeUnloadTest::CloseInspectedTab, this));
602 // Tests that BeforeUnload event gets called on undocked devtools if
603 // we try to close the inspected browser.
604 IN_PROC_BROWSER_TEST_F(DevToolsBeforeUnloadTest,
605 TestUndockedDevToolsInspectedBrowserClose) {
606 RunBeforeUnloadSanityTest(false, base::Bind(
607 &DevToolsBeforeUnloadTest::CloseInspectedBrowser, this));
610 // Tests that BeforeUnload event gets called on undocked devtools if
611 // we try to exit application.
612 IN_PROC_BROWSER_TEST_F(DevToolsBeforeUnloadTest,
613 TestUndockedDevToolsApplicationClose) {
614 RunBeforeUnloadSanityTest(false, base::Bind(
615 &chrome::CloseAllBrowsers));
618 // Tests that inspected tab gets closed if devtools renderer
619 // becomes unresponsive during beforeunload event interception.
620 // @see http://crbug.com/322380
621 IN_PROC_BROWSER_TEST_F(DevToolsUnresponsiveBeforeUnloadTest,
622 TestUndockedDevToolsUnresponsive) {
623 ASSERT_TRUE(test_server()->Start());
624 LoadTestPage(kDebuggerTestPage);
625 DevToolsWindow* devtools_window = OpenDevToolWindowOnWebContents(
626 GetInspectedTab(), false);
627 content::WindowedNotificationObserver devtools_close_observer(
628 content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
629 content::Source<content::WebContents>(
630 devtools_window->web_contents()));
632 ASSERT_TRUE(content::ExecuteScript(
633 devtools_window->web_contents()->GetRenderViewHost(),
634 "window.addEventListener('beforeunload',"
635 "function(event) { while (true); });"));
636 CloseInspectedTab();
637 devtools_close_observer.Wait();
640 // Tests that closing worker inspector window does not cause browser crash
641 // @see http://crbug.com/323031
642 IN_PROC_BROWSER_TEST_F(DevToolsBeforeUnloadTest,
643 TestWorkerWindowClosing) {
644 ASSERT_TRUE(test_server()->Start());
645 LoadTestPage(kDebuggerTestPage);
646 DevToolsWindow* devtools_window = OpenDevToolWindowOnWebContents(
647 GetInspectedTab(), false);
648 content::WindowedNotificationObserver devtools_close_observer(
649 content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
650 content::Source<content::WebContents>(
651 devtools_window->web_contents()));
653 OpenDevToolsPopupWindow(devtools_window);
654 CloseDevToolsPopupWindow(devtools_window);
657 // Tests that BeforeUnload event gets called on devtools that are opened
658 // on another devtools.
659 IN_PROC_BROWSER_TEST_F(DevToolsBeforeUnloadTest,
660 TestDevToolsOnDevTools) {
661 ASSERT_TRUE(test_server()->Start());
662 LoadTestPage(kDebuggerTestPage);
664 std::vector<DevToolsWindow*> windows;
665 std::vector<content::WindowedNotificationObserver*> close_observers;
666 content::WebContents* inspected_web_contents = GetInspectedTab();
667 for (int i = 0; i < 3; ++i) {
668 DevToolsWindow* devtools_window = OpenDevToolWindowOnWebContents(
669 inspected_web_contents, i == 0);
670 windows.push_back(devtools_window);
671 content::WindowedNotificationObserver* close_observer =
672 new content::WindowedNotificationObserver(
673 content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
674 content::Source<content::WebContents>(
675 devtools_window->web_contents()));
676 close_observers.push_back(close_observer);
677 inspected_web_contents = devtools_window->web_contents();
680 InjectBeforeUnloadListener(windows[0]->web_contents());
681 InjectBeforeUnloadListener(windows[2]->web_contents());
682 // Try to close second devtools.
684 content::WindowedNotificationObserver cancel_browser(
685 chrome::NOTIFICATION_BROWSER_CLOSE_CANCELLED,
686 content::NotificationService::AllSources());
687 chrome::CloseWindow(windows[1]->browser());
688 CancelModalDialog();
689 cancel_browser.Wait();
691 // Try to close browser window.
693 content::WindowedNotificationObserver cancel_browser(
694 chrome::NOTIFICATION_BROWSER_CLOSE_CANCELLED,
695 content::NotificationService::AllSources());
696 chrome::CloseWindow(browser());
697 AcceptModalDialog();
698 CancelModalDialog();
699 cancel_browser.Wait();
701 // Try to exit application.
703 content::WindowedNotificationObserver close_observer(
704 chrome::NOTIFICATION_BROWSER_CLOSED,
705 content::Source<Browser>(browser()));
706 chrome::StartKeepAlive();
707 chrome::CloseAllBrowsers();
708 AcceptModalDialog();
709 AcceptModalDialog();
710 close_observer.Wait();
712 for (size_t i = 0; i < close_observers.size(); ++i) {
713 close_observers[i]->Wait();
714 delete close_observers[i];
718 // Tests scripts panel showing.
719 // TODO(pfeldman): figure out flake.
720 IN_PROC_BROWSER_TEST_F(DevToolsSanityTest, DISABLED_TestShowScriptsTab) {
721 RunTest("testShowScriptsTab", kDebuggerTestPage);
724 // Tests that scripts tab is populated with inspected scripts even if it
725 // hadn't been shown by the moment inspected paged refreshed.
726 // @see http://crbug.com/26312
727 IN_PROC_BROWSER_TEST_F(
728 DevToolsSanityTest,
729 TestScriptsTabIsPopulatedOnInspectedPageRefresh) {
730 // Clear inspector settings to ensure that Elements will be
731 // current panel when DevTools window is open.
732 content::BrowserContext* browser_context =
733 GetInspectedTab()->GetBrowserContext();
734 Profile::FromBrowserContext(browser_context)->GetPrefs()->
735 ClearPref(prefs::kWebKitInspectorSettings);
737 RunTest("testScriptsTabIsPopulatedOnInspectedPageRefresh",
738 kDebuggerTestPage);
741 // Tests that chrome.devtools extension is correctly exposed.
742 IN_PROC_BROWSER_TEST_F(DevToolsExtensionTest,
743 TestDevToolsExtensionAPI) {
744 LoadExtension("devtools_extension");
745 RunTest("waitForTestResultsInConsole", std::string());
748 // Disabled on Windows due to flakiness. http://crbug.com/183649
749 #if defined(OS_WIN)
750 #define MAYBE_TestDevToolsExtensionMessaging DISABLED_TestDevToolsExtensionMessaging
751 #else
752 #define MAYBE_TestDevToolsExtensionMessaging TestDevToolsExtensionMessaging
753 #endif
755 // Tests that chrome.devtools extension can communicate with background page
756 // using extension messaging.
757 IN_PROC_BROWSER_TEST_F(DevToolsExtensionTest,
758 MAYBE_TestDevToolsExtensionMessaging) {
759 LoadExtension("devtools_messaging");
760 RunTest("waitForTestResultsInConsole", std::string());
763 // Tests that chrome.experimental.devtools extension is correctly exposed
764 // when the extension has experimental permission.
765 IN_PROC_BROWSER_TEST_F(DevToolsExperimentalExtensionTest,
766 TestDevToolsExperimentalExtensionAPI) {
767 LoadExtension("devtools_experimental");
768 RunTest("waitForTestResultsInConsole", std::string());
771 // Tests that a content script is in the scripts list.
772 // History of flakiness: http://crbug.com/114104, http://crbug.com/315288.
773 IN_PROC_BROWSER_TEST_F(DevToolsExtensionTest,
774 DISABLED_TestContentScriptIsPresent) {
775 LoadExtension("simple_content_script");
776 RunTest("testContentScriptIsPresent", kPageWithContentScript);
779 // Fails quite consistently on Win XP: crbug.com/317725.
780 #if defined(OS_WIN) || defined(OS_MACOSX)
781 #define MAYBE_TestNoScriptDuplicatesOnPanelSwitch \
782 DISABLED_TestNoScriptDuplicatesOnPanelSwitch
783 #else
784 #define MAYBE_TestNoScriptDuplicatesOnPanelSwitch \
785 TestNoScriptDuplicatesOnPanelSwitch
786 #endif
788 // Tests that scripts are not duplicated after Scripts Panel switch.
789 IN_PROC_BROWSER_TEST_F(DevToolsSanityTest,
790 MAYBE_TestNoScriptDuplicatesOnPanelSwitch) {
791 RunTest("testNoScriptDuplicatesOnPanelSwitch", kDebuggerTestPage);
794 // Tests that debugger works correctly if pause event occurs when DevTools
795 // frontend is being loaded.
796 // Disabled because of flakiness on all platforms: crbug.com/329036
797 IN_PROC_BROWSER_TEST_F(DevToolsSanityTest,
798 DISABLED_TestPauseWhenLoadingDevTools) {
799 RunTest("testPauseWhenLoadingDevTools", kPauseWhenLoadingDevTools);
802 // Tests that pressing 'Pause' will pause script execution if the script
803 // is already running.
804 #if defined(OS_WIN)
805 // Timing out on windows tryservers: http://crbug.com/219515
806 #define MAYBE_TestPauseWhenScriptIsRunning DISABLED_TestPauseWhenScriptIsRunning
807 #elif defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(ARCH_CPU_ARM_FAMILY)
808 // Timing out on linux ARM bot: https://crbug/238453
809 #define MAYBE_TestPauseWhenScriptIsRunning DISABLED_TestPauseWhenScriptIsRunning
810 #else
811 #define MAYBE_TestPauseWhenScriptIsRunning TestPauseWhenScriptIsRunning
812 #endif
813 IN_PROC_BROWSER_TEST_F(DevToolsSanityTest,
814 MAYBE_TestPauseWhenScriptIsRunning) {
815 RunTest("testPauseWhenScriptIsRunning", kPauseWhenScriptIsRunning);
818 // Tests network timing.
819 IN_PROC_BROWSER_TEST_F(DevToolsSanityTest, TestNetworkTiming) {
820 RunTest("testNetworkTiming", kSlowTestPage);
823 // Tests network size.
824 IN_PROC_BROWSER_TEST_F(DevToolsSanityTest, TestNetworkSize) {
825 RunTest("testNetworkSize", kChunkedTestPage);
828 // Tests raw headers text.
829 IN_PROC_BROWSER_TEST_F(DevToolsSanityTest, TestNetworkSyncSize) {
830 RunTest("testNetworkSyncSize", kChunkedTestPage);
833 // Tests raw headers text.
834 IN_PROC_BROWSER_TEST_F(DevToolsSanityTest, TestNetworkRawHeadersText) {
835 RunTest("testNetworkRawHeadersText", kChunkedTestPage);
838 // Tests that console messages are not duplicated on navigation back.
839 IN_PROC_BROWSER_TEST_F(DevToolsSanityTest, TestConsoleOnNavigateBack) {
840 RunTest("testConsoleOnNavigateBack", kNavigateBackTestPage);
844 // Tests that external navigation from inspector page is always handled by
845 // DevToolsWindow and results in inspected page navigation.
846 IN_PROC_BROWSER_TEST_F(DevToolsSanityTest, TestDevToolsExternalNavigation) {
847 OpenDevToolsWindow(kDebuggerTestPage, true);
848 GURL url = test_server()->GetURL(kNavigateBackTestPage);
849 // TODO(dgozman): remove this once notifications are gone.
850 // Right now notifications happen after observers, so DevTools window is
851 // already loaded, but we still catch it's notification when looking for
852 // all sources.
853 content::WaitForLoadStop(window_->web_contents());
854 content::WindowedNotificationObserver observer(
855 content::NOTIFICATION_LOAD_STOP,
856 content::NotificationService::AllSources());
857 ASSERT_TRUE(content::ExecuteScript(
858 window_->web_contents(),
859 std::string("window.location = \"") + url.spec() + "\""));
860 observer.Wait();
862 ASSERT_TRUE(window_->web_contents()->GetURL().
863 SchemeIs(chrome::kChromeDevToolsScheme));
864 ASSERT_EQ(url, GetInspectedTab()->GetURL());
865 CloseDevToolsWindow();
868 #if defined(OS_WIN) || defined(OS_MACOSX)
869 // Flakily times out: http://crbug.com/163411
870 #define MAYBE_TestReattachAfterCrash DISABLED_TestReattachAfterCrash
871 #else
872 #define MAYBE_TestReattachAfterCrash TestReattachAfterCrash
873 #endif
874 // Tests that inspector will reattach to inspected page when it is reloaded
875 // after a crash. See http://crbug.com/101952
876 IN_PROC_BROWSER_TEST_F(DevToolsSanityTest, MAYBE_TestReattachAfterCrash) {
877 OpenDevToolsWindow(kDebuggerTestPage, false);
879 content::CrashTab(GetInspectedTab());
880 content::WindowedNotificationObserver observer(
881 content::NOTIFICATION_LOAD_STOP,
882 content::Source<NavigationController>(
883 &browser()->tab_strip_model()->GetActiveWebContents()->
884 GetController()));
885 chrome::Reload(browser(), CURRENT_TAB);
886 observer.Wait();
888 RunTestFunction(window_, "testReattachAfterCrash");
889 CloseDevToolsWindow();
892 IN_PROC_BROWSER_TEST_F(DevToolsSanityTest, TestPageWithNoJavaScript) {
893 OpenDevToolsWindow("about:blank", false);
894 std::string result;
895 ASSERT_TRUE(
896 content::ExecuteScriptAndExtractString(
897 window_->GetRenderViewHost(),
898 "window.domAutomationController.send("
899 " '' + (window.uiTests && (typeof uiTests.runTest)));",
900 &result));
901 ASSERT_EQ("function", result) << "DevTools front-end is broken.";
902 CloseDevToolsWindow();
905 #if defined(OS_MACOSX)
906 #define MAYBE_InspectSharedWorker DISABLED_InspectSharedWorker
907 #else
908 #define MAYBE_InspectSharedWorker InspectSharedWorker
909 #endif
910 // Flakily fails with 25s timeout: http://crbug.com/89845
911 IN_PROC_BROWSER_TEST_F(WorkerDevToolsSanityTest, MAYBE_InspectSharedWorker) {
912 #if defined(OS_WIN) && defined(USE_ASH)
913 // Disable this test in Metro+Ash for now (http://crbug.com/262796).
914 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests))
915 return;
916 #endif
918 RunTest("testSharedWorker", kSharedWorkerTestPage);
921 // http://crbug.com/100538
922 #if defined(OS_MACOSX) || defined(OS_WIN)
923 #define MAYBE_PauseInSharedWorkerInitialization DISABLED_PauseInSharedWorkerInitialization
924 #else
925 #define MAYBE_PauseInSharedWorkerInitialization PauseInSharedWorkerInitialization
926 #endif
928 // http://crbug.com/106114 is masking
929 // MAYBE_PauseInSharedWorkerInitialization into
930 // DISABLED_PauseInSharedWorkerInitialization
931 IN_PROC_BROWSER_TEST_F(WorkerDevToolsSanityTest,
932 MAYBE_PauseInSharedWorkerInitialization) {
933 ASSERT_TRUE(test_server()->Start());
934 GURL url = test_server()->GetURL(kReloadSharedWorkerTestPage);
935 ui_test_utils::NavigateToURL(browser(), url);
937 scoped_refptr<WorkerData> worker_data = WaitForFirstSharedWorker();
938 OpenDevToolsWindowForSharedWorker(worker_data.get());
940 TerminateWorker(worker_data);
942 // Reload page to restart the worker.
943 ui_test_utils::NavigateToURL(browser(), url);
945 // Wait until worker script is paused on the debugger statement.
946 RunTestFunction(window_, "testPauseInSharedWorkerInitialization");
947 CloseDevToolsWindow();
950 class DevToolsAgentHostTest : public InProcessBrowserTest {};
952 // Tests DevToolsAgentHost retention by its target.
953 IN_PROC_BROWSER_TEST_F(DevToolsAgentHostTest, TestAgentHostReleased) {
954 ui_test_utils::NavigateToURL(browser(), GURL("about:blank"));
955 RenderViewHost* rvh = browser()->tab_strip_model()->GetWebContentsAt(0)->
956 GetRenderViewHost();
957 DevToolsAgentHost* agent_raw = DevToolsAgentHost::GetOrCreateFor(rvh).get();
958 const std::string agent_id = agent_raw->GetId();
959 ASSERT_EQ(agent_raw, DevToolsAgentHost::GetForId(agent_id)) <<
960 "DevToolsAgentHost cannot be found by id";
961 browser()->tab_strip_model()->
962 CloseWebContentsAt(0, TabStripModel::CLOSE_NONE);
963 ASSERT_FALSE(DevToolsAgentHost::GetForId(agent_id).get())
964 << "DevToolsAgentHost is not released when the tab is closed";
967 class RemoteDebuggingTest: public ExtensionApiTest {
968 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
969 ExtensionApiTest::SetUpCommandLine(command_line);
970 command_line->AppendSwitchASCII(switches::kRemoteDebuggingPort, "9222");
972 // Override the extension root path.
973 PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir_);
974 test_data_dir_ = test_data_dir_.AppendASCII("devtools");
978 IN_PROC_BROWSER_TEST_F(RemoteDebuggingTest, RemoteDebugger) {
979 #if defined(OS_WIN) && defined(USE_ASH)
980 // Disable this test in Metro+Ash for now (http://crbug.com/262796).
981 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests))
982 return;
983 #endif
985 ASSERT_TRUE(RunExtensionTest("target_list")) << message_;