fix(driver): skip pre-erase for replace-on-input drivers

The web driver's InputText already replaces content via select-all, so
the runner's unconditional EraseText was a redundant round-trip on
every InputText. A new optional TextReplacer capability lets a driver
assert replace semantics; the runner skips the erase when asserted.
This commit is contained in:
pj committed 2026-06-06 00:35:13 +05:30
1 parent 6009adac48
commit 29ec13adcd
5 files changed
+64 -3

No files matched your search

+13 -3
View File
@@ -512,9 +512,12 @@ func applyAction(ctx context.Context, drv driver.DeviceDriver, action verifier.A
// holds before typing. Appending instead lets repeated draws grow
// the field without bound (e.g. into a max-length validation error
// the fuzzer can never escape) and makes retried typing land twice.
if count := existingTextLength(action, tree); count > 0 {
if err := drv.EraseText(ctx, count); err != nil {
return err
// Drivers whose InputText already replaces skip the erase entirely.
if !inputReplacesText(drv) {
if count := existingTextLength(action, tree); count > 0 {
if err := drv.EraseText(ctx, count); err != nil {
return err
}
}
}
return drv.InputText(ctx, action.Text)
@@ -567,6 +570,13 @@ func collectLogs(ctx context.Context, drv driver.DeviceDriver, since time.Time)
return result
}
// inputReplacesText reports whether the driver's InputText replaces existing
// content, making the runner's pre-erase redundant.
func inputReplacesText(drv driver.DeviceDriver) bool {
replacer, ok := drv.(driver.TextReplacer)
return ok && replacer.ReplacesTextOnInput()
}
// existingTextLength returns the character count of the InputText target's
// current text, so the runner can erase it before typing. Zero when the
// target cannot be resolved or holds no text.