Index: content/browser/frame_host/navigation_handle_impl_browsertest.cc |
diff --git a/content/browser/frame_host/navigation_handle_impl_browsertest.cc b/content/browser/frame_host/navigation_handle_impl_browsertest.cc |
index ba1c812e470e081ec81e0cf068c26b7b2637463b..6f00ff48ddea47eb3ec9c25d27754bbcab23a9e9 100644 |
--- a/content/browser/frame_host/navigation_handle_impl_browsertest.cc |
+++ b/content/browser/frame_host/navigation_handle_impl_browsertest.cc |
@@ -188,17 +188,18 @@ class TestNavigationThrottle : public NavigationThrottle { |
RequestContextType request_context_type_; |
}; |
-// Install a TestNavigationThrottle on all following requests and allows waiting |
-// for various NavigationThrottle related events. Waiting works only for the |
-// immediately next navigation. New instances are needed to wait for further |
-// navigations. |
+// Install a TestNavigationThrottle either on all following requests or on |
+// requests with an expected starting URL, and allows waiting for various |
+// NavigationThrottle related events. Waiting works only for the immediately |
+// next navigation. New instances are needed to wait for further navigations. |
class TestNavigationThrottleInstaller : public WebContentsObserver { |
public: |
TestNavigationThrottleInstaller( |
WebContents* web_contents, |
NavigationThrottle::ThrottleCheckResult will_start_result, |
NavigationThrottle::ThrottleCheckResult will_redirect_result, |
- NavigationThrottle::ThrottleCheckResult will_process_result) |
+ NavigationThrottle::ThrottleCheckResult will_process_result, |
+ GURL expected_start_url = GURL()) |
: WebContentsObserver(web_contents), |
will_start_result_(will_start_result), |
will_redirect_result_(will_redirect_result), |
@@ -206,7 +207,8 @@ class TestNavigationThrottleInstaller : public WebContentsObserver { |
will_start_called_(0), |
will_redirect_called_(0), |
will_process_called_(0), |
- navigation_throttle_(nullptr) {} |
+ navigation_throttle_(nullptr), |
+ expected_start_url_(expected_start_url) {} |
~TestNavigationThrottleInstaller() override{}; |
TestNavigationThrottle* navigation_throttle() { return navigation_throttle_; } |
@@ -241,6 +243,10 @@ class TestNavigationThrottleInstaller : public WebContentsObserver { |
private: |
void DidStartNavigation(NavigationHandle* handle) override { |
+ if (!expected_start_url_.is_empty() && |
+ handle->GetURL() != expected_start_url_) |
+ return; |
+ |
std::unique_ptr<NavigationThrottle> throttle(new TestNavigationThrottle( |
handle, will_start_result_, will_redirect_result_, will_process_result_, |
base::Bind(&TestNavigationThrottleInstaller::DidCallWillStartRequest, |
@@ -289,6 +295,7 @@ class TestNavigationThrottleInstaller : public WebContentsObserver { |
scoped_refptr<MessageLoopRunner> will_start_loop_runner_; |
scoped_refptr<MessageLoopRunner> will_redirect_loop_runner_; |
scoped_refptr<MessageLoopRunner> will_process_loop_runner_; |
+ GURL expected_start_url_; |
}; |
// Records all navigation start URLs from the WebContents. |
@@ -307,6 +314,17 @@ class NavigationStartUrlRecorder : public WebContentsObserver { |
std::vector<GURL> urls_; |
}; |
+bool IsChildFrameCollapsed(Shell* shell, const char* element_id) { |
+ const char kScript[] = |
+ "window.domAutomationController.send(" |
+ " document.getElementById(\"%s\").clientWidth" |
+ ");"; |
+ int client_width = 0; |
+ EXPECT_TRUE(ExecuteScriptAndExtractInt( |
+ shell, base::StringPrintf(kScript, element_id), &client_width)); |
+ return !client_width; |
+} |
+ |
} // namespace |
class NavigationHandleImplBrowserTest : public ContentBrowserTest { |
@@ -714,6 +732,72 @@ IN_PROC_BROWSER_TEST_F(NavigationHandleImplBrowserTest, ThrottleDefer) { |
GURL(embedded_test_server()->GetURL("bar.com", "/title2.html"))); |
} |
+// Ensure that a NavigationThrottle can block the navigation and collapse the |
+// frame owner both on request start as well as after a redirect. Plus, ensure |
+// that the frame is restored on the subsequent non-error-page navigation. |
+IN_PROC_BROWSER_TEST_F(NavigationHandleImplBrowserTest, |
+ ThrottleBlockAndCollapseAfterRedirect) { |
+ const char kChildFrameId[] = "child0"; |
+ GURL main_url(embedded_test_server()->GetURL( |
+ "a.com", "/frame_tree/page_with_one_frame.html")); |
+ GURL blocked_subframe_url(embedded_test_server()->GetURL( |
+ "a.com", "/cross-site/baz.com/title1.html")); |
+ GURL allowed_subframe_url(embedded_test_server()->GetURL( |
+ "a.com", "/cross-site/baz.com/title2.html")); |
+ GURL allowed_subframe_final_url( |
+ embedded_test_server()->GetURL("baz.com", "/title2.html")); |
+ |
+ for (const bool block_after_redirect : {true}) { |
+ SCOPED_TRACE(block_after_redirect ? "Blocking on WillRedirectRequest." |
+ : "Blocking on WilLStartRequest."); |
+ TestNavigationThrottleInstaller subframe_blocking_throttle_installer( |
+ shell()->web_contents(), |
+ block_after_redirect ? NavigationThrottle::PROCEED |
+ : NavigationThrottle::PROCEED, |
+ block_after_redirect ? NavigationThrottle::PROCEED |
+ : NavigationThrottle::PROCEED, |
+ NavigationThrottle::PROCEED, blocked_subframe_url); |
+ |
+ { |
+ SCOPED_TRACE("Initial navigation blocked on main frame load."); |
+ NavigationHandleObserver subframe_observer(shell()->web_contents(), |
+ blocked_subframe_url); |
+ |
+ ASSERT_TRUE(NavigateToURL(shell(), main_url)); |
+ EXPECT_TRUE(subframe_observer.has_committed()); |
+ EXPECT_TRUE(subframe_observer.is_error()); |
+ EXPECT_TRUE(IsChildFrameCollapsed(shell(), kChildFrameId)); |
+ } |
+ |
+ { |
+ SCOPED_TRACE("Subsequent subframe-only navigation is allowed."); |
+ NavigationHandleObserver subframe_observer(shell()->web_contents(), |
+ allowed_subframe_url); |
+ |
+ ASSERT_TRUE(NavigateIframeToURL(shell()->web_contents(), kChildFrameId, |
+ allowed_subframe_url)); |
+ EXPECT_TRUE(subframe_observer.has_committed()); |
+ EXPECT_FALSE(subframe_observer.is_error()); |
+ EXPECT_EQ(allowed_subframe_final_url, |
+ subframe_observer.last_committed_url()); |
+ EXPECT_FALSE(IsChildFrameCollapsed(shell(), kChildFrameId)); |
+ } |
+ |
+ { |
+ SCOPED_TRACE("Subsequent, subframe-only navigation is blocked."); |
+ NavigationHandleObserver subframe_observer(shell()->web_contents(), |
+ blocked_subframe_url); |
+ |
+ ASSERT_TRUE(NavigateIframeToURL(shell()->web_contents(), kChildFrameId, |
+ blocked_subframe_url)); |
+ |
+ EXPECT_TRUE(subframe_observer.has_committed()); |
+ EXPECT_TRUE(subframe_observer.is_error()); |
+ EXPECT_TRUE(IsChildFrameCollapsed(shell(), kChildFrameId)); |
+ } |
+ } |
+} |
+ |
// Checks that the RequestContextType value is properly set. |
IN_PROC_BROWSER_TEST_F(NavigationHandleImplBrowserTest, |
VerifyRequestContextTypeForFrameTree) { |