Files
HARRY-BEAR 7323deb885 fix(1688): extract detail images from shadow DOM with lazy-render scrolling (#2272)
* fix(1688): extract detail images from shadow DOM with lazy-render scrolling

The product detail section lives inside the shadow root of a custom
element (v-detail-e with class html-description). Plain CSS selectors
like `.html-description img` cannot pierce shadowRoot, so the detail
group never matched any element and detail_images was always empty.

Fix by collecting all img/source elements (walking shadow roots) and
checking ancestry through the shadow host chain with closest(), plus
scrolling further and settling on the detail container so its lazy
content renders before extraction.

Adds a jsdom regression test covering shadow-root detail images,
light-DOM main gallery images, and plain-class detail containers.

* fix(1688): address review — restore deleted tests, dedupe the traversal, poll instead of sleep

Review fixes on top of the shadow-DOM detail extraction:

- Restore the two tests this PR replaced. `normalizeAssets` (grouping,
  counts, blob: filtering) and `normalizeMediaUrl` both lost all coverage;
  the 14 -> 15 test count hid that, since three new cases were added while
  two existing ones were removed. Now 17, with the new jsdom cases
  alongside the originals rather than in place of them.

- Inject the module-level `inDetailContainer` via toString() instead of
  keeping a hand-copied twin inside the evaluated script. The copy meant
  the unit tests exercised code that was not what ran in the page, and the
  two could drift silently. This is the convention already used in
  clis/gov-policy/search.js and clis/codex/sidebar.js.

- Check `node.closest(selector)` at each level of the walk, not only
  `host.matches(...)`. A detail container that is a plain element inside a
  shadow root rather than the host itself was previously missed.

- Replace `autoScroll(6) + autoScroll(4) + wait(3)` with one autoScroll,
  a scrollIntoView, and a bounded poll on the deep detail-image count.
  autoScroll keeps no state between calls, so 6+4 was identical to a
  single 10 and the comment about a "second confirmation pass" described
  something that did not happen; the fixed 3s wait was then paid on every
  call even when the content had already rendered. The poll returns as
  soon as the count is stable, capped at ~5s.

- Use an <img> rather than a <source srcset> in the shadow fixture:
  defaultSrcProps does not read srcset, so asserting on it implied
  coverage the adapter does not actually have.

---------

Co-authored-by: jackwener <jakevingoo@gmail.com>
2026-08-23 03:01:18 +08:00
..