How to implement //*[contains(text(), '"example"')] to construct an Xpath for dynamic contents for Selenium Webdriver:? - selenium

I'm working through Selenium Webdriver, and I've come up to the issue of dynamic objects as a DOM ID. One of my instances gets generated as an ID, something like this:
"//*[#id="888itsAnExampleBoi573"]/div[1]/div[2]",
and I need to click on the button in the example item to Make Stuff Happen.
Because I cannot predict what an objectID will be for my dynamic content, however, I would like to be able to do this, instead:
//*[contains(text(), 'example')]/div[1]/div[2].
I've tried to do this, but I'm returned a strange error:
Caused by: org.openqa.selenium.InvalidSelectorException: invalid
selector: Unable to locate an element with the xpath expression
//*[contains(text(), 'example')]/div/div/div[1]/div[3]/div
because of the following error:
SyntaxError: Failed to execute 'evaluate' on 'Document':
The string '//*[contains(text(), 'example')]/div/div/div[1]/div[3]/div'
is not a valid XPath expression.
On a different element that is a hyperlink with text elements, I've been able to use contains(text()) to solve things, so I believe I've formatted this correctly.
I've tried a few different things to solve this issue, but am at somewhat of a loss as to how to solve this. Does anyone have any ideas or resources to point me towards? Or better yet, a solution?

This error message...
Caused by: org.openqa.selenium.InvalidSelectorException: invalid selector: Unable to locate an element with the xpath expression //*[contains(text(), 'example')]/div/div/div[1]/div[3]/div because of the following error: SyntaxError: Failed to execute 'evaluate' on 'Document': The string '//*[contains(text(), 'example')]/div/div/div[1]/div[3]/div' is not a valid XPath expression.
...implies that the Locator Strategy is not a valid XPath expression.
The expressions:
'//*[contains(text(), 'example')]/div/div/div[1]/div[3]/div'
"//*[contains(text(), "example")]/div/div/div[1]/div[3]/div"
Are invalid as '' and "" were present in multiple places within the xpath.
Solution
As an effective alternative dynamic xpath for the following:
"//*[#id="888itsAnExampleBoi573"]/div[1]/div[2]"
will be:
"//*[contains(#id,'itsAnExampleBoi')]/div[1]/div[2]"

It appears that in order to solve this, sometimes you must frame the question. As I had been using a relative XPATH, I had been working under the pretense that the text div itself was where I would be able to access elements that were not the children of my div. They were actually only loosely related!
"//*[contains(text(), 'Flag this')]
//parent::div
//parent::div[contains(#class,'exampleDrop')]
//child::div[contains(#class, 'pointed exampleAction')]"
I ended up installing Chropath and spidering around the DOM, finding the div with the text in it, and using a relative path in this statement. If you're having issues like these, sometimes I would recommend making sure that you're asking the right question.

Related

Protractor get the second element of an ocurrence

I have an issue and I'm quite new with protractor.
I need to get an element by its text, right now it is not possible to change how the UI is built to use better selectors.
So what I have right now is a span tag with the text Summary inside of it, to retrieve the element using XPath I do the following:
const myElement = element(by.xpath("//span[text()='Summary']"));
That works for the first occurrence when there's only one element on the screen, however, when there are two elements, it fails with the following error:
Failed: element not interactable
Possibly because it is trying to access the first element which is toggled.
So I tried accessing the element index as I read around with:
element(by.xpath("//span[text()='Summary']")[1]);
And got the following error:
Failed: Invalid locator
I read somewhere that the values start on 1 and not on 0 so I tried with:
element(by.xpath("//span[text()='Summary']")[2]);
Yet, I'm still getting the same error:
Failed: Invalid locator
Is there a way I can get to these second element?
When you are using list slicing then there exist more then one elements. So you can try to use elements instead of element
element(by.xpath("(//span[text()='Summary'])[2]");
OR
element(by.xpath("(//span[contains(text(),'Summary')])[2]");
You can try this XPath, it has additional brackets, you have been almost there.
(//span[text()='Summary'])[2]
Reference:
XPath query to get nth instance of an element

getting InvalidSelectorException while locating for an element using the using same xpath that works fine in firepath with 1 matching node

org.openqa.selenium.InvalidSelectorException: invalid selector: Unable to locate an element with the xpath expression //a[Contains(Text(),'Forgot Password?')] because of the following error:
SyntaxError: Failed to execute 'evaluate' on 'Document': The string '//a[Contains(Text(),'Forgot Password?')]' is not a valid XPath expression.
you have messed up with the syntax or expression you have entered
//a[Contains(Text(),'Forgot Password?')]
this has to be like
//a[contains(text(),'Forgot Password?')]
Error says it all, your xPath expression is not valid. You cannot change pre-defined keyword, like text() to Text(). Try //a[contains(text(),'Forgot Password')] or //a[contains(.,'Forgot Password')]
For more about InvalidSelectorException please refer this.

Selenium xPath: Invalid selector -- When passing multiple condition for the same element

Invalid selector: Unable to locate an element with the XPath expression:
//span[#class='title-subGrid-lite-TextAutoEllipsis’][text()[contains(.,'My Emails')]
Correct me.
This error message...
org.openqa.selenium.InvalidSelectorException: invalid selector: Unable to locate an element with the xpath expression //span[#class='title-subGrid-lite-TextAutoEllipsis’][text()[contains(.,'My Emails')]
...implies that the XPath which you have used was not a valid one.
The xpath expression you have used as follows have a couple of issues:
//span[#class='title-subGrid-lite-TextAutoEllipsis’][text()[contains(.,'My Emails')]
The class attribute needs to be properly placed in-between single quotes i.e. '...'.
The text attribute needs to be properly placed in-between [...]
The simple XPath expression which must have catered to your requirement is:
//span[#class='title-subGrid-lite-TextAutoEllipsis'][contains(.,'My Emails')]
As an alternative you can also try:
//span[#class='title-subGrid-lite-TextAutoEllipsis' and contains(.,'My Emails')]
Perhaps you must be looking for:
//span[#class='title-subGrid-lite-TextAutoEllipsis'][normalize-space()='My Emails']

Getting org.openqa.selenium.InvalidSelectorException only for Chrome

I am tring to find a button in a webpage using find elements, the page can contain one of the below button ID's.
driver.findElements(By.xpath("//*[contains(#id,'topBtn')]"))
driver.findElements(By.xpath("//*[contains(#id,'WSMplasticTop')]"))
driver.findElements(By.xpath("//*[contains(#id,'bottomApplyBtn')]"))
The above code is working as expected when i use the Firefox Driver, where as getting the below error when i run in Chrome Driver.
org.openqa.selenium.InvalidSelectorException: invalid selector: Unable to locate an element with the xpath expression //*[contains(#id='bottomApplyBtn')] because of the following error:
SyntaxError: Failed to execute 'evaluate' on 'Document': The string '//*[contains(#id='bottomApplyBtn')]' is not a valid XPath expression.
Just wanted to know whether i have done any mistake
Try to use
'//*[contains(#id,'bottomApplyBtn')]'
instead of
'//*[contains(#id='bottomApplyBtn')]'
When you are using contains method in your XPath expression, you basically are using an inbuilt method to find the element.
This method takes 2 parameters.
First the tag you in which you want to search.
Second is the actual text value which you are looking for inside the above tag.
Basically you have to call the method with 2 parameters and that 2 parameters should be comma separated.
So //*[contains(#id='bottomApplyBtn')] is wrong you should instead remove this = sign.
//*[contains(#id, 'bottomApplyBtn')]
|_______|____________________ Parameter 1
|__________________________________Parameter 2
Hope it helps!

How take XPATH inside a iframe?

Im trying to get the XPATH inside a iframe called "gadget_6"
i need the xpath of select div. Using selenium i do:
self.change_frame('__gadget_6') #Change to the correct iframe
after that, i try to do:
self.selec_orgvdc = self.driver.find_element(By.XPATH,'/html/body/div[5]/div/div/div/table/tbody/tr/td/div')
for posteriorly do:
self.selec_orgvdc.click
but i obtain the error:
InvalidSelectorException: Message: invalid selector: Unable to locate an element with the xpath expression /html/body/div[5]/div/div/div/table/tbody/tr/td/div because of the following error:
SyntaxError: Failed to execute 'evaluate' on 'Document': The string '/html/body/div[5]/div/div/div/table/tbody/tr/td/div' is not a valid XPath expression.
Someone can help me?
New modification:
self.change_frame('__gadget_6')
time.sleep(4)
self.logger.info("Buscando orgvdc")
#self.selec_orgvdc = self.driver.find_element(By.CSS_SELECTOR,'div.GN4Y2ATIMD table div.gwt-Label')
self.selec_orgvdc = self.driver.find_element(By.XPATH,'//div[5]/div/div/div/table/tbody/tr/td/div')
self.logger.info("Encontrado!")
Hi to work with xpath inside iframe first you have to sitch your driver instance ti that iframe then only you can perform any action
1.To switch to an iframe plz do it like : driver.switchTo().frame("selfservice");
Also looking at your source code i can clearly see there is 2 (two) i frames
1.iframe id = __gadget_6
2.iframe id = selfservice
hence i can guess why its not working in your case cause you are switching to a wrong i frame
now try this xpath //*[#class='GN4Y2ATIMD']/div/div/div/table/tbody/tr/td/div to perform click this will surely work.
XPath shouldn't include the /html/body. try this:
self.selec_orgvdc = self.driver.find_element(By.XPATH,'//div[5]/div/div/div/table/tbody/tr/td/div')
Note that this will be quite brittle. Even better would be to do something like this CSS:
self.selec_orgvdc = self.driver.find_element(By.CSS,'div.GN4Y2ATIMD table div.gwt-Label')