From 047c53a2e74d1dc7f599af539d0b57ccf1c728e5 Mon Sep 17 00:00:00 2001 From: PJ Date: Sat, 15 Aug 2026 20:52:43 +0530 Subject: [PATCH] test(browser): the cross-host fixture uses the object selector form --- test/browser/browser_test.go | 14 ++++++++++---- test/browser/testdata/find-order/spec.ts | 10 +++++----- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/test/browser/browser_test.go b/test/browser/browser_test.go index 1cab5d4..b94732d 100644 --- a/test/browser/browser_test.go +++ b/test/browser/browser_test.go @@ -281,11 +281,17 @@ func TestBrowserAxFindAgreesAcrossHosts(t *testing.T) { if err := verifierInstance.PushSnapshot(verifier.SnapshotInput{Tree: tree}); err != nil { t.Fatalf("push snapshot: %v", err) } - change, ok := verifierInstance.ChangedExtractors()["found"] - if !ok { - t.Fatal("the goja host recorded no reading for the found extractor") + if count := verifierInstance.ExtractorCount(); count != 1 { + t.Fatalf("the goja host registered %d extractors, want the fixture's 1", count) + } + // ChangedExtractors omits an extractor whose reading is null and unchanged, + // which is exactly what a selector resolving nothing produces. With the + // count checked above, an absent entry is a null reading and not a missing + // extractor, so reporting it as null names the real failure. + fromGoja := "null" + if change, ok := verifierInstance.ChangedExtractors()["found"]; ok { + fromGoja = string(change.Curr) } - fromGoja := string(change.Curr) // Pinned, not just compared: two hosts that both resolved nothing would // agree on undefined and prove nothing about the walk. diff --git a/test/browser/testdata/find-order/spec.ts b/test/browser/testdata/find-order/spec.ts index 854c367..2145321 100644 --- a/test/browser/testdata/find-order/spec.ts +++ b/test/browser/testdata/find-order/spec.ts @@ -4,11 +4,11 @@ import { always, extract, taps } from "@sanderling/spec"; // compared between the two hosts by TestBrowserAxFindAgreesAcrossHosts, which // drives each host's production path and never asks one what the other said. // -// Written in the "k:v" string grammar because that is the one form both hosts -// resolve the same way: the object form {id: "x"} reaches the goja host as a -// plain attribute filter, and a web hierarchy dump carries the id under -// resource-id, so it matches nothing there. -const found = extract((s) => s.ax.find("id:x")?.text).named("found"); +// Written in the object form on purpose. It used to reach the goja host as a +// plain attribute filter looking for an `id` attribute a dump never carries +// (the web dump files the DOM id under resource-id), so it resolved nothing +// there while the V8 host resolved it against the live DOM. +const found = extract((s) => s.ax.find({ id: "x" })?.text).named("found"); const findsTheShadowMatch = always(() => found.current === "shadow");