Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(109)

Unified Diff: ios/chrome/browser/web/push_and_replace_state_navigation_egtest.mm

Issue 2580333003: Upstream Chrome on iOS source code [10/11]. (Closed)
Patch Set: Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « ios/chrome/browser/web/progress_indicator_egtest.mm ('k') | ios/chrome/browser/web/stop_loading_egtest.mm » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ios/chrome/browser/web/push_and_replace_state_navigation_egtest.mm
diff --git a/ios/chrome/browser/web/push_and_replace_state_navigation_egtest.mm b/ios/chrome/browser/web/push_and_replace_state_navigation_egtest.mm
new file mode 100644
index 0000000000000000000000000000000000000000..17997ae5f1417a7b87d7cfb2daa69b573751f28b
--- /dev/null
+++ b/ios/chrome/browser/web/push_and_replace_state_navigation_egtest.mm
@@ -0,0 +1,354 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import <XCTest/XCTest.h>
+
+#include "base/strings/sys_string_conversions.h"
+#include "components/strings/grit/components_strings.h"
+#include "ios/chrome/browser/ui/ui_util.h"
+#import "ios/chrome/test/earl_grey/chrome_earl_grey.h"
+#import "ios/chrome/test/earl_grey/chrome_earl_grey_ui.h"
+#import "ios/chrome/test/earl_grey/chrome_matchers.h"
+#import "ios/chrome/test/earl_grey/chrome_test_case.h"
+#import "ios/testing/earl_grey/disabled_test_macros.h"
+#import "ios/web/public/test/http_server.h"
+#include "ios/web/public/test/http_server_util.h"
+
+namespace {
+
+const char* kHistoryTestUrl =
+ "http://ios/testing/data/http_server_files/history.html";
+const char* kNonPushedUrl =
+ "http://ios/testing/data/http_server_files/pony.html";
+const char* kReplaceStateHashWithObjectURL =
+ "http://ios/testing/data/http_server_files/history.html#replaceWithObject";
+const char* kPushStateHashStringURL =
+ "http://ios/testing/data/http_server_files/history.html#string";
+const char* kReplaceStateHashStringURL =
+ "http://ios/testing/data/http_server_files/history.html#replace";
+const char* kPushStatePathURL =
+ "http://ios/testing/data/http_server_files/path";
+const char* kReplaceStateRootPathSpaceURL = "http://ios/rep lace";
+
+// Matcher for the navigate forward button.
+id<GREYMatcher> forwardButton() {
+ return chrome_test_util::buttonWithAccessibilityLabelId(IDS_ACCNAME_FORWARD);
+}
+// Matcher for the navigate backward button.
+id<GREYMatcher> backButton() {
+ return chrome_test_util::buttonWithAccessibilityLabelId(IDS_ACCNAME_BACK);
+}
+} // namespace
+
+// Tests for pushState/replaceState navigations.
+@interface PushAndReplaceStateNavigationTestCase : ChromeTestCase
+@end
+
+@implementation PushAndReplaceStateNavigationTestCase
+
+// Tests calling history.pushState() multiple times and navigating back/forward.
+- (void)testHtml5HistoryPushStateThenGoBackAndForward {
+ const GURL pushStateHashWithObjectURL = web::test::HttpServer::MakeUrl(
+ "http://ios/testing/data/http_server_files/history.html#pushWithObject");
+ const GURL pushStateRootPathURL =
+ web::test::HttpServer::MakeUrl("http://ios/rootpath");
+ const GURL pushStatePathSpaceURL =
+ web::test::HttpServer::MakeUrl("http://ios/pa%20th");
+ web::test::SetUpFileBasedHttpServer();
+ [ChromeEarlGrey loadURL:web::test::HttpServer::MakeUrl(kHistoryTestUrl)];
+
+ // Push 3 URLs. Verify that the URL changed and the status was updated.
+ [ChromeEarlGrey tapWebViewElementWithID:@"pushStateHashWithObject"];
+ [self assertStatusText:@"pushStateHashWithObject"
+ withURL:pushStateHashWithObjectURL
+ pageLoaded:NO];
+
+ [ChromeEarlGrey tapWebViewElementWithID:@"pushStateRootPath"];
+ [self assertStatusText:@"pushStateRootPath"
+ withURL:pushStateRootPathURL
+ pageLoaded:NO];
+
+ [ChromeEarlGrey tapWebViewElementWithID:@"pushStatePathSpace"];
+ [self assertStatusText:@"pushStatePathSpace"
+ withURL:pushStatePathSpaceURL
+ pageLoaded:NO];
+
+ // Go back and check that the page doesn't load and the status text is updated
+ // by the popstate event.
+ [[EarlGrey selectElementWithMatcher:backButton()] performAction:grey_tap()];
+ [self assertStatusText:@"pushStateRootPath"
+ withURL:pushStateRootPathURL
+ pageLoaded:NO];
+
+ [[EarlGrey selectElementWithMatcher:backButton()] performAction:grey_tap()];
+ [self assertStatusText:@"pushStateHashWithObject"
+ withURL:pushStateHashWithObjectURL
+ pageLoaded:NO];
+
+ [ChromeEarlGrey tapWebViewElementWithID:@"goBack"];
+ const GURL historyTestURL = web::test::HttpServer::MakeUrl(kHistoryTestUrl);
+ [self assertStatusText:NULL withURL:historyTestURL pageLoaded:NO];
+
+ // Go forward 2 pages and check that the page doesn't load and the status text
+ // is updated by the popstate event.
+ [ChromeEarlGrey tapWebViewElementWithID:@"goForward2"];
+ [self assertStatusText:@"pushStateRootPath"
+ withURL:pushStateRootPathURL
+ pageLoaded:NO];
+}
+
+// Tests that calling replaceState() changes the current history entry.
+- (void)testHtml5HistoryReplaceStateThenGoBackAndForward {
+ web::test::SetUpFileBasedHttpServer();
+ const GURL initialURL = web::test::HttpServer::MakeUrl(kNonPushedUrl);
+ [ChromeEarlGrey loadURL:initialURL];
+ [ChromeEarlGrey loadURL:web::test::HttpServer::MakeUrl(kHistoryTestUrl)];
+
+ // Replace the URL and go back then forward.
+ const GURL replaceStateHashWithObjectURL =
+ web::test::HttpServer::MakeUrl(kReplaceStateHashWithObjectURL);
+ [ChromeEarlGrey tapWebViewElementWithID:@"replaceStateHashWithObject"];
+ [self assertStatusText:@"replaceStateHashWithObject"
+ withURL:replaceStateHashWithObjectURL
+ pageLoaded:NO];
+
+ [[EarlGrey selectElementWithMatcher:backButton()] performAction:grey_tap()];
+ [[EarlGrey selectElementWithMatcher:chrome_test_util::omniboxText(
+ initialURL.GetContent())]
+ assertWithMatcher:grey_notNil()];
+
+ [[EarlGrey selectElementWithMatcher:forwardButton()]
+ performAction:grey_tap()];
+ [self assertStatusText:@"replaceStateHashWithObject"
+ withURL:replaceStateHashWithObjectURL
+ pageLoaded:YES];
+
+ // Push URL then replace it. Do this twice.
+ const GURL pushStateHashStringURL =
+ web::test::HttpServer::MakeUrl(kPushStateHashStringURL);
+ [ChromeEarlGrey tapWebViewElementWithID:@"pushStateHashString"];
+ [self assertStatusText:@"pushStateHashString"
+ withURL:pushStateHashStringURL
+ pageLoaded:NO];
+
+ const GURL replaceStateHashStringURL =
+ web::test::HttpServer::MakeUrl(kReplaceStateHashStringURL);
+ [ChromeEarlGrey tapWebViewElementWithID:@"replaceStateHashString"];
+ [self assertStatusText:@"replaceStateHashString"
+ withURL:replaceStateHashStringURL
+ pageLoaded:NO];
+
+ const GURL pushStatePathURL =
+ web::test::HttpServer::MakeUrl(kPushStatePathURL);
+ [ChromeEarlGrey tapWebViewElementWithID:@"pushStatePath"];
+ [self assertStatusText:@"pushStatePath"
+ withURL:pushStatePathURL
+ pageLoaded:NO];
+
+ const GURL replaceStateRootPathSpaceURL =
+ web::test::HttpServer::MakeUrl(kReplaceStateRootPathSpaceURL);
+ [ChromeEarlGrey tapWebViewElementWithID:@"replaceStateRootPathSpace"];
+ [self assertStatusText:@"replaceStateRootPathSpace"
+ withURL:replaceStateRootPathSpaceURL
+ pageLoaded:NO];
+
+ // Go back and check URLs.
+ [[EarlGrey selectElementWithMatcher:backButton()] performAction:grey_tap()];
+ [self assertStatusText:@"replaceStateHashString"
+ withURL:replaceStateHashStringURL
+ pageLoaded:NO];
+ [[EarlGrey selectElementWithMatcher:backButton()] performAction:grey_tap()];
+ [self assertStatusText:@"replaceStateHashWithObject"
+ withURL:replaceStateHashWithObjectURL
+ pageLoaded:NO];
+
+ // Go forward and check URL.
+ [ChromeEarlGrey tapWebViewElementWithID:@"goForward2"];
+ [self assertStatusText:@"replaceStateRootPathSpace"
+ withURL:replaceStateRootPathSpaceURL
+ pageLoaded:NO];
+}
+
+// Tests that page loads occur when navigating to or past a non-pushed URL.
+- (void)testHtml5HistoryNavigatingPastNonPushedURL {
+ GURL nonPushedURL = web::test::HttpServer::MakeUrl(kNonPushedUrl);
+ web::test::SetUpFileBasedHttpServer();
+ const GURL historyTestURL = web::test::HttpServer::MakeUrl(kHistoryTestUrl);
+ [ChromeEarlGrey loadURL:historyTestURL];
+
+ // Push same URL twice. Verify that URL changed and the status was updated.
+ const GURL pushStateHashStringURL =
+ web::test::HttpServer::MakeUrl(kPushStateHashStringURL);
+ [ChromeEarlGrey tapWebViewElementWithID:@"pushStateHashString"];
+ [self assertStatusText:@"pushStateHashString"
+ withURL:pushStateHashStringURL
+ pageLoaded:NO];
+ [ChromeEarlGrey tapWebViewElementWithID:@"pushStateHashString"];
+ [self assertStatusText:@"pushStateHashString"
+ withURL:pushStateHashStringURL
+ pageLoaded:NO];
+
+ // Load a non-pushed URL.
+ [ChromeEarlGrey loadURL:nonPushedURL];
+
+ // Load history.html and push another URL.
+ [ChromeEarlGrey loadURL:historyTestURL];
+ [ChromeEarlGrey tapWebViewElementWithID:@"pushStateHashString"];
+ [self assertStatusText:@"pushStateHashString"
+ withURL:pushStateHashStringURL
+ pageLoaded:NO];
+
+ // At this point the history looks like this:
+ // [NTP, history.html, #string, #string, nonPushedURL, history.html, #string]
+
+ // Go back (to second history.html) and verify page did not load.
+ [[EarlGrey selectElementWithMatcher:backButton()] performAction:grey_tap()];
+ [self assertStatusText:nil withURL:historyTestURL pageLoaded:NO];
+
+ // Go back twice (to second #string) and verify page did load.
+ [[EarlGrey selectElementWithMatcher:backButton()] performAction:grey_tap()];
+ [[EarlGrey selectElementWithMatcher:backButton()] performAction:grey_tap()];
+ [self assertStatusText:nil withURL:pushStateHashStringURL pageLoaded:YES];
+
+ // Go back once (to first #string) and verify page did not load.
+ [[EarlGrey selectElementWithMatcher:backButton()] performAction:grey_tap()];
+ [self assertStatusText:@"pushStateHashString"
+ withURL:pushStateHashStringURL
+ pageLoaded:NO];
+
+ // Go forward 4 entries at once (to third #string) and verify page did load.
+ [ChromeEarlGrey tapWebViewElementWithID:@"goForward4"];
+
+ [self assertStatusText:nil withURL:pushStateHashStringURL pageLoaded:YES];
+
+ // Go back 4 entries at once (to first #string) and verify page did load.
+ [ChromeEarlGrey tapWebViewElementWithID:@"goBack4"];
+
+ [self assertStatusText:NULL withURL:pushStateHashStringURL pageLoaded:YES];
+}
+
+// Tests calling pushState with unicode characters.
+- (void)testHtml5HistoryPushUnicodeCharacters {
+ const GURL pushStateUnicodeURLEncoded = web::test::HttpServer::MakeUrl(
+ "http://ios/testing/data/http_server_files/"
+ "history.html#unicode%E1%84%91");
+ const GURL pushStateUnicode2URLEncoded = web::test::HttpServer::MakeUrl(
+ "http://ios/testing/data/http_server_files/"
+ "history.html#unicode2%E2%88%A2");
+ std::string pushStateUnicodeLabel = "Action: pushStateUnicodeᄑ";
+ NSString* pushStateUnicodeStatus = @"pushStateUnicodeᄑ";
+ std::string pushStateUnicode2Label = "Action: pushStateUnicode2∢";
+ NSString* pushStateUnicode2Status = @"pushStateUnicode2∢";
+
+ web::test::SetUpFileBasedHttpServer();
+ [ChromeEarlGrey loadURL:web::test::HttpServer::MakeUrl(kHistoryTestUrl)];
+
+ // TODO(crbug.com/643458): The fact that the URL shows %-escaped is due to
+ // NSURL escaping to make UIWebView/JS happy. See if it's possible to
+ // represent differently such that it displays unescaped.
+ // Do 2 push states with unicode characters.
+ [ChromeEarlGrey tapWebViewElementWithID:@"pushStateUnicode"];
+ [[EarlGrey
+ selectElementWithMatcher:chrome_test_util::omniboxText(
+ pushStateUnicodeURLEncoded.GetContent())]
+ assertWithMatcher:grey_notNil()];
+ [[EarlGrey selectElementWithMatcher:chrome_test_util::webViewContainingText(
+ pushStateUnicodeLabel)]
+ assertWithMatcher:grey_notNil()];
+
+ [ChromeEarlGrey tapWebViewElementWithID:@"pushStateUnicode2"];
+ [[EarlGrey
+ selectElementWithMatcher:chrome_test_util::omniboxText(
+ pushStateUnicode2URLEncoded.GetContent())]
+ assertWithMatcher:grey_notNil()];
+ [[EarlGrey selectElementWithMatcher:chrome_test_util::webViewContainingText(
+ pushStateUnicode2Label)]
+ assertWithMatcher:grey_notNil()];
+
+ // Do a push state without a unicode character.
+ const GURL pushStatePathURL =
+ web::test::HttpServer::MakeUrl(kPushStatePathURL);
+ [ChromeEarlGrey tapWebViewElementWithID:@"pushStatePath"];
+
+ [self assertStatusText:@"pushStatePath"
+ withURL:pushStatePathURL
+ pageLoaded:NO];
+
+ // Go back and check the unicode in the URL and status.
+ [[EarlGrey selectElementWithMatcher:backButton()] performAction:grey_tap()];
+ [self assertStatusText:pushStateUnicode2Status
+ withURL:pushStateUnicode2URLEncoded
+ pageLoaded:NO];
+
+ [[EarlGrey selectElementWithMatcher:backButton()] performAction:grey_tap()];
+ [self assertStatusText:pushStateUnicodeStatus
+ withURL:pushStateUnicodeURLEncoded
+ pageLoaded:NO];
+}
+
+// Tests that pushState/replaceState handling properly handles <base>.
+- (void)testHtml5HistoryWithBase {
+ std::map<GURL, std::string> responses;
+ GURL originURL =
+ web::test::HttpServer::MakeUrl("http://foo.com/foo/bar.html");
+ GURL pushResultURL = originURL.GetOrigin().Resolve("pushed/relative/url");
+ GURL replaceResultURL =
+ originURL.GetOrigin().Resolve("replaced/relative/url");
+
+ // A simple HTML page with a base tag that makes all relative URLs
+ // domain-relative, a button to trigger a relative pushState, and a button
+ // to trigger a relative replaceState.
+ NSString* baseTag = @"<base href=\"/\">";
+ NSString* pushAndReplaceButtons =
+ @"<input type=\"button\" value=\"pushState\" "
+ "id=\"pushState\" onclick=\"history.pushState("
+ "{}, 'Foo', './pushed/relative/url');\"><br>"
+ "<input type=\"button\" value=\"replaceState\" "
+ "id=\"replaceState\" onclick=\"history.replaceState("
+ "{}, 'Foo', './replaced/relative/url');\"><br>";
+ NSString* simplePage =
+ @"<!doctype html><html><head>%@</head><body>%@</body></html>";
+ responses[originURL] = base::SysNSStringToUTF8(
+ [NSString stringWithFormat:simplePage, baseTag, pushAndReplaceButtons]);
+ web::test::SetUpSimpleHttpServer(responses);
+
+ [ChromeEarlGrey loadURL:originURL];
+ [ChromeEarlGrey tapWebViewElementWithID:@"pushState"];
+ [[EarlGrey selectElementWithMatcher:chrome_test_util::omniboxText(
+ pushResultURL.GetContent())]
+ assertWithMatcher:grey_notNil()];
+
+ [ChromeEarlGrey tapWebViewElementWithID:@"replaceState"];
+ [[EarlGrey selectElementWithMatcher:chrome_test_util::omniboxText(
+ replaceResultURL.GetContent())]
+ assertWithMatcher:grey_notNil()];
+}
+
+#pragma mark - Utility methods
+
+// Assert that status text |status| is displayed in the webview, that "onloaded"
+// text is displayed if pageLoaded is YES, and that the URL is as expected.
+- (void)assertStatusText:(NSString*)status
+ withURL:(const GURL&)urlToVerify
+ pageLoaded:(BOOL)pageLoaded {
+ id<GREYMatcher> pageLoadedMatcher =
+ pageLoaded ? chrome_test_util::webViewContainingText("onload")
+ : chrome_test_util::webViewNotContainingText("onload");
+ [[EarlGrey selectElementWithMatcher:pageLoadedMatcher]
+ assertWithMatcher:grey_notNil()];
+
+ if (status != NULL) {
+ NSString* statusLabel = [NSString stringWithFormat:@"Action: %@", status];
+ [[EarlGrey
+ selectElementWithMatcher:chrome_test_util::webViewContainingText(
+ base::SysNSStringToUTF8(statusLabel))]
+ assertWithMatcher:grey_notNil()];
+ }
+
+ [[EarlGrey selectElementWithMatcher:chrome_test_util::omniboxText(
+ urlToVerify.GetContent())]
+ assertWithMatcher:grey_notNil()];
+}
+
+@end
« no previous file with comments | « ios/chrome/browser/web/progress_indicator_egtest.mm ('k') | ios/chrome/browser/web/stop_loading_egtest.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698