| Index: content/browser/frame_host/navigation_controller_impl_browsertest.cc
|
| diff --git a/content/browser/frame_host/navigation_controller_impl_browsertest.cc b/content/browser/frame_host/navigation_controller_impl_browsertest.cc
|
| index 7a89b26c1d1e5a179453f9ccdeabc4965d0ca207..01d1c3488a02babb4c2a1ae7e554338ee910d9dd 100644
|
| --- a/content/browser/frame_host/navigation_controller_impl_browsertest.cc
|
| +++ b/content/browser/frame_host/navigation_controller_impl_browsertest.cc
|
| @@ -1070,4 +1070,96 @@ IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest,
|
| ResourceDispatcherHost::Get()->SetDelegate(nullptr);
|
| }
|
|
|
| +namespace {
|
| +
|
| +class FailureWatcher : public WebContentsObserver {
|
| + public:
|
| + // Observes failure for the specified |node|.
|
| + explicit FailureWatcher(FrameTreeNode* node)
|
| + : WebContentsObserver(
|
| + node->current_frame_host()->delegate()->GetAsWebContents()),
|
| + frame_tree_node_id_(node->frame_tree_node_id()),
|
| + message_loop_runner_(new MessageLoopRunner) {}
|
| +
|
| + void Wait() {
|
| + message_loop_runner_->Run();
|
| + }
|
| +
|
| + private:
|
| + void DidFailLoad(RenderFrameHost* render_frame_host,
|
| + const GURL& validated_url,
|
| + int error_code,
|
| + const base::string16& error_description) override {
|
| + RenderFrameHostImpl* rfh =
|
| + static_cast<RenderFrameHostImpl*>(render_frame_host);
|
| + if (rfh->frame_tree_node()->frame_tree_node_id() != frame_tree_node_id_)
|
| + return;
|
| +
|
| + message_loop_runner_->Quit();
|
| + }
|
| +
|
| + void DidFailProvisionalLoad(
|
| + RenderFrameHost* render_frame_host,
|
| + const GURL& validated_url,
|
| + int error_code,
|
| + const base::string16& error_description) override {
|
| + RenderFrameHostImpl* rfh =
|
| + static_cast<RenderFrameHostImpl*>(render_frame_host);
|
| + if (rfh->frame_tree_node()->frame_tree_node_id() != frame_tree_node_id_)
|
| + return;
|
| +
|
| + message_loop_runner_->Quit();
|
| + }
|
| +
|
| + // The id of the FrameTreeNode whose navigations to observe.
|
| + int frame_tree_node_id_;
|
| +
|
| + // The MessageLoopRunner used to spin the message loop.
|
| + scoped_refptr<MessageLoopRunner> message_loop_runner_;
|
| +};
|
| +
|
| +} // namespace
|
| +
|
| +IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest,
|
| + StopCausesFailureDespiteJavaScriptURL) {
|
| + NavigationControllerImpl& controller =
|
| + static_cast<NavigationControllerImpl&>(
|
| + shell()->web_contents()->GetController());
|
| +
|
| + FrameTreeNode* root =
|
| + static_cast<WebContentsImpl*>(shell()->web_contents())->
|
| + GetFrameTree()->root();
|
| +
|
| + // Start with a normal page.
|
| + GURL url1(embedded_test_server()->GetURL(
|
| + "/navigation_controller/simple_page_1.html"));
|
| + EXPECT_TRUE(NavigateToURL(shell(), url1));
|
| +
|
| + // Have the user decide to go to a different page which is very slow.
|
| + StallDelegate stall_delegate;
|
| + ResourceDispatcherHost::Get()->SetDelegate(&stall_delegate);
|
| + GURL url2(embedded_test_server()->GetURL(
|
| + "/navigation_controller/simple_page_2.html"));
|
| + controller.LoadURL(url2, Referrer(), ui::PAGE_TRANSITION_LINK, std::string());
|
| +
|
| + // That should be the pending entry.
|
| + NavigationEntryImpl* entry = controller.GetPendingEntry();
|
| + ASSERT_NE(nullptr, entry);
|
| + EXPECT_EQ(url2, entry->GetURL());
|
| +
|
| + // Loading a JavaScript URL shouldn't affect the ability to stop.
|
| + {
|
| + FailureWatcher watcher(root);
|
| + GURL js("javascript:(function(){})()");
|
| + controller.LoadURL(js, Referrer(), ui::PAGE_TRANSITION_LINK, std::string());
|
| + // This LoadURL ends up purging the pending entry, which is why this is
|
| + // tricky.
|
| + EXPECT_EQ(nullptr, controller.GetPendingEntry());
|
| + shell()->web_contents()->Stop();
|
| + watcher.Wait();
|
| + }
|
| +
|
| + ResourceDispatcherHost::Get()->SetDelegate(nullptr);
|
| +}
|
| +
|
| } // namespace content
|
|
|