mirror of
https://github.com/priyanshujain/sanderling.git
synced 2026-10-02 19:17:10 +00:00
feat(runner): per-tick HTML capture for WebDriver-capable drivers
Type-asserts driver.WebDriver and writes <run>/html/step-NNNNN.html in parallel with screenshot/hierarchy/metrics. Step.HTMLAvailable flips so the inspect UI can hide the html tab on mobile runs.
This commit is contained in:
1 parent
01e43a869d
commit
d2626eeccc
1 file changed
+51
-8
@@ -73,6 +73,7 @@ func Run(ctx context.Context, options Options) (Summary, error) {
|
|||||||
var hierarchyErr error
|
var hierarchyErr error
|
||||||
var metrics *trace.Metrics
|
var metrics *trace.Metrics
|
||||||
var logs []verifier.LogEntry
|
var logs []verifier.LogEntry
|
||||||
|
var htmlCaptured bool
|
||||||
|
|
||||||
g, _ := errgroup.WithContext(ctx)
|
g, _ := errgroup.WithContext(ctx)
|
||||||
g.Go(func() error {
|
g.Go(func() error {
|
||||||
@@ -89,12 +90,24 @@ func Run(ctx context.Context, options Options) (Summary, error) {
|
|||||||
logs = collectLogs(ctx, options.Driver, logSince)
|
logs = collectLogs(ctx, options.Driver, logSince)
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
if web, ok := options.Driver.(driver.WebDriver); ok {
|
||||||
|
g.Go(func() error {
|
||||||
|
htmlCaptured = captureHTML(ctx, web, options.TraceWriter, logger, si, false)
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
}
|
||||||
if pendingPostScreenshot {
|
if pendingPostScreenshot {
|
||||||
postStep := pendingPostScreenshotStep
|
postStep := pendingPostScreenshotStep
|
||||||
g.Go(func() error {
|
g.Go(func() error {
|
||||||
captureScreenshot(ctx, options, logger, postStep, true)
|
captureScreenshot(ctx, options, logger, postStep, true)
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
if web, ok := options.Driver.(driver.WebDriver); ok {
|
||||||
|
g.Go(func() error {
|
||||||
|
captureHTML(ctx, web, options.TraceWriter, logger, postStep, true)
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
}
|
||||||
pendingPostScreenshot = false
|
pendingPostScreenshot = false
|
||||||
}
|
}
|
||||||
g.Wait()
|
g.Wait()
|
||||||
@@ -148,14 +161,15 @@ func Run(ctx context.Context, options Options) (Summary, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
step := trace.Step{
|
step := trace.Step{
|
||||||
Index: stepIndex,
|
Index: stepIndex,
|
||||||
Timestamp: stepStart,
|
Timestamp: stepStart,
|
||||||
Screen: screen,
|
Screen: screen,
|
||||||
Action: traceAction,
|
Action: traceAction,
|
||||||
Violations: violations,
|
Violations: violations,
|
||||||
Hierarchy: tree,
|
Hierarchy: tree,
|
||||||
Residuals: residuals,
|
Residuals: residuals,
|
||||||
Metrics: metrics,
|
Metrics: metrics,
|
||||||
|
HTMLAvailable: htmlCaptured,
|
||||||
}
|
}
|
||||||
if err := options.TraceWriter.WriteStep(step); err != nil {
|
if err := options.TraceWriter.WriteStep(step); err != nil {
|
||||||
return summary, fmt.Errorf("step %d trace: %w", stepIndex, err)
|
return summary, fmt.Errorf("step %d trace: %w", stepIndex, err)
|
||||||
@@ -196,6 +210,9 @@ func Run(ctx context.Context, options Options) (Summary, error) {
|
|||||||
|
|
||||||
if pendingPostScreenshot {
|
if pendingPostScreenshot {
|
||||||
captureScreenshot(ctx, options, logger, pendingPostScreenshotStep, true)
|
captureScreenshot(ctx, options, logger, pendingPostScreenshotStep, true)
|
||||||
|
if web, ok := options.Driver.(driver.WebDriver); ok {
|
||||||
|
captureHTML(ctx, web, options.TraceWriter, logger, pendingPostScreenshotStep, true)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
summary.EndTime = time.Now()
|
summary.EndTime = time.Now()
|
||||||
@@ -397,6 +414,32 @@ func captureMetrics(ctx context.Context, options Options, logger *slog.Logger, s
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// captureHTML pulls the current document HTML from a WebDriver-capable
|
||||||
|
// driver and stamps it into the trace under html/. Returns true on a
|
||||||
|
// successful non-empty write so the Step.HTMLAvailable flag advertises the
|
||||||
|
// payload to the inspect UI.
|
||||||
|
func captureHTML(ctx context.Context, web driver.WebDriver, writer *trace.Writer, logger *slog.Logger, stepIndex int, after bool) bool {
|
||||||
|
html, err := web.Document(ctx)
|
||||||
|
if err != nil {
|
||||||
|
logger.Warn("html capture failed", "step", stepIndex, "after", after, "err", err)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if html == "" {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
var writeErr error
|
||||||
|
if after {
|
||||||
|
writeErr = writer.WriteHTMLAfter(stepIndex, []byte(html))
|
||||||
|
} else {
|
||||||
|
writeErr = writer.WriteHTML(stepIndex, []byte(html))
|
||||||
|
}
|
||||||
|
if writeErr != nil {
|
||||||
|
logger.Warn("html write failed", "step", stepIndex, "after", after, "err", writeErr)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
func captureScreenshot(ctx context.Context, options Options, logger *slog.Logger, stepIndex int, after bool) {
|
func captureScreenshot(ctx context.Context, options Options, logger *slog.Logger, stepIndex int, after bool) {
|
||||||
image, err := options.Driver.Screenshot(ctx)
|
image, err := options.Driver.Screenshot(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
Reference in new issue
Block a user