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/location.h"
10 #include "base/memory/ref_counted.h"
11 #include "base/path_service.h"
12 #include "base/prefs/pref_service.h"
13 #include "base/single_thread_task_runner.h"
14 #include "base/strings/string_number_conversions.h"
15 #include "base/strings/stringprintf.h"
16 #include "base/strings/utf_string_conversions.h"
17 #include "base/test/test_timeouts.h"
18 #include "base/thread_task_runner_handle.h"
19 #include "chrome/browser/chrome_notification_types.h"
20 #include "chrome/browser/devtools/device/tcp_device_provider.h"
21 #include "chrome/browser/devtools/devtools_window_testing.h"
22 #include "chrome/browser/extensions/extension_apitest.h"
23 #include "chrome/browser/extensions/extension_browsertest.h"
24 #include "chrome/browser/extensions/extension_service.h"
25 #include "chrome/browser/extensions/unpacked_installer.h"
26 #include "chrome/browser/lifetime/application_lifetime.h"
27 #include "chrome/browser/profiles/profile.h"
28 #include "chrome/browser/ui/browser.h"
29 #include "chrome/browser/ui/browser_commands.h"
30 #include "chrome/browser/ui/browser_iterator.h"
31 #include "chrome/browser/ui/tabs/tab_strip_model.h"
32 #include "chrome/common/chrome_paths.h"
33 #include "chrome/common/chrome_switches.h"
34 #include "chrome/common/pref_names.h"
35 #include "chrome/common/url_constants.h"
36 #include "chrome/test/base/in_process_browser_test.h"
37 #include "chrome/test/base/test_switches.h"
38 #include "chrome/test/base/ui_test_utils.h"
39 #include "components/app_modal/javascript_app_modal_dialog.h"
40 #include "components/app_modal/native_app_modal_dialog.h"
41 #include "content/public/browser/child_process_data.h"
42 #include "content/public/browser/content_browser_client.h"
43 #include "content/public/browser/devtools_agent_host.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/browser/extension_registry.h"
53 #include "extensions/browser/extension_system.h"
54 #include "extensions/browser/notification_types.h"
55 #include "extensions/common/switches.h"
56 #include "net/test/spawned_test_server/spawned_test_server.h"
57 #include "ui/compositor/compositor_switches.h"
58 #include "ui/gl/gl_switches.h"
60 using app_modal::AppModalDialog
;
61 using app_modal::JavaScriptAppModalDialog
;
62 using app_modal::NativeAppModalDialog
;
63 using content::BrowserThread
;
64 using content::DevToolsAgentHost
;
65 using content::NavigationController
;
66 using content::RenderViewHost
;
67 using content::WebContents
;
68 using content::WorkerService
;
69 using content::WorkerServiceObserver
;
73 const char kDebuggerTestPage
[] = "files/devtools/debugger_test_page.html";
74 const char kPauseWhenLoadingDevTools
[] =
75 "files/devtools/pause_when_loading_devtools.html";
76 const char kPauseWhenScriptIsRunning
[] =
77 "files/devtools/pause_when_script_is_running.html";
78 const char kPageWithContentScript
[] =
79 "files/devtools/page_with_content_script.html";
80 const char kNavigateBackTestPage
[] =
81 "files/devtools/navigate_back.html";
82 const char kChunkedTestPage
[] = "chunked";
83 const char kSlowTestPage
[] =
84 "chunked?waitBeforeHeaders=100&waitBetweenChunks=100&chunksNumber=2";
85 const char kSharedWorkerTestPage
[] =
86 "files/workers/workers_ui_shared_worker.html";
87 const char kSharedWorkerTestWorker
[] =
88 "files/workers/workers_ui_shared_worker.js";
89 const char kReloadSharedWorkerTestPage
[] =
90 "files/workers/debug_shared_worker_initialization.html";
91 const char kReloadSharedWorkerTestWorker
[] =
92 "files/workers/debug_shared_worker_initialization.js";
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::ThreadTaskRunnerHandle::Get()->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::ThreadTaskRunnerHandle::Get()->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 // Disabled because of http://crbug.com/497857
644 IN_PROC_BROWSER_TEST_F(DevToolsBeforeUnloadTest
,
645 DISABLED_TestDevToolsOnDevTools
) {
646 ASSERT_TRUE(test_server()->Start());
647 LoadTestPage(kDebuggerTestPage
);
649 std::vector
<DevToolsWindow
*> windows
;
650 std::vector
<content::WindowedNotificationObserver
*> close_observers
;
651 content::WebContents
* inspected_web_contents
= GetInspectedTab();
652 for (int i
= 0; i
< 3; ++i
) {
653 DevToolsWindow
* devtools_window
= OpenDevToolWindowOnWebContents(
654 inspected_web_contents
, i
== 0);
655 windows
.push_back(devtools_window
);
656 content::WindowedNotificationObserver
* close_observer
=
657 new content::WindowedNotificationObserver(
658 content::NOTIFICATION_WEB_CONTENTS_DESTROYED
,
659 content::Source
<content::WebContents
>(
660 DevToolsWindowTesting::Get(devtools_window
)->
661 main_web_contents()));
662 close_observers
.push_back(close_observer
);
663 inspected_web_contents
=
664 DevToolsWindowTesting::Get(devtools_window
)->main_web_contents();
667 InjectBeforeUnloadListener(
668 DevToolsWindowTesting::Get(windows
[0])->main_web_contents());
669 InjectBeforeUnloadListener(
670 DevToolsWindowTesting::Get(windows
[2])->main_web_contents());
671 // Try to close second devtools.
673 content::WindowedNotificationObserver
cancel_browser(
674 chrome::NOTIFICATION_BROWSER_CLOSE_CANCELLED
,
675 content::NotificationService::AllSources());
676 chrome::CloseWindow(DevToolsWindowTesting::Get(windows
[1])->browser());
678 cancel_browser
.Wait();
680 // Try to close browser window.
682 content::WindowedNotificationObserver
cancel_browser(
683 chrome::NOTIFICATION_BROWSER_CLOSE_CANCELLED
,
684 content::NotificationService::AllSources());
685 chrome::CloseWindow(browser());
688 cancel_browser
.Wait();
690 // Try to exit application.
692 content::WindowedNotificationObserver
close_observer(
693 chrome::NOTIFICATION_BROWSER_CLOSED
,
694 content::Source
<Browser
>(browser()));
695 chrome::IncrementKeepAliveCount();
696 chrome::CloseAllBrowsers();
699 close_observer
.Wait();
701 for (size_t i
= 0; i
< close_observers
.size(); ++i
) {
702 close_observers
[i
]->Wait();
703 delete close_observers
[i
];
707 // Tests scripts panel showing.
708 IN_PROC_BROWSER_TEST_F(DevToolsSanityTest
, TestShowScriptsTab
) {
709 RunTest("testShowScriptsTab", kDebuggerTestPage
);
712 // Tests that scripts tab is populated with inspected scripts even if it
713 // hadn't been shown by the moment inspected paged refreshed.
714 // @see http://crbug.com/26312
715 IN_PROC_BROWSER_TEST_F(
717 TestScriptsTabIsPopulatedOnInspectedPageRefresh
) {
718 RunTest("testScriptsTabIsPopulatedOnInspectedPageRefresh",
722 // Tests that chrome.devtools extension is correctly exposed.
723 IN_PROC_BROWSER_TEST_F(DevToolsExtensionTest
,
724 TestDevToolsExtensionAPI
) {
725 LoadExtension("devtools_extension");
726 RunTest("waitForTestResultsInConsole", std::string());
729 // Disabled on Windows due to flakiness. http://crbug.com/183649
731 #define MAYBE_TestDevToolsExtensionMessaging DISABLED_TestDevToolsExtensionMessaging
733 #define MAYBE_TestDevToolsExtensionMessaging TestDevToolsExtensionMessaging
736 // Tests that chrome.devtools extension can communicate with background page
737 // using extension messaging.
738 IN_PROC_BROWSER_TEST_F(DevToolsExtensionTest
,
739 MAYBE_TestDevToolsExtensionMessaging
) {
740 LoadExtension("devtools_messaging");
741 RunTest("waitForTestResultsInConsole", std::string());
744 // Tests that chrome.experimental.devtools extension is correctly exposed
745 // when the extension has experimental permission.
746 IN_PROC_BROWSER_TEST_F(DevToolsExperimentalExtensionTest
,
747 TestDevToolsExperimentalExtensionAPI
) {
748 LoadExtension("devtools_experimental");
749 RunTest("waitForTestResultsInConsole", std::string());
752 // Tests that a content script is in the scripts list.
753 IN_PROC_BROWSER_TEST_F(DevToolsExtensionTest
,
754 TestContentScriptIsPresent
) {
755 LoadExtension("simple_content_script");
756 RunTest("testContentScriptIsPresent", kPageWithContentScript
);
759 // Tests that scripts are not duplicated after Scripts Panel switch.
760 IN_PROC_BROWSER_TEST_F(DevToolsSanityTest
,
761 TestNoScriptDuplicatesOnPanelSwitch
) {
762 RunTest("testNoScriptDuplicatesOnPanelSwitch", kDebuggerTestPage
);
765 // Tests that debugger works correctly if pause event occurs when DevTools
766 // frontend is being loaded.
767 IN_PROC_BROWSER_TEST_F(DevToolsSanityTest
,
768 TestPauseWhenLoadingDevTools
) {
769 RunTest("testPauseWhenLoadingDevTools", kPauseWhenLoadingDevTools
);
772 // Tests that pressing 'Pause' will pause script execution if the script
773 // is already running.
774 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(ARCH_CPU_ARM_FAMILY)
775 // Timing out on linux ARM bot: https://crbug/238453
776 #define MAYBE_TestPauseWhenScriptIsRunning DISABLED_TestPauseWhenScriptIsRunning
778 #define MAYBE_TestPauseWhenScriptIsRunning TestPauseWhenScriptIsRunning
780 IN_PROC_BROWSER_TEST_F(DevToolsSanityTest
,
781 MAYBE_TestPauseWhenScriptIsRunning
) {
782 RunTest("testPauseWhenScriptIsRunning", kPauseWhenScriptIsRunning
);
785 // Tests network timing.
786 IN_PROC_BROWSER_TEST_F(DevToolsSanityTest
, TestNetworkTiming
) {
787 RunTest("testNetworkTiming", kSlowTestPage
);
790 // Tests network size.
791 IN_PROC_BROWSER_TEST_F(DevToolsSanityTest
, TestNetworkSize
) {
792 RunTest("testNetworkSize", kChunkedTestPage
);
795 // Tests raw headers text.
796 IN_PROC_BROWSER_TEST_F(DevToolsSanityTest
, TestNetworkSyncSize
) {
797 RunTest("testNetworkSyncSize", kChunkedTestPage
);
800 // Tests raw headers text.
801 IN_PROC_BROWSER_TEST_F(DevToolsSanityTest
, TestNetworkRawHeadersText
) {
802 RunTest("testNetworkRawHeadersText", kChunkedTestPage
);
805 // Tests that console messages are not duplicated on navigation back.
807 // Flaking on windows swarm try runs: crbug.com/409285.
808 #define MAYBE_TestConsoleOnNavigateBack DISABLED_TestConsoleOnNavigateBack
810 #define MAYBE_TestConsoleOnNavigateBack TestConsoleOnNavigateBack
812 IN_PROC_BROWSER_TEST_F(DevToolsSanityTest
, MAYBE_TestConsoleOnNavigateBack
) {
813 RunTest("testConsoleOnNavigateBack", kNavigateBackTestPage
);
816 IN_PROC_BROWSER_TEST_F(DevToolsSanityTest
, TestDeviceEmulation
) {
817 RunTest("testDeviceMetricsOverrides", "about:blank");
820 // Tests that settings are stored in profile correctly.
821 IN_PROC_BROWSER_TEST_F(DevToolsSanityTest
, TestSettings
) {
822 OpenDevToolsWindow("about:blank", true);
823 RunTestFunction(window_
, "testSettings");
824 CloseDevToolsWindow();
827 // Tests that external navigation from inspector page is always handled by
828 // DevToolsWindow and results in inspected page navigation.
829 IN_PROC_BROWSER_TEST_F(DevToolsSanityTest
, TestDevToolsExternalNavigation
) {
830 OpenDevToolsWindow(kDebuggerTestPage
, true);
831 GURL url
= test_server()->GetURL(kNavigateBackTestPage
);
832 ui_test_utils::UrlLoadObserver
observer(url
,
833 content::NotificationService::AllSources());
834 ASSERT_TRUE(content::ExecuteScript(
836 std::string("window.location = \"") + url
.spec() + "\""));
839 ASSERT_TRUE(main_web_contents()->GetURL().
840 SchemeIs(content::kChromeDevToolsScheme
));
841 ASSERT_EQ(url
, GetInspectedTab()->GetURL());
842 CloseDevToolsWindow();
845 // Tests that toolbox window is loaded when DevTools window is undocked.
846 IN_PROC_BROWSER_TEST_F(DevToolsSanityTest
, TestToolboxLoadedUndocked
) {
847 OpenDevToolsWindow(kDebuggerTestPage
, false);
848 ASSERT_TRUE(toolbox_web_contents());
849 DevToolsWindow
* on_self
=
850 DevToolsWindowTesting::OpenDevToolsWindowSync(main_web_contents(), false);
851 ASSERT_FALSE(DevToolsWindowTesting::Get(on_self
)->toolbox_web_contents());
852 DevToolsWindowTesting::CloseDevToolsWindowSync(on_self
);
853 CloseDevToolsWindow();
856 // Tests that toolbox window is not loaded when DevTools window is docked.
857 IN_PROC_BROWSER_TEST_F(DevToolsSanityTest
, TestToolboxNotLoadedDocked
) {
858 OpenDevToolsWindow(kDebuggerTestPage
, true);
859 ASSERT_FALSE(toolbox_web_contents());
860 DevToolsWindow
* on_self
=
861 DevToolsWindowTesting::OpenDevToolsWindowSync(main_web_contents(), false);
862 ASSERT_FALSE(DevToolsWindowTesting::Get(on_self
)->toolbox_web_contents());
863 DevToolsWindowTesting::CloseDevToolsWindowSync(on_self
);
864 CloseDevToolsWindow();
867 // Tests that inspector will reattach to inspected page when it is reloaded
868 // after a crash. See http://crbug.com/101952
869 // Disabled. it doesn't check anything right now: http://crbug.com/461790
870 IN_PROC_BROWSER_TEST_F(DevToolsSanityTest
, DISABLED_TestReattachAfterCrash
) {
871 RunTest("testReattachAfterCrash", std::string());
874 IN_PROC_BROWSER_TEST_F(DevToolsSanityTest
, TestPageWithNoJavaScript
) {
875 OpenDevToolsWindow("about:blank", false);
878 content::ExecuteScriptAndExtractString(
879 main_web_contents()->GetRenderViewHost(),
880 "window.domAutomationController.send("
881 " '' + (window.uiTests && (typeof uiTests.runTest)));",
883 ASSERT_EQ("function", result
) << "DevTools front-end is broken.";
884 CloseDevToolsWindow();
887 IN_PROC_BROWSER_TEST_F(WorkerDevToolsSanityTest
, InspectSharedWorker
) {
888 #if defined(OS_WIN) && defined(USE_ASH)
889 // Disable this test in Metro+Ash for now (http://crbug.com/262796).
890 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
891 switches::kAshBrowserTests
))
895 RunTest("testSharedWorker", kSharedWorkerTestPage
, kSharedWorkerTestWorker
);
898 // Disabled, crashes under Dr.Memory and ASan, http://crbug.com/432444.
899 IN_PROC_BROWSER_TEST_F(WorkerDevToolsSanityTest
,
900 DISABLED_PauseInSharedWorkerInitialization
) {
901 ASSERT_TRUE(test_server()->Start());
902 GURL url
= test_server()->GetURL(kReloadSharedWorkerTestPage
);
903 ui_test_utils::NavigateToURL(browser(), url
);
905 scoped_refptr
<WorkerData
> worker_data
=
906 WaitForFirstSharedWorker(kReloadSharedWorkerTestWorker
);
907 OpenDevToolsWindowForSharedWorker(worker_data
.get());
909 // We should make sure that the worker inspector has loaded before
910 // terminating worker.
911 RunTestFunction(window_
, "testPauseInSharedWorkerInitialization1");
913 TerminateWorker(worker_data
);
915 // Reload page to restart the worker.
916 ui_test_utils::NavigateToURL(browser(), url
);
918 // Wait until worker script is paused on the debugger statement.
919 RunTestFunction(window_
, "testPauseInSharedWorkerInitialization2");
920 CloseDevToolsWindow();
923 class DevToolsAgentHostTest
: public InProcessBrowserTest
{};
925 // Tests DevToolsAgentHost retention by its target.
926 IN_PROC_BROWSER_TEST_F(DevToolsAgentHostTest
, TestAgentHostReleased
) {
927 ui_test_utils::NavigateToURL(browser(), GURL("about:blank"));
928 WebContents
* web_contents
= browser()->tab_strip_model()->GetWebContentsAt(0);
929 DevToolsAgentHost
* agent_raw
=
930 DevToolsAgentHost::GetOrCreateFor(web_contents
).get();
931 const std::string agent_id
= agent_raw
->GetId();
932 ASSERT_EQ(agent_raw
, DevToolsAgentHost::GetForId(agent_id
).get())
933 << "DevToolsAgentHost cannot be found by id";
934 browser()->tab_strip_model()->
935 CloseWebContentsAt(0, TabStripModel::CLOSE_NONE
);
936 ASSERT_FALSE(DevToolsAgentHost::GetForId(agent_id
).get())
937 << "DevToolsAgentHost is not released when the tab is closed";
940 class RemoteDebuggingTest
: public ExtensionApiTest
{
941 void SetUpCommandLine(base::CommandLine
* command_line
) override
{
942 ExtensionApiTest::SetUpCommandLine(command_line
);
943 command_line
->AppendSwitchASCII(switches::kRemoteDebuggingPort
, "9222");
945 // Override the extension root path.
946 PathService::Get(chrome::DIR_TEST_DATA
, &test_data_dir_
);
947 test_data_dir_
= test_data_dir_
.AppendASCII("devtools");
951 // Fails on CrOS. crbug.com/431399
952 #if defined(OS_CHROMEOS)
953 #define MAYBE_RemoteDebugger DISABLED_RemoteDebugger
955 #define MAYBE_RemoteDebugger RemoteDebugger
957 IN_PROC_BROWSER_TEST_F(RemoteDebuggingTest
, MAYBE_RemoteDebugger
) {
958 #if defined(OS_WIN) && defined(USE_ASH)
959 // Disable this test in Metro+Ash for now (http://crbug.com/262796).
960 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
961 switches::kAshBrowserTests
))
965 ASSERT_TRUE(RunExtensionTest("target_list")) << message_
;
968 using DevToolsPolicyTest
= InProcessBrowserTest
;
969 IN_PROC_BROWSER_TEST_F(DevToolsPolicyTest
, PolicyTrue
) {
970 browser()->profile()->GetPrefs()->SetBoolean(prefs::kDevToolsDisabled
, true);
971 ui_test_utils::NavigateToURL(browser(), GURL("about:blank"));
972 content::WebContents
* web_contents
=
973 browser()->tab_strip_model()->GetWebContentsAt(0);
974 scoped_refptr
<content::DevToolsAgentHost
> agent(
975 content::DevToolsAgentHost::GetOrCreateFor(web_contents
));
976 DevToolsWindow::OpenDevToolsWindow(web_contents
);
977 DevToolsWindow
* window
= DevToolsWindow::FindDevToolsWindow(agent
.get());
978 ASSERT_FALSE(window
);
981 class DevToolsPixelOutputTests
: public DevToolsSanityTest
{
983 void SetUpCommandLine(base::CommandLine
* command_line
) override
{
984 command_line
->AppendSwitch(switches::kEnablePixelOutputInTests
);
985 command_line
->AppendSwitch(switches::kUseGpuInTests
);
989 // This test enables switches::kUseGpuInTests which causes false positives
990 // with MemorySanitizer.
991 #if defined(MEMORY_SANITIZER) || \
992 (defined(OS_CHROMEOS) && defined(OFFICIAL_BUILD))
993 #define MAYBE_TestScreenshotRecording DISABLED_TestScreenshotRecording
995 #define MAYBE_TestScreenshotRecording TestScreenshotRecording
997 // Tests raw headers text.
998 IN_PROC_BROWSER_TEST_F(DevToolsPixelOutputTests
,
999 MAYBE_TestScreenshotRecording
) {
1000 RunTest("testScreenshotRecording", std::string());