Commit 4fba42af authored by Lan Wei's avatar Lan Wei Committed by Chromium LUCI CQ

Simulate user inputs in input-events/input-events-get-target-ranges.html

Use testdriver Action API to simulate key actions in
input-events/input-events-get-target-ranges.html Added . We have to
disable it because we do not support key actions in gpuBenchmarking
when running the tests in our chromium bots.

Bug: 1145677
Change-Id: I5176f374aaa79d771a78ef651f63098f039101da
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2533965
Commit-Queue: Lan Wei <lanwei@chromium.org>
Reviewed-by: default avatarMustaq Ahmed <mustaq@chromium.org>
Cr-Commit-Position: refs/heads/master@{#833135}
parent f1f9eac7
...@@ -2121,6 +2121,7 @@ crbug.com/1040611 external/wpt/uievents/order-of-events/mouse-events/wheel-basic ...@@ -2121,6 +2121,7 @@ crbug.com/1040611 external/wpt/uievents/order-of-events/mouse-events/wheel-basic
crbug.com/1040611 external/wpt/uievents/order-of-events/mouse-events/wheel-scrolling.html [ Failure Timeout ] crbug.com/1040611 external/wpt/uievents/order-of-events/mouse-events/wheel-scrolling.html [ Failure Timeout ]
crbug.com/893480 external/wpt/css/css-scroll-snap/input/keyboard.html [ Failure Timeout ] crbug.com/893480 external/wpt/css/css-scroll-snap/input/keyboard.html [ Failure Timeout ]
crbug.com/893480 external/wpt/infrastructure/testdriver/actions/textEditCommands.html [ Failure Timeout ] crbug.com/893480 external/wpt/infrastructure/testdriver/actions/textEditCommands.html [ Failure Timeout ]
crbug.com/893480 external/wpt/input-events/input-events-get-target-ranges.html [ Failure Timeout ]
# isInputPending requires threaded compositing and layerized iframes # isInputPending requires threaded compositing and layerized iframes
crbug.com/910421 external/wpt/is-input-pending/* [ Skip ] crbug.com/910421 external/wpt/is-input-pending/* [ Skip ]
......
<!DOCTYPE html>
<meta charset="utf-8">
<title>InputEvent.getTargetRanges() behavior</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-actions.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<p>To manually run this test, please follow the steps below:<br/>
1. Place caret at the end of 'hel<i>lo wo</i><b>rld</b>'.<br/>
2. Press Ctrl-Backspace (Alt-Backspace on macOS) to delete word backwards.<br/>
3. Place caret at the end of 'test2' => Press 'a' key.<br/>
4. Select 'test2a' => Press 'b' key.<br/>
5. Select 'b' => Bold text through context menu or Command-b on macOS.<br/>
6. Place caret at the end of 'test3' => Press 'a' key => Press Backspace key.<br/>
<br/>
If a "PASS" result appears the test passes, otherwise it fails</p>
<p id="test1_editable" contenteditable>hel<i>lo wo</i><b>rld</b></p>
<p id="test2_editable" contenteditable>test2</p>
<textarea id="test3_plain">test3</textarea>
<script>
function resolveWhen(condition) {
return new Promise((resolve, reject) => {
function tick() {
if (condition())
resolve();
else
requestAnimationFrame(tick.bind(this));
}
tick();
});
}
let modifier_key = "\uE009";
if(navigator.platform.includes('Mac'))
modifier_key = "\uE03D";
const commands = {
COPY: 'copy',
CUT: 'cut',
PASTE: 'paste',
SELECTALL: 'select all',
DELETEALL: 'delete all',
BOLD: 'bold',
}
const backspace = "\uE003";
function clickOnTarget(target) {
return new test_driver.Actions()
.pointerMove(0, 0, {origin: target})
.pointerDown()
.pointerUp()
.send();
}
function sendTextCommand(command) {
let command_key = "";
if(command == "copy")
command_key = "c";
else if (command == "cut")
command_key = "x";
else if (command == "paste")
command_key = "v";
else if (command == "select all")
command_key = "a";
else if (command == "delete all")
command_key = backspace;
else if (command == "bold")
command_key = "b";
return new test_driver.Actions()
.keyDown(modifier_key)
.keyDown(command_key)
.keyUp(command_key)
.keyUp(modifier_key)
.send();
}
function sendTextCommandAtTarget(target, command) {
return clickOnTarget(target).then(() => {
return sendTextCommand(command);
});
}
function addTextAtTarget(target, char) {
return test_driver.send_keys(target, char);
}
promise_test(async test => {
const test1_editable = document.getElementById('test1_editable');
let lastBeforeInput;
test1_editable.addEventListener('beforeinput', test.step_func(function() {
assert_equals(event.inputType, 'deleteWordBackward');
const ranges = event.getTargetRanges();
assert_equals(ranges.length, 1);
const range = ranges[0];
assert_true(range instanceof StaticRange);
assert_equals(range.startOffset, 3);
assert_equals(range.startContainer.textContent, 'lo wo');
assert_equals(range.endOffset, 3);
assert_equals(range.endContainer.textContent, 'rld');
assert_equals(test1_editable.innerHTML, 'hel<i>lo wo</i><b>rld</b>');
lastBeforeInput = event;
}));
test1_editable.addEventListener('input', test.step_func(function() {
assert_equals(event.inputType, 'deleteWordBackward');
assert_equals(test1_editable.innerHTML, 'hel<i>lo&nbsp;</i>');
assert_equals(lastBeforeInput.inputType, 'deleteWordBackward');
assert_equals(lastBeforeInput.getTargetRanges().length, 0,
'getTargetRanges() should be empty after the event has finished dispatching.');
}));
await sendTextCommandAtTarget(test1_editable, commands.DELETEALL);
await resolveWhen(() => { return test1_editable.innerHTML == 'hel<i>lo&nbsp;</i>' });
}, 'getTargetRanges() returns correct range and cleared after dispatch.');
promise_test(async test => {
const expectedEventLog = ['test2-5-test2-5', 'test2a-0-test2a-6', 'b-0-b-1'];
const actualEventLog = [];
const test2_editable = document.getElementById('test2_editable');
test2_editable.addEventListener('beforeinput', test.step_func(function() {
const ranges = event.getTargetRanges();
assert_equals(ranges.length, 1);
const range = ranges[0];
actualEventLog.push(
`${range.startContainer.textContent}-${range.startOffset}-${range.endContainer.textContent}-${range.endOffset}`);
}));
await addTextAtTarget(test2_editable, "a");
await sendTextCommandAtTarget(test2_editable, commands.SELECTALL);
await addTextAtTarget(test2_editable, "b");
await sendTextCommandAtTarget(test2_editable, commands.SELECTALL);
await sendTextCommand(commands.BOLD);
await resolveWhen(() => { return actualEventLog.length == expectedEventLog.length });
assert_array_equals(actualEventLog, expectedEventLog,
`Expected: ${expectedEventLog}; Actual: ${actualEventLog}.`);
}, 'Actions other than deletion should have current selection as target ranges.');
promise_test(async test => {
const test3_plain = document.getElementById('test3_plain');
let event_type;
test3_plain.addEventListener('beforeinput', test.step_func(function() {
assert_equals(event.getTargetRanges().length, 0,
'getTargetRanges() should return empty array on textarea.');
if (event.inputType === 'deleteContentBackward')
event_type = event.inputType;
}));
await addTextAtTarget(test3_plain, "a");
await addTextAtTarget(test3_plain, backspace);
await resolveWhen(() => { return event_type == 'deleteContentBackward' });
}, 'Textarea should have empty target range.');
</script>
importAutomationScript('/input-events/inputevent_common_input.js');
function inject_input() {
let isMacOSX = navigator.userAgent.indexOf("Mac OS X") != -1;
return collapseEndAndKeyDown('#test1_editable', 'Backspace', [isMacOSX ? 'altKey' : 'ctrlKey']).then(() => {
return collapseEndAndKeyDown('#test2_editable', 'a');
}).then(() => {
return selectAndKeyDown('#test2_editable', 'b');
}).then(() => {
selectAndExecCommand('#test2_editable', 'bold');
return focusAndKeyDown('#test3_plain', 'a');
}).then(() => {
return keyDown('Backspace');
});
}
<!DOCTYPE html> <!DOCTYPE html>
<meta charset="utf-8"> <meta charset="utf-8">
<title>InputEvent.getTargetRanges() behavior</title> <title>InputEvent.getTargetRanges() behavior</title>
<script src="/resources/testharness.js"></script> <script src="../../../resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script> <script src="../../../resources/testharnessreport.js"></script>
<script src="../../../resources/testdriver.js"></script>
<script src="../../../resources/testdriver-actions.js"></script>
<script src="../../../resources/testdriver-vendor.js"></script>
<script src="resources/inputevent_common_input.js"></script>
<!--
This layout tests is a duplicate of a WPT test wpt/input-events/
input-events-get-target-ranges.html. We need this duplicated test
to maintain test coverage because testdriver's key actions are not
supported in GpuBenchmarking::PointerActionSequence, which is used
to run layout tests.
-->
<p>To manually run this test, please follow the steps below:<br/> <p>To manually run this test, please follow the steps below:<br/>
1. Place caret at the end of 'hel<i>lo wo</i><b>rld</b>'.<br/> 1. Place caret at the end of 'hel<i>lo wo</i><b>rld</b>'.<br/>
2. Press Ctrl-Backspace (Alt-Backspace on macOS) to delete word backwards.<br/> 2. Press Ctrl-Backspace (Alt-Backspace on macOS) to delete word backwards.<br/>
...@@ -16,6 +27,20 @@ If a "PASS" result appears the test passes, otherwise it fails</p> ...@@ -16,6 +27,20 @@ If a "PASS" result appears the test passes, otherwise it fails</p>
<p id="test2_editable" contenteditable>test2</p> <p id="test2_editable" contenteditable>test2</p>
<textarea id="test3_plain">test3</textarea> <textarea id="test3_plain">test3</textarea>
<script> <script>
function inject_input() {
let isMacOSX = navigator.userAgent.indexOf("Mac OS X") != -1;
return collapseEndAndKeyDown('#test1_editable', 'Backspace', [isMacOSX ? 'altKey' : 'ctrlKey']).then(() => {
return collapseEndAndKeyDown('#test2_editable', 'a');
}).then(() => {
return selectAndKeyDown('#test2_editable', 'b');
}).then(() => {
selectAndExecCommand('#test2_editable', 'bold');
return focusAndKeyDown('#test3_plain', 'a');
}).then(() => {
return keyDown('Backspace');
});
}
async_test(t => { async_test(t => {
const test1_editable = document.getElementById('test1_editable'); const test1_editable = document.getElementById('test1_editable');
let lastBeforeInput; let lastBeforeInput;
...@@ -73,4 +98,6 @@ async_test(t => { ...@@ -73,4 +98,6 @@ async_test(t => {
t.done(); t.done();
})); }));
}, 'Textarea should have empty target range.'); }, 'Textarea should have empty target range.');
inject_input();
</script> </script>
// Returns a Promise for future conversion into WebDriver-backed API.
function keyDown(key, modifiers) {
return new Promise(function(resolve, reject) {
if (window.eventSender) {
eventSender.keyDown(key, modifiers);
resolve();
} else {
reject();
}
});
}
function selectTarget(selector) {
const target = document.querySelector(selector);
if (target.select) {
target.select();
} else {
const selection = window.getSelection();
selection.collapse(target, 0);
selection.extend(target, 1);
}
}
function focusAndKeyDown(selector, key) {
const target = document.querySelector(selector);
return test_driver.send_keys(target, key);
}
function collapseEndAndKeyDown(selector, key, modifiers) {
const target = document.querySelector(selector);
window.getSelection().collapse(target.lastElementChild || target, 1);
return keyDown(key, modifiers);
}
function selectAndKeyDown(selector, key) {
const target = document.querySelector(selector);
selectTarget(selector);
return test_driver.send_keys(target, key);
}
function selectAndExecCommand(selector, command) {
assert_not_equals(window.testRunner, undefined, 'This test requires testRunner.');
selectTarget(selector);
testRunner.execCommand(command);
}
...@@ -118,6 +118,8 @@ ...@@ -118,6 +118,8 @@
eventSenderKeys = "ArrowDown"; eventSenderKeys = "ArrowDown";
} else if (charCode == 0xE00C) { } else if (charCode == 0xE00C) {
eventSenderKeys = "Escape"; eventSenderKeys = "Escape";
} else if (charCode == 0xE003) {
eventSenderKeys = "Backspace";
} else if (charCode == 0xE009) { } else if (charCode == 0xE009) {
eventSenderKeys = "ControlLeft"; eventSenderKeys = "ControlLeft";
modifierValue = "ctrlKey"; modifierValue = "ctrlKey";
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment