diff --git a/internal/driver/chrome/translate.go b/internal/driver/chrome/translate.go index b8e2684..f89fcb3 100644 --- a/internal/driver/chrome/translate.go +++ b/internal/driver/chrome/translate.go @@ -64,7 +64,15 @@ func TranslateStringSelector(selector string) (string, bool, error) { return `:is([data-testid="` + escaped + `"], [id="` + escaped + `"])`, false, nil case "testID", "testid", "data-testid": return `[data-testid="` + cssEscape(value) + `"]`, false, nil - case "placeholder", "placeholderValue", "hintText": + case "placeholder": + // The attribute the markup writes. hintText and placeholderValue name + // the accessible-name ladder above it instead (fieldHint in driver.go), + // which no CSS says, so they fall through to a match that reaches + // nothing and the step fails by name. Building this selector for them + // tapped a field whose hint is its aria-label and whose placeholder + // happens to carry the value, which is an element neither matcher + // names: a selector reaches here only where the dump resolved it to no + // coordinates at all. return `[placeholder="` + cssEscape(value) + `"]`, false, nil default: if !attrNamePattern.MatchString(kind) { diff --git a/internal/driver/chrome/translate_test.go b/internal/driver/chrome/translate_test.go index a781db2..687499a 100644 --- a/internal/driver/chrome/translate_test.go +++ b/internal/driver/chrome/translate_test.go @@ -44,6 +44,13 @@ func TestTranslateStringSelector_KnownKeys(t *testing.T) { {"testTag:submit", `:is([data-testid="submit"], [id="submit"])`, false}, {"testID:submit", `[data-testid="submit"]`, false}, {"placeholder:Email", `[placeholder="Email"]`, false}, + // hintText and placeholderValue name the accessible-name ladder, which + // no CSS says, so they reach nothing here rather than the field whose + // placeholder happens to carry the value and whose hint is its + // aria-label. Both matchers name that field by its aria-label alone, so + // a tap by placeholder acts on an element nobody selected. + {"hintText:Email", `[hintText*="Email"]`, false}, + {"placeholderValue:Email", `[placeholderValue*="Email"]`, false}, } for _, testCase := range cases { got, isXPath, err := TranslateStringSelector(testCase.selector)