Skip to content

feat: add live-preview example for Change() capability#35

Merged
adnaan merged 4 commits intomainfrom
feat/live-preview-example
Mar 26, 2026
Merged

feat: add live-preview example for Change() capability#35
adnaan merged 4 commits intomainfrom
feat/live-preview-example

Conversation

@adnaan
Copy link
Copy Markdown
Contributor

@adnaan adnaan commented Mar 26, 2026

Summary

  • Adds a live-preview example demonstrating the Change() method convention for Tier 1 auto-inferred input bindings
  • Controller has Change() + Submit() methods, template uses standard HTML forms with no lvt-* attributes
  • WebSocket e2e tests verify capabilities: ["change"] in the initial render and that Change() dispatches correctly
  • Browser e2e test (chromedp) verifies page loads and form submission works

Files

File Purpose
live-preview/main.go Server with PreviewController (Change + Submit)
live-preview/preview.tmpl Standard HTML form — no lvt-* attributes
live-preview/live_preview_test.go WebSocket + browser e2e tests
test-all.sh Added live-preview to working examples
.gitignore Added live-preview/live-preview binary

Test plan

  • TestWebSocketCapabilities — confirms capabilities=["change"] in initial WS render
  • TestWebSocketChangeAction — confirms Change() dispatches and updates state
  • TestLivePreviewE2E — browser e2e (requires Docker Chrome)
  • Example builds cleanly

Dependencies

Depends on livetemplate/livetemplate#253 (capabilities metadata feature). WebSocket capability tests will pass once that PR is merged and the examples go.mod is updated.

🤖 Generated with Claude Code

Example showing the Change() method convention for Tier 1 auto-inferred
input bindings. The controller's Change() method triggers the server to
include "change" in the capabilities metadata of the initial render.

Includes WebSocket tests verifying:
- capabilities=["change"] in initial render response
- Change() method dispatches correctly via WebSocket

Depends on: livetemplate/livetemplate#253

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings March 26, 2026 06:38
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new live-preview example to the LiveTemplate examples repo to demonstrate the Change() method convention (Tier 1 auto-inferred input bindings) using a plain HTML form (no lvt-* attributes), with accompanying WebSocket and browser E2E tests.

Changes:

  • Added live-preview example server (PreviewController with Change() and Submit()) and template using a standard POST form.
  • Added WebSocket tests for initial capabilities metadata and change action dispatch, plus a chromedp browser E2E test.
  • Registered the new example in test-all.sh and ignored its built binary in .gitignore.

Reviewed changes

Copilot reviewed 4 out of 5 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
test-all.sh Includes live-preview in the working examples test matrix.
live-preview/preview.tmpl New template showing a standard HTML form with DevMode/CDN client loading.
live-preview/main.go New example server wiring Change() + Submit() into a LiveTemplate handler.
live-preview/live_preview_test.go Adds WebSocket and browser E2E coverage for the example behavior.
.gitignore Ignores the live-preview compiled binary.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +56 to +63
for i := 0; i < 50; i++ {
if resp, err := http.Get(serverURL); err == nil {
resp.Body.Close()
break
}
time.Sleep(100 * time.Millisecond)
}

Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

startServer() polls http://localhost: but never fails the test if the server never becomes reachable (it breaks on success, otherwise returns after ~5s regardless). This can lead to confusing downstream failures in WebSocket dialing. Track whether a successful HTTP response was observed and t.Fatalf with the captured server logs if the server didn't start in time (optionally using an http.Client with a timeout per request).

Suggested change
for i := 0; i < 50; i++ {
if resp, err := http.Get(serverURL); err == nil {
resp.Body.Close()
break
}
time.Sleep(100 * time.Millisecond)
}
// Use an HTTP client with a short timeout to avoid hanging on each attempt.
client := &http.Client{
Timeout: 200 * time.Millisecond,
}
serverReady := false
for i := 0; i < 50; i++ {
resp, err := client.Get(serverURL)
if err == nil {
resp.Body.Close()
serverReady = true
break
}
if resp != nil && resp.Body != nil {
resp.Body.Close()
}
time.Sleep(100 * time.Millisecond)
}
if !serverReady {
t.Fatalf("server did not become reachable at %s within timeout; logs:\n%s", serverURL, logs.String())
}

Copilot uses AI. Check for mistakes.
<body>
<h1>Live Preview</h1>
<form method="POST">
<input name="Name" value="{{.Name}}" placeholder="Type your name...">
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The text input relies on placeholder text only and has no associated or aria-label. This is an accessibility issue for screen readers and also reduces usability when the placeholder disappears on typing. Add a visible (preferred) or at least an aria-label tied to the input.

Suggested change
<input name="Name" value="{{.Name}}" placeholder="Type your name...">
<label for="name-input">Name</label>
<input id="name-input" name="Name" value="{{.Name}}" placeholder="Type your name...">

Copilot uses AI. Check for mistakes.
adnaan and others added 3 commits March 26, 2026 12:17
…it in headless Chrome

TestWebSocketCapabilities now skips gracefully when the capabilities
field is absent (requires livetemplate/livetemplate#253).

Form submit test uses JS to set input value and dispatch events for
reliable behavior in headless Chrome.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Form submit via chromedp is unreliable in headless CI due to WS timing.
The Submit() and Change() methods are already tested reliably via
TestWebSocketChangeAction. The browser test now verifies the LiveTemplate
wrapper is correctly rendered.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ility

Address Copilot review comments: fail fast with server logs when the test
server does not become reachable, and add a visible <label> for the name
input to improve screen reader support.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@adnaan adnaan merged commit 2a80139 into main Mar 26, 2026
8 checks passed
@adnaan adnaan deleted the feat/live-preview-example branch March 26, 2026 07:36
@adnaan adnaan mentioned this pull request Apr 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants