1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "content/browser/frame_host/render_frame_host_impl.h"
6 #include "content/browser/web_contents/web_contents_impl.h"
7 #include "content/public/browser/render_frame_host.h"
8 #include "content/public/browser/web_contents.h"
9 #include "content/public/common/content_client.h"
10 #include "content/public/test/content_browser_test.h"
11 #include "content/public/test/content_browser_test_utils.h"
12 #include "content/public/test/test_utils.h"
13 #include "content/shell/browser/shell.h"
14 #include "content/test/test_content_browser_client.h"
20 RenderFrameHostImpl
* ToRFHI(RenderFrameHost
* render_frame_host
) {
21 return static_cast<RenderFrameHostImpl
*>(render_frame_host
);
24 // Implementation of ContentBrowserClient that overrides
25 // OverridePageVisibilityState() and allows consumers to set a value.
26 class PrerenderTestContentBrowserClient
: public TestContentBrowserClient
{
28 PrerenderTestContentBrowserClient()
29 : override_enabled_(false),
30 visibility_override_(blink::WebPageVisibilityStateVisible
)
32 ~PrerenderTestContentBrowserClient() override
{}
34 void EnableVisibilityOverride(
35 blink::WebPageVisibilityState visibility_override
) {
36 override_enabled_
= true;
37 visibility_override_
= visibility_override
;
40 void OverridePageVisibilityState(
41 RenderFrameHost
* render_frame_host
,
42 blink::WebPageVisibilityState
* visibility_state
) override
{
43 if (override_enabled_
)
44 *visibility_state
= visibility_override_
;
48 bool override_enabled_
;
49 blink::WebPageVisibilityState visibility_override_
;
51 DISALLOW_COPY_AND_ASSIGN(PrerenderTestContentBrowserClient
);
54 } // anonymous namespace
56 using RenderFrameHostImplBrowserTest
= ContentBrowserTest
;
58 // Test that when creating a new window, the main frame is correctly focused.
59 IN_PROC_BROWSER_TEST_F(RenderFrameHostImplBrowserTest
, IsFocused_AtLoad
) {
61 NavigateToURL(shell(), GetTestUrl("render_frame_host", "focus.html")));
63 // The main frame should be focused.
64 WebContents
* web_contents
= shell()->web_contents();
65 EXPECT_TRUE(ToRFHI(web_contents
->GetMainFrame())->IsFocused());
68 // Test that if the content changes the focused frame, it is correctly exposed.
69 // Disabled to to flaky failures: crbug.com/452631
70 IN_PROC_BROWSER_TEST_F(RenderFrameHostImplBrowserTest
,
71 DISABLED_IsFocused_Change
) {
73 NavigateToURL(shell(), GetTestUrl("render_frame_host", "focus.html")));
75 WebContents
* web_contents
= shell()->web_contents();
77 std::string frames
[2] = { "frame1", "frame2" };
78 for (const std::string
& frame
: frames
) {
79 ExecuteScriptAndGetValue(
80 web_contents
->GetMainFrame(), "focus" + frame
+ "()");
82 // The main frame is not the focused frame in the frame tree but the main
83 // frame is focused per RFHI rules because one of its descendant is focused.
84 EXPECT_NE(web_contents
->GetMainFrame(), web_contents
->GetFocusedFrame());
85 EXPECT_TRUE(ToRFHI(web_contents
->GetFocusedFrame())->IsFocused());
86 EXPECT_TRUE(ToRFHI(web_contents
->GetMainFrame())->IsFocused());
87 EXPECT_EQ(frame
, web_contents
->GetFocusedFrame()->GetFrameName());
91 // Tests focus behavior when the focused frame is removed from the frame tree.
92 IN_PROC_BROWSER_TEST_F(RenderFrameHostImplBrowserTest
, RemoveFocusedFrame
) {
94 NavigateToURL(shell(), GetTestUrl("render_frame_host", "focus.html")));
96 WebContentsImpl
* web_contents
=
97 static_cast<WebContentsImpl
*>(shell()->web_contents());
99 ExecuteScriptAndGetValue(web_contents
->GetMainFrame(), "focusframe4()");
101 // TODO(nick,mlamouri): Add calls to RFHI::IsFocused here once they're not
102 // flaky. See http://crbug.com/452631, http://crbug.com/464033, etc.
103 EXPECT_NE(web_contents
->GetMainFrame(), web_contents
->GetFocusedFrame());
104 EXPECT_EQ("frame4", web_contents
->GetFocusedFrame()->GetFrameName());
106 web_contents
->GetFocusedFrame()->GetParent()->GetFrameName());
107 EXPECT_NE(-1, web_contents
->GetFrameTree()->focused_frame_tree_node_id_
);
109 ExecuteScriptAndGetValue(web_contents
->GetMainFrame(), "detachframe(3)");
110 EXPECT_EQ(nullptr, web_contents
->GetFocusedFrame());
111 EXPECT_EQ(-1, web_contents
->GetFrameTree()->focused_frame_tree_node_id_
);
113 ExecuteScriptAndGetValue(web_contents
->GetMainFrame(), "focusframe2()");
114 EXPECT_NE(nullptr, web_contents
->GetFocusedFrame());
115 EXPECT_NE(web_contents
->GetMainFrame(), web_contents
->GetFocusedFrame());
116 EXPECT_NE(-1, web_contents
->GetFrameTree()->focused_frame_tree_node_id_
);
118 ExecuteScriptAndGetValue(web_contents
->GetMainFrame(), "detachframe(2)");
119 EXPECT_EQ(nullptr, web_contents
->GetFocusedFrame());
120 EXPECT_EQ(-1, web_contents
->GetFrameTree()->focused_frame_tree_node_id_
);
123 // Test that even if the frame is focused in the frame tree but its
124 // RenderWidgetHost is not focused, it is not considered as focused.
125 IN_PROC_BROWSER_TEST_F(RenderFrameHostImplBrowserTest
, IsFocused_Widget
) {
127 NavigateToURL(shell(), GetTestUrl("render_frame_host", "focus.html")));
128 WebContents
* web_contents
= shell()->web_contents();
130 // A second window is created and navigated. It takes the focus.
131 Shell
* new_shell
= CreateBrowser();
133 NavigateToURL(new_shell
, GetTestUrl("render_frame_host", "focus.html")));
134 EXPECT_TRUE(ToRFHI(new_shell
->web_contents()->GetMainFrame())->IsFocused());
136 // The first opened window is no longer focused. The main frame is still the
137 // focused frame in the frame tree but as far as RFH is concerned, the frame
139 EXPECT_EQ(web_contents
->GetMainFrame(), web_contents
->GetFocusedFrame());
141 #if defined(OS_MACOSX)
142 EXPECT_TRUE(ToRFHI(web_contents
->GetMainFrame())->IsFocused());
144 EXPECT_FALSE(ToRFHI(web_contents
->GetMainFrame())->IsFocused());
148 // Test that a frame is visible/hidden depending on its WebContents visibility
150 // Flaky on Mac. http://crbug.com/467670
151 #if defined(OS_MACOSX)
152 #define MAYBE_GetVisibilityState_Basic DISABLED_GetVisibilityState_Basic
154 #define MAYBE_GetVisibilityState_Basic GetVisibilityState_Basic
156 IN_PROC_BROWSER_TEST_F(RenderFrameHostImplBrowserTest
,
157 MAYBE_GetVisibilityState_Basic
) {
158 EXPECT_TRUE(NavigateToURL(shell(), GURL("data:text/html,foo")));
159 WebContents
* web_contents
= shell()->web_contents();
161 EXPECT_EQ(blink::WebPageVisibilityStateVisible
,
162 web_contents
->GetMainFrame()->GetVisibilityState());
164 web_contents
->WasHidden();
165 EXPECT_EQ(blink::WebPageVisibilityStateHidden
,
166 web_contents
->GetMainFrame()->GetVisibilityState());
169 // Test that a frame visibility can be overridden by the ContentBrowserClient.
170 IN_PROC_BROWSER_TEST_F(RenderFrameHostImplBrowserTest
,
171 GetVisibilityState_Override
) {
172 EXPECT_TRUE(NavigateToURL(shell(), GURL("data:text/html,foo")));
173 WebContents
* web_contents
= shell()->web_contents();
175 PrerenderTestContentBrowserClient new_client
;
176 ContentBrowserClient
* old_client
= SetBrowserClientForTesting(&new_client
);
178 EXPECT_EQ(blink::WebPageVisibilityStateVisible
,
179 web_contents
->GetMainFrame()->GetVisibilityState());
181 new_client
.EnableVisibilityOverride(blink::WebPageVisibilityStatePrerender
);
182 EXPECT_EQ(blink::WebPageVisibilityStatePrerender
,
183 web_contents
->GetMainFrame()->GetVisibilityState());
185 SetBrowserClientForTesting(old_client
);
188 } // namespace content