Click on different html class with the same name - java

I have an html radiobox with Yes or Not choice.
But the Yes and Not class have the same class name.
CODE FOR YES
<div class="quantumWizTogglePaperradioRadioContainer"><div class="quantumWizTogglePaperradioOffRadio exportOuterCircle"><div class="quantumWizTogglePaperradioOnRadio exportInnerCircle"></div></div></div>
CODE FOR NOT
<div class="quantumWizTogglePaperradioRadioContainer"><div class="quantumWizTogglePaperradioOffRadio exportOuterCircle"><div class="quantumWizTogglePaperradioOnRadio exportInnerCircle"></div></div></div>
When I use this code, the program click on the first one in the radiobox form.
radioButton = String.format("//div[#class='quantumWizTogglePaperradioOffRadio exportOuterCircle']");
driver.findElement(By.xpath(radioButton)).click();
how can I recognize them?

If there are only 2 radiobox, use this in the order
First radiobox :
radioButton = String.format("(//div[#class='quantumWizTogglePaperradioOffRadio exportOuterCircle'])[1]");
Second radiobox :
radioButton = String.format("(//div[#class='quantumWizTogglePaperradioOffRadio exportOuterCircle'])[2]");

I will suggest using absolute XPath rather than relative XPath it might resolve it. please see below how absolute XPath is different from relative using the google search bar.
Relative XPath - `//*[#id="tsf"]/div[2]/div/div[1]/div/div[1]/input`
absolute XPath - `/html/body/div/div[3]/form/div[2]/div/div[1]/div/div[1]/input`
or you can use the reference of other elements, For example, suppose if you have a div before with yes and no option with id="Radiobutton". you can still recognize yes and no as below as
yes - //*[#id="Radiobutton"]/div[1]
No - //*[#id="Radiobutton"]/div[2]
Let me know if you need any clarification
You can see above the radio button I can give you an example with that. so we are trying to get possible Paths for radio buttons in div highlighted in black. similar to your problem it has the same class name. so below are the some of possible ways to do it
relative XPath Using Form id which is up in the hierarchy
Yes - `//*[#id="create-form"]/div[3]/div/div/div/ul/li/div[2]/div/div/div[1]`
No - `//*[#id="create-form"]/div[3]/div/div/div/ul/li/div[2]/div/div/div[2]`
Using Absolute path - the absolute path is tracking hierarchy from top to the element. In this case it will be
Yes - `/html/body/div/section/div/div/div/div/form/div[3]/div/div/div/ul/li/div[2]/div/div/div[1]`
No - `/html/body/div/section/div/div/div/div/form/div[3]/div/div/div/ul/li/div[2]/div/div/div[2]`
If you see the difference here between 1 and 2. In absolute path instead of starting from form id as a reference, it starts right from HTML tag and tracks the element in DOM tree.

Related

Send text to div in Selenium + Java

I want to send a text to a div element in web.whatsapp. I tried several ways ie using XPath, cssSelector, class name etc. but none is working for me.
This textbox comes when we attach an image in web.whatsapp.
Please step into the div and use the div with the class "selectable-text". As this is a contenteditable div you should be able to click into it and call then sendKeys() onto the element.
if this does not help please let me know then I will look in our code how we are filling such divs exactly.
You need to drill down further until you get to a web element that takes an input.

CSS Selector: Anchor text of href contains

I am currently working with Selenium and have now reached the interesting, yet incredibly difficult, world of CSS selectors.
I'm currently looking at selecting the different options of the Google tool bar. E.g when you search for something, on the results page you get options to search for the same term but under images, news, videos etc
I'm particularly interested in selecting the "Images" link.
I've been working on it for quite a while and the closest i have got is the below selector:
div a.q.qs[href]
This drills down into the right sub classes but there are 16 of them. Despite hours of aimless searching, i'm unable to complete the query with a contains method around the anchor text, which is unique in the targeted sub classes.
I'm aware there is a By LinkText option in Selenium, but i'm not sure if the anchor text is unique across the entire page. Also, i really want to understand CSS selectors in general so even if it was, i want to resolve this particular issue so i can apply it to future problems.
I'm looking for something like the below pseudo CSS selector:
div a.q.qs[href].Anchorcontains("Images")
Can anyone help?
All links have a unique parameter called tbm: its value is isch for images, so I'd go with
a[href*="tbm=isch"]
There are sometimes ways to get what you want with CSS selectors but if you want to find an element by contained text, you will have to use either link text/partial link text if it's a link or XPath for everything else.
The XPath for what you want is
//div[#id='hdtb-msb-vis']//a[.='Images']
You could use //a[.='Images'] but that returns two elements, one of which is not visible.
To break this down
// at any level
div find a DIV
[#id='hdtb-msb-vis'] that contains an ID of 'hdtb-msb-vis'
//a that has a child A at any level
[.='Images'] that contains text (.) equal to 'Images'
If you want to explore by link text, you can write something like
int count = driver.findElements(By.linkText("Images")).size();
and print count. My guess is that it will be 2, one of which is not visible. You can use Selenium to further filter this down to only the visible link, if you wanted.
You are going to have the same issue with BackSlash's CSS selector answer. You can tweak it slightly and solve this problem with the CSS selector locator
#hdtb-msb-vis a[href*='tbm=isch']
Here are some links to CSS references that will help you get started: W3C reference, SauceLabs CSS Selectors tips, and Taming Advanced CSS Selectors.

Selenium search text in a page section and click on a button inside it

I am using Webdriver and Java. My problem is that the page is splitted in 2 sections, both with the same name //div[#class='sg-content-box sg-content-box--spaced']
I want to click on the button Aprobă near the user David2211 (his answer can appear first or second)
My problem is that i don't know how to do click on the button in that specific area, for that specific username
For things like this, you have to use XPath since we are looking for an element that contains specific text. In this case, we will be looking for an element that contains the username 'David2211' and then a button that contains the text 'Aprobă'. I would assume that you will use this code more than once using different usernames so I would put this in a function so that it's easier to reuse.
The function
public void approveAnswerByUsername(String username)
{
driver.findElement(By.xpath("//a[contains(.,'" + username
+ "')]/ancestor::div[contains(#class, 'js-answer-element')]//div[contains(#class,'js-approve-button-text')][contains(.,'Aprobă')]")).click();
}
and you call it like
approveAnswerByUsername("David2211");
This XPath is rather large and complicated but it looks for an A tag that contains the specified username, goes up the DOM to find a parent DIV that encloses the entire answer and then navigates back down the DOM to find a DIV that contains the 'Aprobă' text.
Try Below xpath to locate the same element
Here you have to pass the user's name whose button you wants to click
//li/a[contains(.,'David2211')]/../../../preceding-sibling::div//button[#title='Aprobă']
The only thing specific to your button is indeed the username. I would suggest to get the xpath of the username's node, and then try to get its button from the parent's node using the xpath :
//{username's xpath}/parent::div[#class='sg-content-box sg-content-box--spaced']/{button's xpath}
It seems quite barbaric but that's the only way I see.
A challenging xpath after many days. Thanks for asking this question. Try this below xpath.
"//li/a[contains(text(),'DemonBolt')]/ancestor::div[#class='sg-content-box sg-content-box--spaced']//div[#class='sg-label__text js-approve-button-text']"
or
"//li/a[contains(text(),'DemonBolt')]/ancestor::div[#class='‌​sg-content-box sg-content-box--spaced']//div[contains(text(),'Aprobă')]"
Just change the text DemonBolt with the name whom you need to approve.
Hope this helps. Thanks.
Here is the Answer to your Question:
To click on the button Aprobă near the user David2211 (his answer can appear anywhere) you can use the following code block:
JavascriptExecutor je = (JavascriptExecutor)driver;
WebElement element = driver.findElement(By.xpath("//a[contains(text(),'David2211')]//preceding::button[2]/div/div[contains(text(),'Aproba')]"));
je.executeScript("arguments[0].scrollIntoView(true);",element);
element.click();
Let me know if this Answers your Question.

Selenium / ChromeDriver - Clicking in the center of an element

So I ran into a new issue today that I have not experienced for, and it relates to the nature of the Chrome Driver (I believe Chrome is the only one that does this..). I am aware that when you click an element using .click() it clicks in the center. However this is troubling because I am trying to click a checkbox that just so happens to have a link nested in the center.
I have tried using the JavaScript Executor as well and no luck.. Does anyone know a way around this? Yes I have tried just accessing the box but it doesnt have an identifier I can use..
You can click using coordinates
Coordinates co = element.getCoordinates();
This issue could be resolved by two methods
Method 1: Find correct xpath of checkboxx use default click
driver.findElement(By.xpath("CheckBoxXPath").click();
Method 2: If you really want to click on centre of WebElement then you Actions class method click(WebElement target) this method click on mid of WebElement.
Refer How to use Actions class clcik method
Since you didn't add here the check box html I will assume it is something like:
<input type="checkbox" id="checkbox_id">
<label for="checkbox_id">Something</label>
So you just have to click the input and not the label. It will look like this:
driver.findElemnt(By.id("checkbox_id")).click();
Or using xPath:
driver.findElemnt(By.xpath("//input[#type='checkbox']")).click();

Getting element in WebDriver, not by xpath

I am using webdriver for test automation on site which code is auto-generated probably in GWT.
All id's are in form like "x-auto-4009" which is not to reliable way of getting to elements.
I have page with something like form.
It's like
Label name | <---- Input ---->
Label name | <---- Input ---->
Label name | <---- Input ---->
Each new line is coded as new table in html.
Can you tell me what is the best way of getting to specific Input in more generic way?
I wrote a method that takes a label name and then it finds all elements by tag TR. Next it get's theese allRows and scans them for labelname. If it's found then i find within that row elements with tag input and that is my goal. It works fine but it takes some time to do find all those elements and loop through them.
I don't want to use xpath or locating elements through those fragile id's.
Can you recommend me any other way of doing that?
Thanks in advance,
regards.
If you can't use xpath, I think the only other way to do this would be to alter the code for the page.
It is possible to set these GWT ID values so that they have a clearer and more consistent value. See: https://developers.google.com/web-toolkit/doc/latest/DevGuideUiCss#widgets.
Less appealing is the option to give each input a class or name attribute by which you'd identify them, and then search By.class() or By.name().
Why not xpath? That's the most direct way to do it. Your existing approach is the slower alternative.
Use this xpath selection: <label> with text containing the "name", then its parent <td>, then its parent <tr>, then the first <input> in that row:
WebElement input = driver.findElement(By.xpath(
"//label[contains(text(), '"+name+"')]/../../input"
));
I have not tested this. Might have to adjust to your table structure, too.

Categories