I wanted to locate a element of a web page using class name in Selenium. This is the web element that I tried:
<button class="signup-button b green">Get Started!</button>
When I try this way, I was unable to locate the button;
driver.findElement(By.className("signup-button")).click();
But, using css selector like below, it was working;
driver.findElement(By.cssSelector("button.signup-button")).click();
What is the reason for that sometimes working and other times not working?
As you are able to locate the following element:
<button class="signup-button b green">Get Started!</button>
using:
driver.findElement(By.cssSelector("button.signup-button")).click();
but was unable to locate the same element using:
driver.findElement(By.className("signup-button")).click();
That's because there were other elements which renders within the HTML DOM with className as signup-button even before the desired element, which possibly may be invisible by design.
Ideally, you should also be able to use a xpath based Locator Strategy:
driver.findElement(By.xpath("//button[#class='signup-button' and text()='Get Started!']")).click();
Best Practices
But as per best practices, you need to use WebDriverWait for the elementToBeClickable() and you can use either of the following Locator Strategies:
cssSelector:
new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.cssSelector("button.signup-button"))).click();
xpath:
new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.xpath("//button[#class='signup-button' and text()='Get Started!']"))).click();
References
You can find a couple of relevant discussions in:
NoSuchElementException, Selenium unable to locate element
You need to use relative xpath , if you could not have locators like id and class name
Can you try with //button[contains(text(),"Get Started!")] this xpath
Related
Element HTML:
Inbox
What I tried:
driver.findElement(By.cssSelector("a[text='Log out']"));
then
driver.findElement(By.xpath("//a[.='Log out']"));
Element snapshot:
HTML
driver.findElement(By.linkText("Log out"));
Something like that should work, you should provide the page html for a better response.
My response is based on the fact that in your first try you are saying text='Log out'.
findElement in selenium works with locatorStrategies (By.cssSelector/By.linkText...) the one that i used (linkText) search in all the anchor tags that are found in the pages () and analyze the text inside the tag, if the text is matched the driver will find the element.
Let me know if it works, otherwise provide me the web page html snippet.
I've seen the actual screen, you must change Log out with Inbox
driver.findElement(By.linkText("Inbox"));
Given the HTML:
Inbox
You need to take care of a couple of things here as follows:
Within cssSelector doesn't supports the :contains("text") method
Within xpath for exact text matches you need to use text()
Solution
To identify the element you can use either of the following locator strategies:
Using linkText:
WebElement element = driver.findElement(By.linkText("Log out"));
Using cssSelector:
WebElement element = driver.findElement(By.cssSelector("a[href$='INBOX'][title='View the Inbox']"));
Using xpath:
WebElement element = driver.findElement(By.xpath("//a[text()='Inbox' and #title='View the Inbox']"));
I want to locate the "item1" div tag in the following DOM. I tried in different ways. But I could not make it happen.
<html></html>
<frameset ... >
<frame>
</frame>
<frame id= "dynamic value" name = "dynamic value">
<html >
<head></head>
<body>
<div name = "item1">
<div name = "item2">
So , I tried the following ways to locate it. But no such element exception was thrown.
driver.getElementsByTagName("frame")[1].getElementsByTagName("div")[0]
driver.swithTo().frame(1);
driver.getElementsByTagName("div")[0]
You should switch to frame before you search for an element.
Try this:
frame = driver.getElementsByTagName("frame")[1]
driver.swithTo().frame(frame);
driver.getElementsByTagName("div")[0]
Note, I am not sure what is getElementsByTagName(), it looks like some sort of custom method for findElement(), so I just copypasted it into my solution from your example.
getElementsByTagName() DOM method in JavaScript
Source
Seems like you are using wrong method to locate an element using tag name.
In Selenium Java, Use below code snippet to switch into frame
driver.swithTo().frame(1); // index = 1 means 2nd frame
driver.findElements(By.tagName("div"))[0]
And with ExplicitWait conditions (to avoid synchronization related issue)
WebDriverWait wait = new WebDriverWait(driver,10);
wait.until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(frameName);
There are a couple of things you need to consider:
Using Selenium while dealing with <iframe> you can safely ignore the <frameset>
It would be difficult to identify the desired <iframe> through their index as it will be inconclusive which <iframe> loads faster.
As the the desired element is within an <iframe> so to locate the element you have to:
Induce WebDriverWait for the desired frameToBeAvailableAndSwitchToIt().
Induce WebDriverWait for the desired visibilityOfElementLocated().
You can use either of the following Locator Strategies:
Using CSS_SELECTOR:
new WebDriverWait(driver, 20).until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(By.cssSelector("iframe#dynamicValue[name='dynamicValue']")));
WebElement element = new WebDriverWait(driver, 20).until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("div[name='item1']")));
Using XPATH:
new WebDriverWait(driver, 20).until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(By.xpath("//iframe[#id='dynamicValue' and #name='dynamicValue']")));
WebElement element = new WebDriverWait(driver, 20).until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//div[#name='item1']")));
Reference
You can find a coupple of relevant discussions in:
Is it possible to switch to an element in a frame without using driver.switchTo().frame(“frameName”) in Selenium Webdriver Java?
Ways to deal with #document under iframe
I have following xpaths, which should be handled on same way by WebDriver, I need to get text content from these.
//*[#id="dialogMessage"]/div[3]
//*[#id="dialogMessage"]/div[3]/p
//*[#id="dialogMessage"]/div[3]/p/span[2]
I tried to use this code to match all of the above ones.
String result_text = driver.findElement(By.xpath("//*[contains(#value, 'dialogMessage')]")).getText();
Only one of these xpaths is present on page in each page loads. I get following error message:
org.openqa.selenium.NoSuchElementException: no such element: Unable to locate element: {"method":"xpath","selector":"//id[contains(#value, 'dialogMessage')]"}
Looks like you're trying to get all elements that contain attribute value equals to dialogMessage instead try using this xpath:
//*[contains(#id, 'dialogMessage')]
or
//*[#id='dialogMessage']
Would you mind helping me to understand how I can handle this dynamic ID?
Here are cases which I have already tried:
driver.findElement(By.xpath("//input[contains(#id,'Username')]")).sendKeys("aaa");
driver.findElement(By.xpath("//input[starts-with(#id,'undefined-undefined-Username-')]")).sendKeys("aaa");
driver.findElement(By.xpath("//*[#type='text']")).sendKeys("aaa");
No way to find that element.
As per the HTML you have shared the element is a dynamic element . To invoke click() on the desired element you can use either of the following solutions:
cssSelector:
driver.findElement(By.cssSelector("label[for^='undefined-undefined-Username-']")).sendKeys("aaa");
xpath:
driver.findElement(By.xpath("//label[starts-with(#for,'undefined-undefined-Username-')][contains(.,'Username')]")).sendKeys("aaa");
Update
As the element is dynamic you may need to induce WebDriverWait for the desired element to be clickable as follows:
cssSelector:
new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.cssSelector("label[for^='undefined-undefined-Username-']"))).sendKeys("aaa");
xpath:
new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.xpath("//label[starts-with(#for,'undefined-undefined-Username-')][contains(.,'Username')]"))).sendKeys("aaa");
I'am trying to automate http://rose.99ats.com/careers.aspx
After clicking on "signup", I couldn't find the element Popup. I used getWindowHandle(), also used driver.swithchto(), but getting error. I can't find element.
Because it's in a new iframe, you need to use driver.switchTo().frame().
Here is a detailed answer on using switchTo(), in which you can't use name/id in your case, index should generally be avoided, so you may try locate the iframe element by css selector or xpath first, then switch to this WebElement.
WebElement popup = driver.findElement(By.cssSelector("iframe[src^='CareerSignUp.aspx']"));
driver.switchTo().frame(popup);
// or by index: driver.switchTo().frame(0);