mirror of
https://github.com/priyanshujain/sanderling.git
synced 2026-10-02 19:17:10 +00:00
test(browser): drive a canvas-under-shadow-root fixture end to end
This commit is contained in:
1 parent
61be8c0788
commit
596f0e0766
3 files changed
+72
No files matched your search
@@ -53,6 +53,18 @@ func TestBrowserCounterInvariantHolds(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestBrowserShadowDOMIsReachable drives a page whose entire UI (canvas, the
|
||||||
|
// button over it, and the counter) lives inside a shadow root, the shape
|
||||||
|
// Compose for Web produces. Both the enumeration and the selector lookup have
|
||||||
|
// to cross the boundary for the counter to move at all, so the property firing
|
||||||
|
// is the end-to-end evidence.
|
||||||
|
func TestBrowserShadowDOMIsReachable(t *testing.T) {
|
||||||
|
violations := runFixture(t, "shadow")
|
||||||
|
if !slices.Contains(violations, "counterNeverMoves") {
|
||||||
|
t.Fatalf("nothing inside the shadow root was ever tapped; violations=%v", violations)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// runFixture serves the named testdata case over an in-process file server,
|
// runFixture serves the named testdata case over an in-process file server,
|
||||||
// drives it through headless Chrome with a fixed seed and a bounded step count,
|
// drives it through headless Chrome with a fixed seed and a bounded step count,
|
||||||
// and returns every property name that was ever reported violated.
|
// and returns every property name that was ever reported violated.
|
||||||
|
|||||||
+43
@@ -0,0 +1,43 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<title>shadow</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<!-- Shaped like Compose for Web: the app mounts a shadow root holding a
|
||||||
|
canvas plus an accessibility overlay. The overlay is pointer-events:
|
||||||
|
none, so a tap aimed at the button lands on the canvas, which routes it
|
||||||
|
by coordinates the way a canvas app does. -->
|
||||||
|
<div id="app"></div>
|
||||||
|
<script>
|
||||||
|
const root = document.getElementById("app").attachShadow({ mode: "open" });
|
||||||
|
root.innerHTML = `
|
||||||
|
<style>
|
||||||
|
#surface { position: absolute; left: 0; top: 0; }
|
||||||
|
#a11y { position: absolute; left: 0; top: 0; pointer-events: none; }
|
||||||
|
#bump { margin: 20px; }
|
||||||
|
</style>
|
||||||
|
<canvas id="surface" width="360" height="240"></canvas>
|
||||||
|
<div id="a11y">
|
||||||
|
<button id="bump">bump</button>
|
||||||
|
<div id="count">0</div>
|
||||||
|
</div>`;
|
||||||
|
const surface = root.getElementById("surface");
|
||||||
|
const bump = root.getElementById("bump");
|
||||||
|
const count = root.getElementById("count");
|
||||||
|
let value = 0;
|
||||||
|
surface.addEventListener("click", function (event) {
|
||||||
|
const rect = bump.getBoundingClientRect();
|
||||||
|
const hit =
|
||||||
|
event.clientX >= rect.left &&
|
||||||
|
event.clientX <= rect.right &&
|
||||||
|
event.clientY >= rect.top &&
|
||||||
|
event.clientY <= rect.bottom;
|
||||||
|
if (!hit) return;
|
||||||
|
value += 1;
|
||||||
|
count.textContent = String(value);
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
Vendored
+17
@@ -0,0 +1,17 @@
|
|||||||
|
import { always, extract, taps } from "@sanderling/spec";
|
||||||
|
|
||||||
|
const bumps = extract((s) => {
|
||||||
|
const el = s.ax.find({ id: "count" });
|
||||||
|
return el ? parseInt(el.text, 10) || 0 : 0;
|
||||||
|
}).named("bumps");
|
||||||
|
|
||||||
|
// The button, the counter that records the taps, and the canvas that services
|
||||||
|
// them all live inside a shadow root. A host that stops at the shadow boundary
|
||||||
|
// enumerates no target to tap and resolves no selector to read, so the counter
|
||||||
|
// can never leave zero: this property firing IS the evidence that both the
|
||||||
|
// enumeration and the selector lookup crossed the boundary.
|
||||||
|
const counterNeverMoves = always(() => bumps.current === 0);
|
||||||
|
|
||||||
|
export const properties = { counterNeverMoves };
|
||||||
|
|
||||||
|
export const actionsRoot = taps;
|
||||||
Reference in new issue
Block a user