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