Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
7 changes: 7 additions & 0 deletions .changeset/wpt-suite-fidelity.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@bomb.sh/web-platform-tests': patch
---

Align the DOM compatibility suite with upstream WPT cases at a shared revision, mirror upstream source paths for tests and helpers, and remove locally authored scenarios and unused code. Keep local harness code in `src/shared`. Expose typed document and global bindings through the test fixture. Configure global bindings alongside upstream file and case selection in `wpt.config.ts`, with includes taking precedence over exclusions instead of requiring other test groups to be enabled. Register a todo when every case is excluded.

Complete supported upstream matrices and record the concrete fixture limitations behind remaining omissions.
3 changes: 3 additions & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Preserve upstream WPT conventions. The shared harness files remain linted.
packages/web-platform-tests/src/compatibility/*/**/*.ts
packages/web-platform-tests/src/wpt/**/*.ts
5 changes: 4 additions & 1 deletion .github/workflows/check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,7 @@ jobs:
- run: pnpm --filter @bomb.sh/web-platform-tests typecheck
- run: pnpm --filter @bomb.sh/web-platform-tests exec playwright install --with-deps chromium
- run: pnpm --filter @bomb.sh/web-platform-tests test:wpt-selectors
- run: pnpm --filter @bomb.sh/web-platform-tests test:browser:input
- name: Report Chromium input compatibility
# Browser conformance differences are informational, not UI build failures.
continue-on-error: true
run: pnpm --filter @bomb.sh/web-platform-tests test:browser:input
7 changes: 3 additions & 4 deletions packages/ui/src/dom.compatibility.test.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import { describe, it, expect } from 'vitest';
import { testDOMCompatibility } from '@bomb.sh/web-platform-tests';
import { Document, Element, Node, Text } from './dom.ts';
import { domFeatures } from '../test/dom-features.ts';
import { Document } from './dom.ts';
import config from '../test/wpt.config.ts';

testDOMCompatibility({
runner: { describe, it, expect },
features: domFeatures,
config,
create: () => new Document(() => {}),
globals: { Document, Element, Node, Text },
});
25 changes: 12 additions & 13 deletions packages/ui/test/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# UI tests

Tests live alongside the implementation in `src/`; this directory contains their shared fixtures and the DOM feature manifest. Run the UI tests from the workspace root:
Tests live alongside the implementation in `src/`; this directory contains their shared fixtures and WPT configuration. Run the UI tests from the workspace root:

```sh
pnpm --filter @clack/ui test
Expand All @@ -18,25 +18,24 @@ Rendering, scheduling, notifications, and lifecycle behavior belong in the UI te

## DOM compatibility

[`dom.compatibility.test.ts`](../src/dom.compatibility.test.ts) registers the shared compatibility suite with Vitest. Its synchronous factory creates a fresh instance of the real [`Document`](../src/dom.ts) for each case, with a no-op render notification callback. The supplied global bindings are the UI's `Document`, `Element`, `Node`, and `Text` classes. This fixture owns no external resources, so it needs no disposal callback.
[`dom.compatibility.test.ts`](../src/dom.compatibility.test.ts) registers the shared compatibility suite with Vitest. Its synchronous factory creates a fresh instance of the real [`Document`](../src/dom.ts) for each case, with a no-op render notification callback. This fixture owns no external resources, so it needs no disposal callback.

[`dom-features.ts`](dom-features.ts) is the source of truth for the features this integration verifies. It satisfies the suite's `DOMFeatures` type and declares every leaf explicitly. The suite also validates the manifest at runtime: omitted, unknown, and non-boolean feature values are configuration errors.
[`wpt.config.ts`](wpt.config.ts) supplies the implementation's `globals` and selects the upstream files and cases enforced by this integration. Add new global bindings there. Omitting `config` runs all adapted cases; `exclude` removes matches and explicit `include` rules take precedence. Source keys support `*` and `**`; values are `true` for a whole source or arrays of exact case names and regular expressions. Unmatched rules are configuration errors. No other test groups must be enabled to run a case.

A `true` leaf enables its registered cases; a `false` leaf leaves those cases unregistered. The suite does not infer support from available methods or turn disabled features into skipped tests. Required feature dependencies must also be enabled; missing dependencies fail configuration before any tests are registered. Individual cases with additional feature requirements run only when those requirements are enabled.
The configuration explicitly excludes unsupported directories. Add includes or narrow exclusions as cases pass. Selecting a source runs all of our adapted cases from that file; it does not imply complete coverage of the upstream file or interface.

Feature names describe the behavior being asserted. For example, `node.basicAppend` covers detached tree construction, while `node.append` also requires moving nodes and rejecting cycles. Passing a narrow feature does not establish support for the broader interface or complete standards conformance. The shared [feature catalogue](../../web-platform-tests/src/compatibility/features.ts) and [registry](../../web-platform-tests/src/compatibility/registry.ts) lead to each feature's cases, prerequisites, and specification references.
Include the source or case in the configuration while implementing it. Vitest's `-t` can narrow the configured selection by source path and case name:

When implementing a feature:
```sh
pnpm --filter @clack/ui test src/dom.compatibility.test.ts -t 'Document-createElement.html.*createElement\(foo\)'
```

1. Read its registered cases and prerequisites to understand the behavior the flag promises.
2. Implement that behavior in the UI, then enable the relevant leaves in `dom-features.ts`.
3. Extend the compatibility fixture when the cases need additional constructors, document parsing options, host input, or resource cleanup.
4. Run the UI tests and add implementation-specific regressions for rendering, notifications, or lifecycle effects.
If the shared package is already built, avoid rebuilding by using `pnpm --filter @clack/ui exec bsh test src/dom.compatibility.test.ts` with the same name filter.

Keep support decisions in the manifest rather than duplicating flag values or test counts in documentation.
When implementing behavior, read the source-named file under [`src/wpt`](../../web-platform-tests/src/wpt), implement its operations, and update the configuration once its cases pass. Extend the fixture when cases need document parsing, host input, or cleanup. Implementation-specific rendering, notification, and lifecycle checks remain in the UI tests.

## Host input

Host input features require a [`DOMInputDriver`](../../web-platform-tests/src/compatibility/input-driver.ts) that delivers input through the normal terminal input pipeline. A terminal adapter must resolve mouse targets through the UI's layout, await operation completion, and release held input during cleanup, including after failures. Calling `dispatchEvent`, invoking `.click()`, or directly assigning control values does not exercise that host behavior.
Host input cases require a [`DOMInputDriver`](../../web-platform-tests/src/shared/input-driver.ts) that delivers input through the normal terminal input pipeline. A terminal adapter must resolve mouse targets through the UI's layout, await operation completion, and release held input during cleanup, including after failures. Calling `dispatchEvent`, invoking `.click()`, or directly assigning control values does not exercise that host behavior.

Keyboard/mouse delivery, platform interaction policies, and trusted-event support are separate feature decisions. Enable each only when the implementation and its adapter can satisfy its cases. The shared suite's [browser tooling](../../web-platform-tests/README.md#development) validates the input contract with Playwright; the UI adapter must use terminal layout and input semantics.
Select keyboard/mouse delivery, platform interaction policies, and trusted-event cases independently as the implementation and its adapter support them. The shared suite's [browser tooling](../../web-platform-tests/README.md#development) validates the input contract with Playwright; the UI adapter must use terminal layout and input semantics.
306 changes: 0 additions & 306 deletions packages/ui/test/dom-features.ts

This file was deleted.

Loading
Loading