I'm testing a web application using Nightwatch.js, which uses Selenium WebDriver to interact with the browser. In my app I have a dynamically created list of items differentiated only by their names and the names are displayed as <input>
values. I need to find an item by its name.
Example HTML representation of document structure:
<div class="item">
<input> <!-- current value: "first" -->
</div>
<div class="item">
<input> <!-- current value: "second" -->
</div>
<div class="item">
<input> <!-- current value: "first" -->
</div>
I need to find div.item
containing an input with the value second
.
Note that the value of an <input>
is determined by the value of its value
property, which might be different from the value of its value
attribute. In my case, the DOM is manipulated by React, so the inputs might not have the value
attribute at all.
Is there a way to find element by property value with Nightwatch (or Selenium WebDriver API)?
I looked over the WebDriver documentation and the only way I see is executing custom JavaScript code, which has some serious drawbacks (e.g. requires own implementation of waiting for element to appear and doesn't interact with Nightwatch page objects). As far as I can see, all of the other methods are concerned with looking at the HTML only (so attributes at best, not properties).
Just to be completely clear, using selectors like input[value=...]
(CSS) or //input[@value=...]
(XPath) is not a solution, as it performs lookup by attribute value, not property value.
You can use .elements()
to get a list of elements with class="item"
and then iterate through all elements using .getValue()
to get the value property of each input. If it matches the name you want, return the element.
function getElementsByValue(xpathSelector, expectedValue, callback) {
const foundElements = [];
browser.elements('xpath', xpathSelector, ({ value }) => value.forEach(inputEl => {
browser.elementIdValue(inputEl.ELEMENT, result => {
if (result.value === expectedValue) {
foundElements.push(inputEl);
}
});
});
browser.perform(() => callback(foundElements));
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With