| Index: chrome/browser/site_per_process_interactive_browsertest.cc
|
| diff --git a/chrome/browser/site_per_process_interactive_browsertest.cc b/chrome/browser/site_per_process_interactive_browsertest.cc
|
| index a468464766300c91f4808faa02a1666896d93878..17fdbe539cda066e20a09ac4add980c8cb00a292 100644
|
| --- a/chrome/browser/site_per_process_interactive_browsertest.cc
|
| +++ b/chrome/browser/site_per_process_interactive_browsertest.cc
|
| @@ -144,3 +144,91 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessInteractiveBrowserTest,
|
| EXPECT_EQ("FOO", result);
|
| }
|
|
|
| +// Ensure that sequential focus navigation (advancing focused elements with
|
| +// <tab> and <shift-tab>) works across cross-process subframes.
|
| +// The test sets up six inputs fields in a page with two cross-process
|
| +// subframes:
|
| +// child1 child2
|
| +// /------------\ /------------\.
|
| +// | 2. <input> | | 4. <input> |
|
| +// 1. <input> | 3. <input> | | 5. <input> | 6. <input>
|
| +// \------------/ \------------/.
|
| +//
|
| +// The test then presses <tab> six times to cycle through focused elements 1-6.
|
| +// The test then repeats this with <shift-tab> to cycle in reverse order.
|
| +IN_PROC_BROWSER_TEST_F(SitePerProcessInteractiveBrowserTest,
|
| + SequentialFocusNavigation) {
|
| + GURL main_url(embedded_test_server()->GetURL(
|
| + "a.com", "/cross_site_iframe_factory.html?a(b,c)"));
|
| + ui_test_utils::NavigateToURL(browser(), main_url);
|
| +
|
| + content::WebContents* web_contents =
|
| + browser()->tab_strip_model()->GetActiveWebContents();
|
| +
|
| + content::RenderFrameHost* main_frame = web_contents->GetMainFrame();
|
| + content::RenderFrameHost* child1 = ChildFrameAt(main_frame, 0);
|
| + ASSERT_NE(nullptr, child1);
|
| + content::RenderFrameHost* child2 = ChildFrameAt(main_frame, 1);
|
| + ASSERT_NE(nullptr, child2);
|
| +
|
| + // Assign a name to each frame. This will be sent along in test messages
|
| + // from focus events.
|
| + EXPECT_TRUE(ExecuteScript(main_frame, "window.name = 'root';"));
|
| + EXPECT_TRUE(ExecuteScript(child1, "window.name = 'child1';"));
|
| + EXPECT_TRUE(ExecuteScript(child2, "window.name = 'child2';"));
|
| +
|
| + // This script will insert two <input> fields in the document, one at the
|
| + // beginning and one at the end. For root frame, this means that we will
|
| + // have an <input>, then two <iframe> elements, then another <input>.
|
| + std::string script =
|
| + "function onFocus(e) {"
|
| + " domAutomationController.setAutomationId(0);"
|
| + " domAutomationController.send(window.name + '-focused-' + e.target.id);"
|
| + "}"
|
| + "var input1 = document.createElement('input');"
|
| + "input1.id = 'input1';"
|
| + "var input2 = document.createElement('input');"
|
| + "input2.id = 'input2';"
|
| + "document.body.insertBefore(input1, document.body.firstChild);"
|
| + "document.body.appendChild(input2);"
|
| + "input1.addEventListener('focus', onFocus, false);"
|
| + "input2.addEventListener('focus', onFocus, false);";
|
| +
|
| + // Add two input fields to each of the three frames.
|
| + EXPECT_TRUE(ExecuteScript(main_frame, script));
|
| + EXPECT_TRUE(ExecuteScript(child1, script));
|
| + EXPECT_TRUE(ExecuteScript(child2, script));
|
| +
|
| + // Helper to simulate a tab press and wait for a focus message.
|
| + auto press_tab_and_wait_for_message = [web_contents](bool reverse) {
|
| + content::DOMMessageQueue msg_queue;
|
| + std::string reply;
|
| + SimulateKeyPress(web_contents, ui::VKEY_TAB, false, reverse /* shift */,
|
| + false, false);
|
| + EXPECT_TRUE(msg_queue.WaitForMessage(&reply));
|
| + return reply;
|
| + };
|
| +
|
| + // Press <tab> six times to focus each of the <input> elements in turn.
|
| + EXPECT_EQ("\"root-focused-input1\"", press_tab_and_wait_for_message(false));
|
| + EXPECT_EQ(main_frame, web_contents->GetFocusedFrame());
|
| + EXPECT_EQ("\"child1-focused-input1\"", press_tab_and_wait_for_message(false));
|
| + EXPECT_EQ(child1, web_contents->GetFocusedFrame());
|
| + EXPECT_EQ("\"child1-focused-input2\"", press_tab_and_wait_for_message(false));
|
| + EXPECT_EQ("\"child2-focused-input1\"", press_tab_and_wait_for_message(false));
|
| + EXPECT_EQ(child2, web_contents->GetFocusedFrame());
|
| + EXPECT_EQ("\"child2-focused-input2\"", press_tab_and_wait_for_message(false));
|
| + EXPECT_EQ("\"root-focused-input2\"", press_tab_and_wait_for_message(false));
|
| + EXPECT_EQ(main_frame, web_contents->GetFocusedFrame());
|
| +
|
| + // Now, press <shift-tab> to navigate focus in the reverse direction.
|
| + EXPECT_EQ("\"child2-focused-input2\"", press_tab_and_wait_for_message(true));
|
| + EXPECT_EQ(child2, web_contents->GetFocusedFrame());
|
| + EXPECT_EQ("\"child2-focused-input1\"", press_tab_and_wait_for_message(true));
|
| + EXPECT_EQ("\"child1-focused-input2\"", press_tab_and_wait_for_message(true));
|
| + EXPECT_EQ(child1, web_contents->GetFocusedFrame());
|
| + EXPECT_EQ("\"child1-focused-input1\"", press_tab_and_wait_for_message(true));
|
| + EXPECT_EQ("\"root-focused-input1\"", press_tab_and_wait_for_message(true));
|
| + EXPECT_EQ(main_frame, web_contents->GetFocusedFrame());
|
| +}
|
| +
|
|
|