feat(folio-web): web sample app + CDP spec tests (#36)

* fix(runner): allow nil connection for web platform

* fix(testrun): skip SDK handshake for web platform

* feat(folio-web): add React/Vite web sample app

* feat(folio-web): add sanderling spec

* fix(chrome): use InsertText for multi-char text input

* feat(hierarchy): add Screen field populated from sanderling-screen attr

* fix(chrome): auto-detect viewport from CSS vars, fix InputText accumulation, expose route as screen

* fix(runner): fall back to hierarchy root screen when snapshot screen is empty

* fix(folio-web): broaden loggedIn extractor to all authenticated pages
This commit is contained in:
pj authored and GitHub committed 2026-04-22 23:59:30 +07:00
1 parent eed99e58aa
commit af7b7e27b0
31 files changed
+2970 -74

No files matched your search

+10 -5
View File
@@ -135,6 +135,9 @@ func Run(ctx context.Context, options Options) (Summary, error) {
if screenErr != nil {
logger.Warn("screen snapshot decode failed", "step", stepIndex, "err", screenErr)
}
if screen == "" && tree != nil && len(tree.Elements) > 0 {
screen = tree.Elements[0].Screen
}
logger.Info("step", "index", stepIndex, "screen", screen, "nodes", treeSize)
verdicts := options.Verifier.EvaluateProperties()
violations := violationNames(verdicts)
@@ -181,8 +184,10 @@ func Run(ctx context.Context, options Options) (Summary, error) {
})
}
if err := options.Connection.Release(ctx); err != nil {
return summary, fmt.Errorf("step %d release: %w", stepIndex, err)
if options.Connection != nil {
if err := options.Connection.Release(ctx); err != nil {
return summary, fmt.Errorf("step %d release: %w", stepIndex, err)
}
}
if nextErr == nil {
@@ -216,9 +221,6 @@ func Run(ctx context.Context, options Options) (Summary, error) {
}
func validate(options Options) error {
if options.Connection == nil {
return errors.New("runner: Connection is required")
}
if options.Driver == nil {
return errors.New("runner: Driver is required")
}
@@ -241,6 +243,9 @@ func validate(options Options) error {
}
func snapshotStep(ctx context.Context, options Options) (agent.Message, error) {
if options.Connection == nil {
return agent.Message{}, nil
}
snapshotTimeout := options.SnapshotTimeout
if snapshotTimeout <= 0 {
snapshotTimeout = 5 * time.Second
+2 -2
View File
@@ -233,8 +233,8 @@ globalThis.actions = __sanderling__.actions(() => [__sanderling__.tap({ on: "id:
func TestRunner_RejectsMissingFields(t *testing.T) {
_, err := Run(context.Background(), Options{Duration: time.Second})
if err == nil || !strings.Contains(err.Error(), "Connection") {
t.Errorf("expected Connection-required error, got %v", err)
if err == nil || !strings.Contains(err.Error(), "Driver") {
t.Errorf("expected Driver-required error, got %v", err)
}
}