问题
Currently, I have the following page object fields:
this.filterTeamDropdown = $("filter-item-edit .dropdown button");
this.teams = this.filterTeamDropdown.all(by.xpath("following-sibling::ul//li[contains(@class, 'dropdown-list-item')]"));
Is there a way to replace the XPath locator for the teams
field and have a CSS selector instead?
The motivation for it is coming from the Style Guide and the recommendation not to use XPaths.
From what I understand, it is impossible to have a CSS selector to go to the next sibling starting from current element in the context. But, are there any alternatives?
回答1:
Saying NEVER to anything is silly. I strongly favor CSS selectors because locating element by id, CSS selector, just about anything... is faster than XPath. But... at the same time we're talking a few ms of difference.
There are some things that XPath can do that no other locator method can. One example that comes to mind is finding an element (other than A
) by contained element text. Other than that I generally stick to CSS selectors when ID doesn't work.
I strongly dislike a lot of people's locator strategies on SO because XPath seems to be the goto way to find elements to the point where it's silly. I've seen people looking for nothing but an id and using XPath. I think part of it is the ease of which you can obtain an XPath, right click on element in inspector and copy XPath and paste in code. The problem with that, as I'm sure you know, is that sometimes (many times?) that results in a very brittle XPath but some/many people don't know any better.
All that said, I'll point you to the W3C CSS Selector reference and maybe you can find what you are looking for. There are some sibling combinators in there but I don't have your HTML so I don't know which, if any, of them would work.
https://www.w3.org/TR/selectors/#selectors
https://www.w3.org/TR/selectors/#adjacent-sibling-combinators
I just read some of the comments below your question and see that you already knew about the +
combinator. Is there some reason you can't reuse your initial locator CSS with the XPath converted string? I don't know if this is even valid/usable but I've combined the two locators you provided in your code after converting the XPath to a CSS selector.
filter-item-edit .dropdown button + ul li.dropdown-list-item
回答2:
There is an another, Protractor-specific way to solve it - use the locator() of the parent element and concatenate to make a child element selector:
this.filterTeamDropdown = $("filter-item-edit .dropdown button");
this.teams = this.filterTeamDropdown.$$(this.filterTeamDropdown.locator().value + " + ul li.dropdown-list-item")
来源:https://stackoverflow.com/questions/38229515/using-css-selectors-instead-of-xpath-locators-when-searching-through-siblings