| 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 c8fa716929efe53b4a79d82206f6b7027f69d236..8c9dc238c7ac0523c29dade46b802f533b547821 100644
|
| --- a/content/browser/site_per_process_browsertest.cc
|
| +++ b/content/browser/site_per_process_browsertest.cc
|
| @@ -5255,5 +5255,90 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, CrossSiteIframeDisplayNone) {
|
| // Waits for the next frame.
|
| observer->Wait();
|
| }
|
| +// This class observes the first change in the text input state
|
| +// for a given RenderWidgetHostViewBase.
|
| +class TextInputStateObserver {
|
| + public:
|
| + TextInputStateObserver(RenderWidgetHostViewBase* view)
|
| + : view_(view),
|
| + state_(*view->current_text_input_state()),
|
| + message_loop_runner_(nullptr) {}
|
| +
|
| + // Hold and keep polling the |view_| until its text input state changes.
|
| + TextInputState WaitUntilStateChanges() {
|
| + while (!DidChangeState()) {
|
| + message_loop_runner_ = new MessageLoopRunner;
|
| + BrowserThread::ID current_thread_id;
|
| + EXPECT_TRUE(
|
| + BrowserThread::GetCurrentThreadIdentifier(¤t_thread_id));
|
| + BrowserThread::PostDelayedTask(current_thread_id, FROM_HERE,
|
| + message_loop_runner_->QuitClosure(),
|
| + base::TimeDelta::FromMicroseconds(500));
|
| + message_loop_runner_->Run();
|
| + }
|
| + return *view_->current_text_input_state();
|
| + }
|
| +
|
| + private:
|
| + bool DidChangeState() {
|
| + TextInputState current = *view_->current_text_input_state();
|
| + return state_.type != current.type || state_.mode != current.mode ||
|
| + state_.value != current.value;
|
| + }
|
| + RenderWidgetHostViewBase* view_;
|
| + TextInputState state_;
|
| + scoped_refptr<MessageLoopRunner> message_loop_runner_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(TextInputStateObserver);
|
| +};
|
| +
|
| +// Verify that by moving the focus between different frames the top-level
|
| +// RenderWidgetHostViewBase tracks the input state properly.
|
| +IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, TextInputStateChanged) {
|
| + GURL main_page_url(embedded_test_server()->GetURL(
|
| + "a.com", "/textinput/page_with_input_field_and_iframe.html"));
|
| + NavigateToURL(shell(), main_page_url);
|
| + GURL cross_origin_url(embedded_test_server()->GetURL(
|
| + "b.com", "/textinput/page_with_input_field_and_iframe.html"));
|
| + FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
|
| + ->GetFrameTree()
|
| + ->root();
|
| + // Wait for the main frame to finish loading.
|
| + EXPECT_TRUE(WaitForRenderFrameReady(root->current_frame_host()));
|
| +
|
| + // Navigate the child frame.
|
| + FrameTreeNode* child_frame_node = root->child_at(0);
|
| + NavigateFrameToURL(child_frame_node, cross_origin_url);
|
| +
|
| + // Wait for the child frame to finish loading.
|
| + EXPECT_TRUE(WaitForRenderFrameReady(child_frame_node->current_frame_host()));
|
| +
|
| + RenderWidgetHostImpl* root_rwh =
|
| + root->current_frame_host()->GetRenderWidgetHost();
|
| + RenderWidgetHostViewBase* root_rwhv = root_rwh->GetView();
|
| +
|
| + EXPECT_EQ(root_rwhv->current_text_input_state()->type,
|
| + ui::TEXT_INPUT_TYPE_NONE);
|
| + // Focus the root (main-frame). This would focus the text input field.
|
| + TextInputStateObserver root_observer(root_rwhv);
|
| + SimulateMouseClick(root_rwh, 1, 1);
|
| + TextInputState new_state = root_observer.WaitUntilStateChanges();
|
| + EXPECT_EQ(new_state.type, ui::TEXT_INPUT_TYPE_TEXT);
|
| +
|
| + // Now focus the child frame and read the text input state.
|
| + RenderWidgetHostImpl* child_rwh =
|
| + child_frame_node->current_frame_host()->GetRenderWidgetHost();
|
| + RenderWidgetHostViewBase* child_rwhv = child_rwh->GetView();
|
| + TextInputStateObserver child_observer(child_rwhv);
|
| + SimulateMouseClick(child_rwh, 1, 1);
|
| + new_state = child_observer.WaitUntilStateChanges();
|
| +
|
| + EXPECT_EQ(new_state.type, ui::TEXT_INPUT_TYPE_TEXT);
|
| +
|
| + // Finally, the top level view should see the child's view.
|
| + new_state = *root_rwhv->current_text_input_state();
|
| + EXPECT_EQ(new_state.type, ui::TEXT_INPUT_TYPE_TEXT);
|
| + EXPECT_EQ(new_state.value, cross_origin_url.spec());
|
| +}
|
|
|
| } // namespace content
|
|
|