I want to find the following item using Selenium. The value of the class changes whenever there is a change. This is inside a complex page (multiple iframes, and other items loaded dynamically). The only unique id is itemid, which is dynamic value and title combination. If I click on this Action, am getting another new set of complex items. I am new to Selenium. How to do that?
HTML:
<td itemid="xxyyy.as123" title="Actions" nowrap="" class="text-button">Actions <img src="../row.gif"></td>
<td itemid="xxyyy.as123" title="Actions" nowrap="" class="text-button button-active">Actions <img src="../row.gif"></td>
<td itemid="xxyyy.as123" title="Actions" nowrap="" class="text-button button-hover">Actions <img src="../row.gif"></td>
The code I tried:
Find by Xpath
var element=driver.FindElement(By.XPath("html/body/div[id='pageContent']/iframe/#document/html/frameset/frame[name='detailsDisplay']/#document/html/body/form[name='tableForm']/div[id='divToolbarContainer']/div[id='divToolbar']/div[1][class='toolbar']/table/tbody/tr/td[title='Actions']"));
Find by Link Text
var element = driver.FindElement(By.LinkText("Actions"));
Any help would be appreciated.
Try
By.CssSelector("td[title="Actions"]");
By.CssSelector("td[itemid="xxyyy.as123"]");
By.CssSelector("td[itemid="xxyyy.as123"][title="Actions"]")
Create Dynamic CSS Selector.
For Example:
driver.FindElement(By.CssSelector("td[itemid$="xxyyy."]")).Click();
Note: In dynamic Elements, there is always a part of locator wich is fixed. we need to generate the locator using this part.
If fixed part is at starting - Use Carrot Character (^)
If fixed part is at Middle - Use Asterisk sign (*)
If fixed part is at End - Use Doller sign ($)
Finally I was able to achieve it, by using the frame names.
driver.SwitchTo().Frame("content").SwitchTo().Frame("detailsDisplay");
var element = driver.FindElement(By.XPath("//*[#id=\"divToolbar\"]/div[1]/table/tbody/tr/td[1]"));
Thanks everyone.
Related
I have a html like this
<td class="random">
<div id="randomID">Product:</div>
</td>
<td class="random">
<div id="randomID">
<input type="text" class="random">
</div>
</td>
my xpath //div[contains(text(),"Product:")] gives me the first element for which I want to send input. How do I get the input xpath so I can do input.sendkeys() on it.
You use either of the xpath to get the input tag.
Use following and index of input tag
//div[contains(text(),"Product:")]/following::input[1]
Or find the td tag and then use following-sibling
//td[.//div[contains(text(),"Product:")]]/following-sibling::td[1]//input
You can use below xpath as well.
//div[text()="Product:"]/following::input[1]
Or
//td[.//div[text()="Product:"]]/following-sibling::td[1]//input
Use following-sibling
Try with following xpath:
//td[contains(.,"Product:")]//following-sibling::td//input
For the provided code, the input is very simple to identify:
//input[#class='random']
Since I can't see any other duplicate code to force you to be more precise, I don't see the problem in using this one.
If you have multiple , and each or some of them have an input inside, in this case:
//div[text()="Product:"]/following::input[1]
Where Product is the visible text of the div that you want to use as a parent, and then you go straight in the first input taken by its index.
Please see the image below which shows code of the web page in Developer Tools window and advise me the correct selector for 'Depreciation Models'. Text highlighted in red is constant, however the surrounding text is dynamic. So I tried using contains selector to locate but unsuccessful. I want to avoid XPATH as number of before and after div elements may keep changing.
I am using Selenium IDE hence the C#/Java code for RC/Webdriver won't help much.
Selenium IDE generated target path is this:
css=#dhxId_rgWATog7lC3E_27572|6059|6152 > td.sub_item_text > div.sub_item_text
I tried
css=contains('27572') > td.sub_item_text > div.sub_item_text
but it didn't work.
Kindly suggest. I am stuck. Thanks.
As you tried the Locator Strategy as :
css=contains('27572') > td.sub_item_text > div.sub_item_text
Reasons for not working
From the snapshot of the HTML you have provided, 27572 is not the innerText but partial string of the id attribute.
As per selenium.common.exceptions.InvalidSelectorException with “span:contains('string')”:
The :contains pseudo-class isn't in the CSS Spec and is not supported by either Firefox or Chrome (even outside WebDriver).
Solution
You can use the following xpath as per the existing DOM Tree:
xpath=//tr[#class='sub_item'][contains(#id,'27572')]//td[#class='sub_item_text']/div[#class='sub_item_text'][contains(.,'Depreciations Models')]
I guess this would be the right approach:
<style>
[id*="27572"] > td.sub_item_text > div.sub_item_text{
color:red;
}
<table>
<tbody>
<tr id="dhxId_rgWATog7lC3E_27572|6059|6152" class="sub_item">
<td class="sub_item_icon">
<i class="fa fa-user epc-down-circled-2"></i>
</td>
<td class="sub_item_text">
<div class="sub_item_text"> Depriciations Models</div>
</td>
</tr>
</tbody>
</table>
It will set all elements that have an id attribute value containing "27572" and inside of it.
I've tried several xpath's for choosing the dropdown list. But nothing is worked.
Some of the xpath's I used are as follows:
By.xpath("//table/tbody/tr[2]/td[2]/span").click;
Or
By.xpath("/td[2]/span[contains(text(),'NATIONAL IDENTITY DOCUMENT')]").click;
Please find the below html tags, I need to select the value either 'ASYLUM SEEKER PERMIT DOCUMENT' or 'NATIONAL IDENTITY DOCUMENT'.
<tbody>
<tr id="jP2Qrg" class="z-comboitem">
<td class="z-comboitem-img"/>
<td class="z-comboitem-text">
<span class="z-comboitem-spacer"/>
ASYLUM SEEKER PERMIT DOCUMENT
</td>
</tr>
<tr id="jP2Qsg" class="z-comboitem z-comboitem-over">
<td class="z-comboitem-img"/>
<td class="z-comboitem-text">
<span class="z-comboitem-spacer"/>
NATIONAL IDENTITY DOCUMENT
</td>
</tr>
</tbody>
When I try to take xpath using firepath, it is dynamic. Every time the xpath and the id is keep changing. So please suggest the xpath which works.
The text is not inside the span text and it is in second td tag. you can try with small change in your code as given below.
By.xpath("//table/tbody/tr[2]/td[2]").click;
or
By.xpath("//td[contains(text(),'NATIONAL IDENTITY DOCUMENT')]").click;
Can you check this..,
By.xpath("//*[contains(text(),'NATIONAL IDENTITY DOCUMENT')]").click;
By.xpath("//*[contains(text(),'ASYLUM SEEKER PERMIT DOCUMENT')]").click;
Try to use below XPath to match required option:
By.xpath("//td[normalize-space()='ASYLUM SEEKER PERMIT DOCUMENT']").click;
or
By.xpath("//td[.='ASYLUM SEEKER PERMIT DOCUMENT']").click;
As #Murthi said, text node is not a child of span, but td. Note that there are some specifics in locating text nodes
Here is the Answer to your Question:
To click on ASYLUM SEEKER PERMIT DOCUMENT you can use the following xpath:
By.xpath("//td[contains(.,'ASYLUM SEEKER PERMIT DOCUMENT') and not (#class='z-comboitem-spacer')]").click;
Let me know if this Answers your Question.
How about this xpaths,
Updated code
(//td[2])[1]//*[starts-with(#class,"z-com")]; // Selects ASYLUM..
(//td[2])[2]//*[starts-with(#class,"z-com")]; // Selects NATIONAL..
This should work if it doesn't have same class name in the same position.
Old xpath's
driver.findelement(By.xpath("(//td[2])[1]")); // selects ASYLUM SEEKER PERMIT DOCUMENT
driver.findelement(By.xpath("(//td[2])[2]")); // selects NATIONAL IDENTITY DOCUMENT
Find out the solution for selecting the dropdown options.
By using List method, I took the list of options available in that field and selected by using clicking the index value of list.
List<WebElement> Idtype = driver.findElements(By.xpath("//tr[2]/td[2][#class = 'z-comboitem-text']"));
Idtype.get(0).click();
What xpath can I use for something like this without using ID? Or if there are more checkboxes but IDs are still different after refreshing page?
<td class="player" style="vertical-align: top;">
<span class="gb-CheckBox">
<input id="gb-uid-120" type="checkbox" value="on" tabindex="0" style="background-color: rgb(255, 255, 255);">
<label for="gb-uid-120"></label>
</span>
</td>
Try following:
//span[#class="gb-CheckBox"]/input[#type="checkbox"]
Why not:
//input[#type='checkbox']
this should be enough and will select all inputs that are checkbox type.
If you need only from a certain area then you need to add a constraint by adding another selector in front of this like:
//div[#class='my_prefered_area']//input[#type='checkbox']
Another way of getting the selector would be to use the pare of the id that does not change like:
//input[contains(#id, 'gb-uid')]
Of course you can also add the restriction for checkbox type:
//input[contains(#id, 'gb-uid')][#type='checkbox']
Seems like you got the answer as most of the ways mentioned above are correct.
Correcting the first one path wit CSS :
td.player>span.gb-CheckBox>input[type='checkbox']
(try it removing the spaces before and after > )
Or
td.player>span.gb-CheckBox>input
Will also work.
As you mentioned, if your Id is changing frequently, that means its an dynamic webelement and
if it is changing at the end(after gb-uid- i.e. gb-uid-120, then gb-uid-121 something like this) then use contains function on Xpath as below:
//span[#class="gb-CheckBox"]/input[contains(#id, 'gb-uid-')]
You can also locate this checkbox easily using cssSelector instead of xpath which would be much faster as below :-
td.player > span.gb-CheckBox > input[type='checkbox']
Using Xpath tool from chrome dev tools, I have been able to get xpath string and a td object. I 'm just wondering how do we find the value of text in a td object using selenium python web-drivers?
for your case you can use .gettext() method of selenium.
Once I found that, the attribute within td which contains the text is changing and i was supposed to fetch the text in those attribute.
like
<td class="table__cell" data-col-index="1">
<div class="ec-table__cell-content ">813.75</div>
</td>
<td class="table__cell" data-col-index="2">
<span class="ec-table__cell-content ">522.12</span>
</td>
So to get text within all td in a list, I used dynamic Xpath way:
By.xpath("//td[contains(#class,'table__cell')]/following::*").getText()
Try to search by xpath. Relatively to some ID.
Example of:
id("body_content")/table/tbody/tr/td[3]
in this case will be shown exact elements of 3rd column only.