- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / browser / devtools / devtools_sanity_browsertest.cc
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.
4
5 #include "base/bind.h"
6 #include "base/cancelable_callback.h"
7 #include "base/command_line.h"
8 #include "base/compiler_specific.h"
9 #include "base/memory/ref_counted.h"
10 #include "base/path_service.h"
11 #include "base/prefs/pref_service.h"
12 #include "base/strings/stringprintf.h"
13 #include "base/strings/utf_string_conversions.h"
14 #include "base/test/test_timeouts.h"
15 #include "chrome/browser/chrome_notification_types.h"
16 #include "chrome/browser/devtools/browser_list_tabcontents_provider.h"
17 #include "chrome/browser/devtools/devtools_window.h"
18 #include "chrome/browser/extensions/extension_apitest.h"
19 #include "chrome/browser/extensions/extension_browsertest.h"
20 #include "chrome/browser/extensions/extension_service.h"
21 #include "chrome/browser/extensions/extension_system.h"
22 #include "chrome/browser/extensions/unpacked_installer.h"
23 #include "chrome/browser/profiles/profile.h"
24 #include "chrome/browser/ui/browser.h"
25 #include "chrome/browser/ui/browser_commands.h"
26 #include "chrome/browser/ui/tabs/tab_strip_model.h"
27 #include "chrome/common/chrome_paths.h"
28 #include "chrome/common/chrome_switches.h"
29 #include "chrome/common/pref_names.h"
30 #include "chrome/common/url_constants.h"
31 #include "chrome/test/base/in_process_browser_test.h"
32 #include "chrome/test/base/test_switches.h"
33 #include "chrome/test/base/ui_test_utils.h"
34 #include "content/public/browser/child_process_data.h"
35 #include "content/public/browser/content_browser_client.h"
36 #include "content/public/browser/devtools_agent_host.h"
37 #include "content/public/browser/devtools_client_host.h"
38 #include "content/public/browser/devtools_http_handler.h"
39 #include "content/public/browser/devtools_manager.h"
40 #include "content/public/browser/notification_registrar.h"
41 #include "content/public/browser/notification_service.h"
42 #include "content/public/browser/render_view_host.h"
43 #include "content/public/browser/web_contents.h"
44 #include "content/public/browser/worker_service.h"
45 #include "content/public/browser/worker_service_observer.h"
46 #include "content/public/common/content_switches.h"
47 #include "content/public/test/browser_test_utils.h"
48 #include "extensions/common/switches.h"
49 #include "net/socket/tcp_listen_socket.h"
50 #include "net/test/spawned_test_server/spawned_test_server.h"
51
52 using content::BrowserThread;
53 using content::DevToolsManager;
54 using content::DevToolsAgentHost;
55 using content::NavigationController;
56 using content::RenderViewHost;
57 using content::WebContents;
58 using content::WorkerService;
59 using content::WorkerServiceObserver;
60
61 namespace {
62
63 const char kDebuggerTestPage[] = "files/devtools/debugger_test_page.html";
64 const char kPauseWhenLoadingDevTools[] =
65     "files/devtools/pause_when_loading_devtools.html";
66 const char kPauseWhenScriptIsRunning[] =
67     "files/devtools/pause_when_script_is_running.html";
68 const char kPageWithContentScript[] =
69     "files/devtools/page_with_content_script.html";
70 const char kNavigateBackTestPage[] =
71     "files/devtools/navigate_back.html";
72 const char kChunkedTestPage[] = "chunked";
73 const char kSlowTestPage[] =
74     "chunked?waitBeforeHeaders=100&waitBetweenChunks=100&chunksNumber=2";
75 const char kSharedWorkerTestPage[] =
76     "files/workers/workers_ui_shared_worker.html";
77 const char kReloadSharedWorkerTestPage[] =
78     "files/workers/debug_shared_worker_initialization.html";
79
80 void RunTestFunction(DevToolsWindow* window, const char* test_name) {
81   std::string result;
82
83   // At first check that JavaScript part of the front-end is loaded by
84   // checking that global variable uiTests exists(it's created after all js
85   // files have been loaded) and has runTest method.
86   ASSERT_TRUE(
87       content::ExecuteScriptAndExtractString(
88           window->GetRenderViewHost(),
89           "window.domAutomationController.send("
90           "    '' + (window.uiTests && (typeof uiTests.runTest)));",
91           &result));
92
93   if (result == "function") {
94     ASSERT_TRUE(
95         content::ExecuteScriptAndExtractString(
96             window->GetRenderViewHost(),
97             base::StringPrintf("uiTests.runTest('%s')", test_name),
98             &result));
99     EXPECT_EQ("[OK]", result);
100   } else {
101     FAIL() << "DevTools front-end is broken.";
102   }
103 }
104
105 class DevToolsSanityTest : public InProcessBrowserTest {
106  public:
107   DevToolsSanityTest()
108       : window_(NULL),
109         inspected_rvh_(NULL) {}
110
111  protected:
112   void RunTest(const std::string& test_name, const std::string& test_page) {
113     OpenDevToolsWindow(test_page);
114     RunTestFunction(window_, test_name.c_str());
115     CloseDevToolsWindow();
116   }
117
118   void OpenDevToolsWindow(const std::string& test_page) {
119     ASSERT_TRUE(test_server()->Start());
120     GURL url = test_server()->GetURL(test_page);
121     ui_test_utils::NavigateToURL(browser(), url);
122
123     content::WindowedNotificationObserver observer(
124         content::NOTIFICATION_LOAD_STOP,
125         content::NotificationService::AllSources());
126     inspected_rvh_ = GetInspectedTab()->GetRenderViewHost();
127     window_ = DevToolsWindow::OpenDevToolsWindow(inspected_rvh_);
128     observer.Wait();
129   }
130
131   WebContents* GetInspectedTab() {
132     return browser()->tab_strip_model()->GetWebContentsAt(0);
133   }
134
135   void ToggleDevToolsWindow() {
136     content::WindowedNotificationObserver close_observer(
137         content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
138         content::Source<content::WebContents>(window_->web_contents()));
139     DevToolsWindow::ToggleDevToolsWindow(inspected_rvh_, false,
140         DevToolsToggleAction::Toggle());
141     close_observer.Wait();
142   }
143
144   void CloseDevToolsWindow() {
145     DevToolsManager* devtools_manager = DevToolsManager::GetInstance();
146     content::WindowedNotificationObserver close_observer(
147         content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
148         content::Source<content::WebContents>(window_->web_contents()));
149     devtools_manager->CloseAllClientHosts();
150     close_observer.Wait();
151   }
152
153   DevToolsWindow* window_;
154   RenderViewHost* inspected_rvh_;
155 };
156
157 // Used to block until a dev tools window gets beforeunload event.
158 class DevToolsWindowBeforeUnloadObserver
159     : public content::WebContentsObserver {
160  public:
161   explicit DevToolsWindowBeforeUnloadObserver(
162       content::WebContents* web_contents);
163   bool Fired();
164  private:
165   // Invoked when the beforeunload handler fires.
166   virtual void BeforeUnloadFired(const base::TimeTicks& proceed_time) OVERRIDE;
167
168   bool m_fired;
169
170   DISALLOW_COPY_AND_ASSIGN(DevToolsWindowBeforeUnloadObserver);
171 };
172
173 DevToolsWindowBeforeUnloadObserver::DevToolsWindowBeforeUnloadObserver(
174     content::WebContents* web_contents)
175     : WebContentsObserver(web_contents),
176       m_fired(false) {
177 }
178
179 bool DevToolsWindowBeforeUnloadObserver::Fired() {
180   return m_fired;
181 }
182
183 void DevToolsWindowBeforeUnloadObserver::BeforeUnloadFired(
184     const base::TimeTicks& proceed_time) {
185   m_fired = true;
186 }
187
188 void TimeoutCallback(const std::string& timeout_message) {
189   FAIL() << timeout_message;
190   base::MessageLoop::current()->Quit();
191 }
192
193 // Base class for DevTools tests that test devtools functionality for
194 // extensions and content scripts.
195 class DevToolsExtensionTest : public DevToolsSanityTest,
196                               public content::NotificationObserver {
197  public:
198   DevToolsExtensionTest() : DevToolsSanityTest() {
199     PathService::Get(chrome::DIR_TEST_DATA, &test_extensions_dir_);
200     test_extensions_dir_ = test_extensions_dir_.AppendASCII("devtools");
201     test_extensions_dir_ = test_extensions_dir_.AppendASCII("extensions");
202   }
203
204  protected:
205   // Load an extension from test\data\devtools\extensions\<extension_name>
206   void LoadExtension(const char* extension_name) {
207     base::FilePath path = test_extensions_dir_.AppendASCII(extension_name);
208     ASSERT_TRUE(LoadExtensionFromPath(path)) << "Failed to load extension.";
209   }
210
211  private:
212   bool LoadExtensionFromPath(const base::FilePath& path) {
213     ExtensionService* service = extensions::ExtensionSystem::Get(
214         browser()->profile())->extension_service();
215     size_t num_before = service->extensions()->size();
216     {
217       content::NotificationRegistrar registrar;
218       registrar.Add(this, chrome::NOTIFICATION_EXTENSION_LOADED,
219                     content::NotificationService::AllSources());
220       base::CancelableClosure timeout(
221           base::Bind(&TimeoutCallback, "Extension load timed out."));
222       base::MessageLoop::current()->PostDelayedTask(
223           FROM_HERE, timeout.callback(), TestTimeouts::action_timeout());
224       extensions::UnpackedInstaller::Create(service)->Load(path);
225       content::RunMessageLoop();
226       timeout.Cancel();
227     }
228     size_t num_after = service->extensions()->size();
229     if (num_after != (num_before + 1))
230       return false;
231
232     return WaitForExtensionViewsToLoad();
233   }
234
235   bool WaitForExtensionViewsToLoad() {
236     // Wait for all the extension render views that exist to finish loading.
237     // NOTE: This assumes that the extension views list is not changing while
238     // this method is running.
239
240     content::NotificationRegistrar registrar;
241     registrar.Add(this, chrome::NOTIFICATION_EXTENSION_HOST_DID_STOP_LOADING,
242                   content::NotificationService::AllSources());
243     base::CancelableClosure timeout(
244         base::Bind(&TimeoutCallback, "Extension host load timed out."));
245     base::MessageLoop::current()->PostDelayedTask(
246         FROM_HERE, timeout.callback(), TestTimeouts::action_timeout());
247
248     ExtensionProcessManager* manager =
249         extensions::ExtensionSystem::Get(browser()->profile())->
250             process_manager();
251     ExtensionProcessManager::ViewSet all_views = manager->GetAllViews();
252     for (ExtensionProcessManager::ViewSet::const_iterator iter =
253              all_views.begin();
254          iter != all_views.end();) {
255       if (!(*iter)->IsLoading())
256         ++iter;
257       else
258         content::RunMessageLoop();
259     }
260
261     timeout.Cancel();
262     return true;
263   }
264
265   virtual void Observe(int type,
266                        const content::NotificationSource& source,
267                        const content::NotificationDetails& details) OVERRIDE {
268     switch (type) {
269       case chrome::NOTIFICATION_EXTENSION_LOADED:
270       case chrome::NOTIFICATION_EXTENSION_HOST_DID_STOP_LOADING:
271         base::MessageLoopForUI::current()->Quit();
272         break;
273       default:
274         NOTREACHED();
275         break;
276     }
277   }
278
279   base::FilePath test_extensions_dir_;
280 };
281
282 class DevToolsExperimentalExtensionTest : public DevToolsExtensionTest {
283  public:
284   virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
285     command_line->AppendSwitch(
286         extensions::switches::kEnableExperimentalExtensionApis);
287   }
288 };
289
290 class WorkerDevToolsSanityTest : public InProcessBrowserTest {
291  public:
292   WorkerDevToolsSanityTest() : window_(NULL) {}
293
294  protected:
295   class WorkerData : public base::RefCountedThreadSafe<WorkerData> {
296    public:
297     WorkerData() : worker_process_id(0), worker_route_id(0) {}
298     int worker_process_id;
299     int worker_route_id;
300
301    private:
302     friend class base::RefCountedThreadSafe<WorkerData>;
303     ~WorkerData() {}
304   };
305
306   class WorkerCreationObserver : public WorkerServiceObserver {
307    public:
308     explicit WorkerCreationObserver(WorkerData* worker_data)
309         : worker_data_(worker_data) {
310     }
311
312    private:
313     virtual ~WorkerCreationObserver() {}
314
315     virtual void WorkerCreated (
316         const GURL& url,
317         const string16& name,
318         int process_id,
319         int route_id) OVERRIDE {
320       worker_data_->worker_process_id = process_id;
321       worker_data_->worker_route_id = route_id;
322       WorkerService::GetInstance()->RemoveObserver(this);
323       BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
324           base::MessageLoop::QuitClosure());
325       delete this;
326     }
327     scoped_refptr<WorkerData> worker_data_;
328   };
329
330   class WorkerTerminationObserver : public WorkerServiceObserver {
331    public:
332     explicit WorkerTerminationObserver(WorkerData* worker_data)
333         : worker_data_(worker_data) {
334     }
335
336    private:
337     virtual ~WorkerTerminationObserver() {}
338
339     virtual void WorkerDestroyed(int process_id, int route_id) OVERRIDE {
340       ASSERT_EQ(worker_data_->worker_process_id, process_id);
341       ASSERT_EQ(worker_data_->worker_route_id, route_id);
342       WorkerService::GetInstance()->RemoveObserver(this);
343       BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
344           base::MessageLoop::QuitClosure());
345       delete this;
346     }
347     scoped_refptr<WorkerData> worker_data_;
348   };
349
350   void RunTest(const char* test_name, const char* test_page) {
351     ASSERT_TRUE(test_server()->Start());
352     GURL url = test_server()->GetURL(test_page);
353     ui_test_utils::NavigateToURL(browser(), url);
354
355     scoped_refptr<WorkerData> worker_data = WaitForFirstSharedWorker();
356     OpenDevToolsWindowForSharedWorker(worker_data.get());
357     RunTestFunction(window_, test_name);
358     CloseDevToolsWindow();
359   }
360
361   static void TerminateWorkerOnIOThread(scoped_refptr<WorkerData> worker_data) {
362     if (WorkerService::GetInstance()->TerminateWorker(
363             worker_data->worker_process_id, worker_data->worker_route_id)) {
364       WorkerService::GetInstance()->AddObserver(
365           new WorkerTerminationObserver(worker_data.get()));
366       return;
367     }
368     FAIL() << "Failed to terminate worker.\n";
369   }
370
371   static void TerminateWorker(scoped_refptr<WorkerData> worker_data) {
372     BrowserThread::PostTask(
373         BrowserThread::IO, FROM_HERE,
374         base::Bind(&TerminateWorkerOnIOThread, worker_data));
375     content::RunMessageLoop();
376   }
377
378   static void WaitForFirstSharedWorkerOnIOThread(
379       scoped_refptr<WorkerData> worker_data) {
380     std::vector<WorkerService::WorkerInfo> worker_info =
381         WorkerService::GetInstance()->GetWorkers();
382     if (!worker_info.empty()) {
383       worker_data->worker_process_id = worker_info[0].process_id;
384       worker_data->worker_route_id = worker_info[0].route_id;
385       BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
386           base::MessageLoop::QuitClosure());
387       return;
388     }
389
390     WorkerService::GetInstance()->AddObserver(
391         new WorkerCreationObserver(worker_data.get()));
392   }
393
394   static scoped_refptr<WorkerData> WaitForFirstSharedWorker() {
395     scoped_refptr<WorkerData> worker_data(new WorkerData());
396     BrowserThread::PostTask(
397         BrowserThread::IO, FROM_HERE,
398         base::Bind(&WaitForFirstSharedWorkerOnIOThread, worker_data));
399     content::RunMessageLoop();
400     return worker_data;
401   }
402
403   void OpenDevToolsWindowForSharedWorker(WorkerData* worker_data) {
404     Profile* profile = browser()->profile();
405     window_ = DevToolsWindow::CreateDevToolsWindowForWorker(profile);
406     window_->Show(DevToolsToggleAction::Show());
407     scoped_refptr<DevToolsAgentHost> agent_host(
408         DevToolsAgentHost::GetForWorker(
409             worker_data->worker_process_id,
410             worker_data->worker_route_id));
411     DevToolsManager::GetInstance()->RegisterDevToolsClientHostFor(
412         agent_host.get(), window_->GetDevToolsClientHostForTest());
413     RenderViewHost* client_rvh = window_->GetRenderViewHost();
414     WebContents* client_contents = WebContents::FromRenderViewHost(client_rvh);
415     if (client_contents->IsLoading()) {
416       content::WindowedNotificationObserver observer(
417           content::NOTIFICATION_LOAD_STOP,
418           content::Source<NavigationController>(
419               &client_contents->GetController()));
420       observer.Wait();
421     }
422   }
423
424   void CloseDevToolsWindow() {
425     Browser* browser = window_->browser();
426     content::WindowedNotificationObserver close_observer(
427         content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
428         content::Source<content::WebContents>(window_->web_contents()));
429     browser->tab_strip_model()->CloseAllTabs();
430     close_observer.Wait();
431   }
432
433   DevToolsWindow* window_;
434 };
435
436 // Test beforeunload event delivery.
437 // Crashes on Win only.  http://crbug.com/313658
438 #if defined(OS_WIN)
439 #define MAYBE_TestBeforeUnloadEvents DISABLED_TestBeforeUnloadEvents
440 #else
441 #define MAYBE_TestBeforeUnloadEvents TestBeforeUnloadEvents
442 #endif
443 IN_PROC_BROWSER_TEST_F(DevToolsSanityTest, MAYBE_TestBeforeUnloadEvents) {
444   OpenDevToolsWindow(kDebuggerTestPage);
445   scoped_ptr<DevToolsWindowBeforeUnloadObserver> contents_observer;
446   contents_observer.reset(
447       new DevToolsWindowBeforeUnloadObserver(window_->web_contents()));
448   ToggleDevToolsWindow();
449   ASSERT_TRUE(contents_observer->Fired());
450 }
451
452 // Tests scripts panel showing.
453 // TODO(pfeldman): figure out flake.
454 IN_PROC_BROWSER_TEST_F(DevToolsSanityTest, DISABLED_TestShowScriptsTab) {
455   RunTest("testShowScriptsTab", kDebuggerTestPage);
456 }
457
458 // Tests that scripts tab is populated with inspected scripts even if it
459 // hadn't been shown by the moment inspected paged refreshed.
460 // @see http://crbug.com/26312
461 IN_PROC_BROWSER_TEST_F(
462     DevToolsSanityTest,
463     TestScriptsTabIsPopulatedOnInspectedPageRefresh) {
464   // Clear inspector settings to ensure that Elements will be
465   // current panel when DevTools window is open.
466   content::BrowserContext* browser_context =
467       GetInspectedTab()->GetBrowserContext();
468   Profile::FromBrowserContext(browser_context)->GetPrefs()->
469       ClearPref(prefs::kWebKitInspectorSettings);
470
471   RunTest("testScriptsTabIsPopulatedOnInspectedPageRefresh",
472           kDebuggerTestPage);
473 }
474
475 // Tests that chrome.devtools extension is correctly exposed.
476 IN_PROC_BROWSER_TEST_F(DevToolsExtensionTest,
477                        TestDevToolsExtensionAPI) {
478   LoadExtension("devtools_extension");
479   RunTest("waitForTestResultsInConsole", std::string());
480 }
481
482 // Disabled on Windows due to flakiness. http://crbug.com/183649
483 #if defined(OS_WIN)
484 #define MAYBE_TestDevToolsExtensionMessaging DISABLED_TestDevToolsExtensionMessaging
485 #else
486 #define MAYBE_TestDevToolsExtensionMessaging TestDevToolsExtensionMessaging
487 #endif
488
489 // Tests that chrome.devtools extension can communicate with background page
490 // using extension messaging.
491 IN_PROC_BROWSER_TEST_F(DevToolsExtensionTest,
492                        MAYBE_TestDevToolsExtensionMessaging) {
493   LoadExtension("devtools_messaging");
494   RunTest("waitForTestResultsInConsole", std::string());
495 }
496
497 // Tests that chrome.experimental.devtools extension is correctly exposed
498 // when the extension has experimental permission.
499 IN_PROC_BROWSER_TEST_F(DevToolsExperimentalExtensionTest,
500                        TestDevToolsExperimentalExtensionAPI) {
501   LoadExtension("devtools_experimental");
502   RunTest("waitForTestResultsInConsole", std::string());
503 }
504
505 // Tests that a content script is in the scripts list.
506 // http://crbug.com/114104
507 IN_PROC_BROWSER_TEST_F(DevToolsExtensionTest,
508                        TestContentScriptIsPresent) {
509   LoadExtension("simple_content_script");
510   RunTest("testContentScriptIsPresent", kPageWithContentScript);
511 }
512
513 // Tests that scripts are not duplicated after Scripts Panel switch.
514 IN_PROC_BROWSER_TEST_F(DevToolsSanityTest,
515                        TestNoScriptDuplicatesOnPanelSwitch) {
516   RunTest("testNoScriptDuplicatesOnPanelSwitch", kDebuggerTestPage);
517 }
518
519 // Tests that debugger works correctly if pause event occurs when DevTools
520 // frontend is being loaded.
521 IN_PROC_BROWSER_TEST_F(DevToolsSanityTest,
522                        TestPauseWhenLoadingDevTools) {
523   RunTest("testPauseWhenLoadingDevTools", kPauseWhenLoadingDevTools);
524 }
525
526 // Tests that pressing 'Pause' will pause script execution if the script
527 // is already running.
528 #if defined(OS_WIN)
529 // Timing out on windows tryservers: http://crbug.com/219515
530 #define MAYBE_TestPauseWhenScriptIsRunning DISABLED_TestPauseWhenScriptIsRunning
531 #elif defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(ARCH_CPU_ARM_FAMILY)
532 // Timing out on linux ARM bot: https://crbug/238453
533 #define MAYBE_TestPauseWhenScriptIsRunning DISABLED_TestPauseWhenScriptIsRunning
534 #else
535 #define MAYBE_TestPauseWhenScriptIsRunning TestPauseWhenScriptIsRunning
536 #endif
537 IN_PROC_BROWSER_TEST_F(DevToolsSanityTest,
538                        MAYBE_TestPauseWhenScriptIsRunning) {
539   RunTest("testPauseWhenScriptIsRunning", kPauseWhenScriptIsRunning);
540 }
541
542 // Tests network timing.
543 IN_PROC_BROWSER_TEST_F(DevToolsSanityTest, TestNetworkTiming) {
544   RunTest("testNetworkTiming", kSlowTestPage);
545 }
546
547 // Tests network size.
548 IN_PROC_BROWSER_TEST_F(DevToolsSanityTest, TestNetworkSize) {
549   RunTest("testNetworkSize", kChunkedTestPage);
550 }
551
552 // Tests raw headers text.
553 IN_PROC_BROWSER_TEST_F(DevToolsSanityTest, TestNetworkSyncSize) {
554   RunTest("testNetworkSyncSize", kChunkedTestPage);
555 }
556
557 // Tests raw headers text.
558 IN_PROC_BROWSER_TEST_F(DevToolsSanityTest, TestNetworkRawHeadersText) {
559   RunTest("testNetworkRawHeadersText", kChunkedTestPage);
560 }
561
562 // Tests that console messages are not duplicated on navigation back.
563 // Disabled: http://crbug.com/260341
564 IN_PROC_BROWSER_TEST_F(DevToolsSanityTest, DISABLED_TestConsoleOnNavigateBack) {
565   RunTest("testConsoleOnNavigateBack", kNavigateBackTestPage);
566 }
567
568
569 // Tests that external navigation from inspector page is always handled by
570 // DevToolsWindow and results in inspected page navigation.
571 IN_PROC_BROWSER_TEST_F(DevToolsSanityTest, TestDevToolsExternalNavigation) {
572   OpenDevToolsWindow(kDebuggerTestPage);
573   GURL url = test_server()->GetURL(kNavigateBackTestPage);
574   content::WindowedNotificationObserver observer(
575       content::NOTIFICATION_LOAD_STOP,
576       content::NotificationService::AllSources());
577   ASSERT_TRUE(content::ExecuteScript(
578       window_->web_contents(),
579       std::string("window.location = \"") + url.spec() + "\""));
580   observer.Wait();
581
582   ASSERT_TRUE(window_->web_contents()->GetURL().
583                   SchemeIs(chrome::kChromeDevToolsScheme));
584   ASSERT_EQ(GetInspectedTab()->GetURL(), url);
585   CloseDevToolsWindow();
586 }
587
588 #if defined(OS_WIN)
589 // Flakily times out: http://crbug.com/163411
590 #define MAYBE_TestReattachAfterCrash DISABLED_TestReattachAfterCrash
591 #else
592 #define MAYBE_TestReattachAfterCrash TestReattachAfterCrash
593 #endif
594 // Tests that inspector will reattach to inspected page when it is reloaded
595 // after a crash. See http://crbug.com/101952
596 IN_PROC_BROWSER_TEST_F(DevToolsSanityTest, MAYBE_TestReattachAfterCrash) {
597   OpenDevToolsWindow(kDebuggerTestPage);
598
599   content::CrashTab(GetInspectedTab());
600   content::WindowedNotificationObserver observer(
601       content::NOTIFICATION_LOAD_STOP,
602       content::Source<NavigationController>(
603           &browser()->tab_strip_model()->GetActiveWebContents()->
604               GetController()));
605   chrome::Reload(browser(), CURRENT_TAB);
606   observer.Wait();
607
608   RunTestFunction(window_, "testReattachAfterCrash");
609   CloseDevToolsWindow();
610 }
611
612 IN_PROC_BROWSER_TEST_F(DevToolsSanityTest, TestPageWithNoJavaScript) {
613   OpenDevToolsWindow("about:blank");
614   std::string result;
615   ASSERT_TRUE(
616       content::ExecuteScriptAndExtractString(
617           window_->GetRenderViewHost(),
618           "window.domAutomationController.send("
619           "    '' + (window.uiTests && (typeof uiTests.runTest)));",
620           &result));
621   ASSERT_EQ("function", result) << "DevTools front-end is broken.";
622   CloseDevToolsWindow();
623 }
624
625 #if defined(OS_MACOSX)
626 #define MAYBE_InspectSharedWorker DISABLED_InspectSharedWorker
627 #else
628 #define MAYBE_InspectSharedWorker InspectSharedWorker
629 #endif
630 // Flakily fails with 25s timeout: http://crbug.com/89845
631 IN_PROC_BROWSER_TEST_F(WorkerDevToolsSanityTest, MAYBE_InspectSharedWorker) {
632 #if defined(OS_WIN) && defined(USE_ASH)
633   // Disable this test in Metro+Ash for now (http://crbug.com/262796).
634   if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests))
635     return;
636 #endif
637
638   RunTest("testSharedWorker", kSharedWorkerTestPage);
639 }
640
641 // http://crbug.com/100538
642 #if defined(OS_MACOSX) || defined(OS_WIN)
643 #define MAYBE_PauseInSharedWorkerInitialization DISABLED_PauseInSharedWorkerInitialization
644 #else
645 #define MAYBE_PauseInSharedWorkerInitialization PauseInSharedWorkerInitialization
646 #endif
647
648 // http://crbug.com/106114 is masking
649 // MAYBE_PauseInSharedWorkerInitialization into
650 // DISABLED_PauseInSharedWorkerInitialization
651 IN_PROC_BROWSER_TEST_F(WorkerDevToolsSanityTest,
652                        MAYBE_PauseInSharedWorkerInitialization) {
653   ASSERT_TRUE(test_server()->Start());
654   GURL url = test_server()->GetURL(kReloadSharedWorkerTestPage);
655   ui_test_utils::NavigateToURL(browser(), url);
656
657   scoped_refptr<WorkerData> worker_data = WaitForFirstSharedWorker();
658   OpenDevToolsWindowForSharedWorker(worker_data.get());
659
660   TerminateWorker(worker_data);
661
662   // Reload page to restart the worker.
663   ui_test_utils::NavigateToURL(browser(), url);
664
665   // Wait until worker script is paused on the debugger statement.
666   RunTestFunction(window_, "testPauseInSharedWorkerInitialization");
667   CloseDevToolsWindow();
668 }
669
670 class DevToolsAgentHostTest : public InProcessBrowserTest {};
671
672 // Tests DevToolsAgentHost retention by its target.
673 IN_PROC_BROWSER_TEST_F(DevToolsAgentHostTest, TestAgentHostReleased) {
674   ui_test_utils::NavigateToURL(browser(), GURL("about:blank"));
675   RenderViewHost* rvh = browser()->tab_strip_model()->GetWebContentsAt(0)->
676       GetRenderViewHost();
677   DevToolsAgentHost* agent_raw = DevToolsAgentHost::GetOrCreateFor(rvh).get();
678   const std::string agent_id = agent_raw->GetId();
679   ASSERT_EQ(agent_raw, DevToolsAgentHost::GetForId(agent_id)) <<
680       "DevToolsAgentHost cannot be found by id";
681   browser()->tab_strip_model()->
682       CloseWebContentsAt(0, TabStripModel::CLOSE_NONE);
683   ASSERT_FALSE(DevToolsAgentHost::GetForId(agent_id).get())
684       << "DevToolsAgentHost is not released when the tab is closed";
685 }
686
687 class RemoteDebuggingTest: public ExtensionApiTest {
688   virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
689     ExtensionApiTest::SetUpCommandLine(command_line);
690     command_line->AppendSwitchASCII(switches::kRemoteDebuggingPort, "9222");
691
692     // Override the extension root path.
693     PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir_);
694     test_data_dir_ = test_data_dir_.AppendASCII("devtools");
695   }
696 };
697
698 IN_PROC_BROWSER_TEST_F(RemoteDebuggingTest, RemoteDebugger) {
699 #if defined(OS_WIN) && defined(USE_ASH)
700   // Disable this test in Metro+Ash for now (http://crbug.com/262796).
701   if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests))
702     return;
703 #endif
704
705   ASSERT_TRUE(RunExtensionTest("target_list")) << message_;
706 }
707
708 }  // namespace