summaryrefslogtreecommitdiffstats
path: root/chrome/browser/session_history_uitest.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/session_history_uitest.cc')
-rw-r--r--chrome/browser/session_history_uitest.cc522
1 files changed, 522 insertions, 0 deletions
diff --git a/chrome/browser/session_history_uitest.cc b/chrome/browser/session_history_uitest.cc
new file mode 100644
index 0000000..06de102
--- /dev/null
+++ b/chrome/browser/session_history_uitest.cc
@@ -0,0 +1,522 @@
+// 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/win_util.h"
+#include "chrome/common/l10n_util.h"
+#include "chrome/test/automation/tab_proxy.h"
+#include "chrome/test/automation/browser_proxy.h"
+#include "chrome/test/ui/ui_test.h"
+#include "net/base/net_util.h"
+#include "net/url_request/url_request_unittest.h"
+
+#include "generated_resources.h"
+
+using std::wstring;
+
+namespace {
+
+const wchar_t kDocRoot[] = L"chrome/test/data";
+
+class SessionHistoryTest : public UITest {
+ protected:
+ SessionHistoryTest() : UITest() {
+ wstring path_prefix = test_data_directory_;
+ file_util::AppendToPath(&path_prefix, L"session_history");
+ path_prefix += file_util::kPathSeparator;
+
+ url_prefix_ = UTF8ToWide(net_util::FilePathToFileURL(path_prefix).spec());
+ }
+
+ virtual void SetUp() {
+ UITest::SetUp();
+
+ window_.reset(automation()->GetBrowserWindow(0));
+ ASSERT_TRUE(window_.get());
+
+ int active_tab_index = -1;
+ ASSERT_TRUE(window_->GetActiveTabIndex(&active_tab_index));
+ tab_.reset(window_->GetTab(active_tab_index));
+ ASSERT_TRUE(tab_.get());
+ }
+
+ // Simulate clicking a link. Only works on the frames.html testserver page.
+ void ClickLink(std::wstring node_id) {
+ GURL url(L"javascript:clickLink('" + node_id + L"')");
+ ASSERT_TRUE(tab_->NavigateToURL(url));
+ }
+
+ // Simulate filling in form data. Only works on the frames.html page with
+ // subframe = form.html, and on form.html itself.
+ void FillForm(std::wstring node_id, std::wstring value) {
+ GURL url(L"javascript:fillForm('" + node_id +
+ L"', '" + value + L"')");
+ // This will return immediately, but since the JS executes synchronously
+ // on the renderer, it will complete before the next navigate message is
+ // processed.
+ ASSERT_TRUE(tab_->NavigateToURLAsync(url));
+ }
+
+ // Simulate submitting a form. Only works on the frames.html page with
+ // subframe = form.html, and on form.html itself.
+ void SubmitForm(std::wstring node_id) {
+ GURL url(L"javascript:submitForm('" + node_id + L"')");
+ ASSERT_TRUE(tab_->NavigateToURL(url));
+ }
+
+ // Navigate session history using history.go(distance).
+ void JavascriptGo(std::string distance) {
+ GURL url("javascript:history.go('" + distance + "')");
+ ASSERT_TRUE(tab_->NavigateToURL(url));
+ }
+
+ wstring GetTabTitle() {
+ wstring title;
+ EXPECT_TRUE(tab_->GetTabTitle(&title));
+ return title;
+ }
+
+ // Try 10 times to get the right tab title.
+ wstring TestTabTitle(const wstring& value) {
+ // Error pages load separately, but the UI automation system does not wait
+ // for error pages to load before returning after a navigation request.
+ // So, we need to sleep a little.
+ DWORD kWaitForErrorPageMsec = 200;
+
+ for (int i = 0; i < 10; ++i) {
+ if (value.compare(GetTabTitle()) == 0)
+ return value;
+ Sleep(kWaitForErrorPageMsec);
+ }
+ return GetTabTitle();
+ }
+
+ GURL GetTabURL() {
+ GURL url;
+ EXPECT_TRUE(tab_->GetCurrentURL(&url));
+ return url;
+ }
+
+ protected:
+ wstring url_prefix_;
+ scoped_ptr<BrowserProxy> window_;
+ scoped_ptr<TabProxy> tab_;
+};
+
+} // namespace
+
+TEST_F(SessionHistoryTest, BasicBackForward) {
+ TestServer server(kDocRoot);
+
+ // about:blank should be loaded first.
+ ASSERT_FALSE(tab_->GoBack());
+ EXPECT_EQ(L"", GetTabTitle());
+
+ ASSERT_TRUE(tab_->NavigateToURL(
+ server.TestServerPage("files/session_history/bot1.html")));
+ EXPECT_EQ(L"bot1", GetTabTitle());
+
+ ASSERT_TRUE(tab_->NavigateToURL(
+ server.TestServerPage("files/session_history/bot2.html")));
+ EXPECT_EQ(L"bot2", GetTabTitle());
+
+ ASSERT_TRUE(tab_->NavigateToURL(
+ server.TestServerPage("files/session_history/bot3.html")));
+ EXPECT_EQ(L"bot3", GetTabTitle());
+
+ // history is [blank, bot1, bot2, *bot3]
+
+ ASSERT_TRUE(tab_->GoBack());
+ EXPECT_EQ(L"bot2", GetTabTitle());
+
+ ASSERT_TRUE(tab_->GoBack());
+ EXPECT_EQ(L"bot1", GetTabTitle());
+
+ ASSERT_TRUE(tab_->GoForward());
+ EXPECT_EQ(L"bot2", GetTabTitle());
+
+ ASSERT_TRUE(tab_->GoBack());
+ EXPECT_EQ(L"bot1", GetTabTitle());
+
+ ASSERT_TRUE(tab_->NavigateToURL(
+ server.TestServerPage("files/session_history/bot3.html")));
+ EXPECT_EQ(L"bot3", GetTabTitle());
+
+ // history is [blank, bot1, *bot3]
+
+ ASSERT_FALSE(tab_->GoForward());
+ EXPECT_EQ(L"bot3", GetTabTitle());
+
+ ASSERT_TRUE(tab_->GoBack());
+ EXPECT_EQ(L"bot1", GetTabTitle());
+
+ ASSERT_TRUE(tab_->GoBack());
+ EXPECT_EQ(L"", GetTabTitle());
+
+ ASSERT_FALSE(tab_->GoBack());
+ EXPECT_EQ(L"", GetTabTitle());
+
+ ASSERT_TRUE(tab_->GoForward());
+ EXPECT_EQ(L"bot1", GetTabTitle());
+
+ ASSERT_TRUE(tab_->GoForward());
+ EXPECT_EQ(L"bot3", GetTabTitle());
+}
+
+// Test that back/forward works when navigating in subframes.
+TEST_F(SessionHistoryTest, FrameBackForward) {
+ // Bug: http://b/1175763, skip this test on Windows 2000 until
+ // flakiness is investigated and fixed.
+ if (win_util::GetWinVersion() <= win_util::WINVERSION_2000)
+ return;
+
+ TestServer server(kDocRoot);
+
+ // about:blank should be loaded first.
+ GURL home(homepage_);
+ ASSERT_FALSE(tab_->GoBack());
+ EXPECT_EQ(L"", GetTabTitle());
+ EXPECT_EQ(home, GetTabURL());
+
+ GURL frames(server.TestServerPage("files/session_history/frames.html"));
+ ASSERT_TRUE(tab_->NavigateToURL(frames));
+ EXPECT_EQ(L"bot1", GetTabTitle());
+ EXPECT_EQ(frames, GetTabURL());
+
+ ClickLink(L"abot2");
+ EXPECT_EQ(L"bot2", GetTabTitle());
+ EXPECT_EQ(frames, GetTabURL());
+
+ ClickLink(L"abot3");
+ EXPECT_EQ(L"bot3", GetTabTitle());
+ EXPECT_EQ(frames, GetTabURL());
+
+ // history is [blank, bot1, bot2, *bot3]
+
+ ASSERT_TRUE(tab_->GoBack());
+ EXPECT_EQ(L"bot2", GetTabTitle());
+ EXPECT_EQ(frames, GetTabURL());
+
+ ASSERT_TRUE(tab_->GoBack());
+ EXPECT_EQ(L"bot1", GetTabTitle());
+ EXPECT_EQ(frames, GetTabURL());
+
+ ASSERT_TRUE(tab_->GoBack());
+ EXPECT_EQ(L"", GetTabTitle());
+ EXPECT_EQ(home, GetTabURL());
+
+ ASSERT_TRUE(tab_->GoForward());
+ EXPECT_EQ(L"bot1", GetTabTitle());
+ EXPECT_EQ(frames, GetTabURL());
+
+ ASSERT_TRUE(tab_->GoForward());
+ EXPECT_EQ(L"bot2", GetTabTitle());
+ EXPECT_EQ(frames, GetTabURL());
+
+ ClickLink(L"abot1");
+ EXPECT_EQ(L"bot1", GetTabTitle());
+ EXPECT_EQ(frames, GetTabURL());
+
+ // history is [blank, bot1, bot2, *bot1]
+
+ ASSERT_FALSE(tab_->GoForward());
+ EXPECT_EQ(L"bot1", GetTabTitle());
+ EXPECT_EQ(frames, GetTabURL());
+
+ ASSERT_TRUE(tab_->GoBack());
+ EXPECT_EQ(L"bot2", GetTabTitle());
+ EXPECT_EQ(frames, GetTabURL());
+
+ ASSERT_TRUE(tab_->GoBack());
+ EXPECT_EQ(L"bot1", GetTabTitle());
+ EXPECT_EQ(frames, GetTabURL());
+}
+
+// Test that back/forward preserves POST data and document state in subframes.
+TEST_F(SessionHistoryTest, FrameFormBackForward) {
+ TestServer server(kDocRoot);
+
+ // about:blank should be loaded first.
+ ASSERT_FALSE(tab_->GoBack());
+ EXPECT_EQ(L"", GetTabTitle());
+
+ GURL frames(server.TestServerPage("files/session_history/frames.html"));
+ ASSERT_TRUE(tab_->NavigateToURL(frames));
+ EXPECT_EQ(L"bot1", GetTabTitle());
+
+ ClickLink(L"aform");
+ EXPECT_EQ(L"form", GetTabTitle());
+ EXPECT_EQ(frames, GetTabURL());
+
+ SubmitForm(L"isubmit");
+ EXPECT_EQ(L"text=&select=a", GetTabTitle());
+ EXPECT_EQ(frames, GetTabURL());
+
+ ASSERT_TRUE(tab_->GoBack());
+ EXPECT_EQ(L"form", GetTabTitle());
+ EXPECT_EQ(frames, GetTabURL());
+
+ // history is [blank, bot1, *form, post]
+
+ ClickLink(L"abot2");
+ EXPECT_EQ(L"bot2", GetTabTitle());
+ EXPECT_EQ(frames, GetTabURL());
+
+ // history is [blank, bot1, form, *bot2]
+
+ ASSERT_TRUE(tab_->GoBack());
+ EXPECT_EQ(L"form", GetTabTitle());
+ EXPECT_EQ(frames, GetTabURL());
+
+ SubmitForm(L"isubmit");
+ EXPECT_EQ(L"text=&select=a", GetTabTitle());
+ EXPECT_EQ(frames, GetTabURL());
+
+ // history is [blank, bot1, form, *post]
+
+// TODO(mpcomplete): reenable this when WebKit bug 10199 is fixed:
+// "returning to a POST result within a frame does a GET instead of a POST"
+#if 0
+ ClickLink(L"abot2");
+ EXPECT_EQ(L"bot2", GetTabTitle());
+ EXPECT_EQ(frames, GetTabURL());
+
+ ASSERT_TRUE(tab_->GoBack());
+ EXPECT_EQ(L"text=&select=a", GetTabTitle());
+ EXPECT_EQ(frames, GetTabURL());
+#endif
+}
+
+// TODO(mpcomplete): enable this when Bug 734372 is fixed:
+// "Doing a session history navigation does not restore newly-created subframe
+// document state"
+#if 0
+// Test that back/forward preserves POST data and document state when navigating
+// across frames (ie, from frame -> nonframe).
+TEST_F(SessionHistoryTest, CrossFrameFormBackForward) {
+ TestServer server(kDocRoot);
+
+ // about:blank should be loaded first.
+ ASSERT_FALSE(tab_->GoBack());
+ EXPECT_EQ(L"", GetTabTitle());
+
+ GURL frames(server.TestServerPage("files/session_history/frames.html"));
+ ASSERT_TRUE(tab_->NavigateToURL(frames));
+ EXPECT_EQ(L"bot1", GetTabTitle());
+
+ ClickLink(L"aform");
+ EXPECT_EQ(L"form", GetTabTitle());
+ EXPECT_EQ(frames, GetTabURL());
+
+ SubmitForm(L"isubmit");
+ EXPECT_EQ(L"text=&select=a", GetTabTitle());
+ EXPECT_EQ(frames, GetTabURL());
+
+ ASSERT_TRUE(tab_->GoBack());
+ EXPECT_EQ(L"form", GetTabTitle());
+ EXPECT_EQ(frames, GetTabURL());
+
+ // history is [blank, bot1, *form, post]
+
+ //ClickLink(L"abot2");
+ GURL bot2("files/session_history/bot2.html");
+ ASSERT_TRUE(tab_->NavigateToURL(bot2));
+ EXPECT_EQ(L"bot2", GetTabTitle());
+ EXPECT_EQ(bot2, GetTabURL());
+
+ // history is [blank, bot1, form, *bot2]
+
+ ASSERT_TRUE(tab_->GoBack());
+ EXPECT_EQ(L"form", GetTabTitle());
+ EXPECT_EQ(frames, GetTabURL());
+
+ SubmitForm(L"isubmit");
+ EXPECT_EQ(L"text=&select=a", GetTabTitle());
+ EXPECT_EQ(frames, GetTabURL());
+}
+#endif
+
+// Test that back/forward entries are created for reference fragment navigations.
+// Bug 730379.
+TEST_F(SessionHistoryTest, FragmentBackForward) {
+ TestServer server(kDocRoot);
+
+ // about:blank should be loaded first.
+ ASSERT_FALSE(tab_->GoBack());
+ EXPECT_EQ(L"", GetTabTitle());
+
+ GURL fragment(server.TestServerPage("files/session_history/fragment.html"));
+ ASSERT_TRUE(tab_->NavigateToURL(fragment));
+ EXPECT_EQ(L"fragment", GetTabTitle());
+ EXPECT_EQ(fragment, GetTabURL());
+
+ GURL::Replacements ref_params;
+
+ ref_params.SetRef("a", url_parse::Component(0, 1));
+ GURL fragment_a(fragment.ReplaceComponents(ref_params));
+ ASSERT_TRUE(tab_->NavigateToURL(fragment_a));
+ EXPECT_EQ(L"fragment", GetTabTitle());
+ EXPECT_EQ(fragment_a, GetTabURL());
+
+ ref_params.SetRef("b", url_parse::Component(0, 1));
+ GURL fragment_b(fragment.ReplaceComponents(ref_params));
+ ASSERT_TRUE(tab_->NavigateToURL(fragment_b));
+ EXPECT_EQ(L"fragment", GetTabTitle());
+ EXPECT_EQ(fragment_b, GetTabURL());
+
+ ref_params.SetRef("c", url_parse::Component(0, 1));
+ GURL fragment_c(fragment.ReplaceComponents(ref_params));
+ ASSERT_TRUE(tab_->NavigateToURL(fragment_c));
+ EXPECT_EQ(L"fragment", GetTabTitle());
+ EXPECT_EQ(fragment_c, GetTabURL());
+
+ // history is [blank, fragment, fragment#a, fragment#b, *fragment#c]
+
+ ASSERT_TRUE(tab_->GoBack());
+ EXPECT_EQ(fragment_b, GetTabURL());
+
+ ASSERT_TRUE(tab_->GoBack());
+ EXPECT_EQ(fragment_a, GetTabURL());
+
+ ASSERT_TRUE(tab_->GoBack());
+ EXPECT_EQ(fragment, GetTabURL());
+
+ ASSERT_TRUE(tab_->GoForward());
+ EXPECT_EQ(fragment_a, GetTabURL());
+
+ GURL bot3(server.TestServerPage("files/session_history/bot3.html"));
+ ASSERT_TRUE(tab_->NavigateToURL(bot3));
+ EXPECT_EQ(L"bot3", GetTabTitle());
+ EXPECT_EQ(bot3, GetTabURL());
+
+ // history is [blank, fragment, fragment#a, bot3]
+
+ ASSERT_FALSE(tab_->GoForward());
+ EXPECT_EQ(bot3, GetTabURL());
+
+ ASSERT_TRUE(tab_->GoBack());
+ EXPECT_EQ(fragment_a, GetTabURL());
+
+ ASSERT_TRUE(tab_->GoBack());
+ EXPECT_EQ(fragment, GetTabURL());
+}
+
+// Test that the javascript window.history object works.
+// NOTE: history.go(N) does not do anything if N is outside the bounds of the
+// back/forward list (such as trigger our start/stop loading events). This
+// means the test will hang if it attempts to navigate too far forward or back,
+// since we'll be waiting forever for a load stop event.
+TEST_F(SessionHistoryTest, JavascriptHistory) {
+ TestServer server(kDocRoot);
+
+ // about:blank should be loaded first.
+ ASSERT_FALSE(tab_->GoBack());
+ EXPECT_EQ(L"", GetTabTitle());
+
+ ASSERT_TRUE(tab_->NavigateToURL(
+ server.TestServerPage("files/session_history/bot1.html")));
+ EXPECT_EQ(L"bot1", GetTabTitle());
+
+ ASSERT_TRUE(tab_->NavigateToURL(
+ server.TestServerPage("files/session_history/bot2.html")));
+ EXPECT_EQ(L"bot2", GetTabTitle());
+
+ ASSERT_TRUE(tab_->NavigateToURL(
+ server.TestServerPage("files/session_history/bot3.html")));
+ EXPECT_EQ(L"bot3", GetTabTitle());
+
+ // history is [blank, bot1, bot2, *bot3]
+
+ JavascriptGo("-1");
+ EXPECT_EQ(L"bot2", GetTabTitle());
+
+ JavascriptGo("-1");
+ EXPECT_EQ(L"bot1", GetTabTitle());
+
+ JavascriptGo("1");
+ EXPECT_EQ(L"bot2", GetTabTitle());
+
+ JavascriptGo("-1");
+ EXPECT_EQ(L"bot1", GetTabTitle());
+
+ JavascriptGo("2");
+ EXPECT_EQ(L"bot3", GetTabTitle());
+
+ // history is [blank, bot1, bot2, *bot3]
+
+ JavascriptGo("-3");
+ EXPECT_EQ(L"", GetTabTitle());
+
+ ASSERT_FALSE(tab_->GoBack());
+ EXPECT_EQ(L"", GetTabTitle());
+
+ JavascriptGo("1");
+ EXPECT_EQ(L"bot1", GetTabTitle());
+
+ ASSERT_TRUE(tab_->NavigateToURL(
+ server.TestServerPage("files/session_history/bot3.html")));
+ EXPECT_EQ(L"bot3", GetTabTitle());
+
+ // history is [blank, bot1, *bot3]
+
+ ASSERT_FALSE(tab_->GoForward());
+ EXPECT_EQ(L"bot3", GetTabTitle());
+
+ JavascriptGo("-1");
+ EXPECT_EQ(L"bot1", GetTabTitle());
+
+ JavascriptGo("-1");
+ EXPECT_EQ(L"", GetTabTitle());
+
+ ASSERT_FALSE(tab_->GoBack());
+ EXPECT_EQ(L"", GetTabTitle());
+
+ JavascriptGo("1");
+ EXPECT_EQ(L"bot1", GetTabTitle());
+
+ JavascriptGo("1");
+ EXPECT_EQ(L"bot3", GetTabTitle());
+
+ // TODO(creis): Test that JavaScript history navigations work across tab
+ // types. For example, load about:network in a tab, then a real page, then
+ // try to go back and forward with JavaScript. Bug 1136715.
+ // (Hard to test right now, because pages like about:network cause the
+ // TabProxy to hang. This is because they do not appear to use the
+ // NotificationService.)
+}
+
+TEST_F(SessionHistoryTest, LocationReplace) {
+ // Test that using location.replace doesn't leave the title of the old page
+ // visible.
+ TestServer server(kDocRoot);
+
+ ASSERT_TRUE(tab_->NavigateToURL(
+ server.TestServerPage("files/session_history/replace.html?no-title.html")));
+ EXPECT_EQ(L"", GetTabTitle());
+}