"More than one element found for locator" warning
Asked Answered
P

4

37

In one of my tests, I'm locating an element using a CSS selector:

element(by.css("ul.nav button"))

There is more than one element matching the query, but, since I need only the first one, I'm okay with the selector.

The problem is, protractor throws a warning:

WARNING - more than one element found for locator By.cssSelector("ul.nav button") - the first result will be used

Is it possible to suppress the warning? In other words, how can I let protractor know that I'm aware of the problem and don't want the warning to be shown anymore?


Using protractor development version (installed directly from the master branch).

Profusion answered 11/2, 2015 at 21:13 Comment(0)
A
68

Try this instead:

element.all(by.css("ul.nav button")).first()

Basically, this tells Protractor that you already know there's more than one element, and you just want the first one (like you said in your question).

Annulment answered 11/2, 2015 at 21:25 Comment(4)
That works! As a bonus and out of curiosity, though, would be useful to know if it is possible to silence the warning, any ideas? Thanks.Profusion
If there was one, it would be here. I don't see anything like that, though, and I think the reason is because non-specific locators make for very fragile tests.Annulment
Yeah, I'm afraid I can turn it off only by setting an appropriate logLevel which would by extension turn off other warnings which is not good. But I totally agree about your last point, makes sense to me. Thanks for the help again.Profusion
You've answered a couple of my questions, so I'm glad I could return the favor.Annulment
K
6

The warning is there for a reason. You've tied your tests too closely to your data. The selector is too general & you should be more specific. Either by saying element(by.css("ul.nav button:nth-child(1)")) or scoping your search differently. Protractor tests aren't supposed to be testing style or dom, they're supposed to be testing business logic.

Kezer answered 15/4, 2015 at 18:30 Comment(1)
After long consideration, I'm downvoting this answer because: 1) it makes an accusation against the OP that, given the simplicity of the question, is completely unwarranted; 2) the given solution, although it may work, depends on a presumed DOM structure which is not stated in the question; 3) the answer claims that the given solution has specific advantages over the OP's code, but in reality it does not have these advantages; and 4) outside of the code sample, the answer amounts to little more than non-sequiturs and sermonizing.Annulment
D
4

Less code:

$$("ul.nav button").first()
Despatch answered 9/8, 2016 at 18:12 Comment(1)
This is great!!Norling
I
2

Do not underestimate xpath. You can solve thousands of problems with it, including this one

let elem = element(by.xpath('(//div//a)[3]'))

You can specify the number of element to use. Keep in mind the numbers start from 1, not 0 as usually in js

Illdefined answered 9/2, 2021 at 2:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.