Index: chrome/browser/devtools/devtools_sanity_browsertest.cc |
diff --git a/chrome/browser/devtools/devtools_sanity_browsertest.cc b/chrome/browser/devtools/devtools_sanity_browsertest.cc |
index e25d5b7486403092cee766d91e92089290b34948..26a3ebc6f9df5a31664d64bd822c47181eedbdf6 100644 |
--- a/chrome/browser/devtools/devtools_sanity_browsertest.cc |
+++ b/chrome/browser/devtools/devtools_sanity_browsertest.cc |
@@ -20,7 +20,10 @@ |
#include "chrome/browser/extensions/extension_service.h" |
#include "chrome/browser/extensions/extension_system.h" |
#include "chrome/browser/extensions/unpacked_installer.h" |
+#include "chrome/browser/lifetime/application_lifetime.h" |
#include "chrome/browser/profiles/profile.h" |
+#include "chrome/browser/ui/app_modal_dialogs/javascript_app_modal_dialog.h" |
+#include "chrome/browser/ui/app_modal_dialogs/native_app_modal_dialog.h" |
#include "chrome/browser/ui/browser.h" |
#include "chrome/browser/ui/browser_commands.h" |
#include "chrome/browser/ui/tabs/tab_strip_model.h" |
@@ -154,36 +157,50 @@ class DevToolsSanityTest : public InProcessBrowserTest { |
RenderViewHost* inspected_rvh_; |
}; |
-// Used to block until a dev tools window gets beforeunload event. |
-class DevToolsWindowBeforeUnloadObserver |
- : public content::WebContentsObserver { |
- public: |
- explicit DevToolsWindowBeforeUnloadObserver( |
- content::WebContents* web_contents); |
- bool Fired(); |
- private: |
- // Invoked when the beforeunload handler fires. |
- virtual void BeforeUnloadFired(const base::TimeTicks& proceed_time) OVERRIDE; |
+class DevToolsBeforeUnloadTest: public DevToolsSanityTest { |
+ protected: |
+ void CloseInspectedTab() { |
+ browser()->tab_strip_model()->CloseWebContentsAt(0, |
+ TabStripModel::CLOSE_NONE); |
+ } |
- bool m_fired; |
+ void InjectBeforeUnloadListener(content::WebContents* web_contents) { |
+ ASSERT_TRUE(content::ExecuteScript(web_contents->GetRenderViewHost(), |
+ "window.addEventListener('beforeunload'," |
+ "function() { return 'Foo'; });")); |
+ } |
- DISALLOW_COPY_AND_ASSIGN(DevToolsWindowBeforeUnloadObserver); |
-}; |
+ DevToolsWindow* OpenDevToolWindowOnWebContents( |
+ content::WebContents* contents) { |
+ content::WindowedNotificationObserver observer( |
+ content::NOTIFICATION_LOAD_STOP, |
+ content::NotificationService::AllSources()); |
+ DevToolsWindow* window = DevToolsWindow::OpenDevToolsWindow( |
+ contents->GetRenderViewHost()); |
+ observer.Wait(); |
+ return window; |
+ } |
-DevToolsWindowBeforeUnloadObserver::DevToolsWindowBeforeUnloadObserver( |
- content::WebContents* web_contents) |
- : WebContentsObserver(web_contents), |
- m_fired(false) { |
-} |
+ void AcceptModalDialog() { |
+ NativeAppModalDialog* native_dialog = GetDialog(); |
+ native_dialog->AcceptAppModalDialog(); |
+ } |
-bool DevToolsWindowBeforeUnloadObserver::Fired() { |
- return m_fired; |
-} |
+ void CancelModalDialog() { |
+ NativeAppModalDialog* native_dialog = GetDialog(); |
+ native_dialog->CancelAppModalDialog(); |
+ } |
-void DevToolsWindowBeforeUnloadObserver::BeforeUnloadFired( |
- const base::TimeTicks& proceed_time) { |
- m_fired = true; |
-} |
+ NativeAppModalDialog* GetDialog() { |
+ AppModalDialog* dialog = ui_test_utils::WaitForAppModalDialog(); |
+ EXPECT_TRUE(dialog->IsJavaScriptModalDialog()); |
+ JavaScriptAppModalDialog* js_dialog = |
+ static_cast<JavaScriptAppModalDialog*>(dialog); |
+ NativeAppModalDialog* native_dialog = js_dialog->native_dialog(); |
+ EXPECT_TRUE(native_dialog); |
+ return native_dialog; |
+ } |
+}; |
void TimeoutCallback(const std::string& timeout_message) { |
FAIL() << timeout_message; |
@@ -440,13 +457,142 @@ class WorkerDevToolsSanityTest : public InProcessBrowserTest { |
#else |
#define MAYBE_TestBeforeUnloadEvents TestBeforeUnloadEvents |
#endif |
-IN_PROC_BROWSER_TEST_F(DevToolsSanityTest, MAYBE_TestBeforeUnloadEvents) { |
+IN_PROC_BROWSER_TEST_F(DevToolsBeforeUnloadTest, MAYBE_TestBeforeUnloadEvents) { |
+ OpenDevToolsWindow(kDebuggerTestPage); |
+ InjectBeforeUnloadListener(window_->web_contents()); |
+ content::WindowedNotificationObserver close_observer( |
+ content::NOTIFICATION_WEB_CONTENTS_DESTROYED, |
+ content::Source<content::WebContents>(window_->web_contents())); |
+ DevToolsWindow::ToggleDevToolsWindow(inspected_rvh_, false, |
+ DevToolsToggleAction::Toggle()); |
+ AcceptModalDialog(); |
+ close_observer.Wait(); |
+} |
+ |
+// Test beforeunload event delivery. |
+IN_PROC_BROWSER_TEST_F(DevToolsBeforeUnloadTest, |
+ TestDockedDevToolsInspectedTabClosing) { |
+ OpenDevToolsWindow(kDebuggerTestPage); |
+ content::WindowedNotificationObserver devtools_close_observer( |
+ content::NOTIFICATION_WEB_CONTENTS_DESTROYED, |
+ content::Source<content::WebContents>(window_->web_contents())); |
+ InjectBeforeUnloadListener(window_->web_contents()); |
+ // try to close browser window |
+ { |
+ content::WindowedNotificationObserver cancel_browser( |
+ chrome::NOTIFICATION_BROWSER_CLOSE_CANCELLED, |
+ content::NotificationService::AllSources()); |
+ chrome::CloseWindow(browser()); |
+ CancelModalDialog(); |
+ cancel_browser.Wait(); |
+ } |
+ // try to close inspected tab |
+ { |
+ content::WindowedNotificationObserver close_observer( |
+ chrome::NOTIFICATION_BROWSER_CLOSED, |
+ content::Source<Browser>(browser())); |
+ CloseInspectedTab(); |
+ AcceptModalDialog(); |
+ close_observer.Wait(); |
+ } |
+ devtools_close_observer.Wait(); |
+} |
+ |
+IN_PROC_BROWSER_TEST_F(DevToolsBeforeUnloadTest, |
+ TestUndockedDevToolsInspectedTabClosing) { |
OpenDevToolsWindow(kDebuggerTestPage); |
- scoped_ptr<DevToolsWindowBeforeUnloadObserver> contents_observer; |
- contents_observer.reset( |
- new DevToolsWindowBeforeUnloadObserver(window_->web_contents())); |
- ToggleDevToolsWindow(); |
- ASSERT_TRUE(contents_observer->Fired()); |
+ content::WindowedNotificationObserver devtools_close_observer( |
+ content::NOTIFICATION_WEB_CONTENTS_DESTROYED, |
+ content::Source<content::WebContents>(window_->web_contents())); |
+ |
+ window_->SetDockSideForTest(DEVTOOLS_DOCK_SIDE_UNDOCKED); |
+ InjectBeforeUnloadListener(window_->web_contents()); |
+ // try to close browser window |
+ { |
+ content::WindowedNotificationObserver cancel_browser( |
+ chrome::NOTIFICATION_BROWSER_CLOSE_CANCELLED, |
+ content::NotificationService::AllSources()); |
+ chrome::CloseWindow(browser()); |
+ CancelModalDialog(); |
+ cancel_browser.Wait(); |
+ } |
+ // try to exit application |
+ { |
+ content::WindowedNotificationObserver cancel_browser( |
+ chrome::NOTIFICATION_BROWSER_CLOSE_CANCELLED, |
+ content::NotificationService::AllSources()); |
+ chrome::CloseAllBrowsers(); |
+ CancelModalDialog(); |
+ cancel_browser.Wait(); |
+ } |
+ // try to close inspected tab |
+ { |
+ content::WindowedNotificationObserver close_observer( |
+ chrome::NOTIFICATION_BROWSER_CLOSED, |
+ content::Source<Browser>(browser())); |
+ CloseInspectedTab(); |
+ AcceptModalDialog(); |
+ close_observer.Wait(); |
+ } |
+ devtools_close_observer.Wait(); |
+} |
+ |
+IN_PROC_BROWSER_TEST_F(DevToolsBeforeUnloadTest, TestDevToolsOnDevTools) { |
+ ASSERT_TRUE(test_server()->Start()); |
+ GURL url = test_server()->GetURL(kDebuggerTestPage); |
+ ui_test_utils::NavigateToURL(browser(), url); |
+ |
+ std::vector<DevToolsWindow*> windows; |
+ std::vector<content::WindowedNotificationObserver*> close_observers; |
+ content::WebContents* inspected_web_contents = GetInspectedTab(); |
+ for (int i = 0; i < 3; ++i) { |
+ DevToolsWindow* devtools_window = OpenDevToolWindowOnWebContents( |
+ inspected_web_contents); |
+ windows.push_back(devtools_window); |
+ content::WindowedNotificationObserver* close_observer = |
+ new content::WindowedNotificationObserver( |
+ content::NOTIFICATION_WEB_CONTENTS_DESTROYED, |
+ content::Source<content::WebContents>( |
+ devtools_window->web_contents())); |
+ close_observers.push_back(close_observer); |
+ inspected_web_contents = devtools_window->web_contents(); |
+ } |
+ |
+ InjectBeforeUnloadListener(windows[0]->web_contents()); |
+ InjectBeforeUnloadListener(windows[2]->web_contents()); |
+ // try to close second DevTools |
+ { |
+ content::WindowedNotificationObserver cancel_browser( |
+ chrome::NOTIFICATION_BROWSER_CLOSE_CANCELLED, |
+ content::NotificationService::AllSources()); |
+ chrome::CloseWindow(windows[1]->browser()); |
+ CancelModalDialog(); |
+ cancel_browser.Wait(); |
+ } |
+ // try to close browser window |
+ { |
+ content::WindowedNotificationObserver cancel_browser( |
+ chrome::NOTIFICATION_BROWSER_CLOSE_CANCELLED, |
+ content::NotificationService::AllSources()); |
+ chrome::CloseWindow(browser()); |
+ AcceptModalDialog(); |
+ CancelModalDialog(); |
+ cancel_browser.Wait(); |
+ } |
+ // try to exit application |
+ { |
+ content::WindowedNotificationObserver close_observer( |
+ chrome::NOTIFICATION_BROWSER_CLOSED, |
+ content::Source<Browser>(browser())); |
+ chrome::CloseAllBrowsers(); |
+ AcceptModalDialog(); |
+ AcceptModalDialog(); |
+ close_observer.Wait(); |
+ } |
+ for (size_t i = 0; i < close_observers.size(); ++i) { |
+ close_observers[i]->Wait(); |
+ delete close_observers[i]; |
+ } |
} |
// Tests scripts panel showing. |