refactor: replace scroll-sentinel id with lvt-scroll-sentinel attribute#313
refactor: replace scroll-sentinel id with lvt-scroll-sentinel attribute#313
Conversation
…bute Updates all generator templates, kit components, golden files, and E2E tests to use the new lvt-scroll-sentinel boolean attribute. Aligns with the framework's lvt-* attribute convention. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Code ReviewOverviewThis PR replaces The motivation is sound: using a custom attribute ( What's Good
Issues & SuggestionsPotential Bug: CSS specificity changeThe rendered CSS in Missing: pagination component JS (if any)The Dependency gate not enforcedThe PR description notes this depends on
E2E suite not fully greenThe test plan notes the full E2E suite is pending the client package publish. This is expected given the dependency, but the PR is open (not draft). It would be safer to keep it in draft until the E2E gate passes. Minor
SummaryThe change is clean, well-scoped, and correctly applied everywhere. The main concern is the unguarded dependency on 🤖 Generated with Claude Code |
There was a problem hiding this comment.
Pull request overview
Refactors the infinite-scroll “sentinel” marker emitted by generated templates from a fixed id="scroll-sentinel" to a dedicated lvt-scroll-sentinel attribute, aligning generator output, kit templates, and E2E/golden expectations.
Changes:
- Replace
id="scroll-sentinel"with thelvt-scroll-sentinelattribute across generator and kit templates/components. - Update the inline JS fallback from
getElementById('scroll-sentinel')toquerySelector('[lvt-scroll-sentinel]'). - Update golden files and E2E assertions/fixtures to match the new sentinel marker.
Reviewed changes
Copilot reviewed 12 out of 12 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| testdata/golden/resource_template.tmpl.golden | Updates golden output to use lvt-scroll-sentinel attribute. |
| internal/kits/system/single/templates/resource/template.tmpl.tmpl | Emits lvt-scroll-sentinel and updates fallback JS to querySelector. |
| internal/kits/system/single/components/pagination.tmpl | Updates pagination component sentinel markup. |
| internal/kits/system/multi/templates/resource/template.tmpl.tmpl | Emits lvt-scroll-sentinel and updates fallback JS to querySelector. |
| internal/kits/system/multi/components/pagination.tmpl | Updates pagination component sentinel markup. |
| internal/generator/templates/resource/template.tmpl.tmpl | Updates generated resource template sentinel + fallback JS selector. |
| internal/generator/templates/components/pagination.tmpl | Updates generated pagination component sentinel markup. |
| e2e/tutorial_test.go | Updates sentinel presence assertion messaging/check. |
| e2e/testdata/golden/resource_template.tmpl.golden | Updates E2E golden output to use lvt-scroll-sentinel. |
| e2e/resource_generation_test.go | Updates resource-gen test to look for new sentinel marker. |
| e2e/rendering_test.go | Updates rendering fixture HTML/CSS/JS to use attribute-based sentinel. |
| e2e/complete_workflow_test.go | Updates workflow E2E test to check for new sentinel marker. |
| if !strings.Contains(tmplStr, `lvt-scroll-sentinel`) { | ||
| t.Error("❌ Template does not contain lvt-scroll-sentinel element") | ||
| } else { | ||
| t.Log("✅ Template contains scroll-sentinel element for infinite scroll") | ||
| t.Log("✅ Template contains lvt-scroll-sentinel element for infinite scroll") | ||
| } |
There was a problem hiding this comment.
This assertion is now too broad: strings.Contains(tmplStr, "lvt-scroll-sentinel") can match the inline JS selector (querySelector('[lvt-scroll-sentinel]')) even if the sentinel element is missing, causing a false-positive test. Tighten the check to look for the actual markup (e.g., an element tag containing the attribute) or parse the template/HTML to assert the sentinel element exists.
| if !strings.Contains(string(tmpl), `lvt-scroll-sentinel`) { | ||
| t.Error("Template missing lvt-scroll-sentinel element") | ||
| } |
There was a problem hiding this comment.
The template check strings.Contains(string(tmpl), "lvt-scroll-sentinel") can also match the JS selector string in the template, so the test may pass even if the sentinel element markup is removed. Consider checking for a more specific substring (e.g. a tag containing the attribute) or validating the parsed output contains an element with [lvt-scroll-sentinel].
| if !strings.Contains(string(tmplContent), `lvt-scroll-sentinel`) { | ||
| t.Error("❌ Template missing lvt-scroll-sentinel") | ||
| } else { | ||
| t.Log("✅ Scroll sentinel element present") | ||
| } |
There was a problem hiding this comment.
This strings.Contains(..., "lvt-scroll-sentinel") check can produce false positives because the template also contains the JS selector string ([lvt-scroll-sentinel]). To ensure you’re actually verifying the sentinel element, tighten the assertion to the element markup (or parse and query for an element with that attribute).
Checks for `<div lvt-scroll-sentinel` instead of bare `lvt-scroll-sentinel` to avoid false positives from the inline JS selector string in the same template. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Code Review — PR #313: Replace scroll-sentinel id with lvt-scroll-sentinel attributeOverviewClean, well-scoped refactor replacing ✅ What's Done Well
|
Replies to review commentsRe: Re: test assertion granularity — The tighter |
dispatchEvent(new Event('submit')) creates a synthetic event that the
client intercepts but WebSocket.send() data never reaches the server.
Use chromedp.Click on the submit button (matching the working Add Post
test) with noValidate=true to bypass HTML5 validation.
Also removes all debugging instrumentation added during investigation.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Code ReviewOverviewThis PR replaces the What's Good
Issues & Suggestions1. Merge order dependency is not enforcedThe PR notes it depends on Suggestion: Add a 2. Non-standard attribute name
Suggestion: If the project intends to use 3.
|
chromedp.Click inside a dialog opened via JavaScript showModal() doesn't properly interact with the top layer. Match the working "Add Post" test pattern: open dialog via clicking the commandfor button, wait for input visibility, then click the submit button. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Code ReviewOverviewThis PR replaces Positive Changes
Issues and Suggestions1. Non-standard custom attribute (notable concern)
If the client library ( 2. CSS selector in /* Before */
#scroll-sentinel { height: 1px; }
/* After */
[lvt-scroll-sentinel] { height: 1px; }The attribute selector works, but it has lower specificity than an ID selector. This is unlikely to cause issues in this test fixture, but worth noting if the sentinel element ever gets conflicting styles. 3. E2E test — potential race in modal open chromedp.Click(`[command="show-modal"][commandfor="add-modal"]`, chromedp.ByQuery),
waitFor(`document.querySelector('dialog#add-modal')?.open === true`, 10*time.Second),The chromedp.WaitVisible(`input[name="title"]`, chromedp.ByQuery),If the modal animation is async or the dialog 4. Removed The old code used 5. Dependency gate The PR correctly notes it depends on SummaryThe core change is clean, well-scoped, and consistently applied. The E2E test improvements are a genuine quality improvement. The main open question is whether 🤖 Generated with Claude Code |
Summary
lvt-scroll-sentinelinstead ofid="scroll-sentinel"getElementByIdtoquerySelectorDepends on: livetemplate/client#92 (must be merged + published first)
Test plan
id="scroll-sentinel"references🤖 Generated with Claude Code