I have the below rule to match an image which works fine
//div[#class="wp-caption alignright" or #class="area"]//img
The problem is that the page is created dynamically and it now contains another image before the one I need to match, so I have a new xpath rule to accommodate for this
(//div[#class="body"]//img)[2]
Is there a way to combine these 2 rules into one as I actually need both?
Thanks
Just combine then with union operator:
//div[#class="wp-caption alignright" or #class="area"]//img | (//div[#class="body"]//img)[2]
You can test it here: http://www.xpathtester.com/obj/cf36d1bd-01c6-41ea-8e9b-2099cc75cf80
Related
I have the same button in two different application , so i want to write the same code for them , but the pb is that there's a difference between the xpaths in the text , one starts with an uppercase letter and the second all in lower case :
xpath1: //span[contains(#class,'text')][contains(text(),'Test')]
xpath2: //span[contains(#class,'text')][contains(text(),'test')]
so i want to use the same function: Click Element ${element}
for both apps , how to do that ?
THANKS
I'm using below format, it works perfect. So you can have multiple xpath using this union operator "|". There are also multiple options, but this works and easy to use.
//span[contains(#class,'text')][contains(text(),'Test')] | //span[contains(#class,'text')][contains(text(),'test')]
or
you can also use below format, but this looks little dirty.
//span[contains(#class,'text')][contains(text(),'Test') or contains(text(),"test")]
On this page
https://en.wikipedia.org/wiki/Trinity_Seven#Episode_list
I have:
//*[text()='Reception']//preceding::th[contains(#id, 'ep')]//following::I
But it only registers following.
The default firepath selector is: .//*[#id='mw-content-text']/div/table[5]/tbody/tr/td[1]/I but this kind of selector is known to break quite frequently. Just wondering if there is a better way of doing this and I thought this might be a way.
Thanks!
:)
- You can see that it's getting stuff under the table which is not what I want :S
Try to use below XPath to match required elements:
//th[contains(#id, 'ep')]/following::I[./following::*[text()='Reception']]
This looks more simple
//tr[contains(#class, 'vevent')]//i
Don't overcomplicate things. You need I tag inside each row. So just find row locator tr[contains(#class, 'vevent')] and get it's I
Another good approach in case you want to check that inside of parent element is located some special element, but you want to find some 3rd element is to use such style: //element[./specific]//child , so in your case:
//tr[contains(#class, 'vevent')][./th[contains(#id,'ep')]]//i
so it's I tag inside row that contains #id,'ep' in header
I have two cq page and I want to retrive these two using jcr:title property using XPATH. The below query is working fine for single.
/jcr:root/content/test//element(*, cq:Page)[((jcr:like(jcr:content/#jcr:title, dell)))]
But I want to excuate it for multiple items. I have tried with following option but it is not working
/jcr:root/content/test//element(*, cq:Page)[((jcr:like(jcr:content/#jcr:title, [dell,samusng])))]
Could anyone help me to write xpath query?
As rakhi4110 already mentioned in the comment, you can combine multiple where clauses with an or just like in SQL. Though I think you either want exact matches or use jcr:containts instead of jcr:like.
Exact match:
/jcr:root/content/test//element(*, cq:Page) [jcr:content/#jcr:title='dell' or jcr:content/#jcr:title='samsung']
Contains:
/jcr:root/content/test//element(*, cq:Page) [jcr:contains(jcr:content/#jcr:title, 'dell') or jcr:contains(jcr:content/#jcr:title, 'samsung')]
Or if you really want to use jcr:like which, as in SQL, uses % for wildcard:
/jcr:root/content/test//element(*, cq:Page) [jcr:like(jcr:content/#jcr:title, '%dell%') or jcr:like(jcr:content/#jcr:title, '%samsung%')]
Am automating things using Selenium. Need your help to handle Dynamic Xpath as below:
Driver.findElement(By.xpath("//[#id='INQ_2985']/div[2]/tr/td/div/div[3]/div")).click();
As above INQ_2985 changes to 2986,2987,2988 etc during each run
HTML CODE:
< div> class="context-menu-item-inner" style="background-image:url(../images/productSmall.png);">Tender Assignment < /div>
Tried different combinations as below but with no success:
// Driver.findElement(By.name("//input[#name='Tender Assignment']")).click();
// Driver.findElement(By.className("context-menu-item-inner")).click();`
Can you help me on this.
you can try using contains() or starts-with() in xpath,
above xpath can be rewritten as follows,
Driver.findElement(By.xpath("//*[starts-with(#id,'INQ')]/div[2]/tr/td/div/div[3]/div")).click();
if you can post more of your html, we can help improve your xpath..
moreover using such long xpath's is not recommended, this may cause your test to fail more often
for example,if a "new table data or div" is added to the UI, above xpath will no longer be valid
you should try and use id, class or other attributes to get closer to the element your trying to find
i personally recommend using cssSelectors over xpath
you can use many methods,
use implicity wait;
driver.findElement(By.xpath("//*[contains(#id,'select2-result-label-535')]").click();
driver.findElement(By.xpath("//*[contains(text(), 'select2-result-label-535')]").click();
Good to use Regular expression
driver.findElement(By.xpath("//*[contains(#id,'INQ_')]")
Note: If you have single ID with name starts from INQ_ then you can take action on the element . If a bunch of ID then you can extract as a List<WebElements> and then match with the specific text of the element ( element.getText().trim() =="Linked Text" and if it matched then take action. You can follow other logic to traverse and match.
you can use css -
div.context-menu-item-inner
Use this xpath:
driver.findElement(By.cssSelector("div.context-menu-item-inner").click();
The best choice is using full xpath instead of id which you can get easily via firebug.
e.g.
/html/body/div[3]/div[3]/div[2]/div/div[2]/div[1]/div/div[1]
if your xpath is varying
Ex: "//*[#id='msg500']" , "//*[#id='msg501']", "//*[#id='msg502']" and so on...
Then use this code in script:
for (int i=0;i<=9;i++) {
String mpath= "//*[#id='msg50"+i+"']";
driver.findElement(By.xpath(mpath)).click();
}
I am trying to quickly find a specific node using XPath but it seems my multiple predicates are not working. The div I need has a specific class, but there are 3 others that have it. I want to select the fourth one so I did the following:
//div[#class='myCLass' and 4]
However the "4" is being ignored. Any help? I am new to XPath.
Thanks.
If a xpath query returns a node set you can always use the [OFFSET] operator to access a certain element of it.
Use the following query to access the fourth element that matches the #class='myClass' predicate:
//div[#class='myCLass'][4]
#WilliamNarmontas answer might be an alternative to the syntax showed above.
Alternatively,
//div[#class='myCLass' and position()=4]
The accepted answer works correctly only if all of the div elements have the same parent. Otherwise use:
(//div[#class='myCLass'])[4]