Skip to content

test: Add browser dist e2e test and document RDF 1.2 support level - #1954

Open
jeswr wants to merge 4 commits into
mainfrom
test/browser-dist-e2e
Open

test: Add browser dist e2e test and document RDF 1.2 support level#1954
jeswr wants to merge 4 commits into
mainfrom
test/browser-dist-e2e

Conversation

@jeswr

@jeswr jeswr commented Jul 4, 2026

Copy link
Copy Markdown
Member

🚧 DRAFT — for @jeswr to review first

Note: This change is agent-generated (Claude Fable 5) from the verified triage of the linked issues.

Closes #7
Follow-up documentation for #1854 (see also #1853)

Part 1 — e2e test for the built browser dist (#7)

Dist vs dev-build: what was untested

The existing playwright e2e (__tests__/e2e-test.ts) serves bundle/index.js — the raw webpack output. What consumers actually load from GitHub Pages is the release artifact shape: latest/index.js plus latest/dynamic-import.js, where dynamic-import.js is derived by scripts/post-webpack.ts (a textual var eyereasoner;export var eyereasoner; transform). That release script only ever ran inside the release job, so a regression in it — or a webpack output change that makes the transform silently no-op, leaving dynamic-import.js with no export — would ship without any CI signal.

The new test (__tests__/e2e-dist-test.ts)

  • beforeAll recreates the released shape from the webpack bundle that the test flow already builds (no second build step added — npm run test:unit runs bundle:webpack before jest): it copies bundle/index.js into a version dir and runs the real npm run bundle:latest -- --name=vdist-test release script, producing bundle/latest/{index.js,dynamic-import.js}.
  • bundle/latest/ is served as a plain static directory (like GitHub Pages), so any chunk/asset the published bundle requests at runtime must exist in the released file set; express.static also sets the charset=utf-8 content-type required for WASM streaming (see "Serving Files" in the README).
  • Both documented consumption paths from the README are exercised in both firefox and chromium (4 cases):
    • Script tag — drives the real examples/prebuilt/index.html rather than a test-only copy of it (per review). The server rewrites the example's GitHub Pages <script src> to the locally built latest/index.js at serve time — never touching the committed example, and failing loudly if the src pattern is not found so the test can never silently fall back to the published bundle — then the test clicks the example's Execute button like a user would and waits for the result. The example is the single source of truth for script-tag consumption and is itself under test: a packaging regression in the example page gets caught too.
    • Dynamic import__test_utils__/dist-dynamic-import.html: const { eyereasoner } = await import('/latest/dynamic-import.js'). This one page remains because no example consumes latest/dynamic-import.js (the rollup example bundles the npm package through webpack instead); it is minimal and reuses the same socrates data and derived-triple assertion as the prebuilt example.
  • The test asserts the derived :Socrates a :Mortal triple — which is not in the input — appears, and that no error was reported (the DOM error element for the dynamic-import page; captured pageerror events for the example page, which has no error element).

Adjacency with #1952

This test intentionally uses the same idioms just introduced on test/e2e-deterministic-waits (#1952): page.waitForFunction with a generous 90s timeout instead of fixed sleeps, and try/finally around the browser lifecycle so a failed expectation cannot leak a browser and hang the jest worker. It is a new file based on main, so the two PRs merge cleanly in either order.

Part 2 — README: RDF 1.2 support level (#1854 follow-up)

Adds a short "RDF 1.2 support" section recording the outcome of #1854: EYE's RDF 1.1/1.2 parsing is experimental (official support targets the N3 spec; n3gen in eyeling is the recommended conversion path, per @josd); annotation syntax desugars to blank-node reifiers with triple terms only as rdf:reifies objects (the pre-1.2 RDF-star CG form is gone); N3.js v2 (#1853) and EYE agree on this model; the dataStar test cases are the guard.

Validation

Playwright cannot run on this (production-shared, browserless) box, so the CI matrix on this PR is the behavioural validation. Locally validated:

  • repo eslint script: exit 0 (0 errors, pre-existing ignore-pattern warning only)
  • standalone tsc --noEmit type-check of __tests__/e2e-dist-test.ts (the repo tsconfig only includes lib/): exit 0
  • artifact-shape mechanics, browserless: real bundle:webpack output contains the var eyereasoner; transform target exactly once; bundle:latest -- --name=vdist-test exits 0 and produces bundle/latest/{index.js,dynamic-import.js} with export var eyereasoner; present in dynamic-import.js only; the test server responds 200 on all routes with text/javascript; charset=utf-8 for the bundles
  • serve-time rewrite, browserless: a headless fetch of the served / route returns the prebuilt example verbatim except <script src="/latest/index.js"> in place of the GitHub Pages URL (and no eyereasoner.github.io reference remains)

🤖 Generated with Claude Code

Jesse Wright and others added 2 commits July 4, 2026 15:34
Serve the release artifact shape (bundle/latest/index.js and
bundle/latest/dynamic-import.js, generated with the same bundle:latest
release script the release workflow uses) and assert a reasoning
round-trip in firefox and chromium for both documented consumption
paths: a plain script tag and an ES module dynamic import.

Uses deterministic page.waitForFunction waits and try/finally browser
cleanup rather than fixed sleeps.

Closes #7

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
EYE's RDF 1.1/1.2 parsing is experimental (official support targets the
N3 spec; n3gen in eyeling is the recommended conversion path), and the
supported behaviour follows RDF 1.2 semantics: annotation syntax
desugars to blank-node reifiers with triple terms only as rdf:reifies
objects, consistently between N3.js v2 and EYE.

Follow-up to #1854 / #1853.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@jeswr

jeswr commented Jul 4, 2026

Copy link
Copy Markdown
Member Author

Please avoid duplicating logic that can be found in https://github.com/eyereasoner/eye-js/blob/main/examples/prebuilt/index.html

…te page

Per review: the script-tag dist test now loads examples/prebuilt/index.html
itself -- clicking its Execute button like a user would -- instead of a
test-only page that duplicated the example's reasoning round-trip. The
server rewrites the example's GitHub Pages script src to the locally built
release artifact at serve time (failing loudly if the src is not found, so
the test can never silently fall back to the published bundle), which makes
the example the single source of truth and puts it under test.

The dynamic-import page stays minimal because no example consumes
latest/dynamic-import.js (the rollup example bundles the npm package); a
comment now records that.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@jeswr
jeswr marked this pull request as ready for review July 4, 2026 21:31
Copilot AI review requested due to automatic review settings July 4, 2026 21:31

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@jeswr
jeswr enabled auto-merge (squash) July 4, 2026 21:31
@jeswr
jeswr disabled auto-merge July 4, 2026 22:05
@jeswr
jeswr added this pull request to the merge queue Jul 4, 2026
@jeswr
jeswr removed this pull request from the merge queue due to a manual request Jul 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

testing

2 participants