blob: 6547788162e29da908890e6a50eea3035d1c3ede [file] [log] [blame]
// 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<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