diff options
-rw-r--r-- | chrome/browser/automation/automation_provider.cc | 20 | ||||
-rw-r--r-- | chrome/browser/automation/automation_provider.h | 4 | ||||
-rw-r--r-- | chrome/test/automated_ui_tests/automated_ui_test_base.cc | 63 | ||||
-rw-r--r-- | chrome/test/automated_ui_tests/automated_ui_test_base.h | 17 | ||||
-rw-r--r-- | chrome/test/automated_ui_tests/automated_ui_test_test.cc | 82 | ||||
-rw-r--r-- | chrome/test/automated_ui_tests/automated_ui_tests.cc | 60 | ||||
-rw-r--r-- | chrome/test/automated_ui_tests/automated_ui_tests.h | 5 | ||||
-rw-r--r-- | chrome/test/automation/automation_messages_internal.h | 10 | ||||
-rw-r--r-- | chrome/test/automation/automation_proxy.cc | 34 | ||||
-rw-r--r-- | chrome/test/automation/automation_proxy.h | 11 |
10 files changed, 240 insertions, 66 deletions
diff --git a/chrome/browser/automation/automation_provider.cc b/chrome/browser/automation/automation_provider.cc index 67e4548..25131e5 100644 --- a/chrome/browser/automation/automation_provider.cc +++ b/chrome/browser/automation/automation_provider.cc @@ -902,10 +902,14 @@ void AutomationProvider::OnMessageReceived(const IPC::Message& message) { GetRedirectsFrom) IPC_MESSAGE_HANDLER(AutomationMsg_BrowserWindowCount, GetBrowserWindowCount) + IPC_MESSAGE_HANDLER(AutomationMsg_NormalBrowserWindowCount, + GetNormalBrowserWindowCount) IPC_MESSAGE_HANDLER(AutomationMsg_BrowserWindow, GetBrowserWindow) IPC_MESSAGE_HANDLER(AutomationMsg_LastActiveBrowserWindow, GetLastActiveBrowserWindow) IPC_MESSAGE_HANDLER(AutomationMsg_ActiveWindow, GetActiveWindow) + IPC_MESSAGE_HANDLER(AutomationMsg_FindNormalBrowserWindow, + FindNormalBrowserWindow) IPC_MESSAGE_HANDLER(AutomationMsg_IsWindowActive, IsWindowActive) IPC_MESSAGE_HANDLER(AutomationMsg_ActivateWindow, ActivateWindow); #if defined(OS_WIN) @@ -1304,6 +1308,11 @@ void AutomationProvider::GetBrowserWindowCount(int* window_count) { *window_count = static_cast<int>(BrowserList::size()); } +void AutomationProvider::GetNormalBrowserWindowCount(int* window_count) { + *window_count = static_cast<int>( + BrowserList::GetBrowserCountForType(profile_, Browser::TYPE_NORMAL)); +} + void AutomationProvider::GetShowingAppModalDialog(bool* showing_dialog, int* dialog_button) { AppModalDialog* dialog_delegate = AppModalDialogQueue::active_dialog(); @@ -1338,14 +1347,21 @@ void AutomationProvider::GetBrowserWindow(int index, int* handle) { *handle = 0; if (index >= 0) { BrowserList::const_iterator iter = BrowserList::begin(); - - for (; (iter != BrowserList::end()) && (index > 0); ++iter, --index); + for (; (iter != BrowserList::end()) && (index > 0); ++iter, --index); if (iter != BrowserList::end()) { *handle = browser_tracker_->Add(*iter); } } } +void AutomationProvider::FindNormalBrowserWindow(int* handle) { + *handle = 0; + Browser* browser = BrowserList::FindBrowserWithType(profile_, + Browser::TYPE_NORMAL); + if (browser) + *handle = browser_tracker_->Add(browser); +} + void AutomationProvider::GetLastActiveBrowserWindow(int* handle) { *handle = 0; Browser* browser = BrowserList::GetLastActive(); diff --git a/chrome/browser/automation/automation_provider.h b/chrome/browser/automation/automation_provider.h index a7cab75..8d62914 100644 --- a/chrome/browser/automation/automation_provider.h +++ b/chrome/browser/automation/automation_provider.h @@ -132,9 +132,13 @@ class AutomationProvider : public base::RefCounted<AutomationProvider>, int handle, int* response_value); void GetBrowserWindowCount(int* window_count); + void GetNormalBrowserWindowCount(int* window_count); void GetShowingAppModalDialog(bool* showing_dialog, int* dialog_button); void ClickAppModalDialogButton(int button, bool* success); + // Be aware that the browser window returned might be of non TYPE_NORMAL + // or in incognito mode. void GetBrowserWindow(int index, int* handle); + void FindNormalBrowserWindow(int* handle); void GetLastActiveBrowserWindow(int* handle); void GetActiveWindow(int* handle); #if defined(OS_WIN) diff --git a/chrome/test/automated_ui_tests/automated_ui_test_base.cc b/chrome/test/automated_ui_tests/automated_ui_test_base.cc index 3cded46..0adebc6 100644 --- a/chrome/test/automated_ui_tests/automated_ui_test_base.cc +++ b/chrome/test/automated_ui_tests/automated_ui_test_base.cc @@ -25,6 +25,54 @@ void AutomatedUITestBase::SetUp() { set_active_browser(automation()->GetBrowserWindow(0)); } +bool AutomatedUITestBase::CloseActiveTab() { + BrowserProxy* browser = active_browser(); + int tab_count; + bool is_timeout; + browser->GetTabCountWithTimeout(&tab_count, + action_max_timeout_ms(), + &is_timeout); + + if (is_timeout) { + LogInfoMessage("get_tab_count_timed_out"); + return false; + } + + if (tab_count > 1) { + scoped_ptr<TabProxy> tab(GetActiveTab()); + // Wait until tab is closed. + return tab->Close(true); + } else if (tab_count == 1) { + // Synchronously close the window if it is not the last window. + return CloseActiveWindow(); + } else { + LogInfoMessage("invalid_tab_count"); + return false; + } +} + +bool AutomatedUITestBase::CloseActiveWindow() { + int browser_windows_count = 0; + if (!automation()->GetNormalBrowserWindowCount(&browser_windows_count)) + return false; + // Avoid quitting the application by not closing the last window. + if (browser_windows_count < 2) + return false; + bool application_closed; + CloseBrowser(active_browser(), &application_closed); + if (application_closed) { + LogErrorMessage("Application closed unexpectedly."); + return false; + } + BrowserProxy* browser = automation()->FindNormalBrowserWindow(); + if (browser == NULL) { + LogErrorMessage("Can't find browser window."); + return false; + } + set_active_browser(browser); + return true; +} + bool AutomatedUITestBase::DuplicateTab() { return RunCommand(IDC_DUPLICATE_TAB); } @@ -91,3 +139,18 @@ bool AutomatedUITestBase::RunCommand(int browser_command) { } return true; } + +TabProxy* AutomatedUITestBase::GetActiveTab() { + BrowserProxy* browser = active_browser(); + if (browser == NULL) { + LogErrorMessage("browser_window_not_found"); + return false; + } + + bool did_timeout; + TabProxy* tab = + browser->GetActiveTabWithTimeout(action_max_timeout_ms(), &did_timeout); + if (did_timeout) + return NULL; + return tab; +} diff --git a/chrome/test/automated_ui_tests/automated_ui_test_base.h b/chrome/test/automated_ui_tests/automated_ui_test_base.h index 163f388..0163b56 100644 --- a/chrome/test/automated_ui_tests/automated_ui_test_base.h +++ b/chrome/test/automated_ui_tests/automated_ui_test_base.h @@ -21,6 +21,18 @@ class AutomatedUITestBase : public UITest { // Actions // NOTE: This list is sorted alphabetically. + // All functions are synchronous unless specified with Async. + + // Close the selected tab in the current browser window. The function will + // not try close the tab if it is the only tab of the last normal window, so + // the application is not got closed. + // Returns true if the tab is closed, false otherwise. + bool CloseActiveTab(); + + // Close the current browser window if it is not the only window left. + // (Closing the last window will get application closed.) + // Returns true if the window is closed, false otherwise. + bool CloseActiveWindow(); // Duplicates the current tab. // Returns true if a duplicated tab is added. @@ -59,6 +71,11 @@ class AutomatedUITestBase : public UITest { } BrowserProxy* active_browser() const { return active_browser_.get(); } + // Get the selected tab within the current active browser window, then + // create a corresponding TabProxy and transfer the ownership to caller. + // If success return the pointer to the newly created TabProxy and the + // caller owns the TabProxy. Return NULL otherwise. + TabProxy* GetActiveTab(); private: scoped_ptr<BrowserProxy> active_browser_; diff --git a/chrome/test/automated_ui_tests/automated_ui_test_test.cc b/chrome/test/automated_ui_tests/automated_ui_test_test.cc index 8fe4043..5256910 100644 --- a/chrome/test/automated_ui_tests/automated_ui_test_test.cc +++ b/chrome/test/automated_ui_tests/automated_ui_test_test.cc @@ -30,7 +30,7 @@ TEST_F(AutomatedUITestBase, DuplicateTab) { ASSERT_EQ(3, tab_count); } -TEST_F(AutomatedUITestBase, OpenCloseBrowserWindow) { +TEST_F(AutomatedUITestBase, OpenBrowserWindow) { int num_browser_windows; int tab_count; automation()->GetBrowserWindowCount(&num_browser_windows); @@ -76,3 +76,83 @@ TEST_F(AutomatedUITestBase, OpenCloseBrowserWindow) { automation()->GetBrowserWindowCount(&num_browser_windows); ASSERT_EQ(1, num_browser_windows); } + +TEST_F(AutomatedUITestBase, CloseBrowserWindow) { + int tab_count; + NewTab(); + active_browser()->GetTabCount(&tab_count); + ASSERT_EQ(2, tab_count); + + ASSERT_TRUE(OpenAndActivateNewBrowserWindow(NULL)); + NewTab(); + NewTab(); + active_browser()->GetTabCount(&tab_count); + ASSERT_EQ(3, tab_count); + + ASSERT_TRUE(OpenAndActivateNewBrowserWindow(NULL)); + NewTab(); + NewTab(); + NewTab(); + active_browser()->GetTabCount(&tab_count); + ASSERT_EQ(4, tab_count); + + ASSERT_TRUE(CloseActiveWindow()); + active_browser()->GetTabCount(&tab_count); + + if (tab_count == 2) { + ASSERT_TRUE(CloseActiveWindow()); + active_browser()->GetTabCount(&tab_count); + ASSERT_EQ(3, tab_count); + } else { + ASSERT_EQ(3, tab_count); + ASSERT_TRUE(CloseActiveWindow()); + active_browser()->GetTabCount(&tab_count); + ASSERT_EQ(2, tab_count); + } + + ASSERT_FALSE(CloseActiveWindow()); +} + +TEST_F(AutomatedUITestBase, CloseTab) { + int num_browser_windows; + int tab_count; + NewTab(); + automation()->GetBrowserWindowCount(&num_browser_windows); + ASSERT_EQ(1, num_browser_windows); + active_browser()->GetTabCount(&tab_count); + ASSERT_EQ(2, tab_count); + + ASSERT_TRUE(OpenAndActivateNewBrowserWindow(NULL)); + NewTab(); + NewTab(); + active_browser()->GetTabCount(&tab_count); + ASSERT_EQ(3, tab_count); + automation()->GetBrowserWindowCount(&num_browser_windows); + ASSERT_EQ(2, num_browser_windows); + + ASSERT_TRUE(CloseActiveTab()); + active_browser()->GetTabCount(&tab_count); + ASSERT_EQ(2, tab_count); + ASSERT_TRUE(CloseActiveTab()); + active_browser()->GetTabCount(&tab_count); + ASSERT_EQ(1, tab_count); + num_browser_windows = 0; + automation()->GetBrowserWindowCount(&num_browser_windows); + ASSERT_EQ(2, num_browser_windows); + + // The browser window is closed by closing this tab. + ASSERT_TRUE(CloseActiveTab()); + automation()->GetBrowserWindowCount(&num_browser_windows); + ASSERT_EQ(1, num_browser_windows); + // Active_browser_ is now the first created window. + active_browser()->GetTabCount(&tab_count); + ASSERT_EQ(2, tab_count); + ASSERT_TRUE(CloseActiveTab()); + active_browser()->GetTabCount(&tab_count); + ASSERT_EQ(1, tab_count); + + // The last tab should not be closed. + ASSERT_FALSE(CloseActiveTab()); + active_browser()->GetTabCount(&tab_count); + ASSERT_EQ(1, tab_count); +} diff --git a/chrome/test/automated_ui_tests/automated_ui_tests.cc b/chrome/test/automated_ui_tests/automated_ui_tests.cc index 2867c23..c35a68b 100644 --- a/chrome/test/automated_ui_tests/automated_ui_tests.cc +++ b/chrome/test/automated_ui_tests/automated_ui_tests.cc @@ -418,44 +418,6 @@ bool AutomatedUITest::ChangeEncoding() { return RunCommandAsync((*encodings)[index].encoding_id); } -bool AutomatedUITest::CloseActiveTab() { - bool return_value = false; - BrowserProxy* browser = active_browser(); - if (browser == NULL) { - AddErrorAttribute("browser_window_not_found"); - return false; - } - int browser_windows_count; - int tab_count; - bool is_timeout; - browser->GetTabCountWithTimeout(&tab_count, - action_max_timeout_ms(), - &is_timeout); - automation()->GetBrowserWindowCount(&browser_windows_count); - // Avoid quitting the application by not closing the last window. - if (tab_count > 1) { - return_value = browser->RunCommandAsync(IDC_CLOSE_TAB); - // Wait for the tab to close before we continue. - if (!browser->WaitForTabCountToBecome(tab_count - 1, - action_max_timeout_ms())) { - AddWarningAttribute("tab_count_failed_to_change"); - return false; - } - } else if (tab_count == 1 && browser_windows_count > 1) { - return_value = browser->RunCommandAsync(IDC_CLOSE_TAB); - // Wait for the window to close before we continue. - if (!automation()->WaitForWindowCountToBecome(browser_windows_count - 1, - action_max_timeout_ms())) { - AddWarningAttribute("window_count_failed_to_change"); - return false; - } - } else { - AddInfoAttribute("would_have_exited_application"); - return false; - } - return return_value; -} - bool AutomatedUITest::FindInPage() { return RunCommandAsync(IDC_FIND); } @@ -481,18 +443,7 @@ bool AutomatedUITest::JavaScriptDebugger() { } bool AutomatedUITest::Navigate() { - BrowserProxy* browser = active_browser(); - if (browser == NULL) { - AddErrorAttribute("browser_window_not_found"); - return false; - } - bool did_timeout; - scoped_ptr<TabProxy> tab( - browser->GetActiveTabWithTimeout(action_max_timeout_ms(), &did_timeout)); - // TODO(devint): This might be masking a bug. I can't think of many - // valid cases where we would get a browser window, but not be able - // to return an active tab. Yet this has happened and has triggered crashes. - // Investigate this. + scoped_ptr<TabProxy> tab(GetActiveTab()); if (tab.get() == NULL) { AddErrorAttribute("active_tab_not_found"); return false; @@ -502,7 +453,7 @@ bool AutomatedUITest::Navigate() { xml_writer_.AddAttribute("url", url); } GURL test_url(url); - did_timeout = false; + bool did_timeout = false; tab->NavigateToURLWithTimeout(test_url, command_execution_timeout_ms(), &did_timeout); @@ -679,12 +630,7 @@ bool AutomatedUITest::FuzzyTestDialog(int num_actions) { } bool AutomatedUITest::ForceCrash() { - BrowserProxy* browser = active_browser(); - if (browser == NULL) { - AddErrorAttribute("browser_window_not_found"); - return false; - } - scoped_ptr<TabProxy> tab(browser->GetActiveTab()); + scoped_ptr<TabProxy> tab(GetActiveTab()); GURL test_url("about:crash"); bool did_timeout; tab->NavigateToURLWithTimeout(test_url, kDebuggingTimeoutMsec, &did_timeout); diff --git a/chrome/test/automated_ui_tests/automated_ui_tests.h b/chrome/test/automated_ui_tests/automated_ui_tests.h index 754b598..4219a96 100644 --- a/chrome/test/automated_ui_tests/automated_ui_tests.h +++ b/chrome/test/automated_ui_tests/automated_ui_tests.h @@ -141,11 +141,6 @@ class AutomatedUITest : public AutomatedUITestBase { // XML element: <ChangeEncoding/> bool ChangeEncoding(); - // Uses accelerator to close the active tab if it isn't the only tab. - // Returns false if active tab is the only tab, true otherwise. - // XML element: <CloseTab/> - bool CloseActiveTab(); - // Opens one of the dialogs (chosen randomly) and exercises it. // XML element: <Dialog/> bool ExerciseDialog(); diff --git a/chrome/test/automation/automation_messages_internal.h b/chrome/test/automation/automation_messages_internal.h index 4f56764..bfbd4d2 100644 --- a/chrome/test/automation/automation_messages_internal.h +++ b/chrome/test/automation/automation_messages_internal.h @@ -895,4 +895,14 @@ IPC_BEGIN_MESSAGES(Automation) // The return value contains the index, which will be -1 on failure. IPC_SYNC_MESSAGE_ROUTED1_1(AutomationMsg_TabIndex, int, int) + // This message requests the handle (int64 app-unique identifier) of + // a valid normal browser window, i.e. normal type and non-incognito mode. + // On error, the returned handle value is 0. + IPC_SYNC_MESSAGE_ROUTED0_1(AutomationMsg_FindNormalBrowserWindow, int) + + // This message requests the number of normal browser windows, i.e. normal + // type and non-incognito mode that the app currently has open. The return + // value is the number of windows. + IPC_SYNC_MESSAGE_ROUTED0_1(AutomationMsg_NormalBrowserWindowCount, int) + IPC_END_MESSAGES(Automation) diff --git a/chrome/test/automation/automation_proxy.cc b/chrome/test/automation/automation_proxy.cc index ef70de8..5489745 100644 --- a/chrome/test/automation/automation_proxy.cc +++ b/chrome/test/automation/automation_proxy.cc @@ -299,6 +299,24 @@ bool AutomationProxy::GetBrowserWindowCount(int* num_windows) { return succeeded; } +bool AutomationProxy::GetNormalBrowserWindowCount(int* num_windows) { + if (!num_windows) { + NOTREACHED(); + return false; + } + + bool succeeded = SendWithTimeout( + new AutomationMsg_NormalBrowserWindowCount(0, num_windows), + command_execution_timeout_ms(), NULL); + + if (!succeeded) { + DLOG(ERROR) << "GetNormalWindowCount did not complete in a timely fashion"; + return false; + } + + return succeeded; +} + bool AutomationProxy::WaitForWindowCountToBecome(int count, int wait_timeout) { const TimeTicks start = TimeTicks::Now(); @@ -438,7 +456,6 @@ WindowProxy* AutomationProxy::GetActiveWindow() { return new WindowProxy(this, tracker_.get(), handle); } - BrowserProxy* AutomationProxy::GetBrowserWindow(int window_index) { int handle = 0; @@ -456,6 +473,21 @@ BrowserProxy* AutomationProxy::GetBrowserWindow(int window_index) { return new BrowserProxy(this, tracker_.get(), handle); } +BrowserProxy* AutomationProxy::FindNormalBrowserWindow() { + int handle = 0; + + if (!SendWithTimeout(new AutomationMsg_FindNormalBrowserWindow(0, &handle), + command_execution_timeout_ms(), NULL)) { + return NULL; + } + + if (handle == 0) { + return NULL; + } + + return new BrowserProxy(this, tracker_.get(), handle); +} + BrowserProxy* AutomationProxy::GetLastActiveBrowserWindow() { int handle = 0; diff --git a/chrome/test/automation/automation_proxy.h b/chrome/test/automation/automation_proxy.h index a3a5b68..7669c6d 100644 --- a/chrome/test/automation/automation_proxy.h +++ b/chrome/test/automation/automation_proxy.h @@ -94,6 +94,11 @@ class AutomationProxy : public IPC::Channel::Listener, // Returns true on success. bool WaitForWindowCountToBecome(int target_count, int wait_timeout); + // Fills the number of open normal browser windows (normal type and + // non-incognito mode) into the given variable, returning true on success. + // False likely indicates an IPC error. + bool GetNormalBrowserWindowCount(int* num_windows); + // Returns whether an app modal dialog window is showing right now (i.e., a // javascript alert), and what buttons it contains. bool GetShowingAppModalDialog(bool* showing_app_modal_dialog, @@ -118,6 +123,12 @@ class AutomationProxy : public IPC::Channel::Listener, // Window numbers are 0-based. BrowserProxy* GetBrowserWindow(int window_index); + // Finds the first browser window that is not incognito mode and of type + // TYPE_NORMAL, and returns its corresponding BrowserProxy, transferring + // ownership of the pointer to the caller. + // On failure, returns NULL. + BrowserProxy* FindNormalBrowserWindow(); + // Returns the BrowserProxy for the browser window which was last active, // transferring ownership of the pointer to the caller. // TODO: If there was no last active browser window, or the last active |