| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 <stddef.h> | 5 #include <stddef.h> |
| 6 #include <utility> | 6 #include <utility> |
| 7 | 7 |
| 8 #include "base/base64.h" | 8 #include "base/base64.h" |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/bind_helpers.h" | 10 #include "base/bind_helpers.h" |
| (...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 179 command.SetInteger(kIdParam, ++last_sent_id_); | 179 command.SetInteger(kIdParam, ++last_sent_id_); |
| 180 command.SetString(kMethodParam, method); | 180 command.SetString(kMethodParam, method); |
| 181 if (params) | 181 if (params) |
| 182 command.Set(kParamsParam, params.release()); | 182 command.Set(kParamsParam, params.release()); |
| 183 | 183 |
| 184 std::string json_command; | 184 std::string json_command; |
| 185 base::JSONWriter::Write(command, &json_command); | 185 base::JSONWriter::Write(command, &json_command); |
| 186 agent_host_->DispatchProtocolMessage(this, json_command); | 186 agent_host_->DispatchProtocolMessage(this, json_command); |
| 187 // Some messages are dispatched synchronously. | 187 // Some messages are dispatched synchronously. |
| 188 // Only run loop if we are not finished yet. | 188 // Only run loop if we are not finished yet. |
| 189 if (in_dispatch_ && wait) | 189 if (in_dispatch_ && wait) { |
| 190 WaitForResponse(); | 190 waiting_for_command_result_id_ = last_sent_id_; |
| 191 base::RunLoop().Run(); |
| 192 } |
| 191 in_dispatch_ = false; | 193 in_dispatch_ = false; |
| 192 } | 194 } |
| 193 | 195 |
| 194 void WaitForResponse() { | |
| 195 waiting_for_command_result_id_ = last_sent_id_; | |
| 196 base::RunLoop().Run(); | |
| 197 } | |
| 198 | |
| 199 bool HasValue(const std::string& path) { | 196 bool HasValue(const std::string& path) { |
| 200 base::Value* value = 0; | 197 base::Value* value = 0; |
| 201 return result_->Get(path, &value); | 198 return result_->Get(path, &value); |
| 202 } | 199 } |
| 203 | 200 |
| 204 bool HasListItem(const std::string& path_to_list, | 201 bool HasListItem(const std::string& path_to_list, |
| 205 const std::string& name, | 202 const std::string& name, |
| 206 const std::string& value) { | 203 const std::string& value) { |
| 207 base::ListValue* list; | 204 base::ListValue* list; |
| 208 if (!result_->GetList(path_to_list, &list)) | 205 if (!result_->GetList(path_to_list, &list)) |
| (...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 405 // InterstitialPageDelegate: | 402 // InterstitialPageDelegate: |
| 406 std::string GetHTMLContents() override { return "<p>Interstitial</p>"; } | 403 std::string GetHTMLContents() override { return "<p>Interstitial</p>"; } |
| 407 }; | 404 }; |
| 408 | 405 |
| 409 class SyntheticKeyEventTest : public DevToolsProtocolTest { | 406 class SyntheticKeyEventTest : public DevToolsProtocolTest { |
| 410 protected: | 407 protected: |
| 411 void SendKeyEvent(const std::string& type, | 408 void SendKeyEvent(const std::string& type, |
| 412 int modifier, | 409 int modifier, |
| 413 int windowsKeyCode, | 410 int windowsKeyCode, |
| 414 int nativeKeyCode, | 411 int nativeKeyCode, |
| 415 const std::string& key, | 412 const std::string& key) { |
| 416 bool wait) { | |
| 417 std::unique_ptr<base::DictionaryValue> params(new base::DictionaryValue()); | 413 std::unique_ptr<base::DictionaryValue> params(new base::DictionaryValue()); |
| 418 params->SetString("type", type); | 414 params->SetString("type", type); |
| 419 params->SetInteger("modifiers", modifier); | 415 params->SetInteger("modifiers", modifier); |
| 420 params->SetInteger("windowsVirtualKeyCode", windowsKeyCode); | 416 params->SetInteger("windowsVirtualKeyCode", windowsKeyCode); |
| 421 params->SetInteger("nativeVirtualKeyCode", nativeKeyCode); | 417 params->SetInteger("nativeVirtualKeyCode", nativeKeyCode); |
| 422 params->SetString("key", key); | 418 params->SetString("key", key); |
| 423 SendCommand("Input.dispatchKeyEvent", std::move(params), wait); | 419 SendCommand("Input.dispatchKeyEvent", std::move(params)); |
| 424 } | 420 } |
| 425 }; | 421 }; |
| 426 | 422 |
| 427 class SyntheticMouseEventTest : public DevToolsProtocolTest { | |
| 428 protected: | |
| 429 void SendMouseEvent(const std::string& type, int x, int y, bool wait) { | |
| 430 std::unique_ptr<base::DictionaryValue> params(new base::DictionaryValue()); | |
| 431 params->SetString("type", type); | |
| 432 params->SetInteger("x", x); | |
| 433 params->SetInteger("y", y); | |
| 434 SendCommand("Input.dispatchMouseEvent", std::move(params), wait); | |
| 435 } | |
| 436 }; | |
| 437 | |
| 438 IN_PROC_BROWSER_TEST_F(SyntheticKeyEventTest, KeyEventSynthesizeKey) { | 423 IN_PROC_BROWSER_TEST_F(SyntheticKeyEventTest, KeyEventSynthesizeKey) { |
| 439 NavigateToURLBlockUntilNavigationsComplete(shell(), GURL("about:blank"), 1); | 424 NavigateToURLBlockUntilNavigationsComplete(shell(), GURL("about:blank"), 1); |
| 440 Attach(); | 425 Attach(); |
| 441 ASSERT_TRUE(content::ExecuteScript( | 426 ASSERT_TRUE(content::ExecuteScript( |
| 442 shell()->web_contents()->GetRenderViewHost(), | 427 shell()->web_contents()->GetRenderViewHost(), |
| 443 "function handleKeyEvent(event) {" | 428 "function handleKeyEvent(event) {" |
| 444 "domAutomationController.setAutomationId(0);" | 429 "domAutomationController.setAutomationId(0);" |
| 445 "domAutomationController.send(event.key);" | 430 "domAutomationController.send(event.key);" |
| 446 "}" | 431 "}" |
| 447 "document.body.addEventListener('keydown', handleKeyEvent);" | 432 "document.body.addEventListener('keydown', handleKeyEvent);" |
| 448 "document.body.addEventListener('keyup', handleKeyEvent);")); | 433 "document.body.addEventListener('keyup', handleKeyEvent);")); |
| 449 | 434 |
| 450 DOMMessageQueue dom_message_queue; | 435 DOMMessageQueue dom_message_queue; |
| 451 | 436 |
| 452 // Send enter (keycode 13). | 437 // Send enter (keycode 13). |
| 453 SendKeyEvent("rawKeyDown", 0, 13, 13, "Enter", true); | 438 SendKeyEvent("rawKeyDown", 0, 13, 13, "Enter"); |
| 454 SendKeyEvent("keyUp", 0, 13, 13, "Enter", true); | 439 SendKeyEvent("keyUp", 0, 13, 13, "Enter"); |
| 455 | 440 |
| 456 std::string key; | 441 std::string key; |
| 457 ASSERT_TRUE(dom_message_queue.WaitForMessage(&key)); | 442 ASSERT_TRUE(dom_message_queue.WaitForMessage(&key)); |
| 458 EXPECT_EQ("\"Enter\"", key); | 443 EXPECT_EQ("\"Enter\"", key); |
| 459 ASSERT_TRUE(dom_message_queue.WaitForMessage(&key)); | 444 ASSERT_TRUE(dom_message_queue.WaitForMessage(&key)); |
| 460 EXPECT_EQ("\"Enter\"", key); | 445 EXPECT_EQ("\"Enter\"", key); |
| 461 | 446 |
| 462 // Send escape (keycode 27). | 447 // Send escape (keycode 27). |
| 463 SendKeyEvent("rawKeyDown", 0, 27, 27, "Escape", true); | 448 SendKeyEvent("rawKeyDown", 0, 27, 27, "Escape"); |
| 464 SendKeyEvent("keyUp", 0, 27, 27, "Escape", true); | 449 SendKeyEvent("keyUp", 0, 27, 27, "Escape"); |
| 465 | 450 |
| 466 ASSERT_TRUE(dom_message_queue.WaitForMessage(&key)); | 451 ASSERT_TRUE(dom_message_queue.WaitForMessage(&key)); |
| 467 EXPECT_EQ("\"Escape\"", key); | 452 EXPECT_EQ("\"Escape\"", key); |
| 468 ASSERT_TRUE(dom_message_queue.WaitForMessage(&key)); | 453 ASSERT_TRUE(dom_message_queue.WaitForMessage(&key)); |
| 469 EXPECT_EQ("\"Escape\"", key); | 454 EXPECT_EQ("\"Escape\"", key); |
| 470 } | 455 } |
| 471 | 456 |
| 472 IN_PROC_BROWSER_TEST_F(SyntheticKeyEventTest, KeyboardEventAck) { | |
| 473 NavigateToURLBlockUntilNavigationsComplete(shell(), GURL("about:blank"), 1); | |
| 474 Attach(); | |
| 475 ASSERT_TRUE(content::ExecuteScript( | |
| 476 shell()->web_contents()->GetRenderViewHost(), | |
| 477 "document.body.addEventListener('keydown', () => console.log('x'));")); | |
| 478 | |
| 479 scoped_refptr<InputMsgWatcher> filter = new InputMsgWatcher( | |
| 480 RenderWidgetHostImpl::From( | |
| 481 shell()->web_contents()->GetRenderViewHost()->GetWidget()), | |
| 482 blink::WebInputEvent::MouseMove); | |
| 483 | |
| 484 SendCommand("Runtime.enable", nullptr); | |
| 485 SendKeyEvent("rawKeyDown", 0, 13, 13, "Enter", false); | |
| 486 | |
| 487 // We expect that the console log message event arrives *before* the input | |
| 488 // event ack, and the subsequent command response for Input.dispatchKeyEvent. | |
| 489 WaitForNotification("Runtime.consoleAPICalled"); | |
| 490 EXPECT_THAT(console_messages_, ElementsAre("x")); | |
| 491 EXPECT_FALSE(filter->HasReceivedAck()); | |
| 492 EXPECT_EQ(1u, result_ids_.size()); | |
| 493 | |
| 494 WaitForResponse(); | |
| 495 EXPECT_EQ(2u, result_ids_.size()); | |
| 496 } | |
| 497 | |
| 498 IN_PROC_BROWSER_TEST_F(SyntheticMouseEventTest, MouseEventAck) { | |
| 499 NavigateToURLBlockUntilNavigationsComplete(shell(), GURL("about:blank"), 1); | |
| 500 Attach(); | |
| 501 ASSERT_TRUE(content::ExecuteScript( | |
| 502 shell()->web_contents()->GetRenderViewHost(), | |
| 503 "document.body.addEventListener('mousemove', () => console.log('x'));")); | |
| 504 | |
| 505 scoped_refptr<InputMsgWatcher> filter = new InputMsgWatcher( | |
| 506 RenderWidgetHostImpl::From( | |
| 507 shell()->web_contents()->GetRenderViewHost()->GetWidget()), | |
| 508 blink::WebInputEvent::MouseMove); | |
| 509 | |
| 510 SendCommand("Runtime.enable", nullptr); | |
| 511 SendMouseEvent("mouseMoved", 15, 15, false); | |
| 512 | |
| 513 // We expect that the console log message event arrives *before* the input | |
| 514 // event ack, and the subsequent command response for | |
| 515 // Input.dispatchMouseEvent. | |
| 516 WaitForNotification("Runtime.consoleAPICalled"); | |
| 517 EXPECT_THAT(console_messages_, ElementsAre("x")); | |
| 518 EXPECT_FALSE(filter->HasReceivedAck()); | |
| 519 EXPECT_EQ(1u, result_ids_.size()); | |
| 520 | |
| 521 WaitForResponse(); | |
| 522 EXPECT_EQ(2u, result_ids_.size()); | |
| 523 } | |
| 524 | |
| 525 namespace { | 457 namespace { |
| 526 bool DecodePNG(std::string base64_data, SkBitmap* bitmap) { | 458 bool DecodePNG(std::string base64_data, SkBitmap* bitmap) { |
| 527 std::string png_data; | 459 std::string png_data; |
| 528 if (!base::Base64Decode(base64_data, &png_data)) | 460 if (!base::Base64Decode(base64_data, &png_data)) |
| 529 return false; | 461 return false; |
| 530 return gfx::PNGCodec::Decode( | 462 return gfx::PNGCodec::Decode( |
| 531 reinterpret_cast<unsigned const char*>(png_data.data()), png_data.size(), | 463 reinterpret_cast<unsigned const char*>(png_data.data()), png_data.size(), |
| 532 bitmap); | 464 bitmap); |
| 533 } | 465 } |
| 534 | 466 |
| (...skipping 1042 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1577 EXPECT_EQ("polyglottal", value); | 1509 EXPECT_EQ("polyglottal", value); |
| 1578 found++; | 1510 found++; |
| 1579 } else { | 1511 } else { |
| 1580 FAIL(); | 1512 FAIL(); |
| 1581 } | 1513 } |
| 1582 } | 1514 } |
| 1583 EXPECT_EQ(2u, found); | 1515 EXPECT_EQ(2u, found); |
| 1584 } | 1516 } |
| 1585 | 1517 |
| 1586 } // namespace content | 1518 } // namespace content |
| OLD | NEW |