Commit c08aec2f authored by Danyao Wang's avatar Danyao Wang Committed by Commit Bot

[Nav Experiment] Fix forward navigation after restore.

Navigation entries restored from a previously saved session are inserted
as restore_session.html?targetUrl=<target> URLs. The onload handler
redirects the page to the target URL when loaded. It turns out that
WKWebView does not fire onload handler in back/forward navigation
from an about:blank URL redirected from restore_session.html to another
restore_session.html. Most likely it's because WkWebView consiters this
a same-page navigation. This causes forward navigationt from a restored
app-specific URL to not load the web content.

This CL fixes it by forcing a reload in the WKWebView in this case.

Bug: 814790
Cq-Include-Trybots: master.tryserver.chromium.mac:ios-simulator-cronet;master.tryserver.chromium.mac:ios-simulator-full-configs
Change-Id: Ie6e7ada39388cedd7357a582308f0edc1397ef63
Reviewed-on: https://chromium-review.googlesource.com/974365Reviewed-by: default avatarEugene But <eugenebut@chromium.org>
Commit-Queue: Danyao Wang <danyao@chromium.org>
Cr-Commit-Position: refs/heads/master@{#545166}
parent 6f7e985a
......@@ -13,7 +13,6 @@
#include "ios/chrome/browser/ui/ui_util.h"
#include "ios/chrome/grit/ios_strings.h"
#import "ios/chrome/test/app/chrome_test_util.h"
#include "ios/chrome/test/app/navigation_test_util.h"
#import "ios/chrome/test/app/web_view_interaction_test_util.h"
#import "ios/chrome/test/earl_grey/chrome_earl_grey.h"
#import "ios/chrome/test/earl_grey/chrome_earl_grey_ui.h"
......
......@@ -7,6 +7,7 @@
#include "base/ios/ios_util.h"
#include "components/strings/grit/components_strings.h"
#import "ios/chrome/browser/ui/uikit_ui_util.h"
#import "ios/chrome/test/app/chrome_test_util.h"
#import "ios/chrome/test/app/web_view_interaction_test_util.h"
#import "ios/chrome/test/earl_grey/chrome_earl_grey.h"
#import "ios/chrome/test/earl_grey/chrome_matchers.h"
......@@ -22,6 +23,7 @@
using chrome_test_util::ContentSuggestionCollectionView;
using chrome_test_util::BackButton;
using chrome_test_util::ForwardButton;
using chrome_test_util::PurgeCachedWebViewPages;
using chrome_test_util::OmniboxText;
using chrome_test_util::TapWebViewElementWithId;
......@@ -594,4 +596,40 @@ std::unique_ptr<net::test_server::HttpResponse> WindowLocationHashHandlers(
assertWithMatcher:grey_notNil()];
}
// Tests that navigating forward from a WebUI URL works when resuming from
// session restore. This is a regression test for https://crbug.com/814790.
- (void)testRestoreHistoryToWebUIAndNavigateForward {
GREYAssertTrue(self.testServer->Start(), @"Test server failed to start.");
const GURL destinationURL = self.testServer->GetURL(kSimpleFileBasedTestURL);
[ChromeEarlGrey loadURL:GURL("chrome://version")];
[ChromeEarlGrey loadURL:destinationURL];
[ChromeEarlGrey goBack];
GREYAssert(PurgeCachedWebViewPages(), @"History not restored");
[ChromeEarlGrey waitForWebViewContainingText:"Revision"];
[[EarlGrey selectElementWithMatcher:OmniboxText("chrome://version")]
assertWithMatcher:grey_notNil()];
[ChromeEarlGrey goForward];
[ChromeEarlGrey waitForWebViewContainingText:"pony"];
[[EarlGrey selectElementWithMatcher:OmniboxText(destinationURL.GetContent())]
assertWithMatcher:grey_notNil()];
}
// Tests that navigating forward from NTP works when resuming from session
// restore. This is a regression test for https://crbug.com/814790.
- (void)testRestoreHistoryToNTPAndNavigateForward {
GREYAssertTrue(self.testServer->Start(), @"Test server failed to start.");
const GURL destinationURL = self.testServer->GetURL(kSimpleFileBasedTestURL);
[ChromeEarlGrey loadURL:destinationURL];
[ChromeEarlGrey goBack];
GREYAssert(PurgeCachedWebViewPages(), @"History not restored");
[ChromeEarlGrey goForward];
[ChromeEarlGrey waitForWebViewContainingText:"pony"];
[[EarlGrey selectElementWithMatcher:OmniboxText(destinationURL.GetContent())]
assertWithMatcher:grey_notNil()];
}
@end
......@@ -31,6 +31,7 @@
#endif
using chrome_test_util::OmniboxText;
using chrome_test_util::PurgeCachedWebViewPages;
namespace {
......@@ -45,19 +46,6 @@ const char kPage1Link[] = "page-1";
const char kPage2Link[] = "page-2";
const char kPage3Link[] = "page-3";
// Purges cached web view page, so the next time back navigation will not use
// cached page. Browsers don't have to use fresh version for back forward
// navigation for HTTP pages and may serve version from the cache even if
// Cache-Control response header says otherwise.
bool PurgeCachedWebViewPages() WARN_UNUSED_RESULT;
bool PurgeCachedWebViewPages() {
web::WebState* web_state = chrome_test_util::GetCurrentWebState();
web_state->SetWebUsageEnabled(false);
web_state->SetWebUsageEnabled(true);
web_state->GetNavigationManager()->LoadIfNecessary();
return chrome_test_util::WaitForPageToFinishLoading();
}
// Response provider which can be paused. When it is paused it buffers all
// requests and does not respond to them until |set_paused(false)| is called.
class PausableResponseProvider : public HtmlResponseProvider {
......
......@@ -97,6 +97,12 @@ void WaitForBreakpadQueue();
// Simulates launching Chrome from another application.
void OpenChromeFromExternalApp(const GURL& url);
// Purges cached web view page, so the next time back navigation will not use
// cached page. Browsers don't have to use fresh version for back forward
// navigation for HTTP pages and may serve version from the cache even if
// Cache-Control response header says otherwise.
bool PurgeCachedWebViewPages() WARN_UNUSED_RESULT;
} // namespace chrome_test_util
#endif // IOS_CHROME_TEST_APP_CHROME_TEST_UTIL_H_
......@@ -24,7 +24,9 @@
#import "ios/chrome/browser/ui/main/view_controller_swapping.h"
#import "ios/chrome/browser/ui/ntp/new_tab_page_controller.h"
#import "ios/chrome/browser/ui/tab_switcher/tab_switcher.h"
#include "ios/chrome/test/app/navigation_test_util.h"
#import "ios/chrome/test/app/tab_test_util.h"
#import "ios/web/public/navigation_manager.h"
#import "ios/web/public/test/native_controller_test_util.h"
#import "third_party/breakpad/breakpad/src/client/ios/BreakpadController.h"
......@@ -231,4 +233,12 @@ void OpenChromeFromExternalApp(const GURL& url) {
applicationDidBecomeActive:[UIApplication sharedApplication]];
}
bool PurgeCachedWebViewPages() {
web::WebState* web_state = chrome_test_util::GetCurrentWebState();
web_state->SetWebUsageEnabled(false);
web_state->SetWebUsageEnabled(true);
web_state->GetNavigationManager()->LoadIfNecessary();
return chrome_test_util::WaitForPageToFinishLoading();
}
} // namespace chrome_test_util
......@@ -4929,12 +4929,29 @@ registerLoadRequestForURL:(const GURL&)requestURL
}
- (void)webViewLoadingStateDidChange {
if ([_webView isLoading] || ![self isCurrentNavigationBackForward]) {
if (_webView.loading)
return;
}
GURL webViewURL = net::GURLWithNSURL([_webView URL]);
// When traversing history restored from a previous session, WKWebView does
// not fire 'pageshow', 'onload', 'popstate' or any of the
// WKNavigationDelegate callbacks for back/forward navigation from an
// app-specific URL to another entry. Loading state KVO is the only observable
// event in this scenario, so force a reload to trigger redirect from
// restore_session.html to the restored URL.
bool previousURLIsAppSpecific =
IsPlaceholderUrl(_documentURL) ||
web::GetWebClient()->IsAppSpecificURL(_documentURL);
if (web::GetWebClient()->IsSlimNavigationManagerEnabled() &&
web::IsRestoreSessionUrl(webViewURL) && previousURLIsAppSpecific) {
[_webView reload];
return;
}
if (![self isCurrentNavigationBackForward])
return;
// For failed navigations, WKWebView will sometimes revert to the previous URL
// before committing the current navigation or resetting the web view's
// |isLoading| property to NO. If this is the first navigation for the web
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment