[M120][Tizen][Onscreen] Fix build errors for TV profile
[platform/framework/web/chromium-efl.git] / chrome / browser / chrome_render_widget_host_browsertests.cc
1 // Copyright 2020 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "base/command_line.h"
6 #include "base/run_loop.h"
7 #include "base/strings/stringprintf.h"
8 #include "base/test/test_timeouts.h"
9 #include "build/build_config.h"
10 #include "chrome/browser/ui/browser.h"
11 #include "chrome/browser/ui/browser_window.h"
12 #include "chrome/browser/ui/location_bar/location_bar.h"
13 #include "chrome/browser/ui/tabs/tab_strip_model.h"
14 #include "chrome/test/base/in_process_browser_test.h"
15 #include "chrome/test/base/interactive_test_utils.h"
16 #include "chrome/test/base/ui_test_utils.h"
17 #include "components/omnibox/browser/omnibox_view.h"
18 #include "content/public/browser/browser_thread.h"
19 #include "content/public/browser/focused_node_details.h"
20 #include "content/public/browser/render_widget_host_view.h"
21 #include "content/public/browser/web_contents.h"
22 #include "content/public/test/browser_test.h"
23 #include "content/public/test/browser_test_utils.h"
24 #include "content/public/test/content_browser_test.h"
25 #include "content/public/test/content_browser_test_utils.h"
26 #include "content/public/test/test_utils.h"
27 #include "net/dns/mock_host_resolver.h"
28 #include "net/test/embedded_test_server/embedded_test_server.h"
29 #include "url/gurl.h"
30
31 class ActiveRenderWidgetHostBrowserTest : public InProcessBrowserTest {
32  public:
33   ActiveRenderWidgetHostBrowserTest() = default;
34
35   ActiveRenderWidgetHostBrowserTest(const ActiveRenderWidgetHostBrowserTest&) =
36       delete;
37   ActiveRenderWidgetHostBrowserTest& operator=(
38       const ActiveRenderWidgetHostBrowserTest&) = delete;
39
40   ~ActiveRenderWidgetHostBrowserTest() override = default;
41
42   void SetUpCommandLine(base::CommandLine* command_line) override {
43     content::IsolateAllSitesForTesting(command_line);
44   }
45
46   void SetUpOnMainThread() override {
47     host_resolver()->AddRule("*", "127.0.0.1");
48
49     // Add content/test/data for cross_site_iframe_factory.html
50     embedded_test_server()->ServeFilesFromSourceDirectory("content/test/data");
51
52     ASSERT_TRUE(embedded_test_server()->Start());
53   }
54 };
55
56 IN_PROC_BROWSER_TEST_F(ActiveRenderWidgetHostBrowserTest,
57                        DocumentIsActiveAndFocused) {
58   GURL main_url(embedded_test_server()->GetURL(
59       "a.com", "/cross_site_iframe_factory.html?a(b(c),d)"));
60
61   //  Site A ------------ proxies for B C D
62   //    |--Site B ------- proxies for A C D
63   //    |    +--Site C -- proxies for A B D
64   //    +--Site D ------- proxies for A B C
65   // Where A = http://a.com/
66   //       B = http://b.com/
67   //       C = http://c.com/
68   //       D = http://d.com/
69   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), main_url));
70
71   content::WebContents* web_contents =
72       browser()->tab_strip_model()->GetActiveWebContents();
73   content::RenderFrameHost* main_frame_a = web_contents->GetPrimaryMainFrame();
74   content::RenderFrameHost* child_frame_b = ChildFrameAt(main_frame_a, 0);
75   ASSERT_NE(nullptr, child_frame_b);
76   content::RenderFrameHost* child_frame_d = ChildFrameAt(main_frame_a, 1);
77   ASSERT_NE(nullptr, child_frame_d);
78   content::RenderFrameHost* child_frame_c = ChildFrameAt(child_frame_b, 0);
79   ASSERT_NE(nullptr, child_frame_c);
80
81   EXPECT_NE(main_frame_a->GetSiteInstance(), child_frame_b->GetSiteInstance());
82   EXPECT_NE(main_frame_a->GetSiteInstance(), child_frame_d->GetSiteInstance());
83   EXPECT_NE(child_frame_b->GetSiteInstance(), child_frame_c->GetSiteInstance());
84
85   // Helper function to check document.hasFocus() for a given frame.
86   // hasFocus internally calls FocusController::IsDocumentFocused which
87   // return true only iff document is  active and focused.
88   auto document_is_active_and_focused =
89       [](content::RenderFrameHost* rfh) -> bool {
90     return EvalJs(rfh, "document.hasFocus()").ExtractBool();
91   };
92
93   // Helper function to check a property of document.activeElement in the
94   // specified frame.
95   auto verify_active_element_property = [](content::RenderFrameHost* rfh,
96                                            const std::string& property,
97                                            const std::string& expected_value) {
98     std::string script = base::StringPrintf(
99         "document.activeElement.%s.toLowerCase();", property.c_str());
100     EXPECT_EQ(expected_value, EvalJs(rfh, script));
101   };
102
103   // The main_frame_a should have a focus to start with.
104   EXPECT_EQ(main_frame_a, web_contents->GetFocusedFrame());
105   EXPECT_TRUE(document_is_active_and_focused(main_frame_a));
106   EXPECT_FALSE(document_is_active_and_focused(child_frame_b));
107   EXPECT_FALSE(document_is_active_and_focused(child_frame_c));
108   EXPECT_FALSE(document_is_active_and_focused(child_frame_d));
109   verify_active_element_property(main_frame_a, "tagName", "body");
110
111   // After focusing child_frame_b, document.hasFocus() should return
112   // true for child_frame_b and all its ancestor frames.
113   EXPECT_TRUE(ExecJs(child_frame_b, "window.focus();"));
114   EXPECT_EQ(child_frame_b, web_contents->GetFocusedFrame());
115   EXPECT_TRUE(document_is_active_and_focused(main_frame_a));
116   EXPECT_TRUE(document_is_active_and_focused(child_frame_b));
117   EXPECT_FALSE(document_is_active_and_focused(child_frame_c));
118   EXPECT_FALSE(document_is_active_and_focused(child_frame_d));
119   verify_active_element_property(main_frame_a, "tagName", "iframe");
120   verify_active_element_property(main_frame_a, "src",
121                                  child_frame_b->GetLastCommittedURL().spec());
122
123   // After focusing child_frame_c, document.hasFocus() should return
124   // true for child_frame_c and all its ancestor frames.
125   EXPECT_TRUE(ExecJs(child_frame_c, "window.focus();"));
126   EXPECT_EQ(child_frame_c, web_contents->GetFocusedFrame());
127   EXPECT_TRUE(document_is_active_and_focused(main_frame_a));
128   EXPECT_TRUE(document_is_active_and_focused(child_frame_b));
129   EXPECT_TRUE(document_is_active_and_focused(child_frame_c));
130   EXPECT_FALSE(document_is_active_and_focused(child_frame_d));
131   verify_active_element_property(main_frame_a, "tagName", "iframe");
132   // Check document.activeElement in main_frame_a.  It should still
133   // point to <iframe> for the b.com frame, since Blink computes the
134   // focused iframe element by walking the parent chain of the focused
135   // frame until it hits the current frame.  This logic should still
136   // work with remote frames.
137   verify_active_element_property(main_frame_a, "src",
138                                  child_frame_b->GetLastCommittedURL().spec());
139
140   // After focusing child_frame_d, document.hasFocus() should return
141   // true for child_frame_d and all its ancestor frames.
142   EXPECT_TRUE(ExecJs(child_frame_d, "window.focus();"));
143   EXPECT_EQ(child_frame_d, web_contents->GetFocusedFrame());
144   EXPECT_TRUE(document_is_active_and_focused(main_frame_a));
145   EXPECT_FALSE(document_is_active_and_focused(child_frame_b));
146   EXPECT_FALSE(document_is_active_and_focused(child_frame_c));
147   EXPECT_TRUE(document_is_active_and_focused(child_frame_d));
148   verify_active_element_property(main_frame_a, "tagName", "iframe");
149   verify_active_element_property(main_frame_a, "src",
150                                  child_frame_d->GetLastCommittedURL().spec());
151
152   // After focusing main_frame_a, document.hasFocus() should return
153   // true for main_frame_a and since it's a root of tree, all its
154   // descendants should return false. On the renderer side, both the
155   // 'active' and 'focus' states for blink::FocusController will be
156   // true.
157   EXPECT_TRUE(ExecJs(main_frame_a, "window.focus();"));
158   EXPECT_EQ(main_frame_a, web_contents->GetFocusedFrame());
159   EXPECT_TRUE(document_is_active_and_focused(main_frame_a));
160   EXPECT_FALSE(document_is_active_and_focused(child_frame_b));
161   EXPECT_FALSE(document_is_active_and_focused(child_frame_c));
162   EXPECT_FALSE(document_is_active_and_focused(child_frame_d));
163   verify_active_element_property(main_frame_a, "tagName", "body");
164
165   // Focus the URL bar.
166   OmniboxView* omnibox =
167       browser()->window()->GetLocationBar()->GetOmniboxView();
168   // Give the omnibox focus.
169   omnibox->SetFocus(/*is_user_initiated=*/true);
170   base::RunLoop().RunUntilIdle();
171   EXPECT_EQ(main_frame_a, web_contents->GetFocusedFrame());
172
173   // `omnibox->SetFocus()` should call blur event on main_frame_a and
174   // deactivate the active render widget, but on Mac calling
175   // `omnibox->SetFocus()` function doesn't invoke
176   // RWHI::SetActive(false). As a result, `blink::FocusController`'s
177   // 'active' state maintains the previous value of false.
178   //
179   // This table sums up `blink::FocusController`'s 'active' and 'focus'
180   // states on different platforms after focusing the omnibox:
181   //
182   // |        | Linux |  Mac  | Windows |
183   // | active | false | true  | false   |
184   // | focus  | false | false | false   |
185   //
186   // Since `document.hasFocus()` only returns true iff the document is
187   // both active and focus, the test still expects
188   // `document.hasFocus()` to be false on all platforms.
189   //
190   // Note that there is no separate API to test active state of the
191   // document. Instead, Mac's active behavior is separately tested in
192   // `ActiveRenderWidgetHostBrowserTest.FocusOmniBox`.
193   EXPECT_FALSE(document_is_active_and_focused(main_frame_a));
194   EXPECT_FALSE(document_is_active_and_focused(child_frame_b));
195   EXPECT_FALSE(document_is_active_and_focused(child_frame_c));
196   EXPECT_FALSE(document_is_active_and_focused(child_frame_d));
197   // body tag is active by default.
198   verify_active_element_property(main_frame_a, "tagName", "body");
199   verify_active_element_property(child_frame_b, "tagName", "body");
200   verify_active_element_property(child_frame_c, "tagName", "body");
201   verify_active_element_property(child_frame_d, "tagName", "body");
202 }
203
204 // This test verifies that on Mac, moving the focus from webcontents to Omnibox
205 // doesn't change the 'active' state and old value of the active state is
206 // retained.
207 //
208 // FakeFrameWidget has Optional<bool> 'active' state which is
209 // uninitialised at the beginning. omnibox->SetFocus() invokes
210 // RWHI::SetActive(false) for webcontents and there is a IPC call to
211 // renderer which changes 'active' state to false.
212 //
213 // On Mac, calling omnibox->SetFocus function doesn't invoke
214 // RWHI::SetActive(false). Hence there is no IPC call to renderer and
215 // 'active' state maintains old value.
216 IN_PROC_BROWSER_TEST_F(ActiveRenderWidgetHostBrowserTest, FocusOmniBox) {
217   GURL main_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
218   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), main_url));
219
220   content::WebContents* web_contents =
221       browser()->tab_strip_model()->GetActiveWebContents();
222
223   content::RenderFrameHost* main_frame = web_contents->GetPrimaryMainFrame();
224   EXPECT_EQ(main_frame, web_contents->GetFocusedFrame());
225
226   mojo::PendingAssociatedReceiver<blink::mojom::FrameWidget>
227       blink_frame_widget_receiver =
228           content::BindFakeFrameWidgetInterfaces(main_frame);
229   content::FakeFrameWidget fake_frame_widget(
230       std::move(blink_frame_widget_receiver));
231
232   // Main frame is already focused at this point and now focus URL bar.
233   OmniboxView* omnibox =
234       browser()->window()->GetLocationBar()->GetOmniboxView();
235   // Give the omnibox focus.
236   omnibox->SetFocus(/*is_user_initiated=*/true);
237
238   base::RunLoop().RunUntilIdle();
239 #if BUILDFLAG(IS_MAC)
240   // On MacOS, calling omnibox->SetFocus function doesn't invoke
241   // RWHI::SetActive. Hence there is no IPC call to renderer and
242   // FakeFrameWidget's 'active' state remains uninitialised.
243   EXPECT_EQ(fake_frame_widget.GetActive(), absl::nullopt);
244 #else
245   EXPECT_EQ(fake_frame_widget.GetActive(), false);
246 #endif
247 }