test: cover the src/ JSX link and image hygiene contract (tests/jsx-link-hygiene.test.mjs) - #343
Open
kubestellar-hive[bot] wants to merge 1 commit into
Open
kubestellar-hive[bot] wants to merge 1 commit into
kubestellar-hive[bot] wants to merge 1 commit into
Conversation
Adds tests/jsx-link-hygiene.test.mjs, asserting that every target="_blank" anchor under src/ severs window.opener via rel, that every <img> declares an alt attribute, and that no literal href/src uses plain http. The repository declares no ESLint configuration, so eslint-plugin-jsx-a11y and react/jsx-no-target-blank never run, and no existing test reads a JSX attribute. All three invariants hold on main today; this pins them. Closes #342 Signed-off-by: kubestellar-hive[bot] <kubestellar-hive@hive.kubestellar.io>
Contributor
Author
|
Important Held for human review by the hive's ACMM level gate. This PR was opened by the "quality" agent while Hive policy required a human checkpoint for that agent. Non-outreach agents are held at ACMM L3–L5; the Hive will automatically remove the |
This was referenced Sep 20, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Test Improvement
Adds one new test-only file,
tests/jsx-link-hygiene.test.mjs(4 tests). It isthe first test in this repository to read a JSX attribute.
Files claimed by this PR:
tests/jsx-link-hygiene.test.mjs(new). Nothingelse — no production code, no workflow, no
package.json, no lockfile, no newdependency. It uses only
node:test,node:assert/strict,node:fs,node:pathandnode:url. It does not modifytests/helpers.mjs(claimedby #231), does not import
docusaurus.config.js(claimed by #275), andadds no JSX transform or import path (claimed by #229) — it scans source
text, so it needs neither.
The gap
src/holds 10 JSX files with 21<a>tags (19 of themtarget="_blank")and 8
<img>tags, and nothing checks any of them.The repository declares no ESLint configuration — no
.eslintrc*, noeslint.config.*, noeslintConfigkey inpackage.json— soeslint-plugin-jsx-a11yandreact/jsx-no-target-blank, the rules thatnormally own this ground, never run.
npm run checkis prettier, markdownlint,cspell and markdown-link-check; none of them models JSX attributes.
docusaurus buildcompiles JSX without auditing it.Every failure mode here is silent — clean build, green deploy:
target="_blank"with norelhands the opened page a livewindow.openerhandle back to this site (reverse tabnabbing). Modern browsers imply
noopener; older ones and in-app webviews do not.<img>with noaltmakes a screen reader announce the file name.http://href is blocked as mixed content on the https site.All three hold on
maintoday, which is the point: pinning a currently-greeninvariant costs nothing and stops the first regression. The
relspellings arealready drifting — 10 anchors say
rel="noreferrer"and 9 sayrel="noopener noreferrer"— so a future omission would read as one morevariant rather than a defect.
What the 4 tests assert
least 5 images, and every scanned
<a>carries anhref. That lastclause is the real guard: a scanner that terminated a tag at the first
>inside an attribute value would return truncated tags and every assertion
below would pass by finding nothing.
target="_blank"anchor has a literalrelwhose token list includesnoopenerornoreferrer.<img>declares analtattribute.alt=""is accepted — it is thecorrect, deliberate marking for the 6 decorative images here; a missing
attribute is not.
href/srcinsrc/uses plainhttp://.Implementation note
The scanner tracks quote and brace nesting when locating the end of an opening
tag, because this repository really does write
>inside attribute values —aria-label={${organization} — ${awardLabel}}inAwardsTimeline, and arrowfunctions in
MemberDirectory. Attributes whose value is a JSX expressionrather than a string literal are treated as not statically known and skipped,
so the test cannot produce a false failure on a computed
rel.It walks
src/by file extension rather than assuming oneindex.jspercomponent directory, so it keeps working after the
MemberDirectorysplit in#118.
Verification
node --test tests/jsx-link-hygiene.test.mjs— 4/4 pass at00b44df.Full suite
node --test— 59/59 pass (55 before, +4).Mutation-checked, not just run green. Four independent mutations of
src/, each reverted afterwards, each failing exactly the intended test witha message naming the file:
rel="noreferrer"fromCNCFProjectCard-> test 2 failsMetricsDashboardrelto"nofollow"-> test 2 failsalt=""from aCommunityPeopleimage -> test 3 failsFooterCNCF href tohttp://-> test 4 failsgit statusclean afterwards; the committed diff is the one new test file.npx prettier --check tests/jsx-link-hygiene.test.mjsclean.Coverage evidence
node --test --experimental-test-coverage, local clone ofcncf/endusersat parent revision00b44dfafternpm ci, node v26.8.2,2026-09-20. Baseline 55/55 pass with no test reading any JSX attribute;
after, 59/59.
playwright/cypress/puppeteerand publishes no coverage artifact from anysuite (tracked in [quality] CI publishes no coverage evidence, so coverage findings cannot be verified #186). No claim is made that these paths lack end-to-end
coverage.
Related Issue
Closes #342 — merging this lands the only deliverable that issue describes, so nothing is left for it to track.
Filed by quality agent (hold-gated mode). Human review required.
— hive: agent=quality backend=copilot model=claude-opus-5