I'm trying to click on an element but I always get the error "cannot locate an element using..".
I've tried it with find by class, by csselector, and by XPath. I also tried the a class first and then the span class element but it's still not working. It's definitely the correct frame, too.
It's really weird because it worked two weeks ago, I didn't change anything in the code and now it's not working. Is it possible that the element is constantly changing? If so, how can I make sure that it still finds the element without adjusting my code every time?
<a class="ui-dialog-titlebar-icon ui-dialog-titlebar-close ui-corner-all" href="#" aria-label="Close" role="button">
<span class="ui-icon ui-icon closethick">
::after
</span>
</a>
This is my current code now which still isn't working:
driver.switchTo().defaultContent();
driver.switchTo().frame("frame_vehicleFileTab");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
WebElement closePrint = (new WebDriverWait(driver, 10)).until(
ExpectedConditions.elementToBeClickable(By.xpath("//*[#aria-label='Close']")));
closePrint.click();
After trying DebanjanB's suggestion by searching for the element:
driver.findElement(By.xpath("//a[#class='ui-dialog-titlebar-icon ui-dialog-titlebar-close ui-corner-all' and #aria-label='Close']")).click();
I get this error: org.openqa.selenium.ElementNotInteractableException: Element could not be scrolled into view
Update: I fixed it by getting the Selenium IDE extension for Firefox and then choosing the xpath that was generated by the extension together with the javascript executor:
WebElement closePrint = (new WebDriverWait(driver, 10)).until(
ExpectedConditions.presenceOfElementLocated(By.xpath("//div[#id='FileTab:Form:j_id674351400_da78919']/div/a/span")));
JavascriptExecutor js1 = (JavascriptExecutor)driver;
js1.executeScript("arguments[0].click();", closePrint);
I don't know why that xpath works now but I'm glad it does. Thanks everyone for your suggestions!
It will be tough to locate the element through the <span> tag as it is a pseudo element. To locate the element you can use either of the following Locator Strategies:
cssSelector:
new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.cssSelector("a.ui-dialog-titlebar-icon.ui-dialog-titlebar-close.ui-corner-all[aria-label='Close']"))).click();
xpath:
new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.xpath("//a[#class='ui-dialog-titlebar-icon ui-dialog-titlebar-close ui-corner-all' and #aria-label='Close']"))).click();
As far as I can see in the HTML you have provided:
You can use By.XPATH with this XPATH: "//*[#aria-label='Close']".
Like this:
d.findElement(By.xpath("//*[#aria-label='Close']")).click();
EDIT:
Try using Actions with an Offset this helps if there is an element covering it, this happens with iFrames.
Here is a code snip:
WebElement closePrint = new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.xpath("//a[#class='ui-dialog-titlebar-icon ui-dialog-titlebar-close ui-corner-all' and #aria-label='Close']")));
int width = closePrint.getSize().getWidth();
Actions clicker= new Actions(driver);
act.moveToElement(closePrint).moveByOffset((width/2)-2, 0).click().perform();
Hope this helps you!
In addition to DebanjanB's suggestion, I would also suggest you to use below JavaScript utility to scroll down till the element is visible.
WebElement element = driver.findElement(By.xpath("//a[#class='ui-dialog-titlebar-icon ui-dialog-titlebar-close ui-corner-all' and #aria-label='Close']"));
((JavascriptExecutor) driver).executeScript("arguments[0].scrollIntoView(true);", element);
Related
I'm trying to select an element based on its text contents. I am using XPath to achieve this.
I am just puzzled as this should work?
WebElement link = obj.driver.findElement(By.xpath("//div[contains(text(), 'Notifications')]"));
I'll even copy the HTML code:
<div class="linkWrap noCount">Notifications <span class="count _5wk0 hidden_elem uiSideNavCountText">(<span class="countValue fsm">0</span><span class="maxCountIndicator"></span>)</span></div>
The div element has the words "Notifications" inside it. So why doesn't it work.
Go to this page on Facebook: https://www.facebook.com/settings
Use this chrome extension to highlight any area via xPath.
You have a space before the word Notifications:
WebElement link = obj.driver.findElement(By.xpath("//div[contains(text(), 'Notifications')]"));
You should also add a wait for element before trying to find the element:
WebDriverWait wait = new WebDriverWait(webDriver, timeoutInSeconds);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//div[contains(text(), 'Notifications')]"));
WebElement link = obj.driver.findElement(By.xpath("//div[contains(text(), 'Notifications')]"));
I found the issue with the help of some amazing people in this community.
Ok, so my element was in an iFrame.
In order to access the element, I must first access the iFrame
WebElement iframe = obj.driver.findElement(By.xpath("//iframe[#tabindex='-1']"));
obj.driver.switchTo().frame(iframe);
I am trying to create a test where I have to fill out some information inside an iframe. Getting access to the iframe work fine and I can fill out information inside the frame. The issue is that when I find out a element 'A' it has a postback attached to it which reloads the content inside the iframe, to find out another element 'B'. So i am not able to find that element.I am getting below error:
org.openqa.selenium.WebDriverException: unknown error: Element <iframe style="overflow-x:hidden;" id="t5" height="1350" frameborder="0" width="98%" src="https://edata.ndtv.com/coronavirus/table/india_table.html?shgraph=1&days=7" cd_frame_id_="7da8f2aea5a580b3a6e90a9d5016fa0d">...</iframe> is not clickable at point (554, 7). Other element would receive the click: <div class="topnav2014" style="border-bottom: none;">...</div>
(Session info: chrome=85.0.4183.83)
Here are my observations: When I first locate the iframe it looks like this:
<iframe style="overflow-x:hidden;" id="t5" height="1350" frameborder="0" width="98%" src="https://edata.ndtv.com/coronavirus/table/india_table.html?shgraph=1&days=7">
After the postback has occurred it looks like this:
<iframe style="overflow-x:hidden;" id="t5" height="1350" frameborder="0" width="98%" src="https://edata.ndtv.com/coronavirus/table/india_table.html?shgraph=1&days=7" cd_frame_id_="a5006acf28d8c288313681ab9ad7a4fa">
I can easily find element A:
But element B i am not able to find
The code fails when I try to get hold of the iframe element.
How can I get hold of the iframe again, after the postback inside the frame?
I have tried this suggestion also but it is not working
//Ensure that you are back to the base frame
driver.SwitchTo().DefaultContent();
//SwitchTo the intended frame
driver.SwitchTo().Frame(driver.FindElement(By.XPath("//iframe[contains(#src,'<removed for clearity>')]")));
Use a driver.executescript() for the first problem since another element is receiving the click.
element = driver.findElement(By.id(""));
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("arguments[0].click();", element);
This error message...
org.openqa.selenium.WebDriverException: unknown error: Element <iframe style="overflow-x:hidden;" id="t5" height="1350" frameborder="0" width="98%" src="https://edata.ndtv.com/coronavirus/table/india_table.html?shgraph=1&days=7" cd_frame_id_="7da8f2aea5a580b3a6e90a9d5016fa0d">...</iframe> is not clickable at point (554, 7). Other element would receive the click: <div class="topnav2014" style="border-bottom: none;">...</div>
(Session info: chrome=85.0.4183.83)
...implies that the WebDriverException was raised as you tried to invoke click() on the <iframe> element.
Factually, instead of clicking on the <iframe> element you would invoke click() on an element within the <iframe>. Moreover, as the the desired element is within a <iframe> so you have to:
Induce WebDriverWait for the desired frameToBeAvailableAndSwitchToIt.
Induce WebDriverWait for the desired elementToBeClickable.
You can use either of the following Locator Strategies:
Using xpath:
new WebDriverWait(driver, 10).until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(By.xpath("//iframe_xpath")));
new WebDriverWait(driver, 10).until(ExpectedConditions.elementToBeClickable(By.xpath("element_xpath"))).click();
References
You can find a couple of relevant discussions in:
Ways to deal with #document under iframe
Is it possible to switch to an element in a frame without using driver.switchTo().frame(“frameName”) in Selenium Webdriver Java?
I am able to extract the data of the active cases rise and fall for every state. There is a single frame which contains both the locators shared by you. Check below working code.
driver.get("https://www.ndtv.com/coronavirus");
driver.manage().window().maximize();
WebDriverWait wait = new WebDriverWait(driver, 20);
wait.until(ExpectedConditions.elementToBeClickable(By.className("tab-wrapper")));
driver.switchTo().frame(driver.findElement(By.xpath("//iframe[contains(#src,'https://edata.ndtv.com/coronavirus/table/india_table.html?shgraph=1')]")));
//cases down
List<WebElement> eleCasesUp = driver.findElements(By.xpath("//tr//td[3]//p//span[#class='data-up']"));
List<String> casesUpList = new ArrayList<String>();
for (WebElement element : eleCasesUp) {
casesUpList.add(element.getText());
}
//cases up
List<WebElement> eleCasesDown = driver.findElements(By.xpath("//tr//td[3]//p//span[#class='data-down']"));
List<String> casesDownList = new ArrayList<String>();
for (WebElement element : eleCasesDown) {
casesDownList.add(element.getText());
}
System.out.println("Cases Up List -->" + casesUpList);
System.out.println("Cases Down List -->" + casesDownList);
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'm automating some website in which I need to log out. I'm facing a hard time in this code:
WebDriverWait wait = new WebDriverWait(d, 10);
WebElement Category_Body = wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("user logout")));
Category_Body.click();
d.findElement(By.id("logout_user")).click();
Thread.sleep(1000);
HTML:
<a class="user logout" title="Sign out" data-target="#confirm_popup" data-toggle="modal"></a>
Error:
org.openqa.selenium.NoSuchElementException: no such element: Unable to locate element: {"method":"id","selector":"user logout"}
Try the following code for that:
WebDriverWait wait = new WebDriverWait(d, 10);
WebElement Category_Body = wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector(".user.logout")));
Category_Body.click();
PS: You can do this with ExpectedCondition.elementToBeClickable, also.
Hope it helps you!
I think the issue is with the identifier
You have used
WebElement Category_Body = wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("user logout")));
But according to your HTML
<a class="user logout" title="Sign out" data-target="#confirm_popup" data-toggle="modal"></a>
The link have no id called "User Logout"
With out using id try to use class By.findElementByClassName("user logout")
As a Second solution, try to use xpath ( which will work most of the time )
If both the solutions are not usable you can use the JavascriptExecutor ( The elements which are hard to capture can be easily handled with JavascriptExecutor )
NOTE: The main issue is with you using "user logout" when there is no such ID
Cheers
As per your to locate the desired element to logout within the Model Box you need to induce WebDriverWait for the element to be clickable and you can use either of the the following options:
cssSelector:
new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.cssSelector("a.user.logout[title='Sign out'][data-toggle='modal']"))).click();
xpath:
new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.xpath("//a[#class='user logout' and #title='Sign out'][#data-toggle='modal']"))).click();
I'm having trouble locating a span element in Selenium using java.
the HTML looks like:
<div class="settings-padding">
<span>Settings</span>
</div>
And I've tried the following with no luck:
By.xpath("span[.='Settings']")
and
By.xpath("span[text()='Settings']")
and
By.cssSelector("div[class='settings-padding']"))
as well as some other similar attempts. Could you point me to the best method to do this? As it stands I constantly get "Unable to locate element" error in eclipse.
Your all xpath are looks OK, Just some syntactically incorrect. you are missing // in your xpath
The correct xpath are as below :-
By by = By.xpath("//span[.='Settings']")
Or
By by = By.xpath("//span[text()='Settings']")
Or
By by = By.xpath("//div[#class='settings-padding']/span"))
Or you can use cssSelector as :-
By by = By.cssSelector("div.settings-padding > span"))
Using anyone of the above By locator you can locate element as below :-
WebDriverWait wait = new WebDriverWait(driver, 10);
WebElement el = wait.until(presenceOfElementLocated(by));
Hope it helps...:)
For the element below
<span class="test-button__text">
Test Text
</span>
The following solution works for me
driver.find_element_by_xpath("//span[contains(#class, 'test-button__text') and text()='Test Text']")