Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "base/command_line.h" | 5 #include "base/command_line.h" |
| 6 #include "base/strings/string_number_conversions.h" | 6 #include "base/strings/string_number_conversions.h" |
| 7 #include "chrome/browser/renderer_context_menu/render_view_context_menu_browsert est_util.h" | 7 #include "chrome/browser/renderer_context_menu/render_view_context_menu_browsert est_util.h" |
| 8 #include "chrome/browser/ui/browser.h" | 8 #include "chrome/browser/ui/browser.h" |
| 9 #include "chrome/browser/ui/browser_window.h" | 9 #include "chrome/browser/ui/browser_window.h" |
| 10 #include "chrome/browser/ui/exclusive_access/fullscreen_controller_test.h" | 10 #include "chrome/browser/ui/exclusive_access/fullscreen_controller_test.h" |
| 11 #include "chrome/browser/ui/tabs/tab_strip_model.h" | 11 #include "chrome/browser/ui/tabs/tab_strip_model.h" |
| 12 #include "chrome/test/base/in_process_browser_test.h" | 12 #include "chrome/test/base/in_process_browser_test.h" |
| 13 #include "chrome/test/base/interactive_test_utils.h" | 13 #include "chrome/test/base/interactive_test_utils.h" |
| 14 #include "chrome/test/base/ui_test_utils.h" | 14 #include "chrome/test/base/ui_test_utils.h" |
| 15 #include "components/guest_view/browser/guest_view_manager_delegate.h" | 15 #include "components/guest_view/browser/guest_view_manager_delegate.h" |
| 16 #include "components/guest_view/browser/test_guest_view_manager.h" | 16 #include "components/guest_view/browser/test_guest_view_manager.h" |
| 17 #include "content/public/browser/navigation_handle.h" | 17 #include "content/public/browser/navigation_handle.h" |
| 18 #include "content/public/browser/render_frame_host.h" | 18 #include "content/public/browser/render_frame_host.h" |
| 19 #include "content/public/browser/render_widget_host.h" | 19 #include "content/public/browser/render_widget_host.h" |
| 20 #include "content/public/browser/render_widget_host_view.h" | 20 #include "content/public/browser/render_widget_host_view.h" |
| 21 #include "content/public/browser/web_contents.h" | 21 #include "content/public/browser/web_contents.h" |
| 22 #include "content/public/test/browser_test_utils.h" | 22 #include "content/public/test/browser_test_utils.h" |
| 23 #include "content/public/test/content_browser_test_utils.h" | 23 #include "content/public/test/content_browser_test_utils.h" |
| 24 #include "content/public/test/test_navigation_observer.h" | 24 #include "content/public/test/test_navigation_observer.h" |
| 25 #include "content/public/test/test_utils.h" | 25 #include "content/public/test/test_utils.h" |
| 26 #include "extensions/browser/api/extensions_api_client.h" | 26 #include "extensions/browser/api/extensions_api_client.h" |
| 27 #include "extensions/common/constants.h" | 27 #include "extensions/common/constants.h" |
| 28 #include "net/dns/mock_host_resolver.h" | 28 #include "net/dns/mock_host_resolver.h" |
| 29 #include "net/test/embedded_test_server/embedded_test_server.h" | 29 #include "net/test/embedded_test_server/embedded_test_server.h" |
| 30 #include "ui/base/test/ui_controls.h" | |
| 30 #include "ui/display/display.h" | 31 #include "ui/display/display.h" |
| 31 #include "ui/display/screen.h" | 32 #include "ui/display/screen.h" |
| 32 #include "url/gurl.h" | 33 #include "url/gurl.h" |
| 33 | 34 |
| 34 class SitePerProcessInteractiveBrowserTest : public InProcessBrowserTest { | 35 class SitePerProcessInteractiveBrowserTest : public InProcessBrowserTest { |
| 35 public: | 36 public: |
| 36 SitePerProcessInteractiveBrowserTest() {} | 37 SitePerProcessInteractiveBrowserTest() {} |
| 37 ~SitePerProcessInteractiveBrowserTest() override {} | 38 ~SitePerProcessInteractiveBrowserTest() override {} |
| 38 | 39 |
| 39 void SetUpCommandLine(base::CommandLine* command_line) override { | 40 void SetUpCommandLine(base::CommandLine* command_line) override { |
| (...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 273 EXPECT_EQ("\"child2-focused-input2\"", press_tab_and_wait_for_message(true)); | 274 EXPECT_EQ("\"child2-focused-input2\"", press_tab_and_wait_for_message(true)); |
| 274 EXPECT_EQ(child2, web_contents->GetFocusedFrame()); | 275 EXPECT_EQ(child2, web_contents->GetFocusedFrame()); |
| 275 EXPECT_EQ("\"child2-focused-input1\"", press_tab_and_wait_for_message(true)); | 276 EXPECT_EQ("\"child2-focused-input1\"", press_tab_and_wait_for_message(true)); |
| 276 EXPECT_EQ("\"child1-focused-input2\"", press_tab_and_wait_for_message(true)); | 277 EXPECT_EQ("\"child1-focused-input2\"", press_tab_and_wait_for_message(true)); |
| 277 EXPECT_EQ(child1, web_contents->GetFocusedFrame()); | 278 EXPECT_EQ(child1, web_contents->GetFocusedFrame()); |
| 278 EXPECT_EQ("\"child1-focused-input1\"", press_tab_and_wait_for_message(true)); | 279 EXPECT_EQ("\"child1-focused-input1\"", press_tab_and_wait_for_message(true)); |
| 279 EXPECT_EQ("\"root-focused-input1\"", press_tab_and_wait_for_message(true)); | 280 EXPECT_EQ("\"root-focused-input1\"", press_tab_and_wait_for_message(true)); |
| 280 EXPECT_EQ(main_frame, web_contents->GetFocusedFrame()); | 281 EXPECT_EQ(main_frame, web_contents->GetFocusedFrame()); |
| 281 } | 282 } |
| 282 | 283 |
| 284 // TODO(http://crbug.com/702330): Enable this test. | |
|
alexmos
2017/03/24 23:55:39
nit: https
avallee
2017/03/27 19:54:24
Done.
| |
| 285 // Ensures that renderers know to advance focus to sibling frames and parent | |
| 286 // frames in the presence of mouse click initiated focus changes. | |
| 287 IN_PROC_BROWSER_TEST_F(SitePerProcessInteractiveBrowserTest, | |
| 288 DISABLED_TabAndMouseFocusNavigation) { | |
| 289 GURL main_url(embedded_test_server()->GetURL( | |
| 290 "a.com", "/cross_site_iframe_factory.html?a(b,c)")); | |
| 291 ui_test_utils::NavigateToURL(browser(), main_url); | |
| 292 | |
| 293 content::WebContents* web_contents = | |
| 294 browser()->tab_strip_model()->GetActiveWebContents(); | |
| 295 | |
| 296 content::RenderFrameHost* main_frame = web_contents->GetMainFrame(); | |
| 297 content::RenderFrameHost* child1 = ChildFrameAt(main_frame, 0); | |
| 298 ASSERT_NE(nullptr, child1); | |
| 299 content::RenderFrameHost* child2 = ChildFrameAt(main_frame, 1); | |
| 300 ASSERT_NE(nullptr, child2); | |
| 301 | |
| 302 // Assign a name to each frame. This will be sent along in test messages | |
| 303 // from focus events. | |
| 304 EXPECT_TRUE(ExecuteScript(main_frame, "window.name = 'root';")); | |
| 305 EXPECT_TRUE(ExecuteScript(child1, "window.name = 'child1';")); | |
| 306 EXPECT_TRUE(ExecuteScript(child2, "window.name = 'child2';")); | |
| 307 | |
| 308 // This script will insert two <input> fields in the document, one at the | |
| 309 // beginning and one at the end. For root frame, this means that we will | |
| 310 // have an <input>, then two <iframe> elements, then another <input>. | |
|
alexmos
2017/03/24 23:55:39
Perhaps also mention what it sends back. It's kin
avallee
2017/03/27 19:54:24
Done.
| |
| 311 std::string script = | |
| 312 "function onFocus(e) {" | |
| 313 " console.log(window.name+'-focused-'+ e.target.id);" | |
| 314 " domAutomationController.setAutomationId(0);" | |
| 315 " domAutomationController.send(window.name + '-focused-' + e.target.id);" | |
| 316 "}" | |
| 317 "" | |
| 318 "function getElementCoords(element) {" | |
| 319 " var rect = element.getBoundingClientRect();" | |
| 320 " return Math.floor(rect.left + 0.5 * rect.width) +','+" | |
| 321 " Math.floor(rect.top + 0.5 * rect.height);" | |
| 322 "}" | |
| 323 "function getIframeCoords(element) {" | |
| 324 " var rect = element.getBoundingClientRect();" | |
| 325 " return Math.floor(rect.left) +','+" | |
| 326 " Math.floor(rect.top);" | |
| 327 "}" | |
| 328 "" | |
| 329 "document.styleSheets[0].insertRule('input {width:100%;margin:0;}', 1);" | |
| 330 "document.styleSheets[0].insertRule('h2 {margin:0;}', 1);" | |
| 331 "var input1 = document.createElement('input');" | |
| 332 "input1.id = 'input1';" | |
| 333 "input1.addEventListener('focus', onFocus, false);" | |
| 334 "var input2 = document.createElement('input');" | |
| 335 "input2.id = 'input2';" | |
| 336 "input2.addEventListener('focus', onFocus, false);" | |
| 337 "document.body.insertBefore(input1, document.body.firstChild);" | |
| 338 "document.body.appendChild(input2);" | |
| 339 "" | |
| 340 "var frames = document.querySelectorAll('iframe');" | |
| 341 "frames = Array.prototype.map.call(frames, getIframeCoords).join(';');" | |
| 342 "var inputCoords = [input1, input2].map(getElementCoords).join(';');" | |
| 343 "if (frames) {" | |
| 344 " inputCoords = inputCoords + ':' + frames;" | |
| 345 "}" | |
| 346 "domAutomationController.send(inputCoords);"; | |
| 347 | |
| 348 auto parse_points = [](const std::string& input, const gfx::Point& offset) { | |
| 349 base::StringPairs pieces; | |
| 350 base::SplitStringIntoKeyValuePairs(input, ',', ';', &pieces); | |
| 351 std::vector<gfx::Point> points; | |
| 352 for (const auto& piece : pieces) { | |
| 353 int x, y; | |
| 354 EXPECT_TRUE(base::StringToInt(piece.first, &x)); | |
| 355 EXPECT_TRUE(base::StringToInt(piece.second, &y)); | |
| 356 points.push_back(gfx::Point(x + offset.x(), y + offset.y())); | |
| 357 } | |
| 358 return points; | |
| 359 }; | |
| 360 auto parse_points_and_offsets = [parse_points](const std::string& input) { | |
| 361 auto pieces = base::SplitString(input, ":", base::TRIM_WHITESPACE, | |
| 362 base::SPLIT_WANT_NONEMPTY); | |
| 363 gfx::Point origin; | |
|
alexmos
2017/03/24 23:55:39
is there a better name? I'm thinking of the docum
avallee
2017/03/27 19:54:24
Well both the input points and the offset points f
alexmos
2017/03/27 23:09:28
Yes, either one of those sounds fine.
| |
| 364 return make_pair(parse_points(pieces[0], origin), | |
| 365 parse_points(pieces[1], origin)); | |
| 366 }; | |
| 367 | |
| 368 // Add two input fields to each of the three frames. | |
| 369 std::string result; | |
| 370 EXPECT_TRUE(ExecuteScriptAndExtractString(main_frame, script, &result)); | |
| 371 auto parsed = parse_points_and_offsets(result); | |
| 372 auto main_points = parsed.first; | |
|
alexmos
2017/03/24 23:55:39
nit: I'd rename to something like main_frame_input
avallee
2017/03/27 19:54:24
Done.
| |
| 373 | |
| 374 EXPECT_TRUE(ExecuteScriptAndExtractString(child1, script, &result)); | |
| 375 auto child1_points = parse_points(result, parsed.second[0]); | |
| 376 EXPECT_TRUE(ExecuteScriptAndExtractString(child2, script, &result)); | |
| 377 auto child2_points = parse_points(result, parsed.second[1]); | |
| 378 | |
| 379 // Helper to simulate a tab press and wait for a focus message. | |
| 380 auto press_tab_and_wait_for_message = [web_contents](bool reverse) { | |
| 381 content::DOMMessageQueue msg_queue; | |
| 382 std::string reply; | |
| 383 LOG(ERROR) << "SimulateKeyPress"; | |
|
alexmos
2017/03/24 23:55:39
Did you want to leave these and the console.log()
avallee
2017/03/27 19:54:25
nope, missed a couple.
| |
| 384 SimulateKeyPress(web_contents, ui::DomKey::TAB, ui::DomCode::TAB, | |
| 385 ui::VKEY_TAB, false, reverse /* shift */, false, false); | |
| 386 EXPECT_TRUE(msg_queue.WaitForMessage(&reply)); | |
| 387 LOG(ERROR) << "the reply is: " << reply; | |
| 388 return reply; | |
| 389 }; | |
| 390 | |
| 391 auto click_element_and_wait_for_message = | |
| 392 [web_contents](const gfx::Point& point) { | |
| 393 content::DOMMessageQueue msg_queue{web_contents}; | |
|
alexmos
2017/03/24 23:55:39
Why the {} and not just ()? And do you need it at
avallee
2017/03/27 19:54:24
Gone, this was trying to fix the failure that I di
| |
| 394 | |
| 395 auto content_bounds = web_contents->GetContainerBounds(); | |
| 396 ui_controls::SendMouseMove(point.x() + content_bounds.x(), | |
| 397 point.y() + content_bounds.y()); | |
| 398 ui_controls::SendMouseClick(ui_controls::LEFT); | |
| 399 | |
| 400 std::string reply; | |
| 401 EXPECT_TRUE(msg_queue.WaitForMessage(&reply)); | |
| 402 return reply; | |
| 403 }; | |
| 404 | |
| 405 // Tab from child1 back to root. | |
| 406 EXPECT_EQ("\"root-focused-input1\"", | |
| 407 click_element_and_wait_for_message(main_points[0])); | |
| 408 EXPECT_EQ(main_frame, web_contents->GetFocusedFrame()); | |
| 409 EXPECT_EQ("\"child1-focused-input1\"", | |
| 410 click_element_and_wait_for_message(child1_points[0])); | |
| 411 EXPECT_EQ(child1, web_contents->GetFocusedFrame()); | |
| 412 EXPECT_EQ("\"root-focused-input1\"", press_tab_and_wait_for_message(true)); | |
| 413 EXPECT_EQ(main_frame, web_contents->GetFocusedFrame()); | |
| 414 | |
| 415 // Tab from child2 forward to root. | |
| 416 EXPECT_EQ("\"root-focused-input2\"", | |
| 417 click_element_and_wait_for_message(main_points[1])); | |
| 418 EXPECT_EQ(main_frame, web_contents->GetFocusedFrame()); | |
| 419 EXPECT_EQ("\"child2-focused-input2\"", | |
| 420 click_element_and_wait_for_message(child2_points[1])); | |
| 421 EXPECT_EQ(child2, web_contents->GetFocusedFrame()); | |
| 422 EXPECT_EQ("\"root-focused-input2\"", press_tab_and_wait_for_message(false)); | |
| 423 EXPECT_EQ(main_frame, web_contents->GetFocusedFrame()); | |
| 424 | |
| 425 // Tab forward from child1 to child2. | |
| 426 EXPECT_EQ("\"child2-focused-input1\"", | |
| 427 click_element_and_wait_for_message(child2_points[0])); | |
| 428 EXPECT_EQ(child2, web_contents->GetFocusedFrame()); | |
| 429 EXPECT_EQ("\"child1-focused-input2\"", | |
| 430 click_element_and_wait_for_message(child1_points[1])); | |
| 431 EXPECT_EQ(child1, web_contents->GetFocusedFrame()); | |
| 432 LOG(ERROR) << "before fail"; | |
|
alexmos
2017/03/24 23:55:39
remove? (also below)
avallee
2017/03/27 19:54:24
Done.
| |
| 433 EXPECT_EQ("\"child2-focused-input1\"", press_tab_and_wait_for_message(false)); | |
| 434 LOG(ERROR) << "after fail"; | |
| 435 EXPECT_EQ(child2, web_contents->GetFocusedFrame()); | |
| 436 | |
| 437 // Tab backward from child2 to child1. | |
| 438 EXPECT_EQ("\"child1-focused-input2\"", | |
| 439 click_element_and_wait_for_message(child1_points[1])); | |
| 440 EXPECT_EQ(child1, web_contents->GetFocusedFrame()); | |
| 441 EXPECT_EQ("\"child2-focused-input1\"", | |
| 442 click_element_and_wait_for_message(child2_points[0])); | |
| 443 EXPECT_EQ(child2, web_contents->GetFocusedFrame()); | |
| 444 EXPECT_EQ("\"child1-focused-input2\"", press_tab_and_wait_for_message(true)); | |
| 445 EXPECT_EQ(child1, web_contents->GetFocusedFrame()); | |
| 446 | |
| 447 // Ensure there are no pending focus events after tabbing. | |
| 448 EXPECT_EQ("\"root-focused-input1\"", | |
| 449 click_element_and_wait_for_message(main_points[0])) | |
| 450 << "Unexpected extra focus events."; | |
| 451 } | |
| 452 | |
| 283 namespace { | 453 namespace { |
| 284 | 454 |
| 285 // Helper to retrieve the frame's (window.innerWidth, window.innerHeight). | 455 // Helper to retrieve the frame's (window.innerWidth, window.innerHeight). |
| 286 gfx::Size GetFrameSize(content::RenderFrameHost* frame) { | 456 gfx::Size GetFrameSize(content::RenderFrameHost* frame) { |
| 287 int width = 0; | 457 int width = 0; |
| 288 EXPECT_TRUE(ExecuteScriptAndExtractInt( | 458 EXPECT_TRUE(ExecuteScriptAndExtractInt( |
| 289 frame, "domAutomationController.send(window.innerWidth);", &width)); | 459 frame, "domAutomationController.send(window.innerWidth);", &width)); |
| 290 | 460 |
| 291 int height = 0; | 461 int height = 0; |
| 292 EXPECT_TRUE(ExecuteScriptAndExtractInt( | 462 EXPECT_TRUE(ExecuteScriptAndExtractInt( |
| (...skipping 624 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 917 send_right_mouse_event(child_view->GetRenderWidgetHost(), 10, 20, | 1087 send_right_mouse_event(child_view->GetRenderWidgetHost(), 10, 20, |
| 918 blink::WebInputEvent::MouseUp); | 1088 blink::WebInputEvent::MouseUp); |
| 919 menu_waiter.WaitForMenuOpenAndClose(); | 1089 menu_waiter.WaitForMenuOpenAndClose(); |
| 920 | 1090 |
| 921 gfx::Point point_in_root_window = | 1091 gfx::Point point_in_root_window = |
| 922 child_view->TransformPointToRootCoordSpace(gfx::Point(10, 20)); | 1092 child_view->TransformPointToRootCoordSpace(gfx::Point(10, 20)); |
| 923 | 1093 |
| 924 EXPECT_EQ(point_in_root_window.x(), menu_waiter.params().x); | 1094 EXPECT_EQ(point_in_root_window.x(), menu_waiter.params().x); |
| 925 EXPECT_EQ(point_in_root_window.y(), menu_waiter.params().y); | 1095 EXPECT_EQ(point_in_root_window.y(), menu_waiter.params().y); |
| 926 } | 1096 } |
| OLD | NEW |