Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(637)

Side by Side Diff: content/browser/devtools/protocol/devtools_protocol_browsertest.cc

Issue 2387353004: Delay Input.dispatchKeyEvent response until after key event ack. (Closed)
Patch Set: add test, address review comments about docs Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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 waiting_for_command_result_id_ = last_sent_id_; 190 WaitForResponse();
191 base::RunLoop().Run();
192 }
193 in_dispatch_ = false; 191 in_dispatch_ = false;
194 } 192 }
195 193
194 void WaitForResponse() {
195 waiting_for_command_result_id_ = last_sent_id_;
196 base::RunLoop().Run();
197 }
198
196 bool HasValue(const std::string& path) { 199 bool HasValue(const std::string& path) {
197 base::Value* value = 0; 200 base::Value* value = 0;
198 return result_->Get(path, &value); 201 return result_->Get(path, &value);
199 } 202 }
200 203
201 bool HasListItem(const std::string& path_to_list, 204 bool HasListItem(const std::string& path_to_list,
202 const std::string& name, 205 const std::string& name,
203 const std::string& value) { 206 const std::string& value) {
204 base::ListValue* list; 207 base::ListValue* list;
205 if (!result_->GetList(path_to_list, &list)) 208 if (!result_->GetList(path_to_list, &list))
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after
402 // InterstitialPageDelegate: 405 // InterstitialPageDelegate:
403 std::string GetHTMLContents() override { return "<p>Interstitial</p>"; } 406 std::string GetHTMLContents() override { return "<p>Interstitial</p>"; }
404 }; 407 };
405 408
406 class SyntheticKeyEventTest : public DevToolsProtocolTest { 409 class SyntheticKeyEventTest : public DevToolsProtocolTest {
407 protected: 410 protected:
408 void SendKeyEvent(const std::string& type, 411 void SendKeyEvent(const std::string& type,
409 int modifier, 412 int modifier,
410 int windowsKeyCode, 413 int windowsKeyCode,
411 int nativeKeyCode, 414 int nativeKeyCode,
412 const std::string& key) { 415 const std::string& key,
416 bool wait) {
413 std::unique_ptr<base::DictionaryValue> params(new base::DictionaryValue()); 417 std::unique_ptr<base::DictionaryValue> params(new base::DictionaryValue());
414 params->SetString("type", type); 418 params->SetString("type", type);
415 params->SetInteger("modifiers", modifier); 419 params->SetInteger("modifiers", modifier);
416 params->SetInteger("windowsVirtualKeyCode", windowsKeyCode); 420 params->SetInteger("windowsVirtualKeyCode", windowsKeyCode);
417 params->SetInteger("nativeVirtualKeyCode", nativeKeyCode); 421 params->SetInteger("nativeVirtualKeyCode", nativeKeyCode);
418 params->SetString("key", key); 422 params->SetString("key", key);
419 SendCommand("Input.dispatchKeyEvent", std::move(params)); 423 SendCommand("Input.dispatchKeyEvent", std::move(params), wait);
420 } 424 }
421 }; 425 };
422 426
423 IN_PROC_BROWSER_TEST_F(SyntheticKeyEventTest, KeyEventSynthesizeKey) { 427 IN_PROC_BROWSER_TEST_F(SyntheticKeyEventTest, KeyEventSynthesizeKey) {
424 NavigateToURLBlockUntilNavigationsComplete(shell(), GURL("about:blank"), 1); 428 NavigateToURLBlockUntilNavigationsComplete(shell(), GURL("about:blank"), 1);
425 Attach(); 429 Attach();
426 ASSERT_TRUE(content::ExecuteScript( 430 ASSERT_TRUE(content::ExecuteScript(
427 shell()->web_contents()->GetRenderViewHost(), 431 shell()->web_contents()->GetRenderViewHost(),
428 "function handleKeyEvent(event) {" 432 "function handleKeyEvent(event) {"
429 "domAutomationController.setAutomationId(0);" 433 "domAutomationController.setAutomationId(0);"
430 "domAutomationController.send(event.key);" 434 "domAutomationController.send(event.key);"
431 "}" 435 "}"
432 "document.body.addEventListener('keydown', handleKeyEvent);" 436 "document.body.addEventListener('keydown', handleKeyEvent);"
433 "document.body.addEventListener('keyup', handleKeyEvent);")); 437 "document.body.addEventListener('keyup', handleKeyEvent);"));
434 438
435 DOMMessageQueue dom_message_queue; 439 DOMMessageQueue dom_message_queue;
436 440
437 // Send enter (keycode 13). 441 // Send enter (keycode 13).
438 SendKeyEvent("rawKeyDown", 0, 13, 13, "Enter"); 442 SendKeyEvent("rawKeyDown", 0, 13, 13, "Enter", true);
439 SendKeyEvent("keyUp", 0, 13, 13, "Enter"); 443 SendKeyEvent("keyUp", 0, 13, 13, "Enter", true);
440 444
441 std::string key; 445 std::string key;
442 ASSERT_TRUE(dom_message_queue.WaitForMessage(&key)); 446 ASSERT_TRUE(dom_message_queue.WaitForMessage(&key));
443 EXPECT_EQ("\"Enter\"", key); 447 EXPECT_EQ("\"Enter\"", key);
444 ASSERT_TRUE(dom_message_queue.WaitForMessage(&key)); 448 ASSERT_TRUE(dom_message_queue.WaitForMessage(&key));
445 EXPECT_EQ("\"Enter\"", key); 449 EXPECT_EQ("\"Enter\"", key);
446 450
447 // Send escape (keycode 27). 451 // Send escape (keycode 27).
448 SendKeyEvent("rawKeyDown", 0, 27, 27, "Escape"); 452 SendKeyEvent("rawKeyDown", 0, 27, 27, "Escape", true);
449 SendKeyEvent("keyUp", 0, 27, 27, "Escape"); 453 SendKeyEvent("keyUp", 0, 27, 27, "Escape", true);
450 454
451 ASSERT_TRUE(dom_message_queue.WaitForMessage(&key)); 455 ASSERT_TRUE(dom_message_queue.WaitForMessage(&key));
452 EXPECT_EQ("\"Escape\"", key); 456 EXPECT_EQ("\"Escape\"", key);
453 ASSERT_TRUE(dom_message_queue.WaitForMessage(&key)); 457 ASSERT_TRUE(dom_message_queue.WaitForMessage(&key));
454 EXPECT_EQ("\"Escape\"", key); 458 EXPECT_EQ("\"Escape\"", key);
455 } 459 }
456 460
461 IN_PROC_BROWSER_TEST_F(SyntheticKeyEventTest, DispatchKeyEventBlocksUntilAck) {
462 GURL test_url = GetTestUrl("devtools", "key_event_test.html");
463 NavigateToURLBlockUntilNavigationsComplete(shell(), test_url, 1);
464 Attach();
465
466 DOMMessageQueue dom_message_queue;
467 scoped_refptr<InputMsgWatcher> filter = new InputMsgWatcher(
468 RenderWidgetHostImpl::From(
469 shell()->web_contents()->GetRenderViewHost()->GetWidget()),
470 blink::WebInputEvent::RawKeyDown);
471
472 // Call Input.dispatchKeyEvent, but don't wait for a response.
473 SendKeyEvent("rawKeyDown", 0, 13, 13, "Enter", false);
474 // Make sure we've entered the page's keydown event listener.
475 std::string message;
476 ASSERT_TRUE(dom_message_queue.WaitForMessage(&message));
477 EXPECT_EQ("\"entered keydown listener\"", message);
478 // Check that an ack was not received before the response.
479 ASSERT_FALSE(filter->HasReceivedAck());
480 // Check that an ack is received after the response.
481 WaitForResponse();
482 ASSERT_EQ(INPUT_EVENT_ACK_STATE_NOT_CONSUMED, filter->WaitForAck());
483 }
484
457 namespace { 485 namespace {
458 bool DecodePNG(std::string base64_data, SkBitmap* bitmap) { 486 bool DecodePNG(std::string base64_data, SkBitmap* bitmap) {
459 std::string png_data; 487 std::string png_data;
460 if (!base::Base64Decode(base64_data, &png_data)) 488 if (!base::Base64Decode(base64_data, &png_data))
461 return false; 489 return false;
462 return gfx::PNGCodec::Decode( 490 return gfx::PNGCodec::Decode(
463 reinterpret_cast<unsigned const char*>(png_data.data()), png_data.size(), 491 reinterpret_cast<unsigned const char*>(png_data.data()), png_data.size(),
464 bitmap); 492 bitmap);
465 } 493 }
466 494
(...skipping 928 matching lines...) Expand 10 before | Expand all | Expand 10 after
1395 command_params.reset(new base::DictionaryValue()); 1423 command_params.reset(new base::DictionaryValue());
1396 command_params->SetBoolean("autoAttach", false); 1424 command_params->SetBoolean("autoAttach", false);
1397 command_params->SetBoolean("waitForDebuggerOnStart", false); 1425 command_params->SetBoolean("waitForDebuggerOnStart", false);
1398 SendCommand("Target.setAutoAttach", std::move(command_params), false); 1426 SendCommand("Target.setAutoAttach", std::move(command_params), false);
1399 params = WaitForNotification("Target.detachedFromTarget", true); 1427 params = WaitForNotification("Target.detachedFromTarget", true);
1400 EXPECT_TRUE(params->GetString("targetId", &temp)); 1428 EXPECT_TRUE(params->GetString("targetId", &temp));
1401 EXPECT_EQ(target_id, temp); 1429 EXPECT_EQ(target_id, temp);
1402 } 1430 }
1403 1431
1404 } // namespace content 1432 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698