docs: correct the false statements on DeviceDriver and in the runner

Snapshot is not atomic on any driver, only the sidecar takes a lock. An empty
minLevel is not a default: the three implementations genuinely disagree, so the
comment names that and says the runner always passes one. HeapBytes is RSS only
on Android. The startup gate uses FocusedWindowChecker on top of
ForegroundChecker, never instead. WebAction names no type in the tree. Run
relaunches the app it says the caller must launch, and the errgroup propagates
no error because all three goroutines return nil.
This commit is contained in:
pj committed 2026-08-22 21:31:13 +05:30
1 parent 3caf53cfb6
commit 658574b568
2 files changed
+30 -37

No files matched your search

+18 -18
View File
@@ -52,16 +52,16 @@ type DeviceDriver interface {
Hierarchy(ctx context.Context) (string, error)
Screenshot(ctx context.Context) (Image, error)
// Snapshot returns the hierarchy and screenshot captured back-to-back
// under a backend-side mutex, so the pair describes the same on-device
// frame. Prefer this over calling Hierarchy and Screenshot separately:
// independent reads can land on different frames during transitions.
// Snapshot returns the hierarchy and screenshot as one paired capture,
// the closest a driver can put them and the reason to prefer it over
// separate Hierarchy and Screenshot reads. It is not atomic: no driver
// freezes the frame while the two reads run.
Snapshot(ctx context.Context) (string, Image, error)
// RecentLogs returns log entries at or after `since`, filtered to
// `minLevel` or above. An empty minLevel defaults to "E". A driver with
// no log source returns ErrNotSupported rather than an empty slice: the
// two are the same answer to a spec reading state.logs, and only one of
// them means the app logged nothing.
// `minLevel` or above. Drivers disagree on an empty minLevel (sidecar
// defaults to "E", Chrome returns every level), so the runner always
// passes one. A driver with no log source returns ErrNotSupported, not
// an empty slice: only one of the two means the app logged nothing.
RecentLogs(ctx context.Context, since time.Time, minLevel string) ([]LogEntry, error)
WaitForIdle(ctx context.Context, duration time.Duration) error
@@ -70,10 +70,11 @@ type DeviceDriver interface {
// verdict, so reporting it true without one tells the caller a check
// passed that never ran.
Health(ctx context.Context) (Health, error)
// Metrics samples the app's CPU and memory at the time of the call.
// CPUPercent is percent of a single core (multi-core apps can exceed
// 100). HeapBytes is resident set size; TotalMemoryBytes includes
// native allocations. A driver that cannot sample returns
// Metrics samples the app's memory, plus CPU where the platform exposes
// it (Chrome does not). CPUPercent is percent of a single core, so
// multi-core apps can exceed 100. HeapBytes and TotalMemoryBytes are the
// platform's nearest pair: RSS and virtual size on Android, used and
// total JS heap on Chrome. A driver that cannot sample returns
// ErrNotSupported rather than a zeroed sample.
Metrics(ctx context.Context, bundleID string) (Metrics, error)
}
@@ -115,11 +116,10 @@ type TextReplacer interface {
}
// FocusedWindowChecker is the optional capability for reporting which app owns
// the focused (on-screen) window. The startup gate prefers it over
// ForegroundChecker: the resumed-activity signal flips to a freshly launched
// app before its first frame draws, so observing on it alone can capture the
// previous app's screen. The focused window only names the app once its window
// is actually up.
// the focused (on-screen) window. The startup gate uses it on top of
// ForegroundChecker, never instead: the resumed-activity signal flips to a
// freshly launched app before its first frame draws, so a gate on that alone
// can let the first observe read the previous app's screen.
type FocusedWindowChecker interface {
// FocusedWindowApp returns the package owning the focused window, or ""
// when no window is focused yet (e.g. mid-launch transition).
@@ -193,7 +193,7 @@ type Metrics struct {
// mobile drivers stay binary-compatible by simply not implementing it.
//
// Element references never cross V8/host. V8 serializes targets as {x, y}
// (or bounds) into the returned WebAction JSON; the host dispatches via the
// (or bounds) into the returned action JSON; the host dispatches via the
// normal DeviceDriver methods (Tap, InputText, etc.).
type WebDriver interface {
// InstallBundle injects the given JS source so it runs once per