OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/memory/ptr_util.h" | 5 #include "base/memory/ptr_util.h" |
6 #include "base/strings/string_number_conversions.h" | 6 #include "base/strings/string_number_conversions.h" |
| 7 #include "base/strings/sys_string_conversions.h" |
7 #include "base/strings/utf_string_conversions.h" | 8 #include "base/strings/utf_string_conversions.h" |
8 #include "base/test/ios/wait_util.h" | 9 #include "base/test/ios/wait_util.h" |
| 10 #import "ios/web/navigation/navigation_item_impl.h" |
9 #import "ios/web/public/navigation_item.h" | 11 #import "ios/web/public/navigation_item.h" |
10 #import "ios/web/public/navigation_manager.h" | 12 #import "ios/web/public/navigation_manager.h" |
11 #import "ios/web/public/test/http_server.h" | 13 #import "ios/web/public/test/http_server.h" |
12 #include "ios/web/public/test/http_server_util.h" | 14 #include "ios/web/public/test/http_server_util.h" |
13 #import "ios/web/public/test/web_view_interaction_test_util.h" | 15 #import "ios/web/public/test/web_view_interaction_test_util.h" |
14 #import "ios/web/public/web_state/web_state.h" | 16 #import "ios/web/public/web_state/web_state.h" |
15 #import "ios/web/test/web_int_test.h" | 17 #import "ios/web/test/web_int_test.h" |
16 #include "testing/gtest/include/gtest/gtest.h" | 18 #include "testing/gtest/include/gtest/gtest.h" |
17 #include "testing/gtest_mac.h" | 19 #include "testing/gtest_mac.h" |
18 #include "url/url_canon.h" | 20 #include "url/url_canon.h" |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
75 const std::string& title, | 77 const std::string& title, |
76 const GURL& url) { | 78 const GURL& url) { |
77 ASSERT_EQ(state_operations_url(), GetLastCommittedItem()->GetURL()); | 79 ASSERT_EQ(state_operations_url(), GetLastCommittedItem()->GetURL()); |
78 std::string url_spec = url.possibly_invalid_spec(); | 80 std::string url_spec = url.possibly_invalid_spec(); |
79 NSString* set_params_script = [NSString | 81 NSString* set_params_script = [NSString |
80 stringWithFormat:kUpdateStateParamsScriptFormat, state_object.c_str(), | 82 stringWithFormat:kUpdateStateParamsScriptFormat, state_object.c_str(), |
81 title.c_str(), url_spec.c_str()]; | 83 title.c_str(), url_spec.c_str()]; |
82 ExecuteJavaScript(set_params_script); | 84 ExecuteJavaScript(set_params_script); |
83 } | 85 } |
84 | 86 |
| 87 // Returns the state object returned by JavaScript. |
| 88 std::string GetJavaScriptState() { |
| 89 return base::SysNSStringToUTF8(ExecuteJavaScript(@"window.history.state")); |
| 90 } |
| 91 |
85 // Executes JavaScript to check whether the onload text is visible. | 92 // Executes JavaScript to check whether the onload text is visible. |
86 bool IsOnLoadTextVisible() { | 93 bool IsOnLoadTextVisible() { |
87 return [ExecuteJavaScript(kOnLoadCheckScript) boolValue]; | 94 return [ExecuteJavaScript(kOnLoadCheckScript) boolValue]; |
88 } | 95 } |
89 | 96 |
90 // Executes JavaScript to check whether the no-op text is visible. | 97 // Executes JavaScript to check whether the no-op text is visible. |
91 bool IsNoOpTextVisible() { | 98 bool IsNoOpTextVisible() { |
92 return [ExecuteJavaScript(kNoOpCheckScript) boolValue]; | 99 return [ExecuteJavaScript(kNoOpCheckScript) boolValue]; |
93 } | 100 } |
94 | 101 |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
231 SetStateParams(empty_state, new_title, empty_url); | 238 SetStateParams(empty_state, new_title, empty_url); |
232 ASSERT_TRUE(web::test::TapWebViewElementWithId(web_state(), kReplaceStateId)); | 239 ASSERT_TRUE(web::test::TapWebViewElementWithId(web_state(), kReplaceStateId)); |
233 // Wait for the title to be reflected in the NavigationItem. | 240 // Wait for the title to be reflected in the NavigationItem. |
234 base::test::ios::WaitUntilCondition(^bool { | 241 base::test::ios::WaitUntilCondition(^bool { |
235 return GetLastCommittedItem()->GetTitle() == ASCIIToUTF16(new_title); | 242 return GetLastCommittedItem()->GetTitle() == ASCIIToUTF16(new_title); |
236 }); | 243 }); |
237 // Verify that the forward navigation was not pruned. | 244 // Verify that the forward navigation was not pruned. |
238 EXPECT_EQ(GetIndexOfNavigationItem(GetLastCommittedItem()) + 1, | 245 EXPECT_EQ(GetIndexOfNavigationItem(GetLastCommittedItem()) + 1, |
239 GetIndexOfNavigationItem(about_blank_item)); | 246 GetIndexOfNavigationItem(about_blank_item)); |
240 } | 247 } |
| 248 |
| 249 // Tests that calling window.history.replaceState() with a new state object |
| 250 // replaces the state object for the current NavigationItem. |
| 251 TEST_F(HistoryStateOperationsTest, StateReplacement) { |
| 252 // Navigate to about:blank then navigate back to the test page. The created |
| 253 // NavigationItem can be used later to verify that the state is replaced |
| 254 // rather than pushed. |
| 255 GURL about_blank("about:blank"); |
| 256 LoadUrl(about_blank); |
| 257 web::NavigationItem* about_blank_item = GetLastCommittedItem(); |
| 258 ExecuteBlockAndWaitForLoad(state_operations_url(), ^{ |
| 259 navigation_manager()->GoBack(); |
| 260 }); |
| 261 ASSERT_EQ(state_operations_url(), GetLastCommittedItem()->GetURL()); |
| 262 // Set up the state parameters and tap the replace state button. |
| 263 std::string new_state("STATE OBJECT"); |
| 264 std::string empty_title; |
| 265 GURL empty_url; |
| 266 SetStateParams(new_state, empty_title, empty_url); |
| 267 ASSERT_TRUE(web::test::TapWebViewElementWithId(web_state(), kReplaceStateId)); |
| 268 // Verify that the state is reflected in the JavaScript context. |
| 269 base::test::ios::WaitUntilCondition(^bool { |
| 270 return GetJavaScriptState() == new_state; |
| 271 }); |
| 272 // Verify that the state is reflected in the latest NavigationItem. |
| 273 std::string serialized_state("\"STATE OBJECT\""); |
| 274 base::test::ios::WaitUntilCondition(^bool { |
| 275 web::NavigationItemImpl* item = |
| 276 static_cast<web::NavigationItemImpl*>(GetLastCommittedItem()); |
| 277 std::string item_state = |
| 278 base::SysNSStringToUTF8(item->GetSerializedStateObject()); |
| 279 return item_state == serialized_state; |
| 280 }); |
| 281 // Verify that the forward navigation was not pruned. |
| 282 EXPECT_EQ(GetIndexOfNavigationItem(GetLastCommittedItem()) + 1, |
| 283 GetIndexOfNavigationItem(about_blank_item)); |
| 284 } |
OLD | NEW |