Index: content/browser/site_per_process_browsertest.cc |
diff --git a/content/browser/site_per_process_browsertest.cc b/content/browser/site_per_process_browsertest.cc |
index 6bb654a15b58f2bf84fac0ded993a0b6cd45f212..0424ebf51f4bd00ac5d348b6c294c1f5eaa709fe 100644 |
--- a/content/browser/site_per_process_browsertest.cc |
+++ b/content/browser/site_per_process_browsertest.cc |
@@ -97,6 +97,37 @@ void NavigateNamedFrame(const ToRenderFrameHost& caller_frame, |
EXPECT_TRUE(success); |
} |
+// Helper function to simulate pressing and releasing the provided key. Unlike |
+// SimulateKeyPress in browser_test_utils, which always routes the event |
+// through the top frame's RenderWidgetHost, this function routes the keyboard |
+// event to the focused frame's RenderWidgetHost. |
+void RouteKeyboardEvent(WebContentsImpl* web_contents, base::char16 key) { |
alexmos
2015/10/23 23:40:16
I wanted to just change SimulateKeyPress in browse
kenrb
2015/10/28 21:07:05
I don't think you want it in the content API, so i
alexmos
2015/10/29 05:26:29
You're right, I got confused and thought that it d
|
+ RenderWidgetHostImpl* target_rwh = web_contents->GetFocusedRenderWidgetHost(); |
+ |
+ NativeWebKeyboardEvent event; |
+ event.text[0] = key; |
+ event.unmodifiedText[0] = key; |
+ |
+ event.type = blink::WebKeyboardEvent::RawKeyDown; |
+ target_rwh->ForwardKeyboardEvent(event); |
+ event.type = blink::WebKeyboardEvent::Char; |
+ target_rwh->ForwardKeyboardEvent(event); |
+ event.type = blink::WebKeyboardEvent::KeyUp; |
+ target_rwh->ForwardKeyboardEvent(event); |
+} |
+ |
+// Helper function to generate a click on the given RenderWidgetHost. The |
+// mouse event is forwarded directly to the RenderWidgetHost without any |
+// hit-testing. |
+void SimulateMouseClick(RenderWidgetHost* rwh, int x, int y) { |
+ blink::WebMouseEvent mouse_event; |
+ mouse_event.type = blink::WebInputEvent::MouseDown; |
+ mouse_event.button = blink::WebPointerProperties::ButtonLeft; |
+ mouse_event.x = x; |
+ mouse_event.y = y; |
+ rwh->ForwardMouseEvent(mouse_event); |
+} |
+ |
class RedirectNotificationObserver : public NotificationObserver { |
public: |
// Register to listen for notifications of the given type from either a |
@@ -3488,14 +3519,8 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, |
DOMMessageQueue msg_queue; |
// Click on the cross-process subframe. |
- blink::WebMouseEvent mouse_event; |
- mouse_event.type = blink::WebInputEvent::MouseDown; |
- mouse_event.button = blink::WebPointerProperties::ButtonLeft; |
- mouse_event.x = 1; |
- mouse_event.y = 1; |
- RenderWidgetHost* rwh_child = |
- root->child_at(0)->current_frame_host()->GetRenderWidgetHost(); |
- rwh_child->ForwardMouseEvent(mouse_event); |
+ SimulateMouseClick( |
+ root->child_at(0)->current_frame_host()->GetRenderWidgetHost(), 1, 1); |
// Check that the main frame lost focus and fired blur event on the input |
// text field. |
@@ -3509,8 +3534,8 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, |
EXPECT_EQ(root->child_at(0), root->frame_tree()->GetFocusedFrame()); |
// Click on the root frame. |
- shell()->web_contents()->GetRenderViewHost()->GetWidget()->ForwardMouseEvent( |
- mouse_event); |
+ SimulateMouseClick( |
+ shell()->web_contents()->GetRenderViewHost()->GetWidget(), 1, 1); |
// Check that the subframe lost focus and fired blur event on its |
// document's body. |
@@ -3626,4 +3651,47 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, OpenerSetLocation) { |
EXPECT_EQ(shell()->web_contents()->GetLastCommittedURL(), cross_url); |
} |
+// Ensure that a cross-process subframe can receive keyboard events when in |
+// focus. |
+IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, |
+ SubframeKeyboardEventRouting) { |
+ GURL main_url(embedded_test_server()->GetURL( |
+ "a.com", "/frame_tree/page_with_one_frame.html")); |
+ EXPECT_TRUE(NavigateToURL(shell(), main_url)); |
+ |
+ WebContentsImpl* web_contents = |
+ static_cast<WebContentsImpl*>(shell()->web_contents()); |
+ FrameTreeNode* root = web_contents->GetFrameTree()->root(); |
+ |
+ GURL frame_url( |
+ embedded_test_server()->GetURL("b.com", "/page_with_input_field.html")); |
+ NavigateFrameToURL(root->child_at(0), frame_url); |
+ EXPECT_TRUE(WaitForRenderFrameReady(root->child_at(0)->current_frame_host())); |
+ |
+ // Click on the subframe to focus it. |
+ SimulateMouseClick( |
+ root->child_at(0)->current_frame_host()->GetRenderWidgetHost(), 1, 1); |
+ |
+ // Focus the input field in the subframe. The return value "input-focus" |
+ // will be sent once the input field's focus event fires. |
+ std::string result; |
+ EXPECT_TRUE(ExecuteScriptAndExtractString( |
+ root->child_at(0)->current_frame_host(), "focusInputField()", &result)); |
+ EXPECT_EQ(result, "input-focus"); |
+ |
+ // The subframe should now be focused. |
+ EXPECT_EQ(root->child_at(0), root->frame_tree()->GetFocusedFrame()); |
+ |
+ // Generate a few keyboard events and route them to currently focused frame. |
+ RouteKeyboardEvent(web_contents, 'f'); |
+ RouteKeyboardEvent(web_contents, 'o'); |
+ RouteKeyboardEvent(web_contents, 'o'); |
+ |
+ // Verify that the input field in the subframe received the keystrokes. |
+ EXPECT_TRUE(ExecuteScriptAndExtractString( |
+ root->child_at(0)->current_frame_host(), |
+ "window.domAutomationController.send(getInputFieldText());", &result)); |
+ EXPECT_EQ("foo", result); |
+} |
+ |
} // namespace content |