forked from Pissandshittium/pissandshittium
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Rewrite hr-timestamp/input-events.html to a browser test
hr-timestamp/input-events.htmlEvent timestamp tests that the received events on the page should be equal to the timestamp provided by the eventSender's recorded last event. But we should deprecate eventSender in the future, and GpuBenchmarking sends events based on the current system time, which cannot be equal to the received events' timestamp. Bug: 1047176 Change-Id: I225dec07b1928ae254d61e8a8384ebfc7dab75e6 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2173421 Commit-Queue: Lan Wei <lanwei@chromium.org> Reviewed-by: David Bokan <bokan@chromium.org> Reviewed-by: Majid Valipour <majidvp@chromium.org> Cr-Commit-Position: refs/heads/master@{#790868}
- Loading branch information
Showing
9 changed files
with
348 additions
and
50 deletions.
There are no files selected for viewing
319 changes: 319 additions & 0 deletions
319
content/browser/renderer_host/input/input_event_browsertest.cc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,319 @@ | ||
// Copyright 2020 The Chromium Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#include "base/command_line.h" | ||
#include "base/json/json_reader.h" | ||
#include "base/macros.h" | ||
#include "base/strings/utf_string_conversions.h" | ||
#include "base/test/bind_test_util.h" | ||
#include "base/test/scoped_feature_list.h" | ||
#include "build/build_config.h" | ||
#include "content/browser/renderer_host/input/synthetic_gesture_controller.h" | ||
#include "content/browser/renderer_host/input/synthetic_gesture_target.h" | ||
#include "content/browser/renderer_host/input/synthetic_pointer_driver.h" | ||
#include "content/browser/renderer_host/render_widget_host_impl.h" | ||
#include "content/browser/renderer_host/render_widget_host_view_base.h" | ||
#include "content/browser/web_contents/web_contents_impl.h" | ||
#include "content/public/browser/render_view_host.h" | ||
#include "content/public/browser/render_widget_host_view.h" | ||
#include "content/public/common/content_switches.h" | ||
#include "content/public/test/browser_test.h" | ||
#include "content/public/test/browser_test_utils.h" | ||
#include "content/public/test/content_browser_test.h" | ||
#include "content/public/test/content_browser_test_utils.h" | ||
#include "content/public/test/hit_test_region_observer.h" | ||
#include "content/shell/browser/shell.h" | ||
#include "content/shell/common/shell_switches.h" | ||
#include "third_party/blink/public/common/input/synthetic_web_input_event_builders.h" | ||
#include "third_party/blink/public/common/input/web_input_event.h" | ||
#include "ui/events/blink/blink_features.h" | ||
#include "ui/events/keycodes/dom/keycode_converter.h" | ||
|
||
namespace { | ||
|
||
const std::string kEventListenerDataURL = R"HTML( | ||
<!DOCTYPE html> | ||
<meta name='viewport' content='width=device-width'/> | ||
<style> | ||
html, body { | ||
margin: 0; | ||
} | ||
.spacer { height: 10000px; } | ||
</style> | ||
<div class=spacer></div> | ||
<script type="text/javascript"> | ||
window.eventCounts = | ||
{mousedown: 0, keydown: 0, touchstart: 0, click: 0, wheel: 0}; | ||
window.eventTimeStamp = | ||
{mousedown: 0, keydown: 0, touchstart: 0, click: 0, wheel: 0}; | ||
function recordEvent(e) { | ||
eventCounts[e.type]++; | ||
if (eventCounts[e.type] == 1) | ||
eventTimeStamp[e.type] = e.timeStamp; | ||
} | ||
for (var evt in eventCounts) { | ||
document.addEventListener(evt, recordEvent); | ||
} | ||
document.title='ready'; | ||
</script>)HTML"; | ||
|
||
} // namespace | ||
|
||
namespace content { | ||
|
||
class InputEventBrowserTest : public ContentBrowserTest { | ||
public: | ||
InputEventBrowserTest() = default; | ||
~InputEventBrowserTest() override = default; | ||
|
||
RenderWidgetHostImpl* GetWidgetHost() { | ||
return RenderWidgetHostImpl::From( | ||
shell()->web_contents()->GetRenderViewHost()->GetWidget()); | ||
} | ||
|
||
protected: | ||
void SetUpCommandLine(base::CommandLine* command_line) override { | ||
ContentBrowserTest::SetUpCommandLine(command_line); | ||
command_line->AppendSwitch(switches::kExposeInternalsForTesting); | ||
} | ||
|
||
void LoadURL(const std::string& page_data) { | ||
const GURL data_url("data:text/html," + page_data); | ||
EXPECT_TRUE(NavigateToURL(shell(), data_url)); | ||
|
||
RenderWidgetHostImpl* host = GetWidgetHost(); | ||
frame_observer_ = std::make_unique<RenderFrameSubmissionObserver>( | ||
host->render_frame_metadata_provider()); | ||
host->GetView()->SetSize(gfx::Size(400, 400)); | ||
|
||
base::string16 ready_title(base::ASCIIToUTF16("ready")); | ||
TitleWatcher watcher(shell()->web_contents(), ready_title); | ||
ignore_result(watcher.WaitAndGetTitle()); | ||
|
||
// We need to wait until hit test data is available. We use our own | ||
// HitTestRegionObserver here because we have the RenderWidgetHostImpl | ||
// available. | ||
HitTestRegionObserver observer(host->GetFrameSinkId()); | ||
observer.WaitForHitTestData(); | ||
} | ||
|
||
// ContentBrowserTest: | ||
void PostRunTestOnMainThread() override { | ||
// Delete this before the WebContents is destroyed. | ||
frame_observer_.reset(); | ||
ContentBrowserTest::PostRunTestOnMainThread(); | ||
} | ||
|
||
bool URLLoaded() { | ||
base::string16 ready_title(base::ASCIIToUTF16("ready")); | ||
TitleWatcher watcher(shell()->web_contents(), ready_title); | ||
const base::string16 title = watcher.WaitAndGetTitle(); | ||
return title == ready_title; | ||
} | ||
|
||
int ExecuteScriptAndExtractInt(const std::string& script) { | ||
int value = 0; | ||
EXPECT_TRUE(content::ExecuteScriptAndExtractInt( | ||
shell(), "domAutomationController.send(" + script + ")", &value)); | ||
return value; | ||
} | ||
|
||
double ExecuteScriptAndExtractDouble(const std::string& script) { | ||
double value = 0; | ||
EXPECT_TRUE(content::ExecuteScriptAndExtractDouble( | ||
shell(), "domAutomationController.send(" + script + ")", &value)); | ||
return value; | ||
} | ||
|
||
void SimulateSyntheticMousePressAt(base::TimeTicks event_time) { | ||
DCHECK(URLLoaded()); | ||
|
||
std::unique_ptr<SyntheticPointerDriver> synthetic_pointer_driver = | ||
SyntheticPointerDriver::Create(SyntheticGestureParams::MOUSE_INPUT); | ||
RenderWidgetHostImpl* render_widget_host = GetWidgetHost(); | ||
auto* root_view = render_widget_host->GetView()->GetRootView(); | ||
std::unique_ptr<SyntheticGestureTarget> synthetic_gesture_target; | ||
if (root_view) | ||
synthetic_gesture_target = root_view->CreateSyntheticGestureTarget(); | ||
else | ||
synthetic_gesture_target = | ||
render_widget_host->GetView()->CreateSyntheticGestureTarget(); | ||
|
||
synthetic_pointer_driver->Press(50, 50, 0, | ||
SyntheticPointerActionParams::Button::LEFT); | ||
synthetic_pointer_driver->DispatchEvent(synthetic_gesture_target.get(), | ||
event_time); | ||
|
||
synthetic_pointer_driver->Release( | ||
0, SyntheticPointerActionParams::Button::LEFT); | ||
synthetic_pointer_driver->DispatchEvent(synthetic_gesture_target.get(), | ||
event_time); | ||
} | ||
|
||
void SimulateSyntheticKeyDown(base::TimeTicks event_time) { | ||
DCHECK(URLLoaded()); | ||
|
||
content::NativeWebKeyboardEvent event( | ||
blink::WebKeyboardEvent::Type::kRawKeyDown, | ||
blink::WebInputEvent::kNoModifiers, event_time); | ||
event.windows_key_code = ui::VKEY_DOWN; | ||
event.native_key_code = | ||
ui::KeycodeConverter::DomCodeToNativeKeycode(ui::DomCode::ARROW_DOWN); | ||
event.dom_code = static_cast<int>(ui::DomCode::ARROW_DOWN); | ||
event.dom_key = ui::DomKey::ARROW_DOWN; | ||
GetWidgetHost()->ForwardKeyboardEvent(event); | ||
} | ||
|
||
void SimulateSyntheticTouchTapAt(base::TimeTicks event_time) { | ||
DCHECK(URLLoaded()); | ||
|
||
std::unique_ptr<SyntheticPointerDriver> synthetic_pointer_driver = | ||
SyntheticPointerDriver::Create(SyntheticGestureParams::TOUCH_INPUT); | ||
RenderWidgetHostImpl* render_widget_host = GetWidgetHost(); | ||
auto* root_view = render_widget_host->GetView()->GetRootView(); | ||
std::unique_ptr<SyntheticGestureTarget> synthetic_gesture_target; | ||
if (root_view) | ||
synthetic_gesture_target = root_view->CreateSyntheticGestureTarget(); | ||
else | ||
synthetic_gesture_target = | ||
render_widget_host->GetView()->CreateSyntheticGestureTarget(); | ||
|
||
synthetic_pointer_driver->Press(50, 50, 0, | ||
SyntheticPointerActionParams::Button::LEFT); | ||
synthetic_pointer_driver->DispatchEvent(synthetic_gesture_target.get(), | ||
event_time); | ||
|
||
synthetic_pointer_driver->Release( | ||
0, SyntheticPointerActionParams::Button::LEFT); | ||
synthetic_pointer_driver->DispatchEvent(synthetic_gesture_target.get(), | ||
event_time); | ||
} | ||
|
||
void SimulateSyntheticWheelScroll(base::TimeTicks event_time) { | ||
DCHECK(URLLoaded()); | ||
|
||
double x = 50; | ||
double y = 50; | ||
blink::WebMouseWheelEvent wheel_event = | ||
blink::SyntheticWebMouseWheelEventBuilder::Build( | ||
x, y, x, y, 20, 20, 0, | ||
ui::ScrollGranularity::kScrollByPrecisePixel); | ||
wheel_event.phase = blink::WebMouseWheelEvent::kPhaseBegan; | ||
wheel_event.SetTimeStamp(event_time); | ||
GetWidgetHost()->ForwardWheelEvent(wheel_event); | ||
} | ||
|
||
private: | ||
std::unique_ptr<RenderFrameSubmissionObserver> frame_observer_; | ||
|
||
DISALLOW_COPY_AND_ASSIGN(InputEventBrowserTest); | ||
}; | ||
|
||
#if defined(OS_ANDROID) | ||
// Android does not support synthetic mouse events. | ||
// TODO(lanwei): support dispatching WebMouseEvent in | ||
// SyntheticGestureTargetAndroid. | ||
#define MAYBE_MouseDownEventTimeStamp DISABLED_MouseDownEventTimeStamp | ||
#else | ||
#define MAYBE_MouseDownEventTimeStamp MouseDownEventTimeStamp | ||
#endif | ||
IN_PROC_BROWSER_TEST_F(InputEventBrowserTest, MAYBE_MouseDownEventTimeStamp) { | ||
LoadURL(kEventListenerDataURL); | ||
|
||
MainThreadFrameObserver frame_observer( | ||
shell()->web_contents()->GetRenderViewHost()->GetWidget()); | ||
base::TimeTicks event_time = base::TimeTicks::Now(); | ||
int64_t event_time_ms = event_time.since_origin().InMilliseconds(); | ||
SimulateSyntheticMousePressAt(event_time); | ||
while (ExecuteScriptAndExtractInt("eventCounts.mousedown") == 0) | ||
frame_observer.Wait(); | ||
|
||
int64_t monotonic_time = ExecuteScriptAndExtractDouble( | ||
"internals.zeroBasedDocumentTimeToMonotonicTime(eventTimeStamp." | ||
"mousedown)"); | ||
EXPECT_EQ(1, ExecuteScriptAndExtractInt("eventCounts.mousedown")); | ||
EXPECT_EQ(event_time_ms, monotonic_time); | ||
} | ||
|
||
IN_PROC_BROWSER_TEST_F(InputEventBrowserTest, KeyDownEventTimeStamp) { | ||
LoadURL(kEventListenerDataURL); | ||
|
||
MainThreadFrameObserver frame_observer( | ||
shell()->web_contents()->GetRenderViewHost()->GetWidget()); | ||
|
||
base::TimeTicks event_time = base::TimeTicks::Now(); | ||
int64_t event_time_ms = event_time.since_origin().InMilliseconds(); | ||
SimulateSyntheticKeyDown(event_time); | ||
|
||
while (ExecuteScriptAndExtractInt("eventCounts.keydown") == 0) | ||
frame_observer.Wait(); | ||
|
||
int64_t monotonic_time = ExecuteScriptAndExtractDouble( | ||
"internals.zeroBasedDocumentTimeToMonotonicTime(eventTimeStamp." | ||
"keydown)"); | ||
EXPECT_EQ(1, ExecuteScriptAndExtractInt("eventCounts.keydown")); | ||
EXPECT_EQ(event_time_ms, monotonic_time); | ||
} | ||
|
||
IN_PROC_BROWSER_TEST_F(InputEventBrowserTest, TouchStartEventTimeStamp) { | ||
LoadURL(kEventListenerDataURL); | ||
|
||
MainThreadFrameObserver frame_observer( | ||
shell()->web_contents()->GetRenderViewHost()->GetWidget()); | ||
|
||
base::TimeTicks event_time = base::TimeTicks::Now(); | ||
int64_t event_time_ms = event_time.since_origin().InMilliseconds(); | ||
SimulateSyntheticTouchTapAt(event_time); | ||
|
||
while (ExecuteScriptAndExtractInt("eventCounts.touchstart") == 0) | ||
frame_observer.Wait(); | ||
|
||
int64_t monotonic_time = ExecuteScriptAndExtractDouble( | ||
"internals.zeroBasedDocumentTimeToMonotonicTime(eventTimeStamp." | ||
"touchstart)"); | ||
EXPECT_EQ(1, ExecuteScriptAndExtractInt("eventCounts.touchstart")); | ||
EXPECT_EQ(event_time_ms, monotonic_time); | ||
} | ||
|
||
IN_PROC_BROWSER_TEST_F(InputEventBrowserTest, ClickEventTimeStamp) { | ||
LoadURL(kEventListenerDataURL); | ||
|
||
MainThreadFrameObserver frame_observer( | ||
shell()->web_contents()->GetRenderViewHost()->GetWidget()); | ||
|
||
base::TimeTicks event_time = base::TimeTicks::Now(); | ||
int64_t event_time_ms = event_time.since_origin().InMilliseconds(); | ||
SimulateSyntheticTouchTapAt(event_time); | ||
|
||
while (ExecuteScriptAndExtractInt("eventCounts.click") == 0) | ||
frame_observer.Wait(); | ||
|
||
int64_t monotonic_time = ExecuteScriptAndExtractDouble( | ||
"internals.zeroBasedDocumentTimeToMonotonicTime(eventTimeStamp." | ||
"click)"); | ||
EXPECT_EQ(1, ExecuteScriptAndExtractInt("eventCounts.click")); | ||
EXPECT_EQ(event_time_ms, monotonic_time); | ||
} | ||
|
||
IN_PROC_BROWSER_TEST_F(InputEventBrowserTest, WheelEventTimeStamp) { | ||
LoadURL(kEventListenerDataURL); | ||
|
||
MainThreadFrameObserver frame_observer( | ||
shell()->web_contents()->GetRenderViewHost()->GetWidget()); | ||
|
||
base::TimeTicks event_time = base::TimeTicks::Now(); | ||
int64_t event_time_ms = event_time.since_origin().InMilliseconds(); | ||
SimulateSyntheticWheelScroll(event_time); | ||
|
||
while (ExecuteScriptAndExtractInt("eventCounts.wheel") == 0) | ||
frame_observer.Wait(); | ||
|
||
int64_t monotonic_time = ExecuteScriptAndExtractDouble( | ||
"internals.zeroBasedDocumentTimeToMonotonicTime(eventTimeStamp." | ||
"wheel)"); | ||
EXPECT_GE(ExecuteScriptAndExtractInt("eventCounts.wheel"), 1); | ||
EXPECT_EQ(event_time_ms, monotonic_time); | ||
} | ||
|
||
} // namespace content |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.