Files
pbakaus_impeccable/tests/fixtures/antipatterns/shadowed-form-id.html
T
Paul BakausandClaude Fable 5 507725c935 Harden detector against form.id shadowing and gradient/non-rendered false positives
Fixes three detector bugs that surfaced on real-world (Shopify) URL scans:

#407 — DOM named-property shadowing crash. On a <form> with a named control
like <input name="id"> (every Shopify product form), HTMLFormElement's
[LegacyOverrideBuiltIns] behavior makes `form.id` return the input element, not
the id string, so `elId.startsWith(...)` throws and aborts the whole scan. Read
the id via getAttribute whenever `el.id` is not a string, at all three sites:
checkQuality (checks.mjs) and collectBrowserFindings + generateSelector
(browser/injected/index.mjs). Regenerated the browser bundle.

#408 — tiny-text / undersized-ui-text flagged non-rendered elements. On sites
that set html{font-size:62.5%} the root computes to 10px, so <script>/<style>/
<title>/<noscript> and display:none / visibility:hidden blocks — whose JS/CSS/
JSON-LD text clears the hasDirectText gate — produced dozens of phantom "10px
body text" findings. Added isNonRenderedText() (tag list + head descendants +
display/visibility) and gated both text-size floors on it.

#409 — contrast rules misjudged gradients. Case A: background-clip:text paints
its glyphs with the element's own gradient, not a backdrop, so measuring the
never-painted `color` against those stops is a guaranteed false positive; skip
the backdrop-contrast checks when bgClip is 'text' (the gradient-text pattern
flag still fires). Case B: a translucent gradient stop (e.g. a 9%-alpha accent
glow) was treated as an opaque accent; composite alpha stops over the resolved
surface beneath the gradient in resolveGradientStops(), dropping the stop rather
than guessing when that surface is unresolvable.

Fixtures + tests: shadowed-form-id.html (browser, #407), nonrendered-text.html
(#408), and gradient-clipped + alpha-glow cases added to color.html (#409).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-24 16:17:24 -07:00

51 lines
2.1 KiB
HTML

<!DOCTYPE html>
<!--
Regression fixture for issue #407: DOM named-property shadowing.
HTMLFormElement is [LegacyOverrideBuiltIns], so a named control shadows even
builtin getters: a <form> containing <input name="id"> makes `form.id` return
the INPUT ELEMENT, not the id string. Reading `.startsWith` on it throws
"elId.startsWith is not a function". Every Shopify product form ships an
<input name="id"> (the variant id), so this crashed the URL scan of essentially
every Shopify page. `<input name="className">` shadows `form.className` the same
way. The detector must read these via getAttribute (immune to shadowing).
-->
<html lang="en">
<head>
<meta charset="utf-8">
<title>Shadowed form.id regression fixture</title>
<style>
body { font-family: system-ui, sans-serif; background: #ffffff; color: #1a1a1a; margin: 0; padding: 24px; }
.product { max-width: 640px; margin: 0 auto; }
h1 { font-size: 28px; margin: 0 0 12px; }
.price { font-size: 20px; font-weight: 600; }
form { margin-top: 16px; }
.add-to-cart { background: #1a1a1a; color: #ffffff; border: 0; padding: 12px 24px; border-radius: 6px; font-size: 16px; cursor: pointer; }
label { display: block; margin: 8px 0 4px; font-size: 14px; }
select, input[type="number"] { padding: 8px; font-size: 14px; }
</style>
</head>
<body>
<main class="product">
<h1>Impeccable Test Product</h1>
<p class="price">$49.00</p>
<!-- Shopify-style product form: the <input name="id"> shadows form.id. -->
<form method="post" action="/cart/add" id="product-form">
<input type="hidden" name="id" value="4001">
<input type="hidden" name="className" value="variant-default">
<label for="qty">Quantity</label>
<input type="number" id="qty" name="quantity" value="1" min="1">
<label for="variant">Variant</label>
<select id="variant" name="options[Size]">
<option value="s">Small</option>
<option value="m">Medium</option>
<option value="l">Large</option>
</select>
<button type="submit" class="add-to-cart">Add to cart</button>
</form>
</main>
<script src="/js/detect-antipatterns-browser.js"></script>
</body>
</html>