Allow selectors to further search for elements by text and tag name#10046
Allow selectors to further search for elements by text and tag name#10046christian-bromann merged 3 commits intowebdriverio:mainfrom RahulARanger:main
Conversation
christian-bromann
left a comment
There was a problem hiding this comment.
Awesome work, one suggestion.
christian-bromann
left a comment
There was a problem hiding this comment.
👍 Thanks a lot!
And congrats on your first WebdriverIO contribution 🎉
|
I have the same issue in my side. I cannot find a tr by text now: |
|
You might want to try |
Thanks Christian, that works. |
|
But I reproduced another issue. If an element is present inside the element and the text is after this element, the search doesn't work. |
The example has 3 elements, 2 TextNodes, and one "A" Tag. Hence |
|
For me, the example has only 2 elements. An element with tag and one with "A" inside the "P" element |
Proposed changes
Aims to solve Issue: #10040.
Types of changes
Checklist
Further comments
Currently, for selecting an element by Tag Name and Content, we are following the XPath of the form:
.//{'*' if not tag else tag}[normalize-space(text()) = "{text}"]Example:
.//span[normalize-space(text()) = "Sign in"]It fetches the text specific to that node and normalizes
it. but we would not be able to find the parent element as it might have some child nodes.
In order to select the element Button, we cannot have the selector:
$("button=Click Me!")to select the button. but we can select span with a similar syntax:$("span=Click Me!").Suggestion:
If we would have used the following XPath expression of the form:
.//{'*' if not tag else tag}[normalize-space() = "{text}"]Example:
.//button[normalize-space() = "Click Me!"]we can select both button and span based on our request. as it is converting the text (inside of its child nodes if exists) and normalizes it.
But that had an edge case:
Selector:
$(div=Deep)would select all the div s with "not-me' as the first found. Expected result is the div with class "main". But the Current Implementation would select the right selector.So the Fix is to cater to both the type of scenarios. keeping the current implementation as stricter part and the suggestion as the looser part.
Suggested Selector is form:
.//tag[normalize-space(text()) = "text"] | .//tag[not(.//tag[normalize-space(text()) = "text"]) and normalize-space() = "text"]Explanation
.//tag[normalize-space(text()) = "text"]and if it exists,not(.//tag[normalize-space(text()) = "text"]becomes false so right side of union operator is null.//tag[normalize-space(text()) = "text"]same as existing implemetation.//tag[normalize-space(text()) = "text"]doesn't exist,.//tag[true and normalize-space(text()) = "text"]Reviewers: @webdriverio/project-committers