| // 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 "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<WebContentsImpl*>(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 |