Cannot find webelement using Selenium if they are dynamic - java

I'm having difficulties in locating a web element in seleniumn the html is as follows:
<div class="d2l-fieldgroup">
<div class=" vui-field-row">
<span class="d2l-field vui-label d2l-offscreen">Do not ask me again for this application</span>
<label class="d2l-checkbox-container">
<input name="dontAsk" value="0" type="hidden">
<input id="dontAsk" class="d2l-checkbox vui-input vui-outline" type="checkbox">
Do not ask me again for this application
</label>
</div>
</div>
I need to click on the checkbox or text but I just cant seem to be able to do this as I always get an error back saying:
Unable to locate element: {"method":"class name","selector"
I tried this:
WebElement do_not_ask_resourcebank = driver.findElement(By.className("d2l-fieldgroup"));
do_not_ask_resourcebank.click();
But get the following error:
no such element: Unable to locate element: {"method":"class name","selector":"d2l-fieldgroup"}
I also tried replacing d2l-fieldgroup with vui-field-row and d2l-checkbox-container
I also tried:
WebElement do_not_ask_resourcebank = driver.findElement(By.cssSelector("html/body/form/div/div[3]/div/label"));
and
WebElement do_not_ask_resourcebank = driver.findElement(By.xpath("id('confirmForm')/x:div/x:div[3]/x:div/x:label"));
but I just cannot seem to click on this element, very frustrating for a newbie like myself. Can someone point me to where I am going wrong?

If you are getting NoSuchElementException as your provided exception, There may be following reasons :-
May be you are locating with incorrect locator, you're locating actually <div> element with class name which looks like dynamically generated class name instead of actual <input type = 'checkbox'> element which you want. And other also looks unstable, You should try to locate desire element using By.id() as :-
WebElement do_not_ask_resourcebank = driver.findElement(By.id("dontAsk"));
May be when you are going to find element, it would not be present on the DOM, So you should implement WebDriverWait to wait until element visible as below :-
WebDriverWait wait = new WebDriverWait(driver, 10);
WebElement el = wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("dontAsk")));
May be this element is inside any frame or iframe. If it is, you need to switch that frame or iframe before finding the element as below :-
WebDriverWait wait = new WebDriverWait(driver, 10);
//Find frame or iframe and switch
wait.until(ExpectedConditions.frameToBeAvailableAndSwitchToIt("your frame id or name"));
//Now find the element
WebElement el = wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("dontAsk")));
//Once all your stuff done with this frame need to switch back to default
driver.switchTo().defaultContent();
Edited :
I havent tried the iframe yet because I am not sure what I am doing I havent used this tool much. The html code for the iframe is : <iframe id="d2l_1_69_954" class="d2l-iframe d2l-iframe-fullscreen d2l_1_67_746" name="d2l_1_69_954" src="/d2l/lms/remoteplugins/lti/launchLti.d2l?ou=6606&plugin‌​Id=f8acc58b-c6d5-42d‌​f-99d9-e334f825c011&‌​d2l_body_type=3" title="TALLPOD" scrolling="auto" allowfullscreen="" onload="this.m_loaded=true;" style="height: 314px;" frameborder="0"> how do you locate this iframe using your example above?
Looks like iframe id and name both are dynamically generated which could be change every time when you locate, you should try to locate this iframe with unique locator, I think it's title name is unique and fixed so you should try to locate this iframe before locating desired element as :-
wait.until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(By.cssSelector("iframe[title='TAFEPOC']"));

Related

Selenium can't find iframe after postback inside the iframe after finding one element inside the frame

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);

Why Am I Getting a NoSuchElementException When Running Tests in Cucumber

I've spent the last few days writing tests in Cucumber. The tests I've written so far work fine, I've been able to click objects, sendkeys over. No problem.
I've now gotten to these page elements that cannot be found no matter what selector I use. I've tried using wait, but even though they are clearly visible on the page, they can't be accessed.
This is happening in both table row elements that I want to click on, and a text input I want to sendkeys to. I've included the latter below.
<input type="text" name="EMPLOYEE_label" value="" class=""
onkeypress="return dtPk(event,this);" onkeydown="return dtKd(event,this);"
onchange="dltCh(this,'EMPLOYEE__test');" size="30" wbvalid="true"
isresolving="false">
Here is the code I am using at present.
webdriver = new ChromeDriver();
WebDriverWait wait = new WebDriverWait(webdriver, 30);
wait.until(ExpectedConditions.visibilityOfElementLocated(By
.name("EMPLOYEE_label")));
JOptionPane.showMessageDialog(null, "WebDriver =" + webdriver);
WebElement empIDTextInput = webdriver.findElement(By.name("EMPLOYEE_label"));
empIDTextInput.sendKeys("Bennett");
Thread.sleep(1000);
gtaProxyPage.clickFindButton().click();
Thread.sleep(1000);
gtaProxyPage.checkAssociateBox().click();
gtaProxyPage.loadTimesheet().click();
Thread.sleep(2000);
EDIT:
I changed the code to this. It more closely resembles what I started with
Thread.sleep(30000);
//this calls for the input element by className.
gtaProxyPage.UserEntersNumberUnderTimesheet().click();
gtaProxyPage.clickFindButton().click();
gtaProxyPage.checkAssociateBox().click();
gtaProxyPage.loadTimesheet().click();
This is the error I'm getting now
org.openqa.selenium.NoSuchElementException: no such element: Unable to locate element: {"method":"class name","selector":"input.triggerButton"}
I switched what I"m doing to click a button that opens a modal, and allows me to use a text field within that. But the button is not being seen.
This error message...
org.openqa.selenium.NoSuchElementException: no such element: Unable to locate element: {"method":"class name","selector":"input.triggerButton"}
...implies that the no such element was found using the Locator Strategy with classname attribute as input.triggerButton.
Irespective of all the changes and manipulation done while publishing the relevant HTML within the question, to send a character sequence to the element:
<input type="text" name="EMPLOYEE_label" value="" class="" onkeypress="return dtPk(event,this);" onkeydown="return dtKd(event,this);" onchange="dltCh(this,'EMPLOYEE__test');" size="30" wbvalid="true" isresolving="false">
As the element is a dynamic element you have to induce WebDriverWait for the element to be clickable and you can use either of the following solutions:
cssSelector:
new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.cssSelector("input[name='EMPLOYEE_label'][onchange*='EMPLOYEE__test']"))).sendKeys("Bennett");
xpath:
new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.xpath("//input[#name='EMPLOYEE_label' and contains(#onchange, 'EMPLOYEE__test')]"))).sendKeys("Bennett");

How to switch to the iframe as per the HTML provided through Selenium and Java?

This way I tried to switch to the frame:
driver.switchTo().frame(driver.findElement(By.xpath(("//iframe[contains(#name,'vfFrameId')]//following::iframe[2]"))));
There are three iframes on the complete html code and I am trying to switch to the third one and I am able to the locate that as well using xpath but after running the script driver is not able to locate that and throwing an exception.
Exception:
no such element: Unable to locate element: {"method":"xpath","selector":"//iframe[contains(#name,'vfFrameId')]//following::iframe[2]"}
HTML:
<div class="windowViewMode-normal oneContent active forcePageHost" data-aura-rendered-by="1330:0" data-aura-class="forcePageHost">
<div class="oneAlohaPage" data-aura-rendered-by="1335:0" data-aura-class="oneAlohaPage">
<force-aloha-page data-data-rendering-service-uid="240" data-aura-rendered-by="1338:0" force-aloha-page_aloha-page="">
<div class="slds-template_iframe slds-card" force-aloha-page_aloha-page="">
<iframe height="100%" width="100%" scrolling="yes" allowtransparency="true" id="vfFrameId_1536141890078" name="vfFrameId_1536141890078" allowfullscreen="true" force-aloha-page_aloha-page="" allow="geolocation *; microphone *; camera *" title="Deploy Data Set"></iframe>
</div>
</force-aloha-page>
</div>
</div>
Here is how you can find the index of each iframe element
List <WebElement> options= driver.findElements(By.tagName("iframe"));
for(WebElement e: options) {
String index=e.getAttribute("index");
System.out.println("Index for: "+e.getAttribute("name")+" is: "+index);// to print out name attribute and index
}
If you are switching from iframe to iframe that don't work all the times. You may need to switch to default content from iframe(1) first and then switch to iframe(2)
driver.switchTo().frame(your locator for 1st iframe here);// to switch to 1st iframe
// your action here
driver.switchTo().defaultContent();
driver.switchTo().frame(your locator for 2nd iframe here); // to switch to 2nd iframe
I am working from your comment:
so you can see the code above where you can see that there are three iframes available on the browser. what happens that i click on one link then to interact with the elements i have to switch to the iframe and here i am able to switch but after clicking on an element ,i am getting navigated to the next page and there is another iframe introduced where i am not able to locate the iframe
You need the following sequence of events:
Switch to your iframe. From this point, your driver instance is pointing at this iframe!
Click on the element that transitions to the next page.
Your driver instance is still pointing at the iframe from step 1! You need to reset it to the top document using: driver.switchTo().defaultContent();.
Only now can you switch to the new iframe on the page you just navigated to.
As per the text based HTML and the HTML snapshot you have shared, it is not evident if there are multiple iframes available. So considering this <iframe> as a unique iframe you need to induce WebDriverWait while switching to the <iframe> as follows:
cssSelector:
new WebDriverWait(driver, 10).until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(By.cssSelector("iframe[id^='vfFrameId_'][name^='vfFrameId_'][title='Deploy Data Set']")));
xpath:
new WebDriverWait(driver, 10).until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(By.xpath("//iframe[starts-with(#id,'vfFrameId_')][starts-with(#name,'vfFrameId_')][#title='Deploy Data Set']")));
Incase there are multiple iframes available with the same attributes which we have used above you can use the following solution:
xpath:
new WebDriverWait(driver, 10).until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(By.xpath("//div[#class='windowViewMode-normal oneContent active forcePageHost' and #data-aura-class='forcePageHost']//following::iframe[1]")));

Selenium, JAVA - how to find such element?

Do you know how to find and click at an element like this:
<div class="offer ctrlOpenOfferInfo">
<a class="linkOffer" href="offer_view.html?id=1007"/>
<p class="photo">
<p class="name">New offer</p>
<p class="price">123</p>
<div class="rate ctrlViewRateOffer" data-value="0.0000">
<p class="date"/>
<div class="hide info">
<div class="bgInfo"/>
using Selenium WebDriver and using the name of the element as there are few very similiar elements on the page?
Here's what I've tired so far:
WebDriverWait wait = new WebDriverWait(driver, 30);
wait.until(ExpectedConditions.invisibilityOfElementLocated(By.xpath("//*[text()='New offer']")));
wait.until(ExpectedConditions.elementToBeClickable(By.xpath(".//*[#id='formDevelopmentElementAdd'][text()='New offer']")));
driver.findElement(By.xpath(".//*[#id='formDevelopmentElementAdd']/div/p[2][text()='New offer']")).click();
or:
driver.findElement(By.xpath("//p[#class='name'][text()='New offer']")).click();
or:
String address = driver.findElement(By.xpath("//*[contains(text(), 'New offer') and #class='name']")).getAttribute("href");
driver.get(baseUrl + address);
or:
driver.findElement(By.xpath("//a[Text()='New offer']")).click();
I've tried these with text, class, xpath...
Assuming you want to click the p tag containing New offer:
I would think this element is not inside an iframe. If so, you must use driver.switchTo().frame("name or xpath or css for frame locator"); first before start looking for element.
Now, how can you find that element. Consider the following options:
Using xpath text based search
//p[.='New offer']
//to be more precise you can do
//p[#classs='name'][.='New offer']
You can use By.className('name') to identify that element even though that name does not look like unique to me
Using cssSelector
.name
using nth-child() function of cssSelector
.offer.ctrlOpenOfferInfo>a>p:nth-child(2)

Selenium Unable to Find Element

I am trying to find an element on a website using Selenium. The page I am looking at is:
http://www.usaswimming.org/DesktopDefault.aspx?TabId=1470&Alias=Rainbow&Lang=en-US
Specifically I am trying to find the element for the "Last Name" input box and send keys in Java. the html looks like this for the text box:
<div class="field">
<input id="ctl62_txtSearchLastName" type="text" maxlength="36" name="ctl00$ctl62$txtSearchLastName">
</div>
Therefore, I initially attempted to get the element through the id which is unique:
WebDriver driver = new InternetExplorerDriver();
driver.get(timeSearchSite);
...
driver.findElement(By.id("ctl62_txtSearchLastName")).sendKeys(lastName);
However this generated the following error:
Exception in thread "main" org.openqa.selenium.NoSuchElementException: Unable to find element with id == ctl62_txtSearchLastName (WARNING: The server did not provide any stacktrace information)
I also tried to use the name which failed similarly. Since this is a javascipt page I thought that I might need to wait before trying to access the element. I tried an explicit and an implicit wait and both resulted in timeouts. My next thought was that I was in the wrong frame but I cannot seem to find another frame. I tried indexing since I don't have names but I couldn't locate any other frames. There is this at the top of the page which might be messing selenium up:
<noscript><iframe src="//www.googletagmanager.com/ns.html?id=GTM-WMWM93" height="0" width="0"
style="display: none; visibility: hidden"></iframe></noscript>
What could be causing this error? How can I locate the element? Any help would be greatly appreciated/
Using an explicit wait worked for me (tried both chrome and firefox):
WebDriverWait wait = new WebDriverWait(driver, 10);
WebElement element = wait.until(
ExpectedConditions.visibilityOfElementLocated(By.id("ctl62_txtSearchLastName"))
);
element.sendKeys("test");
Resulted into:

Categories