Our marketing features page had 63 rows. Every one opened its detail popup through a plain onclick. None of them had an href.
<tr onclick="featurePopUpShow('/marketing/popups/FeatureInfo.asp?section=Main&category=Features&pagename=Mobile%20Home%20Page', 650)" class="featureRow">Sixty-one distinct feature detail pages sat behind those rows, and a crawler had no link to follow to any of them.
What the fix actually was
Wrap the feature name in a real anchor pointing at the same popup URL, keep the row’s own click behavior untouched, and make the new anchor’s own click handler cancel the default navigation and stop the click from also reaching the row underneath it, so a person sees no difference and a crawler gets a real link to walk. The core of the change on the first pass, with names simplified:
this.TagAdd("a", cell, {href: popupHref, cssclass: "featureNameLink", onclick: "event.preventDefault();event.stopPropagation();" + onclickParam + ";return false;"}, featureName);Both the prevented default and the stopped propagation were there from the first edit. There was no earlier version missing one of them.
What the session actually said it hadn’t done
The session that wrote this had no browser automation available to it, Bash and file tools only. So it verified the only way it could: curl requests, before and after, counting exactly what changed. Before, against production with a crawler’s user agent: zero heading tags anywhere on the page, zero real links to the popup content, 63 onclick-only rows, 327 visible words. After, against the working branch on a local dev host: one <h1>, seven <h2> group headers, 63 real href attributes pointing at the 61 individually reachable detail pages, 390 visible words.
Every one of those numbers was a real, checked fact. None of them said anything about whether a person clicking a feature name would still see the popup and nothing else. That question needs a browser actually clicking something, and this session didn’t have one. It said exactly that in its own report, named the one test still missing, a live click-test on the branch before shipping, and stopped there instead of rounding “the markup is right” up to “this works.”
What the second session actually checked
A separate session picked up that exact recommendation and ran it: a real browser, against the local dev copy, not production. Eight specific checks, each against an observed value, not an impression:
- Click the feature name anchor. Record the URL before and after. It must not change.
- Click elsewhere in the same row, off the anchor. Same popup, same content.
- Repeat both on a row in a different feature group, to rule out a per-group difference.
- Confirm the popup closes normally afterward.
- Read the console for the entire sequence.
- Screenshot the feature name: plain text, not a visible link.
- Screenshot the seven group headers for layout defects now that they render as real headings.
- Load a second page that shares the same underlying component and confirm it still renders correctly, with exactly one heading of its own.
The URL never changed across any click. The console carried nothing but a pre-existing, unrelated deprecation notice that fired identically before the change. The feature name rendered as plain gray text, no underline, matching its surroundings exactly. All seven headers rendered clean. The second page, sharing the same code, still worked. Only after all eight came back with real observed values, not assumptions, did the change move toward shipping.
The step neither session skipped
Before any of it went out, the styling reference still pointed at the uncompiled source file, since this codebase compiles CSS at release time only. That had to run through the repo’s own compile step, get repointed at a dated, minified bundle, and get checked again with the exact same curl counts as before, one heading, seven group headers, sixty-three real links, because a compile step changes bytes and the only honest way to know it didn’t change behavior is to check again, not to assume a routine step is a no-op.
The fix shipped the same day and was confirmed live with the same numbers it shipped with in review. What made it trustworthy wasn’t that every check passed. It’s that the session without a browser told the truth about what it couldn’t check, instead of letting a clean set of curl numbers stand in for a claim it never tested.