OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "content/browser/frame_host/navigation_controller_impl.h" | 5 #include "content/browser/frame_host/navigation_controller_impl.h" |
6 | 6 |
7 #include <stdint.h> | 7 #include <stdint.h> |
8 #include <utility> | 8 #include <utility> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 3187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3198 EXPECT_EQ(1, controller.GetLastCommittedEntryIndex()); | 3198 EXPECT_EQ(1, controller.GetLastCommittedEntryIndex()); |
3199 | 3199 |
3200 // 3. Go back, recreating the iframe. | 3200 // 3. Go back, recreating the iframe. |
3201 { | 3201 { |
3202 TestNavigationObserver back_load_observer(shell()->web_contents()); | 3202 TestNavigationObserver back_load_observer(shell()->web_contents()); |
3203 controller.GoBack(); | 3203 controller.GoBack(); |
3204 back_load_observer.Wait(); | 3204 back_load_observer.Wait(); |
3205 } | 3205 } |
3206 ASSERT_EQ(1U, root->child_count()); | 3206 ASSERT_EQ(1U, root->child_count()); |
3207 EXPECT_EQ(main_url, root->current_url()); | 3207 EXPECT_EQ(main_url, root->current_url()); |
3208 | 3208 EXPECT_EQ(blank_url, root->child_at(0)->current_url()); |
3209 // TODO(creis): The child's current_url should be about:blank, but we're not | |
3210 // currently getting a commit in this case. For now, we'll lack a commit for | |
3211 // this frame, similar to the slow URL case. See https://crbug.com/626416. | |
3212 if (SiteIsolationPolicy::UseSubframeNavigationEntries()) | |
3213 EXPECT_TRUE(root->child_at(0)->current_url().is_empty()); | |
3214 else | |
3215 EXPECT_EQ(blank_url, root->child_at(0)->current_url()); | |
3216 | 3209 |
3217 // Verify that the parent was able to script the iframe. | 3210 // Verify that the parent was able to script the iframe. |
3218 { | 3211 { |
3219 std::string value; | 3212 std::string value; |
3220 EXPECT_TRUE(ExecuteScriptAndExtractString( | 3213 EXPECT_TRUE(ExecuteScriptAndExtractString( |
3221 root->child_at(0), | 3214 root->child_at(0), |
3222 "domAutomationController.send(document.body.innerHTML)", &value)); | 3215 "domAutomationController.send(document.body.innerHTML)", &value)); |
3223 EXPECT_EQ(expected_text, value); | 3216 EXPECT_EQ(expected_text, value); |
3224 } | 3217 } |
3225 | 3218 |
3226 EXPECT_EQ(2, controller.GetEntryCount()); | 3219 EXPECT_EQ(2, controller.GetEntryCount()); |
3227 EXPECT_EQ(0, controller.GetLastCommittedEntryIndex()); | 3220 EXPECT_EQ(0, controller.GetLastCommittedEntryIndex()); |
3228 EXPECT_EQ(entry, controller.GetLastCommittedEntry()); | 3221 EXPECT_EQ(entry, controller.GetLastCommittedEntry()); |
3229 | 3222 |
3230 // The entry should have a FrameNavigationEntry for the blank subframe. | 3223 // The entry should have a FrameNavigationEntry for the blank subframe. |
3231 if (SiteIsolationPolicy::UseSubframeNavigationEntries()) { | 3224 if (SiteIsolationPolicy::UseSubframeNavigationEntries()) { |
3232 ASSERT_EQ(1U, entry->root_node()->children.size()); | 3225 ASSERT_EQ(1U, entry->root_node()->children.size()); |
3233 EXPECT_EQ(blank_url, entry->root_node()->children[0]->frame_entry->url()); | 3226 EXPECT_EQ(blank_url, entry->root_node()->children[0]->frame_entry->url()); |
3234 } | 3227 } |
3235 } | 3228 } |
3236 | 3229 |
| 3230 // Verify that we correctly load nested iframes injected into a page if we go |
| 3231 // back and recreate them. Also confirm that form values are not restored for |
| 3232 // forms injected into about:blank pages. See https://crbug.com/657896. |
| 3233 IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest, |
| 3234 FrameNavigationEntry_RecreatedInjectedBlankSubframe) { |
| 3235 // 1. Start on a page that injects a nested iframe into an injected |
| 3236 // about:blank iframe. |
| 3237 GURL main_url(embedded_test_server()->GetURL( |
| 3238 "/navigation_controller/inject_subframe_into_blank_iframe.html")); |
| 3239 GURL blank_url(url::kAboutBlankURL); |
| 3240 GURL inner_url( |
| 3241 embedded_test_server()->GetURL("/navigation_controller/form.html")); |
| 3242 EXPECT_TRUE(NavigateToURL(shell(), main_url)); |
| 3243 NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>( |
| 3244 shell()->web_contents()->GetController()); |
| 3245 FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents()) |
| 3246 ->GetFrameTree() |
| 3247 ->root(); |
| 3248 |
| 3249 // Verify that the inner iframe was able to load. |
| 3250 ASSERT_EQ(1U, root->child_count()); |
| 3251 ASSERT_EQ(1U, root->child_at(0)->child_count()); |
| 3252 ASSERT_EQ(0U, root->child_at(0)->child_at(0)->child_count()); |
| 3253 EXPECT_EQ(main_url, root->current_url()); |
| 3254 EXPECT_EQ(blank_url, root->child_at(0)->current_url()); |
| 3255 EXPECT_EQ(inner_url, root->child_at(0)->child_at(0)->current_url()); |
| 3256 |
| 3257 EXPECT_EQ(1, controller.GetEntryCount()); |
| 3258 EXPECT_EQ(0, controller.GetLastCommittedEntryIndex()); |
| 3259 NavigationEntryImpl* entry = controller.GetLastCommittedEntry(); |
| 3260 |
| 3261 // The entry should have FrameNavigationEntries for the subframes. |
| 3262 if (SiteIsolationPolicy::UseSubframeNavigationEntries()) { |
| 3263 ASSERT_EQ(1U, entry->root_node()->children.size()); |
| 3264 EXPECT_EQ(blank_url, entry->root_node()->children[0]->frame_entry->url()); |
| 3265 EXPECT_EQ(inner_url, |
| 3266 entry->root_node()->children[0]->children[0]->frame_entry->url()); |
| 3267 } |
| 3268 |
| 3269 // Set a value in the form which will be stored in the PageState. |
| 3270 EXPECT_TRUE( |
| 3271 ExecuteScript(root->child_at(0)->child_at(0), |
| 3272 "document.getElementById('itext').value = 'modified';")); |
| 3273 |
| 3274 // 2. Navigate the main frame same-site, destroying the subframes. |
| 3275 GURL main_url_2(embedded_test_server()->GetURL( |
| 3276 "/navigation_controller/simple_page_1.html")); |
| 3277 EXPECT_TRUE(NavigateToURL(shell(), main_url_2)); |
| 3278 ASSERT_EQ(0U, root->child_count()); |
| 3279 EXPECT_EQ(main_url_2, root->current_url()); |
| 3280 |
| 3281 EXPECT_EQ(2, controller.GetEntryCount()); |
| 3282 EXPECT_EQ(1, controller.GetLastCommittedEntryIndex()); |
| 3283 |
| 3284 // 3. Go back, recreating the subframes. |
| 3285 { |
| 3286 TestNavigationObserver back_load_observer(shell()->web_contents()); |
| 3287 controller.GoBack(); |
| 3288 back_load_observer.Wait(); |
| 3289 } |
| 3290 ASSERT_EQ(1U, root->child_count()); |
| 3291 EXPECT_EQ(main_url, root->current_url()); |
| 3292 EXPECT_EQ(blank_url, root->child_at(0)->current_url()); |
| 3293 |
| 3294 // Verify that the inner iframe went to the correct URL. |
| 3295 EXPECT_EQ(inner_url, root->child_at(0)->child_at(0)->current_url()); |
| 3296 |
| 3297 EXPECT_EQ(2, controller.GetEntryCount()); |
| 3298 EXPECT_EQ(0, controller.GetLastCommittedEntryIndex()); |
| 3299 EXPECT_EQ(entry, controller.GetLastCommittedEntry()); |
| 3300 |
| 3301 // The entry should have FrameNavigationEntries for the subframes. |
| 3302 if (SiteIsolationPolicy::UseSubframeNavigationEntries()) { |
| 3303 ASSERT_EQ(1U, entry->root_node()->children.size()); |
| 3304 EXPECT_EQ(blank_url, entry->root_node()->children[0]->frame_entry->url()); |
| 3305 EXPECT_EQ(inner_url, |
| 3306 entry->root_node()->children[0]->children[0]->frame_entry->url()); |
| 3307 } |
| 3308 |
| 3309 // With injected about:blank iframes, we never restore form values from |
| 3310 // PageState. |
| 3311 std::string form_value = "fail"; |
| 3312 EXPECT_TRUE( |
| 3313 ExecuteScriptAndExtractString(root->child_at(0)->child_at(0), |
| 3314 "window.domAutomationController.send(" |
| 3315 "document.getElementById('itext').value);", |
| 3316 &form_value)); |
| 3317 EXPECT_EQ("", form_value); |
| 3318 } |
| 3319 |
| 3320 // Verify that we correctly load a nested iframe created by an injected iframe |
| 3321 // srcdoc if we go back and recreate the frames. Also verify that form values |
| 3322 // are correctly restored for forms within srcdoc frames, unlike forms injected |
| 3323 // into about:blank pages (as tested in |
| 3324 // FrameNavigationEntry_RecreatedInjectedBlankSubframe). |
| 3325 // |
| 3326 // This test worked before and after the fix for https://crbug.com/657896, but |
| 3327 // it failed with a preliminary version of the fix. |
| 3328 IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest, |
| 3329 FrameNavigationEntry_RecreatedInjectedSrcdocSubframe) { |
| 3330 // 1. Start on a page that injects a nested iframe srcdoc which contains a |
| 3331 // nested iframe. |
| 3332 GURL main_url(embedded_test_server()->GetURL( |
| 3333 "/navigation_controller/inject_iframe_srcdoc_with_nested_frame.html")); |
| 3334 GURL blank_url(url::kAboutBlankURL); |
| 3335 GURL inner_url( |
| 3336 embedded_test_server()->GetURL("/navigation_controller/form.html")); |
| 3337 EXPECT_TRUE(NavigateToURL(shell(), main_url)); |
| 3338 NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>( |
| 3339 shell()->web_contents()->GetController()); |
| 3340 FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents()) |
| 3341 ->GetFrameTree() |
| 3342 ->root(); |
| 3343 |
| 3344 // Verify that the inner iframe was able to load. |
| 3345 ASSERT_EQ(1U, root->child_count()); |
| 3346 ASSERT_EQ(1U, root->child_at(0)->child_count()); |
| 3347 ASSERT_EQ(0U, root->child_at(0)->child_at(0)->child_count()); |
| 3348 EXPECT_EQ(main_url, root->current_url()); |
| 3349 EXPECT_EQ(blank_url, root->child_at(0)->current_url()); |
| 3350 EXPECT_EQ(inner_url, root->child_at(0)->child_at(0)->current_url()); |
| 3351 |
| 3352 EXPECT_EQ(1, controller.GetEntryCount()); |
| 3353 EXPECT_EQ(0, controller.GetLastCommittedEntryIndex()); |
| 3354 NavigationEntryImpl* entry = controller.GetLastCommittedEntry(); |
| 3355 |
| 3356 // The entry should have FrameNavigationEntries for the subframes. |
| 3357 if (SiteIsolationPolicy::UseSubframeNavigationEntries()) { |
| 3358 ASSERT_EQ(1U, entry->root_node()->children.size()); |
| 3359 EXPECT_EQ(blank_url, entry->root_node()->children[0]->frame_entry->url()); |
| 3360 EXPECT_EQ(inner_url, |
| 3361 entry->root_node()->children[0]->children[0]->frame_entry->url()); |
| 3362 } |
| 3363 |
| 3364 // Set a value in the form which will be stored in the PageState. |
| 3365 EXPECT_TRUE( |
| 3366 ExecuteScript(root->child_at(0)->child_at(0), |
| 3367 "document.getElementById('itext').value = 'modified';")); |
| 3368 |
| 3369 // 2. Navigate the main frame same-site, destroying the subframes. |
| 3370 GURL main_url_2(embedded_test_server()->GetURL( |
| 3371 "/navigation_controller/simple_page_1.html")); |
| 3372 EXPECT_TRUE(NavigateToURL(shell(), main_url_2)); |
| 3373 ASSERT_EQ(0U, root->child_count()); |
| 3374 EXPECT_EQ(main_url_2, root->current_url()); |
| 3375 |
| 3376 EXPECT_EQ(2, controller.GetEntryCount()); |
| 3377 EXPECT_EQ(1, controller.GetLastCommittedEntryIndex()); |
| 3378 |
| 3379 // 3. Go back, recreating the subframes. |
| 3380 { |
| 3381 TestNavigationObserver back_load_observer(shell()->web_contents()); |
| 3382 controller.GoBack(); |
| 3383 back_load_observer.Wait(); |
| 3384 } |
| 3385 ASSERT_EQ(1U, root->child_count()); |
| 3386 // TODO(creis): This line is unexpectedly failing in PlzNavigate, so the test |
| 3387 // is disabled there for now. |
| 3388 ASSERT_EQ(1U, root->child_at(0)->child_count()); |
| 3389 ASSERT_EQ(0U, root->child_at(0)->child_at(0)->child_count()); |
| 3390 EXPECT_EQ(main_url, root->current_url()); |
| 3391 EXPECT_EQ(blank_url, root->child_at(0)->current_url()); |
| 3392 |
| 3393 // Verify that the inner iframe went to the correct URL. |
| 3394 EXPECT_EQ(inner_url, root->child_at(0)->child_at(0)->current_url()); |
| 3395 |
| 3396 EXPECT_EQ(2, controller.GetEntryCount()); |
| 3397 EXPECT_EQ(0, controller.GetLastCommittedEntryIndex()); |
| 3398 EXPECT_EQ(entry, controller.GetLastCommittedEntry()); |
| 3399 |
| 3400 // The entry should have FrameNavigationEntries for the subframes. |
| 3401 if (SiteIsolationPolicy::UseSubframeNavigationEntries()) { |
| 3402 ASSERT_EQ(1U, entry->root_node()->children.size()); |
| 3403 EXPECT_EQ(blank_url, entry->root_node()->children[0]->frame_entry->url()); |
| 3404 EXPECT_EQ(inner_url, |
| 3405 entry->root_node()->children[0]->children[0]->frame_entry->url()); |
| 3406 } |
| 3407 |
| 3408 // With injected iframe srcdoc pages, we do restore form values from |
| 3409 // PageState. |
| 3410 std::string form_value; |
| 3411 EXPECT_TRUE( |
| 3412 ExecuteScriptAndExtractString(root->child_at(0)->child_at(0), |
| 3413 "window.domAutomationController.send(" |
| 3414 "document.getElementById('itext').value);", |
| 3415 &form_value)); |
| 3416 EXPECT_EQ("modified", form_value); |
| 3417 } |
| 3418 |
3237 // Ensure we don't crash if an onload handler removes an about:blank frame after | 3419 // Ensure we don't crash if an onload handler removes an about:blank frame after |
3238 // recreating it on a back/forward. See https://crbug.com/638166. | 3420 // recreating it on a back/forward. See https://crbug.com/638166. |
3239 IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest, | 3421 IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest, |
3240 FrameNavigationEntry_RemoveRecreatedBlankSubframe) { | 3422 FrameNavigationEntry_RemoveRecreatedBlankSubframe) { |
3241 // 1. Start on a page that removes its about:blank iframe during onload. | 3423 // 1. Start on a page that removes its about:blank iframe during onload. |
3242 GURL main_url(embedded_test_server()->GetURL( | 3424 GURL main_url(embedded_test_server()->GetURL( |
3243 "/navigation_controller/remove_blank_iframe_on_load.html")); | 3425 "/navigation_controller/remove_blank_iframe_on_load.html")); |
3244 GURL blank_url(url::kAboutBlankURL); | 3426 GURL blank_url(url::kAboutBlankURL); |
3245 EXPECT_TRUE(NavigateToURL(shell(), main_url)); | 3427 EXPECT_TRUE(NavigateToURL(shell(), main_url)); |
3246 NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>( | 3428 NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>( |
(...skipping 2253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5500 subframe_delayer.WaitForNavigationFinished(); | 5682 subframe_delayer.WaitForNavigationFinished(); |
5501 EXPECT_EQ(1, controller.GetLastCommittedEntryIndex()); | 5683 EXPECT_EQ(1, controller.GetLastCommittedEntryIndex()); |
5502 EXPECT_EQ(url_a, root->current_url()); | 5684 EXPECT_EQ(url_a, root->current_url()); |
5503 EXPECT_EQ(frame_url_a2, root->child_at(0)->current_url()); | 5685 EXPECT_EQ(frame_url_a2, root->child_at(0)->current_url()); |
5504 | 5686 |
5505 // Let the main frame commit. | 5687 // Let the main frame commit. |
5506 mainframe_delayer.WaitForNavigationFinished(); | 5688 mainframe_delayer.WaitForNavigationFinished(); |
5507 EXPECT_TRUE(WaitForLoadStop(shell()->web_contents())); | 5689 EXPECT_TRUE(WaitForLoadStop(shell()->web_contents())); |
5508 EXPECT_EQ(2, controller.GetLastCommittedEntryIndex()); | 5690 EXPECT_EQ(2, controller.GetLastCommittedEntryIndex()); |
5509 EXPECT_EQ(url_b, root->current_url()); | 5691 EXPECT_EQ(url_b, root->current_url()); |
5510 | 5692 EXPECT_EQ(frame_url_b1, root->child_at(0)->current_url()); |
5511 // TODO(creis): The child's current_url should be about:blank, but we're not | |
5512 // currently getting a commit in this case. For now, we'll lack a commit for | |
5513 // this frame, similar to the slow URL case. See https://crbug.com/626416. | |
5514 if (SiteIsolationPolicy::UseSubframeNavigationEntries()) | |
5515 EXPECT_TRUE(root->child_at(0)->current_url().is_empty()); | |
5516 else | |
5517 EXPECT_EQ(frame_url_b1, root->child_at(0)->current_url()); | |
5518 | 5693 |
5519 // Check the PageState of the previous entry to ensure it isn't corrupted. | 5694 // Check the PageState of the previous entry to ensure it isn't corrupted. |
5520 NavigationEntry* entry = controller.GetEntryAtIndex(1); | 5695 NavigationEntry* entry = controller.GetEntryAtIndex(1); |
5521 EXPECT_EQ(url_a, entry->GetURL()); | 5696 EXPECT_EQ(url_a, entry->GetURL()); |
5522 ExplodedPageState exploded_state; | 5697 ExplodedPageState exploded_state; |
5523 EXPECT_TRUE( | 5698 EXPECT_TRUE( |
5524 DecodePageState(entry->GetPageState().ToEncodedData(), &exploded_state)); | 5699 DecodePageState(entry->GetPageState().ToEncodedData(), &exploded_state)); |
5525 EXPECT_EQ(url_a, GURL(exploded_state.top.url_string.string())); | 5700 EXPECT_EQ(url_a, GURL(exploded_state.top.url_string.string())); |
5526 EXPECT_EQ(frame_url_a2, | 5701 EXPECT_EQ(frame_url_a2, |
5527 GURL(exploded_state.top.children.at(0).url_string.string())); | 5702 GURL(exploded_state.top.children.at(0).url_string.string())); |
(...skipping 1022 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6550 histogram.ExpectTotalCount(kReloadToReloadMetricName, 4); | 6725 histogram.ExpectTotalCount(kReloadToReloadMetricName, 4); |
6551 histogram.ExpectTotalCount(kReloadMainResourceToReloadMetricName, 3); | 6726 histogram.ExpectTotalCount(kReloadMainResourceToReloadMetricName, 3); |
6552 | 6727 |
6553 controller.ReloadToRefreshContent(false); | 6728 controller.ReloadToRefreshContent(false); |
6554 EXPECT_TRUE(WaitForLoadStop(shell()->web_contents())); | 6729 EXPECT_TRUE(WaitForLoadStop(shell()->web_contents())); |
6555 histogram.ExpectTotalCount(kReloadToReloadMetricName, 4); | 6730 histogram.ExpectTotalCount(kReloadToReloadMetricName, 4); |
6556 histogram.ExpectTotalCount(kReloadMainResourceToReloadMetricName, 3); | 6731 histogram.ExpectTotalCount(kReloadMainResourceToReloadMetricName, 3); |
6557 } | 6732 } |
6558 | 6733 |
6559 } // namespace content | 6734 } // namespace content |
OLD | NEW |