Skip to content

test: /xhr dropped from the WPT filter in #4786, losing FormData coverage #5710

Description

@pacocartones

Summary

/xhr was dropped from the test:wpt filter in #4786, which appears to have been incidental — the PR description does not mention it. The practical effect is that undici lost WPT coverage of FormData, since that suite lives under /xhr/formdata/ in WPT rather than under /fetch/.

Separately, /serviceWorkers in the same filter has never matched anything.

I have no stake in the outcome either way — filing this because the data seemed worth surfacing, and only you can say whether the removal was deliberate.

The /xhr removal

#4786 (Remove legacy handler wrappers, merged 2026-02-07, 393094ad50ee) changed:

-"test:wpt": "... run /fetch /mimesniff /xhr /websockets /serviceWorkers /eventsource",
+"test:wpt": "... run /fetch /mimesniff /websockets /serviceWorkers /eventsource",

The PR body describes raw header handling in the cache/decompress interceptors, a shared toRawHeaders utility, snapshot replay raw headers, and a v8 version bump. The filter change is not mentioned.

Evidence that the xhr data has been frozen since: comparing expectation.json at main against that commit, the xhr subtree is byte-identical, while fetch, websockets, eventsource and mimesniff have all changed. #5587 (test: update WPT expectations, 2026-07-27) states it refreshes Fetch and WebSocket expectations; xhr is not included.

What was actually lost

Of the 82 xhr cases that were passing at the time of removal, roughly 80 are FormData conformance, not XMLHttpRequest:

  • xhr/formdata/append.any.html, delete, get, has, set, set-blob, foreach, iteration, constructor
  • the FormData interface: operation append(USVString, Blob, optional USVString) block in xhr/idlharness.any.html

These do not exercise XMLHttpRequest — they are pure FormData tests that happen to live under /xhr/ in WPT's directory layout. undici implements FormData, so this coverage was meaningful and is now silently absent.

/serviceWorkers is a no-op

The WPT directory is service-workers (hyphenated). The filter is a case-sensitive startsWith on the pathname (wpt-runner.mjs:501), so /service-workers/... never matches /serviceWorkers.

Independent confirmation: the runner writes an entry into expectation.json for every test it runs, and expectation.json has no serviceWorkers or service-workers key — its only top-level keys are fetch, mimesniff, websockets, xhr, eventsource. That has been true since 5ceaf613, the commit that introduced the runner in #4486.

Worth noting that correcting the name would be the wrong fix: service worker tests are browser-scoped, and the runner's skip guard at wpt-runner.mjs:493-497 matches serviceworker without a hyphen, so it would not filter them either. Removing the argument is a behavioural no-op; correcting it would pull in a large amount of browser-only churn.

Possible directions

Whichever fits your intent:

  1. If the removal was accidental — restore /xhr to the filter, or narrow it to /xhr/formdata (the matcher supports it: finalPath.startsWith(filter)).
  2. If it was deliberate — the xhr section of expectation.json is dead data and could be dropped.

One caveat on option 1: I have not run the suite, so I cannot say whether the remaining 548 xhr expectations still match current WPT. If they have drifted, restoring the filter would also need an expectation refresh.

Happy to open a PR for whichever direction you prefer, or to leave it with you.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions