// Copyright 2015 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "content/browser/frame_host/render_frame_host_impl.h" #include "base/macros.h" #include "content/browser/web_contents/web_contents_impl.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/web_contents.h" #include "content/public/common/content_client.h" #include "content/public/test/content_browser_test.h" #include "content/public/test/content_browser_test_utils.h" #include "content/public/test/test_utils.h" #include "content/shell/browser/shell.h" #include "content/test/test_content_browser_client.h" namespace content { namespace { // Implementation of ContentBrowserClient that overrides // OverridePageVisibilityState() and allows consumers to set a value. class PrerenderTestContentBrowserClient : public TestContentBrowserClient { public: PrerenderTestContentBrowserClient() : override_enabled_(false), visibility_override_(blink::WebPageVisibilityStateVisible) {} ~PrerenderTestContentBrowserClient() override {} void EnableVisibilityOverride( blink::WebPageVisibilityState visibility_override) { override_enabled_ = true; visibility_override_ = visibility_override; } void OverridePageVisibilityState( RenderFrameHost* render_frame_host, blink::WebPageVisibilityState* visibility_state) override { if (override_enabled_) *visibility_state = visibility_override_; } private: bool override_enabled_; blink::WebPageVisibilityState visibility_override_; DISALLOW_COPY_AND_ASSIGN(PrerenderTestContentBrowserClient); }; } // anonymous namespace // TODO(mlamouri): part of these tests were removed because they were dependent // on an environment were focus is guaranteed. This is only for // interactive_ui_tests so these bits need to move there. // See https://crbug.com/491535 using RenderFrameHostImplBrowserTest = ContentBrowserTest; // Test that when creating a new window, the main frame is correctly focused. IN_PROC_BROWSER_TEST_F(RenderFrameHostImplBrowserTest, IsFocused_AtLoad) { EXPECT_TRUE( NavigateToURL(shell(), GetTestUrl("render_frame_host", "focus.html"))); // The main frame should be focused. WebContents* web_contents = shell()->web_contents(); EXPECT_EQ(web_contents->GetMainFrame(), web_contents->GetFocusedFrame()); } // Test that if the content changes the focused frame, it is correctly exposed. IN_PROC_BROWSER_TEST_F(RenderFrameHostImplBrowserTest, IsFocused_Change) { EXPECT_TRUE( NavigateToURL(shell(), GetTestUrl("render_frame_host", "focus.html"))); WebContents* web_contents = shell()->web_contents(); std::string frames[2] = { "frame1", "frame2" }; for (const std::string& frame : frames) { ExecuteScriptAndGetValue( web_contents->GetMainFrame(), "focus" + frame + "()"); // The main frame is not the focused frame in the frame tree but the main // frame is focused per RFHI rules because one of its descendant is focused. // TODO(mlamouri): we should check the frame focus state per RFHI, see the // general comment at the beginning of this test file. EXPECT_NE(web_contents->GetMainFrame(), web_contents->GetFocusedFrame()); EXPECT_EQ(frame, web_contents->GetFocusedFrame()->GetFrameName()); } } // Tests focus behavior when the focused frame is removed from the frame tree. IN_PROC_BROWSER_TEST_F(RenderFrameHostImplBrowserTest, RemoveFocusedFrame) { EXPECT_TRUE( NavigateToURL(shell(), GetTestUrl("render_frame_host", "focus.html"))); WebContentsImpl* web_contents = static_cast(shell()->web_contents()); ExecuteScriptAndGetValue(web_contents->GetMainFrame(), "focusframe4()"); EXPECT_NE(web_contents->GetMainFrame(), web_contents->GetFocusedFrame()); EXPECT_EQ("frame4", web_contents->GetFocusedFrame()->GetFrameName()); EXPECT_EQ("frame3", web_contents->GetFocusedFrame()->GetParent()->GetFrameName()); EXPECT_NE(-1, web_contents->GetFrameTree()->focused_frame_tree_node_id_); ExecuteScriptAndGetValue(web_contents->GetMainFrame(), "detachframe(3)"); EXPECT_EQ(nullptr, web_contents->GetFocusedFrame()); EXPECT_EQ(-1, web_contents->GetFrameTree()->focused_frame_tree_node_id_); ExecuteScriptAndGetValue(web_contents->GetMainFrame(), "focusframe2()"); EXPECT_NE(nullptr, web_contents->GetFocusedFrame()); EXPECT_NE(web_contents->GetMainFrame(), web_contents->GetFocusedFrame()); EXPECT_NE(-1, web_contents->GetFrameTree()->focused_frame_tree_node_id_); ExecuteScriptAndGetValue(web_contents->GetMainFrame(), "detachframe(2)"); EXPECT_EQ(nullptr, web_contents->GetFocusedFrame()); EXPECT_EQ(-1, web_contents->GetFrameTree()->focused_frame_tree_node_id_); } // Test that a frame is visible/hidden depending on its WebContents visibility // state. IN_PROC_BROWSER_TEST_F(RenderFrameHostImplBrowserTest, GetVisibilityState_Basic) { EXPECT_TRUE(NavigateToURL(shell(), GURL("data:text/html,foo"))); WebContents* web_contents = shell()->web_contents(); web_contents->WasShown(); EXPECT_EQ(blink::WebPageVisibilityStateVisible, web_contents->GetMainFrame()->GetVisibilityState()); web_contents->WasHidden(); EXPECT_EQ(blink::WebPageVisibilityStateHidden, web_contents->GetMainFrame()->GetVisibilityState()); } // Test that a frame visibility can be overridden by the ContentBrowserClient. IN_PROC_BROWSER_TEST_F(RenderFrameHostImplBrowserTest, GetVisibilityState_Override) { EXPECT_TRUE(NavigateToURL(shell(), GURL("data:text/html,foo"))); WebContents* web_contents = shell()->web_contents(); PrerenderTestContentBrowserClient new_client; ContentBrowserClient* old_client = SetBrowserClientForTesting(&new_client); web_contents->WasShown(); EXPECT_EQ(blink::WebPageVisibilityStateVisible, web_contents->GetMainFrame()->GetVisibilityState()); new_client.EnableVisibilityOverride(blink::WebPageVisibilityStatePrerender); EXPECT_EQ(blink::WebPageVisibilityStatePrerender, web_contents->GetMainFrame()->GetVisibilityState()); SetBrowserClientForTesting(old_client); } } // namespace content