diff options
Diffstat (limited to 'testing/web-platform/tests/html/semantics/disabled-elements/event-propagate-disabled-keyboard.tentative.html')
-rw-r--r-- | testing/web-platform/tests/html/semantics/disabled-elements/event-propagate-disabled-keyboard.tentative.html | 135 |
1 files changed, 135 insertions, 0 deletions
diff --git a/testing/web-platform/tests/html/semantics/disabled-elements/event-propagate-disabled-keyboard.tentative.html b/testing/web-platform/tests/html/semantics/disabled-elements/event-propagate-disabled-keyboard.tentative.html new file mode 100644 index 0000000000..3aacf21f1d --- /dev/null +++ b/testing/web-platform/tests/html/semantics/disabled-elements/event-propagate-disabled-keyboard.tentative.html @@ -0,0 +1,135 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>KeyboardEvent propagation on disabled form elements</title> +<link rel="author" href="mailto:avandolder@mozilla.com"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script src="/resources/testdriver-actions.js"></script> +<script> + class CustomControl extends HTMLElement { + static get formAssociated() {return true;} + + constructor() { + super(); + this.internals = this.attachInternals(); + + this.attachShadow({mode: "open", delegatesFocus: true}); + this.shadowRoot.append( + document.querySelector("template").content.cloneNode(true) + ); + } + + get target() { + return this.shadowRoot.getElementById("target"); + } + } + + customElements.define("custom-control", CustomControl) +</script> + +<template> + <div tabindex="0" id="target"> + <slot></slot> + </div> +</template> + +<div tabindex="0" id="reset"></div> + +<form id="form"> + <input> <!-- Sanity check with non-disabled control --> + <select disabled></select> + <textarea disabled></textarea> + <input disabled type="button"> + <input disabled type="checkbox"> + <input disabled type="color" value="#000000"> + <input disabled type="date"> + <input disabled type="datetime-local"> + <input disabled type="email"> + <input disabled type="file"> + <input disabled type="image"> + <input disabled type="month"> + <input disabled type="number"> + <input disabled type="password"> + <input disabled type="radio"> + <input disabled type="range" value="0"> + <input disabled type="reset"> + <input disabled type="search"> + <input disabled type="submit"> + <input disabled type="tel"> + <input disabled type="text"> + <input disabled type="time"> + <input disabled type="url"> + <input disabled type="week"> + + <fieldset disabled><span tabindex="0">Span</span></fieldset> + <button disabled><span tabindex="0">Span</span></button> + <custom-control disabled>Text</custom-control> +</form> + +<script> + const keyEvents = ["keydown", "keyup"]; + + function setupTest(t, element, observingElement) { + const observedEvents = []; + const controller = new AbortController(); + const {signal} = controller; + const listenerFn = t.step_func(event => { + observedEvents.push(event.type); + }); + for (const event of keyEvents) { + observingElement.addEventListener(event, listenerFn, {signal}); + } + t.add_cleanup(() => controller.abort()); + + const target = element; + return {target, observedEvents}; + } + + function fire_trusted_key_events(target) { + const actions = new test_driver.Actions(); + return actions.keyDown("a").keyUp("a").send(); + } + + function fire_untrusted_key_events(target) { + target.dispatchEvent(new KeyboardEvent("keydown", {bubbles: true})); + target.dispatchEvent(new KeyboardEvent("keyup", {bubbles: true})); + } + + const observingElement = document.getElementById("form"); + const reset = document.getElementById("reset"); + + for (const element of observingElement.children) { + promise_test(async t => { + const {observedEvents} = setupTest(t, element, observingElement); + + const target = element.firstElementChild ?? element.target ?? element; + await t.step_func(fire_untrusted_key_events)(target); + await new Promise(resolve => t.step_timeout(resolve, 0)); + + assert_array_equals(observedEvents, keyEvents, "Observed events"); + }, `Untrusted key events on ${element.outerHTML}, observed from <${observingElement.localName}>`); + + // Only test elements with children for trusted key events. + if (!element.firstElementChild && !element.target) { + continue; + } + + promise_test(async t => { + const {observedEvents} = setupTest(t, element, observingElement); + + const target = element.firstElementChild ?? element.target; + + reset.focus(); + assert_not_equals(document.activeElement, target, "Reset current focus"); + target.focus(); + assert_equals(document.activeElement, element.firstElementChild ?? element, "Focus the target element"); + + await t.step_func(fire_trusted_key_events)(target); + await new Promise(resolve => t.step_timeout(resolve, 0)); + + assert_array_equals(observedEvents, keyEvents, "Observed events"); + }, `Trusted key events on ${element.outerHTML}, observed from <${observingElement.localName}>`); + } +</script> |