summaryrefslogtreecommitdiffstats
path: root/chrome/browser/browser_uitest.cc
diff options
context:
space:
mode:
authorinitial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98>2008-07-26 23:55:29 +0000
committerinitial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98>2008-07-26 23:55:29 +0000
commit09911bf300f1a419907a9412154760efd0b7abc3 (patch)
treef131325fb4e2ad12c6d3504ab75b16dd92facfed /chrome/browser/browser_uitest.cc
parent586acc5fe142f498261f52c66862fa417c3d52d2 (diff)
downloadchromium_src-09911bf300f1a419907a9412154760efd0b7abc3.zip
chromium_src-09911bf300f1a419907a9412154760efd0b7abc3.tar.gz
chromium_src-09911bf300f1a419907a9412154760efd0b7abc3.tar.bz2
Add chrome to the repository.
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@15 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/browser_uitest.cc')
-rw-r--r--chrome/browser/browser_uitest.cc362
1 files changed, 362 insertions, 0 deletions
diff --git a/chrome/browser/browser_uitest.cc b/chrome/browser/browser_uitest.cc
new file mode 100644
index 0000000..8213f8f
--- /dev/null
+++ b/chrome/browser/browser_uitest.cc
@@ -0,0 +1,362 @@
+// Copyright 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "base/file_util.h"
+#include "base/string_util.h"
+#include "chrome/app/chrome_dll_resource.h"
+#include "chrome/common/chrome_constants.h"
+#include "chrome/common/l10n_util.h"
+#include "chrome/common/pref_names.h"
+#include "chrome/test/automation/browser_proxy.h"
+#include "chrome/test/automation/tab_proxy.h"
+#include "chrome/test/automation/window_proxy.h"
+#include "chrome/test/ui/ui_test.h"
+#include "chrome/views/view_container.h"
+#include "net/base/net_util.h"
+#include "net/url_request/url_request_unittest.h"
+
+#include "generated_resources.h"
+
+namespace {
+
+// Given a page title, returns the expected window caption string.
+std::wstring WindowCaptionFromPageTitle(std::wstring page_title) {
+ if (page_title.empty())
+ return l10n_util::GetString(IDS_PRODUCT_NAME);
+
+ return l10n_util::GetStringF(IDS_BROWSER_WINDOW_TITLE_FORMAT, page_title);
+}
+
+class BrowserTest : public UITest {
+ protected:
+ HWND GetMainWindow() {
+ scoped_ptr<BrowserProxy> browser(automation()->GetBrowserWindow(0));
+ scoped_ptr<WindowProxy> window(
+ automation()->GetWindowForBrowser(browser.get()));
+
+ HWND window_handle;
+ EXPECT_TRUE(window->GetHWND(&window_handle));
+ return window_handle;
+ }
+
+ std::wstring GetWindowTitle() {
+ HWND window_handle = GetMainWindow();
+ std::wstring result;
+ int length = ::GetWindowTextLength(window_handle) + 1;
+ ::GetWindowText(window_handle, WriteInto(&result, length), length);
+ return result;
+ }
+};
+
+class VisibleBrowserTest : public UITest {
+ protected:
+ VisibleBrowserTest() : UITest() {
+ show_window_ = true;
+ }
+};
+
+} // namespace
+
+// Launch the app on a page with no title, check that the app title was set
+// correctly.
+TEST_F(BrowserTest, NoTitle) {
+ std::wstring test_file = test_data_directory_;
+ file_util::AppendToPath(&test_file, L"title1.html");
+
+ NavigateToURL(net_util::FilePathToFileURL(test_file));
+ Sleep(kWaitForActionMsec); // The browser lazily updates the title.
+
+ EXPECT_EQ(WindowCaptionFromPageTitle(L"title1.html"), GetWindowTitle());
+ EXPECT_EQ(L"title1.html", GetActiveTabTitle());
+}
+
+// Launch the app, navigate to a page with a title, check that the app title
+// was set correctly.
+TEST_F(BrowserTest, Title) {
+ std::wstring test_file = test_data_directory_;
+ file_util::AppendToPath(&test_file, L"title2.html");
+
+ NavigateToURL(net_util::FilePathToFileURL(test_file));
+ Sleep(kWaitForActionMsec); // The browser lazily updates the title.
+
+ const std::wstring test_title(L"Title Of Awesomeness");
+ EXPECT_EQ(WindowCaptionFromPageTitle(test_title), GetWindowTitle());
+ EXPECT_EQ(test_title, GetActiveTabTitle());
+}
+
+// The browser should quit quickly if it receives a WM_ENDSESSION message.
+TEST_F(BrowserTest, WindowsSessionEnd) {
+ std::wstring test_file = test_data_directory_;
+ file_util::AppendToPath(&test_file, L"title1.html");
+
+ NavigateToURL(net_util::FilePathToFileURL(test_file));
+ Sleep(kWaitForActionMsec);
+
+ // Simulate an end of session. Normally this happens when the user
+ // shuts down the pc or logs off.
+ HWND window_handle = GetMainWindow();
+ ASSERT_TRUE(::PostMessageW(window_handle, WM_ENDSESSION, 0, 0));
+
+ Sleep(kWaitForActionMsec);
+ ASSERT_FALSE(IsBrowserRunning());
+
+ // Make sure the UMA metrics say we didn't crash.
+ scoped_ptr<DictionaryValue> local_prefs(GetLocalState());
+ bool exited_cleanly;
+ ASSERT_TRUE(local_prefs.get());
+ ASSERT_TRUE(local_prefs->GetBoolean(prefs::kStabilityExitedCleanly,
+ &exited_cleanly));
+ ASSERT_TRUE(exited_cleanly);
+
+ // And that session end was successful.
+ bool session_end_completed;
+ ASSERT_TRUE(local_prefs->GetBoolean(prefs::kStabilitySessionEndCompleted,
+ &session_end_completed));
+ ASSERT_TRUE(session_end_completed);
+
+ // Make sure session restore says we didn't crash.
+ scoped_ptr<DictionaryValue> profile_prefs(GetDefaultProfilePreferences());
+ ASSERT_TRUE(profile_prefs.get());
+ ASSERT_TRUE(profile_prefs->GetBoolean(prefs::kSessionExitedCleanly,
+ &exited_cleanly));
+ ASSERT_TRUE(exited_cleanly);
+}
+
+// Tests the accelerators for tab navigation. Specifically IDC_SELECT_NEXT_TAB,
+// IDC_SELECT_PREV_TAB, IDC_SELECT_TAB_0, and IDC_SELECT_LAST_TAB.
+TEST_F(BrowserTest, TabNavigationAccelerators) {
+ scoped_ptr<BrowserProxy> window(automation()->GetBrowserWindow(0));
+ ASSERT_TRUE(window.get());
+
+ // Create two new tabs. This way we'll have at least three tabs to navigate
+ // to.
+ int old_tab_count = -1;
+ ASSERT_TRUE(window->GetTabCount(&old_tab_count));
+ ASSERT_TRUE(window->ApplyAccelerator(IDC_NEWTAB));
+ int new_tab_count;
+ ASSERT_TRUE(window->WaitForTabCountToChange(old_tab_count, &new_tab_count,
+ 5000));
+ ASSERT_TRUE(window->ApplyAccelerator(IDC_NEWTAB));
+ old_tab_count = new_tab_count;
+ ASSERT_TRUE(window->WaitForTabCountToChange(old_tab_count, &new_tab_count,
+ 5000));
+ ASSERT_GE(new_tab_count, 2);
+
+ // Activate the second tab.
+ ASSERT_TRUE(window->ActivateTab(1));
+
+ // Navigate to the first tab using an accelerator.
+ ASSERT_TRUE(window->ApplyAccelerator(IDC_SELECT_TAB_0));
+ ASSERT_TRUE(window->WaitForTabToBecomeActive(0, 5000));
+
+ // Navigate to the second tab using the next accelerators.
+ ASSERT_TRUE(window->ApplyAccelerator(IDC_SELECT_NEXT_TAB));
+ ASSERT_TRUE(window->WaitForTabToBecomeActive(1, 5000));
+
+ // Navigate back to the first tab using the previous accelerators.
+ ASSERT_TRUE(window->ApplyAccelerator(IDC_SELECT_PREV_TAB));
+ ASSERT_TRUE(window->WaitForTabToBecomeActive(0, 5000));
+
+ // Navigate to the last tab using the select last accelerator.
+ ASSERT_TRUE(window->ApplyAccelerator(IDC_SELECT_LAST_TAB));
+ ASSERT_TRUE(window->WaitForTabToBecomeActive(new_tab_count - 1, 5000));
+}
+
+TEST_F(BrowserTest, JavascriptAlertActivatesTab) {
+ scoped_ptr<BrowserProxy> window(automation()->GetBrowserWindow(0));
+ int start_index;
+ ASSERT_TRUE(window->GetActiveTabIndex(&start_index));
+ ASSERT_TRUE(window->AppendTab(GURL("about:blank")));
+ int javascript_tab_index;
+ ASSERT_TRUE(window->GetActiveTabIndex(&javascript_tab_index));
+ TabProxy* javascript_tab = window->GetActiveTab();
+ // Switch back to the starting tab, then send the second tab a javascript
+ // alert, which should force it to become active.
+ ASSERT_TRUE(window->ActivateTab(start_index));
+ ASSERT_TRUE(
+ javascript_tab->NavigateToURLAsync(GURL("javascript:alert('Alert!')")));
+ ASSERT_TRUE(window->WaitForTabToBecomeActive(javascript_tab_index,
+ kWaitForActionMaxMsec));
+}
+
+TEST_F(BrowserTest, DuplicateTab) {
+ std::wstring path_prefix = test_data_directory_;
+ file_util::AppendToPath(&path_prefix, L"session_history");
+ path_prefix += file_util::kPathSeparator;
+ GURL url1 = net_util::FilePathToFileURL(path_prefix + L"bot1.html");
+ GURL url2 = net_util::FilePathToFileURL(path_prefix + L"bot2.html");
+ GURL url3 = GURL("about:blank");
+
+ scoped_ptr<BrowserProxy> browser_proxy(automation()->GetBrowserWindow(0));
+
+ // Navigate to the three urls, then go back.
+ scoped_ptr<TabProxy> tab_proxy(browser_proxy->GetTab(0));
+ tab_proxy->NavigateToURL(url1);
+ tab_proxy->NavigateToURL(url2);
+ tab_proxy->NavigateToURL(url3);
+ ASSERT_TRUE(tab_proxy->GoBack());
+
+ int initial_window_count;
+ ASSERT_TRUE(automation()->GetBrowserWindowCount(&initial_window_count));
+
+ // Duplicate the tab.
+ ASSERT_TRUE(browser_proxy->ApplyAccelerator(IDC_DUPLICATE));
+
+ // The duplicated tab ends up in a new window.
+ int window_count;
+ ASSERT_TRUE(automation()->GetBrowserWindowCount(&window_count));
+ ASSERT_TRUE(window_count > initial_window_count);
+
+ browser_proxy.reset(automation()->GetBrowserWindow(1));
+ tab_proxy.reset(browser_proxy->GetTab(0));
+
+ ASSERT_TRUE(tab_proxy->WaitForTabToBeRestored());
+
+ // Verify the stack of urls.
+ GURL url;
+ ASSERT_TRUE(tab_proxy->GetCurrentURL(&url));
+ ASSERT_EQ(url2, url);
+
+ ASSERT_TRUE(tab_proxy->GoForward());
+ ASSERT_TRUE(tab_proxy->GetCurrentURL(&url));
+ ASSERT_EQ(url3, url);
+
+ ASSERT_TRUE(tab_proxy->GoBack());
+ ASSERT_TRUE(tab_proxy->GoBack());
+ ASSERT_TRUE(tab_proxy->GetCurrentURL(&url));
+ ASSERT_EQ(url1, url);
+}
+
+// Test that scripts can fork a new renderer process for a tab in a particular
+// case (which matches following a link in Gmail). The script must open a new
+// tab, set its window.opener to null, and redirect it to a cross-site URL.
+// (Bug 1115708)
+// This test can only run if V8 is in use, and not KJS, because KJS will not
+// set window.opener to null properly.
+#ifdef CHROME_V8
+TEST_F(BrowserTest, NullOpenerRedirectForksProcess) {
+ // This test only works in multi-process mode
+ if (in_process_renderer())
+ return;
+
+ const wchar_t kDocRoot[] = L"chrome/test/data";
+ TestServer server(kDocRoot);
+ std::wstring test_file(test_data_directory_);
+ scoped_ptr<BrowserProxy> window(automation()->GetBrowserWindow(0));
+ scoped_ptr<TabProxy> tab(window->GetActiveTab());
+
+ // Start with a file:// url
+ file_util::AppendToPath(&test_file, L"title2.html");
+ tab->NavigateToURL(net_util::FilePathToFileURL(test_file));
+ int orig_tab_count = -1;
+ ASSERT_TRUE(window->GetTabCount(&orig_tab_count));
+ int orig_process_count = GetBrowserProcessCount();
+ ASSERT_TRUE(orig_process_count >= 1);
+
+ // Use JavaScript URL to "fork" a new tab, just like Gmail. (Open tab to a
+ // blank page, set its opener to null, and redirect it cross-site.)
+ std::wstring url_prefix(L"javascript:(function(){w=window.open();");
+ GURL fork_url(url_prefix +
+ L"w.opener=null;w.document.location=\"http://localhost:1337\";})()");
+
+ // Make sure that a new tab has been created and that we have a new renderer
+ // process for it.
+ tab->NavigateToURLAsync(fork_url);
+ Sleep(kWaitForActionMsec);
+ ASSERT_EQ(orig_process_count + 1, GetBrowserProcessCount());
+ int new_tab_count = -1;
+ ASSERT_TRUE(window->GetTabCount(&new_tab_count));
+ ASSERT_EQ(orig_tab_count + 1, new_tab_count);
+}
+#endif
+
+// Tests that non-Gmail-like script redirects (i.e., non-null window.opener) or
+// a same-page-redirect) will not fork a new process.
+TEST_F(BrowserTest, OtherRedirectsDontForkProcess) {
+ // This test only works in multi-process mode
+ if (in_process_renderer())
+ return;
+
+ const wchar_t kDocRoot[] = L"chrome/test/data";
+ TestServer server(kDocRoot);
+ std::wstring test_file(test_data_directory_);
+ scoped_ptr<BrowserProxy> window(automation()->GetBrowserWindow(0));
+ scoped_ptr<TabProxy> tab(window->GetActiveTab());
+
+ // Start with a file:// url
+ file_util::AppendToPath(&test_file, L"title2.html");
+ tab->NavigateToURL(net_util::FilePathToFileURL(test_file));
+ int orig_tab_count = -1;
+ ASSERT_TRUE(window->GetTabCount(&orig_tab_count));
+ int orig_process_count = GetBrowserProcessCount();
+ ASSERT_TRUE(orig_process_count >= 1);
+
+ // Use JavaScript URL to almost fork a new tab, but not quite. (Leave the
+ // opener non-null.) Should not fork a process.
+ std::wstring url_prefix(L"javascript:(function(){w=window.open();");
+ GURL dont_fork_url(url_prefix +
+ L"w.document.location=\"http://localhost:1337\";})()");
+
+ // Make sure that a new tab but not new process has been created.
+ tab->NavigateToURLAsync(dont_fork_url);
+ Sleep(kWaitForActionMsec);
+ ASSERT_EQ(orig_process_count, GetBrowserProcessCount());
+ int new_tab_count = -1;
+ ASSERT_TRUE(window->GetTabCount(&new_tab_count));
+ ASSERT_EQ(orig_tab_count + 1, new_tab_count);
+
+ // Same thing if the current tab tries to redirect itself.
+ GURL dont_fork_url2(url_prefix +
+ L"document.location=\"http://localhost:1337\";})()");
+
+ // Make sure that no new process has been created.
+ tab->NavigateToURLAsync(dont_fork_url2);
+ Sleep(kWaitForActionMsec);
+ ASSERT_EQ(orig_process_count, GetBrowserProcessCount());
+}
+
+TEST_F(VisibleBrowserTest, WindowOpenClose) {
+ std::wstring test_file(test_data_directory_);
+ file_util::AppendToPath(&test_file, L"window.close.html");
+
+ NavigateToURL(net_util::FilePathToFileURL(test_file));
+
+ int i;
+ for (i = 0; i < 10; ++i) {
+ Sleep(kWaitForActionMaxMsec / 10);
+ std::wstring title = GetActiveTabTitle();
+ if (title == L"PASSED") {
+ // Success, bail out.
+ break;
+ }
+ }
+
+ if (i == 10)
+ FAIL() << "failed to get error page title";
+}