Implement stepUp and stepDown invoke actions

This adds a stepUp and stepDown invoke action for number inputs.

See: https://github.com/openui/open-ui/pull/1029
Bug: 40284894
Change-Id: I5d8ae99e31181125f872254b6f87b1579dfd5bef
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5425043
Reviewed-by: Mason Freed <masonf@chromium.org>
Commit-Queue: Luke <lwarlow@igalia.com>
Cr-Commit-Position: refs/heads/main@{#1283459}
diff --git a/html/semantics/invokers/invoketarget-on-input-number.tentative.html b/html/semantics/invokers/invoketarget-on-input-number.tentative.html
new file mode 100644
index 0000000..b06053b
--- /dev/null
+++ b/html/semantics/invokers/invoketarget-on-input-number.tentative.html
@@ -0,0 +1,78 @@
+<!doctype html>
+<meta charset="utf-8" />
+<meta name="author" title="Luke Warlow" href="mailto:lwarlow@igalia.com" />
+<link rel="help" href="https://open-ui.org/components/invokers.explainer/" />
+<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>
+<script src="resources/invoker-utils.js"></script>
+
+<input type="number" id="invokee" value="0">
+<button id="invokerbutton" invoketarget="invokee"></button>
+
+<script>
+  function reset() {
+    invokee.value = 0;
+    invokerbutton.removeAttribute('invokeaction');
+  }
+
+  // stepUp
+
+  promise_test(async function (t) {
+    t.add_cleanup(reset);
+    assert_equals(invokee.valueAsNumber, 0);
+    invokerbutton.setAttribute("invokeaction", "stepup");
+    await clickOn(invokerbutton);
+    assert_equals(invokee.valueAsNumber, 1);
+  }, "invoking number input with stepup action increments value");
+
+  promise_test(async function (t) {
+    t.add_cleanup(reset);
+    assert_equals(invokee.valueAsNumber, 0);
+    invokerbutton.setAttribute("invokeaction", "sTePuP");
+    await clickOn(invokerbutton);
+    assert_equals(invokee.valueAsNumber, 1);
+  }, "invoking number input with stepup action (case-insensitive) increments value");
+
+  promise_test(async function (t) {
+    t.add_cleanup(reset);
+    assert_equals(invokee.valueAsNumber, 0);
+    invokerbutton.setAttribute("invokeaction", "stepup");
+    invokee.addEventListener("invoke", (e) => e.preventDefault(), {
+      once: true,
+    });
+    await clickOn(invokerbutton);
+    assert_equals(invokee.valueAsNumber, 0);
+  }, "invoking number input with stepup action and preventDefault does not increment value");
+
+  // stepDown
+
+  promise_test(async function (t) {
+    t.add_cleanup(reset);
+    assert_equals(invokee.valueAsNumber, 0);
+    invokerbutton.setAttribute("invokeaction", "stepdown");
+    await clickOn(invokerbutton);
+    assert_equals(invokee.valueAsNumber, -1);
+  }, "invoking number input with stepdown action decrements value");
+
+  promise_test(async function (t) {
+    t.add_cleanup(reset);
+    assert_equals(invokee.valueAsNumber, 0);
+    invokerbutton.setAttribute("invokeaction", "sTePdOwN");
+    await clickOn(invokerbutton);
+    assert_equals(invokee.valueAsNumber, -1);
+  }, "invoking number input with stepdown action (case-insensitive) decrements value");
+
+  promise_test(async function (t) {
+    t.add_cleanup(reset);
+    assert_equals(invokee.valueAsNumber, 0);
+    invokerbutton.setAttribute("invokeaction", "stepdown");
+    invokee.addEventListener("invoke", (e) => e.preventDefault(), {
+      once: true,
+    });
+    await clickOn(invokerbutton);
+    assert_equals(invokee.valueAsNumber, 0);
+  }, "invoking number input with stepdown action and preventDefault does not decrement value");
+</script>