Documentation
¶
Overview ¶
Package testing provides a comprehensive framework for end-to-end testing of LiveTemplate applications.
Quick Start ¶
import lvttest "github.com/livetemplate/lvt/testing"
func TestHomePage(t *testing.T) {
test := lvttest.Setup(t, &lvttest.SetupOptions{
AppPath: "./main.go",
})
defer test.Cleanup()
test.Navigate("/")
assert := lvttest.NewAssert(test)
assert.PageContains("Welcome")
}
Features ¶
- Automatic Chrome/Chromium management (Docker or local)
- Automatic server startup and shutdown
- WebSocket connection handling
- Console log capture (browser, server, WebSocket)
- CRUD operation helpers
- Modal testing
- Search, sort, and pagination testing
- Database seeding and cleanup
- Resource testing for lvt-generated apps
Chrome Modes ¶
The framework supports three Chrome modes:
- Docker (default) - Uses chromedp/headless-shell container
- Local - Uses locally installed Chrome/Chromium
- Shared - Uses shared Chrome instance from TestMain
See Setup() and SetupOptions for configuration.
Code Reduction ¶
This framework dramatically reduces e2e test boilerplate:
- Before: ~100-150 lines per CRUD test
- After: ~10-20 lines per CRUD test
- Reduction: 85-90%
Examples ¶
See examples/testing/ directory for complete examples:
- 01_basic - Simple smoke test
- 02_crud - Full CRUD workflow
- 03_debugging - Console log capture
- 04_assertions - All assertion types
- 05_modal - Modal interactions
- 06_interactions - Search, sort, pagination
- 07_database - Database seeding
- 08_resource - One-liner resource testing
- 09_parallel - Parallel testing with shared Chrome
Package testing provides test utilities for LiveTemplate applications.
HTTPTest provides a lightweight alternative to browser-based E2E tests. It starts the test server and makes HTTP requests directly, without requiring a browser. This is ideal for testing:
- Server-side rendering
- Form submission and validation
- CRUD operations
- API responses
- Template expression validation
For tests that require browser JavaScript execution (WebSocket, focus management, animations), use the browser-based E2ETest instead.
Index ¶
- func CleanupAllTestContainers()
- func CleanupChromeContainers()
- func CleanupTestContainers()
- func GenerateTestAppName(prefix string) string
- func GetAWSCredentials() (accessKeyID, secretAccessKey, bucket, region string, err error)
- func GetChromeTestURL(port int) string
- func GetClientCSS() []byte
- func GetClientLibraryJS() []byte
- func GetFlyAPIToken() (string, error)
- func GetFreePort() (port int, err error)
- func HasCredentials(provider Provider) bool
- func IsTestAppName(name string) bool
- func RequireAWSCredentials(t *stdtesting.T)
- func RequireCredentials(t *stdtesting.T, provider Provider)
- func RequireFlyCredentials(t *stdtesting.T)
- func ServeCSS(w http.ResponseWriter, r *http.Request)
- func ServeClientLibrary(w http.ResponseWriter, r *http.Request)
- func SetupUpdateEventListener() chromedp.Action
- func StartDockerChrome(t *testing.T, debugPort int) error
- func StartTestServer(t *testing.T, mainPath string, port int) *exec.Cmd
- func StopDockerChrome(t *testing.T, debugPort int)
- func ValidateAppName(name string) error
- func ValidateCredentials(provider Provider) error
- func ValidateNoTemplateExpressions(selector string) chromedp.Action
- func ValidatePicoCSS() chromedp.Action
- func ValidateScreenshotWithLLM(t *testing.T, ctx context.Context, pageDescription string)
- func WaitFor(condition string, timeout time.Duration) chromedp.Action
- func WaitForActionResponse(actionName string, timeout time.Duration) chromedp.Action
- func WaitForCount(selector string, expectedCount int, timeout time.Duration) chromedp.Action
- func WaitForMessageCount(expectedCount int, timeout time.Duration) chromedp.Action
- func WaitForServer(t *testing.T, serverURL string, timeout time.Duration)
- func WaitForText(selector, text string, timeout time.Duration) chromedp.Action
- func WaitForUpdateEvent(actionName string, timeout time.Duration) chromedp.Action
- func WaitForWebSocketReady(timeout time.Duration) chromedp.Action
- type Assert
- func (a *Assert) AttributeValue(selector, attribute, expectedValue string) error
- func (a *Assert) ElementCount(selector string, expectedCount int) error
- func (a *Assert) ElementExists(selector string) error
- func (a *Assert) ElementHidden(selector string) error
- func (a *Assert) ElementNotExists(selector string) error
- func (a *Assert) ElementVisible(selector string) error
- func (a *Assert) FormFieldValue(selector, expectedValue string) error
- func (a *Assert) HasClass(selector, className string) error
- func (a *Assert) NoConsoleErrors() error
- func (a *Assert) NoTemplateErrors() error
- func (a *Assert) NotHasClass(selector, className string) error
- func (a *Assert) PageContains(text string) error
- func (a *Assert) PageNotContains(text string) error
- func (a *Assert) TableRowCount(expectedCount int) error
- func (a *Assert) TextContains(selector, expectedSubstring string) error
- func (a *Assert) TextContent(selector, expectedText string) error
- func (a *Assert) WebSocketConnected() error
- type CRUDTester
- func (c *CRUDTester) Create(fields ...Field) error
- func (c *CRUDTester) Delete(recordID string) error
- func (c *CRUDTester) Edit(recordID string, fields ...Field) error
- func (c *CRUDTester) GetTableRows() ([]map[string]string, error)
- func (c *CRUDTester) VerifyExists(searchText string) error
- func (c *CRUDTester) VerifyNotExists(searchText string) error
- type ChromeMode
- type ConsoleLog
- type ConsoleLogger
- func (cl *ConsoleLogger) Clear()
- func (cl *ConsoleLogger) Count() int
- func (cl *ConsoleLogger) CountByType(logType string) int
- func (cl *ConsoleLogger) FilterByType(logType string) []ConsoleLog
- func (cl *ConsoleLogger) FindLog(pattern string) (ConsoleLog, bool)
- func (cl *ConsoleLogger) GetErrors() []ConsoleLog
- func (cl *ConsoleLogger) GetLogs() []ConsoleLog
- func (cl *ConsoleLogger) GetWarnings() []ConsoleLog
- func (cl *ConsoleLogger) HasErrors() bool
- func (cl *ConsoleLogger) HasWarnings() bool
- func (cl *ConsoleLogger) Print()
- func (cl *ConsoleLogger) PrintErrors()
- func (cl *ConsoleLogger) Start(ctx context.Context)
- type DatabaseAssert
- func (d *DatabaseAssert) RecordCount(t *testing.T, table string, expected int)
- func (d *DatabaseAssert) RecordDeleted(t *testing.T, table string, id interface{})
- func (d *DatabaseAssert) RecordExists(t *testing.T, table string, conditions map[string]interface{})
- func (d *DatabaseAssert) RecordNotExists(t *testing.T, table string, conditions map[string]interface{})
- type DeploymentOptions
- type DeploymentTest
- type DockerChromeContext
- type E2ETest
- type Field
- type HTTPAssert
- func (a *HTTPAssert) Contains(t *testing.T, text string)
- func (a *HTTPAssert) ContainsAll(t *testing.T, texts ...string)
- func (a *HTTPAssert) ContentType(t *testing.T, expected string)
- func (a *HTTPAssert) ContentTypeHTML(t *testing.T)
- func (a *HTTPAssert) ContentTypeJSON(t *testing.T)
- func (a *HTTPAssert) ElementCount(t *testing.T, selector string, expected int)
- func (a *HTTPAssert) ElementText(t *testing.T, selector string, expectedText string)
- func (a *HTTPAssert) ElementTextContains(t *testing.T, selector string, expectedSubstring string)
- func (a *HTTPAssert) FormFieldValue(t *testing.T, fieldName string, expectedValue string)
- func (a *HTTPAssert) HasCSRFToken(t *testing.T)
- func (a *HTTPAssert) HasElement(t *testing.T, selector string)
- func (a *HTTPAssert) HasFormField(t *testing.T, fieldName string)
- func (a *HTTPAssert) HasHeader(t *testing.T, name string)
- func (a *HTTPAssert) HasNoElement(t *testing.T, selector string)
- func (a *HTTPAssert) Header(t *testing.T, name, expected string)
- func (a *HTTPAssert) Matches(t *testing.T, pattern string)
- func (a *HTTPAssert) NoTemplateErrors(t *testing.T)
- func (a *HTTPAssert) NotContains(t *testing.T, text string)
- func (a *HTTPAssert) RedirectTo(t *testing.T, expectedLocation string)
- func (a *HTTPAssert) StatusBadRequest(t *testing.T)
- func (a *HTTPAssert) StatusCode(t *testing.T, expected int)
- func (a *HTTPAssert) StatusForbidden(t *testing.T)
- func (a *HTTPAssert) StatusNotFound(t *testing.T)
- func (a *HTTPAssert) StatusOK(t *testing.T)
- func (a *HTTPAssert) StatusRedirect(t *testing.T)
- func (a *HTTPAssert) StatusServerError(t *testing.T)
- func (a *HTTPAssert) StatusUnauthorized(t *testing.T)
- func (a *HTTPAssert) TableRowCount(t *testing.T, expected int)
- type HTTPResponse
- type HTTPSetupOptions
- type HTTPTest
- func (h *HTTPTest) Cleanup()
- func (h *HTTPTest) ClearCookies()
- func (h *HTTPTest) DBPath() string
- func (h *HTTPTest) Delete(path string) *HTTPResponse
- func (h *HTTPTest) ExtractCSRFToken(resp *HTTPResponse) string
- func (h *HTTPTest) FollowRedirect(resp *HTTPResponse) *HTTPResponse
- func (h *HTTPTest) FollowRedirects(resp *HTTPResponse) *HTTPResponse
- func (h *HTTPTest) Get(path string) *HTTPResponse
- func (h *HTTPTest) GetCookie(name string) string
- func (h *HTTPTest) GetWithHeaders(path string, headers map[string]string) *HTTPResponse
- func (h *HTTPTest) OnCleanup(fn func())
- func (h *HTTPTest) PostForm(path string, data url.Values) *HTTPResponse
- func (h *HTTPTest) PostJSON(path string, data interface{}) *HTTPResponse
- func (h *HTTPTest) PostMultipart(path string, fields map[string]string, files map[string][]byte) *HTTPResponse
- func (h *HTTPTest) SetCookie(name, value string)
- func (h *HTTPTest) SetDB(db *sql.DB)
- func (h *HTTPTest) SubmitForm(resp *HTTPResponse, formSelector string, values map[string]string) *HTTPResponse
- func (h *HTTPTest) URL(path string) string
- func (h *HTTPTest) WaitForServer(timeout time.Duration) error
- type ModalTester
- func (m *ModalTester) ClickButton(text string) error
- func (m *ModalTester) ClickSubmit() error
- func (m *ModalTester) Close() error
- func (m *ModalTester) CloseByAction(action string) error
- func (m *ModalTester) FillForm(fields ...Field) error
- func (m *ModalTester) GetText(selector string) (string, error)
- func (m *ModalTester) Open() error
- func (m *ModalTester) OpenByAction(action string) error
- func (m *ModalTester) VerifyHidden() error
- func (m *ModalTester) VerifyText(selector, expectedText string) error
- func (m *ModalTester) VerifyVisible() error
- func (m *ModalTester) WaitForClose(timeout time.Duration) error
- func (m *ModalTester) WaitForOpen(timeout time.Duration) error
- func (m *ModalTester) WithCloseSelector(selector string) *ModalTester
- func (m *ModalTester) WithModalSelector(selector string) *ModalTester
- func (m *ModalTester) WithOpenSelector(selector string) *ModalTester
- type Provider
- type SafeBuffer
- type ServerLogger
- func (sl *ServerLogger) Clear()
- func (sl *ServerLogger) Count() int
- func (sl *ServerLogger) CountMatching(pattern string) int
- func (sl *ServerLogger) FindLog(pattern string) (string, bool)
- func (sl *ServerLogger) FindLogs(pattern string) []string
- func (sl *ServerLogger) GetLastN(n int) []string
- func (sl *ServerLogger) GetLogs() []string
- func (sl *ServerLogger) HasLog(pattern string) bool
- func (sl *ServerLogger) Print()
- func (sl *ServerLogger) PrintLast(n int)
- func (sl *ServerLogger) PrintMatching(pattern string)
- func (sl *ServerLogger) Start()
- func (sl *ServerLogger) Stop()
- func (sl *ServerLogger) Writer() io.Writer
- type SetupOptions
- type SmokeTestOptions
- type SmokeTestResult
- type SmokeTestSuite
- type TestCredentials
- type VisualIssue
- type WSMessage
- type WSMessageLogger
- func (wl *WSMessageLogger) Clear()
- func (wl *WSMessageLogger) Count() int
- func (wl *WSMessageLogger) CountByDirection(direction string) int
- func (wl *WSMessageLogger) CountMatching(pattern string) int
- func (wl *WSMessageLogger) FindMessage(pattern string) (WSMessage, bool)
- func (wl *WSMessageLogger) FindMessages(pattern string) []WSMessage
- func (wl *WSMessageLogger) GetLastN(n int) []WSMessage
- func (wl *WSMessageLogger) GetMessages() []WSMessage
- func (wl *WSMessageLogger) GetMessagesSince(since time.Time) []WSMessage
- func (wl *WSMessageLogger) GetReceived() []WSMessage
- func (wl *WSMessageLogger) GetSent() []WSMessage
- func (wl *WSMessageLogger) HasMessage(pattern string) bool
- func (wl *WSMessageLogger) Print()
- func (wl *WSMessageLogger) PrintLast(n int)
- func (wl *WSMessageLogger) PrintMatching(pattern string)
- func (wl *WSMessageLogger) Start(ctx context.Context)
- func (wl *WSMessageLogger) WaitForMessage(pattern string, timeout time.Duration) (WSMessage, error)
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func CleanupAllTestContainers ¶
func CleanupAllTestContainers()
CleanupAllTestContainers removes both Chrome containers and test app containers. This is a convenience function to run all cleanup operations before tests start.
func CleanupChromeContainers ¶
func CleanupChromeContainers()
CleanupChromeContainers removes any lingering Chrome containers created by the test helpers.
func CleanupTestContainers ¶
func CleanupTestContainers()
CleanupTestContainers removes any lingering test app containers (lvt-test-*). These containers are created by runDockerContainer in e2e tests for integration testing. Unlike Chrome containers which use --rm flag, these can linger if tests crash or are interrupted.
func GenerateTestAppName ¶
GenerateTestAppName generates a unique app name for deployment testing
Format: lvt-test-{random}-{timestamp} Example: lvt-test-a3f4b2-1699123456
The name is guaranteed to: - Be unique (random + timestamp) - Be valid for Fly.io (lowercase, alphanumeric, hyphens only) - Be traceable (includes "test" and timestamp) - Be short enough for Fly.io limits (<32 chars)
func GetAWSCredentials ¶
GetAWSCredentials returns AWS credentials for litestream
func GetChromeTestURL ¶
GetChromeTestURL returns the URL for Chrome (in Docker) to access the test server Chrome container uses host.docker.internal to reach the host on all platforms
func GetClientCSS ¶ added in v0.1.3
func GetClientCSS() []byte
GetClientCSS returns the shared LiveTemplate CSS fetched from CDN. The result is cached in memory (per-process) and on disk (with TTL). On CDN failure, falls back to an expired disk cache if available.
func GetClientLibraryJS ¶
func GetClientLibraryJS() []byte
GetClientLibraryJS returns the LiveTemplate client library JS fetched from CDN. The result is cached in memory (per-process) and on disk (with TTL). On CDN failure, falls back to an expired disk cache if available.
func GetFlyAPIToken ¶
GetFlyAPIToken returns the Fly.io API token from environment
func GetFreePort ¶
GetFreePort asks the kernel for a free open port that is ready to use
func HasCredentials ¶
HasCredentials returns true if credentials are available for the provider (non-testing version)
func IsTestAppName ¶
IsTestAppName checks if a name appears to be a test app
func RequireAWSCredentials ¶
func RequireAWSCredentials(t *stdtesting.T)
RequireAWSCredentials checks if AWS credentials are available (for litestream)
func RequireCredentials ¶
func RequireCredentials(t *stdtesting.T, provider Provider)
RequireCredentials skips the test if credentials for the provider are not available
func RequireFlyCredentials ¶
func RequireFlyCredentials(t *stdtesting.T)
RequireFlyCredentials is a convenience function for Fly.io tests
func ServeCSS ¶ added in v0.1.3
func ServeCSS(w http.ResponseWriter, r *http.Request)
ServeCSS serves the shared LiveTemplate CSS fetched from CDN. This is for development/testing purposes only. In production, serve from CDN directly.
func ServeClientLibrary ¶
func ServeClientLibrary(w http.ResponseWriter, r *http.Request)
ServeClientLibrary serves the LiveTemplate client browser bundle fetched from CDN. This is for development/testing purposes only. In production, serve from CDN directly.
func SetupUpdateEventListener ¶
SetupUpdateEventListener sets up a non-blocking event listener that captures 'lvt:updated' events in window.__capturedEvents array. This must be called BEFORE the action that triggers the event. Then use WaitForUpdateEvent to poll for the captured event.
Example:
chromedp.Run(ctx,
SetupUpdateEventListener(), // Setup listener (non-blocking)
chromedp.SendKeys(...), // Trigger action
WaitForUpdateEvent("search", 5*time.Second), // Poll for captured event
)
func StartDockerChrome ¶
StartDockerChrome starts the chromedp headless-shell Docker container Returns an error if the container fails to start or Chrome fails to become ready
func StartTestServer ¶
StartTestServer starts a Go server on the specified port mainPath should be the path to main.go (e.g., "main.go" or "../../examples/counter/main.go")
func StopDockerChrome ¶
StopDockerChrome stops and removes the Chrome Docker container t can be nil for cleanup scenarios (e.g., TestMain cleanup)
func ValidateAppName ¶
ValidateAppName checks if an app name is valid for Fly.io
func ValidateCredentials ¶
ValidateCredentials checks if required credentials are available for a provider
func ValidateNoTemplateExpressions ¶
ValidateNoTemplateExpressions checks that the specified element does not contain raw Go template expressions like {{if}}, {{range}}, {{define}}, etc. This catches the bug where unflattened templates are used in WebSocket tree generation.
func ValidatePicoCSS ¶ added in v0.1.3
ValidatePicoCSS returns a chromedp.Action that checks the rendered DOM against Pico CSS conventions. Returns an error listing all violations found. Rules checked:
- Forms with text input + button should use <fieldset role="group">
- No unstyled <output data-flash> — use <ins>/<del> instead of FlashTag
- No inline styles except <ins>/<del> block pattern and component internals
- No style="display:none" — use hidden attribute instead
func ValidateScreenshotWithLLM ¶ added in v0.1.3
ValidateScreenshotWithLLM captures a full-page screenshot and sends it to the Claude CLI for visual analysis. Skipped unless LVT_VISUAL_CHECK=true is set. Requires the 'claude' CLI to be installed and authenticated.
Fails the test if any HIGH or CRITICAL severity issues are found. MEDIUM and LOW issues are logged as warnings.
func WaitFor ¶
WaitFor polls a JavaScript condition until it returns true or timeout is reached. This is a generic condition-based wait utility that eliminates arbitrary sleeps.
The condition must be a JavaScript expression that evaluates to a boolean.
Examples:
- WaitFor("document.getElementById('modal').style.display === 'flex'", 5*time.Second)
- WaitFor("document.querySelector('.item').textContent === 'Hello'", 3*time.Second)
- WaitFor("document.querySelectorAll('.item').length === 5", 5*time.Second)
- WaitFor("!document.getElementById('modal').hasAttribute('hidden')", 2*time.Second)
func WaitForActionResponse ¶
WaitForActionResponse waits for a WebSocket message with the specified action name in metadata. This is deterministic - it waits for the exact action to complete, not arbitrary time.
The test should clear window.__wsMessages before triggering the action:
chromedp.Evaluate(`window.__wsMessages = [];`, nil)
// ... trigger action ...
WaitForActionResponse("search", 5*time.Second)
Example:
chromedp.Evaluate(`window.__wsMessages = [];`, nil),
chromedp.SendKeys(`input[name="query"]`, "test", chromedp.ByQuery),
WaitForActionResponse("search", 5*time.Second),
func WaitForCount ¶
WaitForCount waits for a specific number of elements to match the selector. This is a convenience wrapper around WaitFor for counting elements.
The selector is a CSS selector, and expectedCount is the exact number of elements expected. Returns an error if the condition is not met within the timeout.
Examples:
WaitForCount("tbody tr", 3, 5*time.Second)
WaitForCount(".todo-item", 10, 10*time.Second)
WaitForCount("button[disabled]", 0, 3*time.Second)
func WaitForMessageCount ¶
WaitForMessageCount waits for the WebSocket message counter to reach the expected value. This is a deterministic way to wait for updates without relying on arbitrary timeouts. The client increments window.__wsMessageCount after each DOM update completes.
Example:
var initialCount int chromedp.Evaluate(`window.__wsMessageCount || 0`, &initialCount) // ... trigger action ... WaitForMessageCount(initialCount+1, 5*time.Second) // Wait for exactly 1 new message
func WaitForServer ¶
WaitForServer polls an HTTP server until it responds or timeout is reached. This is useful when starting a custom server in tests.
func WaitForText ¶
WaitForText waits for an element's text content to include the specified text. This is a convenience wrapper around WaitFor for common text-matching scenarios.
The selector is a CSS selector, and text is the substring to match. Returns an error if the condition is not met within the timeout.
Examples:
WaitForText("section", "No results found", 5*time.Second)
WaitForText("tbody", "First Todo Item", 10*time.Second)
WaitForText(".status", "Connected", 3*time.Second)
func WaitForUpdateEvent ¶
WaitForUpdateEvent polls for a captured 'lvt:updated' event. Must be used after SetupUpdateEventListener(). Optionally filters by action name if provided.
This is deterministic - it waits for the actual event to fire, not arbitrary timeouts.
func WaitForWebSocketReady ¶
WaitForWebSocketReady waits for the first WebSocket update to be applied by polling for the removal of data-lvt-loading attribute (condition-based waiting). This ensures E2E tests run after the WebSocket connection is established and initial state is synchronized.
Types ¶
type Assert ¶
type Assert struct {
// contains filtered or unexported fields
}
Assert provides assertion helpers for e2e tests.
func NewAssert ¶
NewAssert creates an assertion helper for the given test.
Example:
assert := lvttest.NewAssert(test)
assert.PageContains("Welcome")
assert.WebSocketConnected()
func (*Assert) AttributeValue ¶
AttributeValue verifies that an element has the expected attribute value.
func (*Assert) ElementCount ¶
ElementCount verifies that exactly expectedCount elements match the selector.
func (*Assert) ElementExists ¶
ElementExists verifies that at least one element matches the selector.
func (*Assert) ElementHidden ¶
ElementHidden verifies that an element matching the selector is hidden or doesn't exist.
func (*Assert) ElementNotExists ¶
ElementNotExists verifies that no elements match the selector.
func (*Assert) ElementVisible ¶
ElementVisible verifies that an element matching the selector is visible.
func (*Assert) FormFieldValue ¶
FormFieldValue verifies that a form field has the expected value.
func (*Assert) NoConsoleErrors ¶
NoConsoleErrors verifies that there are no console errors. This is useful for catching JavaScript errors during tests.
func (*Assert) NoTemplateErrors ¶
NoTemplateErrors verifies that the page does not contain raw Go template expressions. This catches bugs where unflattened templates are sent to the client.
func (*Assert) NotHasClass ¶
NotHasClass verifies that an element does NOT have the expected CSS class.
func (*Assert) PageContains ¶
PageContains verifies that the page body contains the given text.
func (*Assert) PageNotContains ¶
PageNotContains verifies that the page body does NOT contain the given text.
func (*Assert) TableRowCount ¶
TableRowCount verifies that a table has the expected number of rows. This counts tbody tr elements by default.
func (*Assert) TextContains ¶
TextContains verifies that an element's text contains the expected substring.
func (*Assert) TextContent ¶
TextContent verifies that an element has the expected text content.
func (*Assert) WebSocketConnected ¶
WebSocketConnected verifies that the WebSocket connection is established. This checks if the data-lvt-loading attribute has been removed from the wrapper.
type CRUDTester ¶
type CRUDTester struct {
// contains filtered or unexported fields
}
CRUDTester provides helpers for testing CRUD operations on resources.
func NewCRUDTester ¶
func NewCRUDTester(test *E2ETest, resourcePath string) *CRUDTester
NewCRUDTester creates a CRUD tester for the given resource path.
Example:
crud := lvttest.NewCRUDTester(test, "/products")
crud.Create(
lvttest.TextField("name", "MacBook Pro"),
lvttest.FloatField("price", 2499.99),
)
func (*CRUDTester) Create ¶
func (c *CRUDTester) Create(fields ...Field) error
Create fills the create form with the given fields and submits it. It waits for the WebSocket update to complete after submission.
func (*CRUDTester) Delete ¶
func (c *CRUDTester) Delete(recordID string) error
Delete clicks the delete button for a record and confirms. The recordID is used to identify which record to delete (e.g., using lvt-data-id).
func (*CRUDTester) Edit ¶
func (c *CRUDTester) Edit(recordID string, fields ...Field) error
Edit opens the edit form for a record, fills the fields, and saves. The recordID is used to identify which record to edit (e.g., using lvt-data-id).
func (*CRUDTester) GetTableRows ¶
func (c *CRUDTester) GetTableRows() ([]map[string]string, error)
GetTableRows extracts table row data from the page. This is useful for verifying record order, content, etc.
func (*CRUDTester) VerifyExists ¶
func (c *CRUDTester) VerifyExists(searchText string) error
VerifyExists checks if a record containing the given text appears in the page.
func (*CRUDTester) VerifyNotExists ¶
func (c *CRUDTester) VerifyNotExists(searchText string) error
VerifyNotExists checks if a record containing the given text does NOT appear in the page.
type ChromeMode ¶
type ChromeMode string
ChromeMode specifies how Chrome should be launched.
const ( // ChromeDocker uses chromedp/headless-shell Docker container (default) ChromeDocker ChromeMode = "docker" // ChromeLocal uses locally installed Chrome/Chromium ChromeLocal ChromeMode = "local" ChromeShared ChromeMode = "shared" )
type ConsoleLog ¶
type ConsoleLogger ¶
type ConsoleLogger struct {
// contains filtered or unexported fields
}
func NewConsoleLogger ¶
func NewConsoleLogger() *ConsoleLogger
func (*ConsoleLogger) Clear ¶
func (cl *ConsoleLogger) Clear()
func (*ConsoleLogger) Count ¶
func (cl *ConsoleLogger) Count() int
func (*ConsoleLogger) CountByType ¶
func (cl *ConsoleLogger) CountByType(logType string) int
func (*ConsoleLogger) FilterByType ¶
func (cl *ConsoleLogger) FilterByType(logType string) []ConsoleLog
func (*ConsoleLogger) FindLog ¶
func (cl *ConsoleLogger) FindLog(pattern string) (ConsoleLog, bool)
func (*ConsoleLogger) GetErrors ¶
func (cl *ConsoleLogger) GetErrors() []ConsoleLog
func (*ConsoleLogger) GetLogs ¶
func (cl *ConsoleLogger) GetLogs() []ConsoleLog
func (*ConsoleLogger) GetWarnings ¶
func (cl *ConsoleLogger) GetWarnings() []ConsoleLog
func (*ConsoleLogger) HasErrors ¶
func (cl *ConsoleLogger) HasErrors() bool
func (*ConsoleLogger) HasWarnings ¶
func (cl *ConsoleLogger) HasWarnings() bool
func (*ConsoleLogger) Print ¶
func (cl *ConsoleLogger) Print()
func (*ConsoleLogger) PrintErrors ¶
func (cl *ConsoleLogger) PrintErrors()
func (*ConsoleLogger) Start ¶
func (cl *ConsoleLogger) Start(ctx context.Context)
type DatabaseAssert ¶
type DatabaseAssert struct {
// contains filtered or unexported fields
}
DatabaseAssert provides database assertion helpers.
func NewDatabaseAssert ¶
func NewDatabaseAssert(test *HTTPTest) *DatabaseAssert
NewDatabaseAssert creates a database assertion helper.
func (*DatabaseAssert) RecordCount ¶
func (d *DatabaseAssert) RecordCount(t *testing.T, table string, expected int)
RecordCount asserts that the table has exactly the expected number of records.
func (*DatabaseAssert) RecordDeleted ¶
func (d *DatabaseAssert) RecordDeleted(t *testing.T, table string, id interface{})
RecordDeleted asserts that a record with the given ID was deleted.
func (*DatabaseAssert) RecordExists ¶
func (d *DatabaseAssert) RecordExists(t *testing.T, table string, conditions map[string]interface{})
RecordExists asserts that a record exists in the table matching the conditions.
func (*DatabaseAssert) RecordNotExists ¶
func (d *DatabaseAssert) RecordNotExists(t *testing.T, table string, conditions map[string]interface{})
RecordNotExists asserts that no record exists in the table matching the conditions.
type DeploymentOptions ¶
type DeploymentOptions struct {
Provider Provider
AppName string // If empty, generates unique name
AppDir string // If empty, creates test app
Region string // Cloud region (defaults vary by provider)
Kit string // App kit: multi, single, simple (default: multi)
// Feature flags
WithAuth bool
WithLitestream bool
WithS3Backup bool
// Resource options
Resources []string // Resources to add (e.g., "posts title content")
}
DeploymentOptions configures deployment test setup
type DeploymentTest ¶
type DeploymentTest struct {
T *stdtesting.T
// App metadata
Provider Provider
AppName string
AppDir string
AppURL string
Region string
// Provider-specific clients (for debugging and inspection)
DockerClient *providers.DockerClient
// contains filtered or unexported fields
}
DeploymentTest manages the lifecycle of a deployed test application
func SetupDeployment ¶
func SetupDeployment(t *stdtesting.T, opts *DeploymentOptions) *DeploymentTest
SetupDeployment creates a test app and prepares it for deployment
func (*DeploymentTest) AddCleanup ¶
func (dt *DeploymentTest) AddCleanup(fn func() error)
AddCleanup registers a cleanup function to be called when test ends
func (*DeploymentTest) Cleanup ¶
func (dt *DeploymentTest) Cleanup() error
Cleanup destroys all resources created during the test
func (*DeploymentTest) Deploy ¶
func (dt *DeploymentTest) Deploy() error
Deploy executes the deployment to the configured provider
func (*DeploymentTest) VerifyHealth ¶
func (dt *DeploymentTest) VerifyHealth() error
VerifyHealth checks if the deployed app is responding
func (*DeploymentTest) VerifyWebSocket ¶
func (dt *DeploymentTest) VerifyWebSocket() error
VerifyWebSocket checks if WebSocket connection can be established
type DockerChromeContext ¶
type DockerChromeContext struct {
Context context.Context
ChromePort int
// contains filtered or unexported fields
}
DockerChromeContext provides a Docker Chrome context for tests that manage their own server. This is useful for tests that need custom server setup (e.g., testing specific template options).
Usage:
chromeCtx, cleanup := e2etest.SetupDockerChrome(t, 60*time.Second) defer cleanup() // Start your custom server on a free port port, _ := e2etest.GetFreePort() // ... start server ... // Use GetChromeTestURL for Docker Chrome to access host url := e2etest.GetChromeTestURL(port) chromedp.Run(chromeCtx.Context, chromedp.Navigate(url), ...)
func SetupDockerChrome ¶
func SetupDockerChrome(t *testing.T, timeout time.Duration) (*DockerChromeContext, func())
SetupDockerChrome starts a Docker Chrome container and returns a chromedp context. Call cleanup() when done to stop the container and cancel the context.
type E2ETest ¶
type E2ETest struct {
T *testing.T
Context context.Context
Cancel context.CancelFunc
ServerPort int
ChromePort int
ChromeMode ChromeMode
ServerCmd *exec.Cmd
AppDir string
AppPath string
// Loggers for debugging
Console *ConsoleLogger
Server *ServerLogger
WebSocket *WSMessageLogger
// contains filtered or unexported fields
}
E2ETest represents a configured e2e test environment with Chrome, server, and test context.
func Setup ¶
func Setup(t *testing.T, opts *SetupOptions) *E2ETest
Setup creates a complete e2e test environment with Chrome, server, and test context. It automatically:
- Starts Chrome (Docker by default)
- Starts the test server
- Creates chromedp context
- Sets up console log capture (if enabled)
Example:
test := lvttest.Setup(t, &lvttest.SetupOptions{
AppPath: "./main.go",
})
defer test.Cleanup()
test.Navigate("/")
func (*E2ETest) Cleanup ¶
func (e *E2ETest) Cleanup()
Cleanup tears down all test resources (Chrome, server, contexts). This should be called with defer after Setup().
type Field ¶
Field represents a form field to be filled during testing.
func FloatField ¶
FloatField creates a field for float input.
func SelectField ¶
SelectField creates a field for select dropdown.
func TextAreaField ¶
TextAreaField creates a field for textarea input.
type HTTPAssert ¶
type HTTPAssert struct {
Response *HTTPResponse
}
HTTPAssert provides assertion helpers for HTTP responses.
func NewHTTPAssert ¶
func NewHTTPAssert(resp *HTTPResponse) *HTTPAssert
NewHTTPAssert creates an assertion helper for the given HTTP response.
Example:
resp := test.Get("/")
assert := lvttest.NewHTTPAssert(resp)
assert.StatusOK(t)
assert.Contains(t, "Welcome")
func (*HTTPAssert) Contains ¶
func (a *HTTPAssert) Contains(t *testing.T, text string)
Contains asserts that the response body contains the expected text.
func (*HTTPAssert) ContainsAll ¶
func (a *HTTPAssert) ContainsAll(t *testing.T, texts ...string)
ContainsAll asserts that the response body contains all expected texts.
func (*HTTPAssert) ContentType ¶
func (a *HTTPAssert) ContentType(t *testing.T, expected string)
ContentType asserts that the response has the expected Content-Type.
func (*HTTPAssert) ContentTypeHTML ¶
func (a *HTTPAssert) ContentTypeHTML(t *testing.T)
ContentTypeHTML asserts that the response is HTML.
func (*HTTPAssert) ContentTypeJSON ¶
func (a *HTTPAssert) ContentTypeJSON(t *testing.T)
ContentTypeJSON asserts that the response is JSON.
func (*HTTPAssert) ElementCount ¶
func (a *HTTPAssert) ElementCount(t *testing.T, selector string, expected int)
ElementCount asserts that exactly n elements match the selector.
func (*HTTPAssert) ElementText ¶
func (a *HTTPAssert) ElementText(t *testing.T, selector string, expectedText string)
ElementText asserts that an element has the expected text content.
func (*HTTPAssert) ElementTextContains ¶
func (a *HTTPAssert) ElementTextContains(t *testing.T, selector string, expectedSubstring string)
ElementTextContains asserts that an element's text contains the expected substring.
func (*HTTPAssert) FormFieldValue ¶
func (a *HTTPAssert) FormFieldValue(t *testing.T, fieldName string, expectedValue string)
FormFieldValue asserts that a form field has the expected value.
func (*HTTPAssert) HasCSRFToken ¶
func (a *HTTPAssert) HasCSRFToken(t *testing.T)
HasCSRFToken asserts that the response contains a CSRF token field.
func (*HTTPAssert) HasElement ¶
func (a *HTTPAssert) HasElement(t *testing.T, selector string)
HasElement asserts that at least one element matches the CSS selector. Note: This uses a simple implementation - for complex selectors, use a full CSS selector library.
func (*HTTPAssert) HasFormField ¶
func (a *HTTPAssert) HasFormField(t *testing.T, fieldName string)
HasFormField asserts that a form field with the given name exists.
func (*HTTPAssert) HasHeader ¶
func (a *HTTPAssert) HasHeader(t *testing.T, name string)
HasHeader asserts that the response has the specified header.
func (*HTTPAssert) HasNoElement ¶
func (a *HTTPAssert) HasNoElement(t *testing.T, selector string)
HasNoElement asserts that no elements match the CSS selector.
func (*HTTPAssert) Header ¶
func (a *HTTPAssert) Header(t *testing.T, name, expected string)
Header asserts that the response has the expected header value.
func (*HTTPAssert) Matches ¶
func (a *HTTPAssert) Matches(t *testing.T, pattern string)
Matches asserts that the response body matches the regular expression.
func (*HTTPAssert) NoTemplateErrors ¶
func (a *HTTPAssert) NoTemplateErrors(t *testing.T)
NoTemplateErrors asserts that the response has no unflattened template expressions. This catches bugs where {{.Field}}, {{if}}, {{range}}, etc. appear in the output.
func (*HTTPAssert) NotContains ¶
func (a *HTTPAssert) NotContains(t *testing.T, text string)
NotContains asserts that the response body does NOT contain the text.
func (*HTTPAssert) RedirectTo ¶
func (a *HTTPAssert) RedirectTo(t *testing.T, expectedLocation string)
RedirectTo asserts that the response redirects to the expected location.
func (*HTTPAssert) StatusBadRequest ¶
func (a *HTTPAssert) StatusBadRequest(t *testing.T)
StatusBadRequest asserts that the response has a 400 status.
func (*HTTPAssert) StatusCode ¶
func (a *HTTPAssert) StatusCode(t *testing.T, expected int)
StatusCode asserts that the response has the expected status code.
func (*HTTPAssert) StatusForbidden ¶
func (a *HTTPAssert) StatusForbidden(t *testing.T)
StatusForbidden asserts that the response has a 403 status.
func (*HTTPAssert) StatusNotFound ¶
func (a *HTTPAssert) StatusNotFound(t *testing.T)
StatusNotFound asserts that the response has a 404 status.
func (*HTTPAssert) StatusOK ¶
func (a *HTTPAssert) StatusOK(t *testing.T)
StatusOK asserts that the response has a 200 OK status.
func (*HTTPAssert) StatusRedirect ¶
func (a *HTTPAssert) StatusRedirect(t *testing.T)
StatusRedirect asserts that the response is a redirect (3xx).
func (*HTTPAssert) StatusServerError ¶
func (a *HTTPAssert) StatusServerError(t *testing.T)
StatusServerError asserts that the response has a 5xx status.
func (*HTTPAssert) StatusUnauthorized ¶
func (a *HTTPAssert) StatusUnauthorized(t *testing.T)
StatusUnauthorized asserts that the response has a 401 status.
func (*HTTPAssert) TableRowCount ¶
func (a *HTTPAssert) TableRowCount(t *testing.T, expected int)
TableRowCount asserts that a table has the expected number of rows.
type HTTPResponse ¶
HTTPResponse wraps an HTTP response with helper methods.
func (*HTTPResponse) FindTemplateErrors ¶
func (r *HTTPResponse) FindTemplateErrors() []string
FindTemplateErrors returns all template error matches found in the response.
func (*HTTPResponse) HasTemplateErrors ¶
func (r *HTTPResponse) HasTemplateErrors() bool
HasTemplateErrors checks if the response body contains unflattened template expressions.
func (*HTTPResponse) String ¶
func (r *HTTPResponse) String() string
String returns the response body as a string.
type HTTPSetupOptions ¶
type HTTPSetupOptions struct {
// AppPath is the path to main.go (e.g., "./cmd/myapp/main.go")
AppPath string
// AppDir is the working directory for the app (defaults to directory of AppPath)
AppDir string
// Port is the server port (auto-allocated if 0)
Port int
// Timeout is the HTTP client timeout (default 10s)
Timeout time.Duration
// DB is an optional database connection for state verification
DB *sql.DB
}
HTTPSetupOptions configures the HTTP test environment.
type HTTPTest ¶
type HTTPTest struct {
T *testing.T
Port int
Client *http.Client
DB *sql.DB
AppDir string
AppPath string
BaseURL string
ServerCmd *exec.Cmd
Server *ServerLogger
// contains filtered or unexported fields
}
HTTPTest represents a configured HTTP test environment. It starts the test server and provides HTTP client methods for testing.
func SetupHTTP ¶
func SetupHTTP(t *testing.T, opts *HTTPSetupOptions) *HTTPTest
SetupHTTP creates a new HTTP test environment. It starts the test server and returns an HTTPTest for making requests.
Example:
test := lvttest.SetupHTTP(t, &lvttest.HTTPSetupOptions{
AppPath: "../../cmd/myapp/main.go",
})
defer test.Cleanup()
resp := test.Get("/")
assert := lvttest.NewHTTPAssert(resp)
assert.StatusOK(t)
func (*HTTPTest) Cleanup ¶
func (h *HTTPTest) Cleanup()
Cleanup tears down the test environment. This is called automatically via t.Cleanup(), but can be called manually if needed.
func (*HTTPTest) DBPath ¶
DBPath returns the path to the test database. This assumes TEST_MODE=1 is set, which uses :memory: by default.
func (*HTTPTest) Delete ¶
func (h *HTTPTest) Delete(path string) *HTTPResponse
Delete performs an HTTP DELETE request and returns the response.
func (*HTTPTest) ExtractCSRFToken ¶
func (h *HTTPTest) ExtractCSRFToken(resp *HTTPResponse) string
ExtractCSRFToken extracts a CSRF token from an HTML response. It looks for a hidden input field named "csrf_token" or "_csrf".
func (*HTTPTest) FollowRedirect ¶
func (h *HTTPTest) FollowRedirect(resp *HTTPResponse) *HTTPResponse
FollowRedirect follows a redirect response and returns the new response. Returns nil if the response is not a redirect.
func (*HTTPTest) FollowRedirects ¶
func (h *HTTPTest) FollowRedirects(resp *HTTPResponse) *HTTPResponse
FollowRedirects follows all redirects until a non-redirect response.
func (*HTTPTest) Get ¶
func (h *HTTPTest) Get(path string) *HTTPResponse
Get performs an HTTP GET request and returns the response.
func (*HTTPTest) GetWithHeaders ¶
func (h *HTTPTest) GetWithHeaders(path string, headers map[string]string) *HTTPResponse
GetWithHeaders performs an HTTP GET request with custom headers.
func (*HTTPTest) OnCleanup ¶
func (h *HTTPTest) OnCleanup(fn func())
OnCleanup registers a function to be called during cleanup.
func (*HTTPTest) PostForm ¶
func (h *HTTPTest) PostForm(path string, data url.Values) *HTTPResponse
PostForm submits form data via POST and returns the response.
func (*HTTPTest) PostJSON ¶
func (h *HTTPTest) PostJSON(path string, data interface{}) *HTTPResponse
PostJSON submits JSON data via POST and returns the response.
func (*HTTPTest) PostMultipart ¶
func (h *HTTPTest) PostMultipart(path string, fields map[string]string, files map[string][]byte) *HTTPResponse
PostMultipart submits multipart form data (for file uploads) and returns the response.
func (*HTTPTest) SubmitForm ¶
func (h *HTTPTest) SubmitForm(resp *HTTPResponse, formSelector string, values map[string]string) *HTTPResponse
SubmitForm extracts a form from the response, fills in values, and submits it. It automatically handles CSRF tokens.
type ModalTester ¶
type ModalTester struct {
// contains filtered or unexported fields
}
ModalTester provides methods for testing modal dialogs.
func NewModalTester ¶
func NewModalTester(test *E2ETest) *ModalTester
NewModalTester creates a modal tester with default selectors. Default modal selector: "[data-test-id='modal']" or ".modal" You can customize selectors using WithSelectors().
func (*ModalTester) ClickButton ¶
func (m *ModalTester) ClickButton(text string) error
ClickButton clicks a button inside the modal. This searches for a button containing the specified text within the modal.
func (*ModalTester) ClickSubmit ¶
func (m *ModalTester) ClickSubmit() error
ClickSubmit clicks the submit button inside the modal and waits for WebSocket update. This is a convenience method for form submission.
func (*ModalTester) Close ¶
func (m *ModalTester) Close() error
Close closes the modal by clicking the close selector. If no close selector is set, this will fail.
func (*ModalTester) CloseByAction ¶
func (m *ModalTester) CloseByAction(action string) error
CloseByAction closes the modal using a LiveTemplate action.
func (*ModalTester) FillForm ¶
func (m *ModalTester) FillForm(fields ...Field) error
FillForm fills a form inside the modal using Field definitions. This is useful for modals that contain forms for create/edit operations.
func (*ModalTester) GetText ¶
func (m *ModalTester) GetText(selector string) (string, error)
GetText gets the text content of an element inside the modal.
func (*ModalTester) Open ¶
func (m *ModalTester) Open() error
Open opens the modal by clicking the open selector. If no open selector is set, this will fail.
func (*ModalTester) OpenByAction ¶
func (m *ModalTester) OpenByAction(action string) error
OpenByAction opens the modal using a LiveTemplate action. This clicks the element with lvt-on-click attribute matching the action.
func (*ModalTester) VerifyHidden ¶
func (m *ModalTester) VerifyHidden() error
VerifyHidden verifies that the modal is hidden.
func (*ModalTester) VerifyText ¶
func (m *ModalTester) VerifyText(selector, expectedText string) error
VerifyText verifies that an element inside the modal contains expected text.
func (*ModalTester) VerifyVisible ¶
func (m *ModalTester) VerifyVisible() error
VerifyVisible verifies that the modal is visible. This checks if the modal element exists and has a visible class or style.
func (*ModalTester) WaitForClose ¶
func (m *ModalTester) WaitForClose(timeout time.Duration) error
WaitForClose waits for the modal to close with a timeout.
func (*ModalTester) WaitForOpen ¶
func (m *ModalTester) WaitForOpen(timeout time.Duration) error
WaitForOpen waits for the modal to open with a timeout.
func (*ModalTester) WithCloseSelector ¶
func (m *ModalTester) WithCloseSelector(selector string) *ModalTester
WithCloseSelector sets the selector for the button/element that closes the modal.
func (*ModalTester) WithModalSelector ¶
func (m *ModalTester) WithModalSelector(selector string) *ModalTester
WithModalSelector sets a custom modal selector.
func (*ModalTester) WithOpenSelector ¶
func (m *ModalTester) WithOpenSelector(selector string) *ModalTester
WithOpenSelector sets the selector for the button/element that opens the modal.
type SafeBuffer ¶
type SafeBuffer struct {
// contains filtered or unexported fields
}
SafeBuffer is a concurrency-safe buffer for capturing logs from processes or goroutines.
func (*SafeBuffer) Bytes ¶
func (b *SafeBuffer) Bytes() []byte
Bytes returns a copy of the buffered bytes.
func (*SafeBuffer) String ¶
func (b *SafeBuffer) String() string
String returns the buffered contents as a string.
type ServerLogger ¶
type ServerLogger struct {
// contains filtered or unexported fields
}
func NewServerLogger ¶
func NewServerLogger() *ServerLogger
func (*ServerLogger) Clear ¶
func (sl *ServerLogger) Clear()
func (*ServerLogger) Count ¶
func (sl *ServerLogger) Count() int
func (*ServerLogger) CountMatching ¶
func (sl *ServerLogger) CountMatching(pattern string) int
func (*ServerLogger) FindLogs ¶
func (sl *ServerLogger) FindLogs(pattern string) []string
func (*ServerLogger) GetLastN ¶
func (sl *ServerLogger) GetLastN(n int) []string
func (*ServerLogger) GetLogs ¶
func (sl *ServerLogger) GetLogs() []string
func (*ServerLogger) HasLog ¶
func (sl *ServerLogger) HasLog(pattern string) bool
func (*ServerLogger) Print ¶
func (sl *ServerLogger) Print()
func (*ServerLogger) PrintLast ¶
func (sl *ServerLogger) PrintLast(n int)
func (*ServerLogger) PrintMatching ¶
func (sl *ServerLogger) PrintMatching(pattern string)
func (*ServerLogger) Start ¶
func (sl *ServerLogger) Start()
func (*ServerLogger) Stop ¶
func (sl *ServerLogger) Stop()
func (*ServerLogger) Writer ¶
func (sl *ServerLogger) Writer() io.Writer
type SetupOptions ¶
type SetupOptions struct {
AppPath string // Path to main.go (e.g., "./main.go")
Port int // Server port (auto-allocated if 0)
Timeout time.Duration // Test timeout (default 60s)
CaptureConsole bool // Capture browser console (default true)
ChromeMode ChromeMode // Chrome mode (default: ChromeDocker)
ChromePath string // Path to local Chrome binary (for ChromeLocal mode)
}
SetupOptions configures the test environment.
type SmokeTestOptions ¶
type SmokeTestOptions struct {
Timeout time.Duration // Total timeout for all tests
RetryDelay time.Duration // Delay between retries
MaxRetries int // Maximum retry attempts
SkipBrowser bool // Skip browser-based tests
}
SmokeTestOptions configures smoke test behavior
func DefaultSmokeTestOptions ¶
func DefaultSmokeTestOptions() *SmokeTestOptions
DefaultSmokeTestOptions returns sensible defaults
type SmokeTestResult ¶
SmokeTestResult represents the result of a single smoke test
type SmokeTestSuite ¶
type SmokeTestSuite struct {
AppURL string
Results []SmokeTestResult
TotalDuration time.Duration
}
SmokeTestSuite represents the results of all smoke tests
func RunSmokeTests ¶
func RunSmokeTests(appURL string, opts *SmokeTestOptions) (*SmokeTestSuite, error)
RunSmokeTests executes all smoke tests against a deployed app
func (*SmokeTestSuite) AllPassed ¶
func (s *SmokeTestSuite) AllPassed() bool
AllPassed returns true if all smoke tests passed
func (*SmokeTestSuite) PrintResults ¶
func (s *SmokeTestSuite) PrintResults()
PrintResults prints smoke test results in a readable format
type TestCredentials ¶
type TestCredentials struct {
// Fly.io credentials
FlyAPIToken string
// AWS credentials (for litestream S3 backups)
AWSAccessKeyID string
AWSSecretAccessKey string
S3Bucket string
S3Region string
// DigitalOcean credentials
DOAPIToken string
// Kubernetes credentials (optional, uses local kubeconfig by default)
KubeConfig string
}
TestCredentials holds all credentials needed for deployment testing
func LoadTestCredentials ¶
func LoadTestCredentials() (*TestCredentials, error)
LoadTestCredentials loads credentials from environment variables
type VisualIssue ¶ added in v0.1.3
type VisualIssue struct {
Severity string `json:"severity"` // HIGH, MEDIUM, LOW
Category string `json:"category"` // ALIGNMENT, HIERARCHY, SPACING, ERROR_STATE, LAYOUT, READABILITY
Description string `json:"description"` // Human-readable description
}
VisualIssue represents a visual problem found by the LLM reviewer.
type WSMessageLogger ¶
type WSMessageLogger struct {
// contains filtered or unexported fields
}
func NewWSMessageLogger ¶
func NewWSMessageLogger() *WSMessageLogger
func RecordWSFrames ¶ added in v0.1.6
func RecordWSFrames(ctx context.Context) *WSMessageLogger
RecordWSFrames is the canonical entry point for capturing WebSocket frames in chromedp tests. Equivalent to NewWSMessageLogger followed by Start, it exists so per-test setup is one line and bounded-size assertions across suites share a single implementation. The capture stops when ctx is cancelled (typically via t.Cleanup of the chromedp context).
func (*WSMessageLogger) Clear ¶
func (wl *WSMessageLogger) Clear()
func (*WSMessageLogger) Count ¶
func (wl *WSMessageLogger) Count() int
func (*WSMessageLogger) CountByDirection ¶
func (wl *WSMessageLogger) CountByDirection(direction string) int
func (*WSMessageLogger) CountMatching ¶
func (wl *WSMessageLogger) CountMatching(pattern string) int
func (*WSMessageLogger) FindMessage ¶
func (wl *WSMessageLogger) FindMessage(pattern string) (WSMessage, bool)
func (*WSMessageLogger) FindMessages ¶
func (wl *WSMessageLogger) FindMessages(pattern string) []WSMessage
func (*WSMessageLogger) GetLastN ¶
func (wl *WSMessageLogger) GetLastN(n int) []WSMessage
func (*WSMessageLogger) GetMessages ¶
func (wl *WSMessageLogger) GetMessages() []WSMessage
func (*WSMessageLogger) GetMessagesSince ¶
func (wl *WSMessageLogger) GetMessagesSince(since time.Time) []WSMessage
func (*WSMessageLogger) GetReceived ¶
func (wl *WSMessageLogger) GetReceived() []WSMessage
func (*WSMessageLogger) GetSent ¶
func (wl *WSMessageLogger) GetSent() []WSMessage
func (*WSMessageLogger) HasMessage ¶
func (wl *WSMessageLogger) HasMessage(pattern string) bool
func (*WSMessageLogger) Print ¶
func (wl *WSMessageLogger) Print()
func (*WSMessageLogger) PrintLast ¶
func (wl *WSMessageLogger) PrintLast(n int)
func (*WSMessageLogger) PrintMatching ¶
func (wl *WSMessageLogger) PrintMatching(pattern string)
func (*WSMessageLogger) Start ¶
func (wl *WSMessageLogger) Start(ctx context.Context)