[Feature]: Add `value` filter method for matching input values
🚀 Feature Request
Proposal
It would be great if there's a built-in way to filter an input by its current value attribute.
This is the way we are currently using:
page.locator("input[value='foo']");
Thank you for considering this!
Example
It would be nice if we could leverage the newer locator methods, something like:
page.getByRole(AriaRole.TEXTBOX)
.filter(new Locator.FilterOptions().setHasValue("foo"));
Motivation
I understand that not every type of element has a value attribute, but think adding this would make our tests more declarative and expressive.
What is your use case for matching on value? You specifically use textbox as your example role, but why would you want to identify a text input via its current contents? Under normal circumstances, you generally don't have a situation where you have an assortment of text fields and you know one of them has the value "foo", but you're not sure which one. Instead, you know that you expect the first one specifically to contain "foo".
We generally recommend that you narrow your selection via other Aria selectors.
I'm working with existing code that does not use unique identifiers for every input field (I know ideally something like data-testid is used instead). Our test pre fills certain inputs with a dynamic name on a certain action, and we want to check that it does that correctly.
Our test pre fills certain inputs
"Certain" implies predetermined (and I would expect that's how you intend it to work). Assuming your test (or even actual) code sets input 0 to "foo" every time the test starts, why can't you use the same mechanism to choose the DOM element you're going to assert the value of?
To be clear, you'd do something like this:
// Narrow this to a single element somehow
const locator = page.locator('input');
await expect(locator).toHaveValue("foo");
The inputs are predetermined, but don't have unique identifiers. So page.locator('input') returns multiple candidates. The "unique identifier" in our case is the input value itself. I also care more about locating the element so I can fill it, or modify the input in some way, rather than asserting that it has such input value.
Again, using data-testid or some other unique identifier for each input element would be ideal, so I understand if this isn't enough of a use case to consider being added in 😅 .
Can you explain in more detail how you're populating these inputs? I do not understand how you could input text and not have some identity information. Even if you just ran:
await page.keyboard.press('Tab');
await page.keyboard.insertText('Input 0');
await page.keyboard.press('Tab');
await page.keyboard.insertText('Input 1');
you'd still have an inherent ordering, and you'd know which value corresponds to which input.
For the record, this has been asked for previously: #34364, #18970, #14679, #3228. However, there was not enough interest in the feature.
@agg23 The inputs are being populated from a backend service upon page load. Frontend frameworks such as Vue allow for dynamic text rendering for inputs without defining a unique identifier for the input itself.
I also have use for this feature. I am doing visual testing. However, a textarea is populated with dynamic content (attachment IDs in markdown). I'd like to have a locator to mask this element, or to write a replacer that replaces the content of the textarea. Unfortunately, I couldn't find a convenient way to only match textareas or other input elements with specific content.
I have a similar requirement, I would like to do
const option = myForm.getByRole("radio", { value: "specific-value" })
option values are independent from i18n - whereas the "name" is not and may vary, I don't care for my tests... I am interested only in the correctness of the option's value.