Selenium is not getting elements - java

I want to fetch some elements but it is throwing error "". My java code is -
driver = new InternetExplorerDriver();
WebDriverWait wait = new WebDriverWait(driver, 60);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.name("New User")));
driver.findElement(By.name("New User")).click();
And HTML code is like bellow hierarchy.
/html/frameset/frame/html/body/table/tr/td/New User
I am using internet explorer 8 so unable to find xpath there fore i have not tied by xpath method.

There is an iframe which you have to switch to:
driver.switchTo().frame(0); // 0 - means, switch to the first frame
WebDriverWait wait = new WebDriverWait(driver, 60);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.name("New User"))).click();

Related

Wait- Expected conditions not working for auto-suggestion within Yahoo Finance page using Selenium and Java

Below code is not able to identify the list of webelements if they are identified inside a wait condition. I get an exception as timeoutexception and unable to identify the element for the specified xpath.
However if I directly access the elements without wait condition , the values are assigned to the list Variable, why is this so?
WebDriverManager.chromedriver().setup();
WebDriver driver = new ChromeDriver();
driver.get("https://www.finance.yahoo.com");
driver.manage().window().maximize();
driver.findElement(By.xpath("//input[#id='yfin-usr-qry']")).sendKeys("nclh");
WebDriverWait wait = new WebDriverWait(driver,5);
List<WebElement>dd_list= wait.until(ExpectedConditions.visibilityOfAllElementsLocatedBy(By.xpath("//ul[#class='modules_list__1zFHY']/li")));
System.out.println(dd_list.size());
for(WebElement ele : dd_list) {
if (ele.getText().contains("NCLH.VI")) {
System.out.println("i got the element");
}
}
why is this so?
The elements that you are targeting are never all visible simultaneously. Your xpath returns 15 elements, of which only 10 are visible. Implying that your condition will never be met (hence the timeout exception). Simply refine your xpath so as to target the elements you are interested in: the ones that have vocation to be visible, e.g. "//ul[#class='modules_list__1zFHY']/li[#data-type='quotes']"
The Yahoo Finance website contains ReactJS enabled elements. So you need to induce WebDriverWait for document.readyState to be complete and you can use the following Locator Strategies:
Code Block:
driver.get("https://www.finance.yahoo.com");
new WebDriverWait(driver, 120).until(webDriver -> ((JavascriptExecutor) webDriver).executeScript("return document.readyState").equals("complete"));
WebElement element = new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.xpath("//input[#id='yfin-usr-qry']")));
element.click();
element.sendKeys("nclh");
System.out.println(new WebDriverWait(driver, 20).until(ExpectedConditions.visibilityOfAllElementsLocatedBy(By.xpath("//ul[#class='modules_list__1zFHY']//li[#data-type='quotes']"))).size())
Console Output:
6
Browser Snapshot:

Get Text of Success alert message in Ant Design and verify it using Selenium

In one of my Projects, I have to verify the success alert text using Selenium. The UI is coded in react JS following Ant design. For verification please follow this link 'https://ant.design/components/message/' and click on Display Normal message. The message is shown above at the top of the page but I am not able to get the text from that using Selenium Webdriver coding in Core Java. Please help.
I tried this code:
driver.findElement(By.cssSelector(".ant-btn-primary")).click();
WebDriverWait wait = new WebDriverWait(driver, 60);
WebElement successmessage = wait.until(ExpectedConditions.visibilityOfElementLocated(By.className("ant-message-custom-content-ant-message-success")));
successmessage.getText();
To extract the text This is a normal message you need to induce WebDriverWait for the visibilityOfElementLocated() and you can use either of the following Locator Strategies:
cssSelector:
driver.get("https://ant.design/components/message/");
new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.cssSelector("button.ant-btn.ant-btn-primary"))).click();
System.out.println(new WebDriverWait(driver, 20).until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("div.ant-message"))).getText());
xpath:
driver.get("https://ant.design/components/message/");
new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.xpath("//button[#class='ant-btn ant-btn-primary']"))).click();
System.out.println(new WebDriverWait(driver, 20).until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//div[#class='ant-message']"))).getText());
Console Output:
This is a normal message
I'm going to suggest:
driver.findElement(By.cssSelector(".ant-btn-primary")).click();
WebDriverWait wait = new WebDriverWait(driver, 15, 100);
String successMessage = wait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector(".ant-message-info > span"))).getText();
The main problem that you have is that the message doesn't last for very long, so you need to get the data out of it quickly before it is destroyed. As a result I have inlined the getText() call so that it's called as soon as the element is found.
I suspect part of your problem is getting an accurate locator. You can make it easier by opening up the chrome dev console, selecting the parent element where the notice message is created and then right clicking on that element and selecting break on -> subtree modifications. This will allow you to look at the intermediate state of the DOM by pausing JavaScript execution one the message is created. This makes it a lot easier to work out what is going on and find relevant locators.
driver.findElement(By.cssSelector(".ant-btn-primary")).click();
WebElement alertElmt = driver.findElement(By.xpath("//*[#class='ant-message']"));
for(int i=1; i<10; i++) {
Thread.sleep(500);
String getText = alertElmt.getText();
if(!getText.equals("")) {
System.out.println(getText);
break;
}
}
//or with webdriverwait
driver.findElement(By.cssSelector(".ant-btn-primary")).click();
WebElement alert = new WebDriverWait(driver,20).until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//*[#class='ant-message']")));
System.out.println(alert.getText());

Unable to traverse through a frame using web driver java

I am trying to get the elements inside the second frame here
but I am getting the error that the element does not exist or the
Unable to locate element: {"method":"xpath","selector":"//frameset/frame[2]//a"}
I have tried every method out there but it does not work for me, this is my code
WebDriver driver = new ChromeDriver();
driver.get("https://dps.psx.com.pk/");
//switch to the mainFrame
WebElement mainFrame = driver.findElement(By.xpath("//frameset/frame[2]//a"));
driver.switchTo().frame(mainFrame);
List<WebElement> childs = mainFrame.findElements(By.xpath(".//*"));
for(WebElement child : childs) {
System.out.println(child);
}
I have also tried waiting for the elements to load and then tried to access the elements inside the frame but still same errors.
The frame locator is //frameset/frame[2], the //a is a drill down into the frame.
You can also use the name attribute directly to switch. switchTo().frame() can receive id, name or WebElement as parameter
driver.switchTo().frame("mainFrame");
If the frame takes time to load you can use explicit wait and ExpectedCondition frameToBeAvailableAndSwitchToIt
WebDriverWait wait = new WebDriverWait(WebDriverRefrence,20);
wait.until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(By.xpath("//frameset/frame[2]")));
As per the HTML you have shared to traverse to the desired frame you have to:
Induce WebDriverWait for the desired frame to be available and switch to it.
Induce WebDriverWait for the desired element to be clickable and you can use the following solution:
Using name:
new WebDriverWait(driver, 10).until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(By.name("mainFrame")));
new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.name("element_name"))).click();
Using xpath:
new WebDriverWait(driver, 10).until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(By.xpath("//frame[#name='mainFrame' and contains(#src,'index1')]")));
new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.xpath("element_xpath"))).click();

How to resolve ElementNotInteractableException: Element is not visible in Selenium webdriver?

Here I have the image of my code and the image of my error. Can anyone help me to resolve this issue?
ElementNotInteractableException
ElementNotInteractableException is the W3C exception which is thrown to indicate that although an element is present on the HTML DOM, it is not in a state that can be interacted with.
Reasons & Solutions :
The reason for ElementNotInteractableException to occur can be numerous.
Temporary Overlay of other WebElement over the WebElement of our interest :
In this case, the direct solution would have been to induce ExplicitWait i.e. WebDriverWait in combination with ExpectedCondition as invisibilityOfElementLocated as folllows:
WebDriverWait wait2 = new WebDriverWait(driver, 10);
wait2.until(ExpectedConditions.invisibilityOfElementLocated(By.xpath("xpath_of_element_to_be_invisible")));
driver.findElement(By.xpath("xpath_element_to_be_clicked")).click();
A better solution will be to get a bit more granular and instead of using ExpectedCondition as invisibilityOfElementLocated we can use ExpectedCondition as elementToBeClickable as follows:
WebDriverWait wait1 = new WebDriverWait(driver, 10);
WebElement element1 = wait1.until(ExpectedConditions.elementToBeClickable(By.xpath("xpath_of_element_to_be_clicked")));
element1.click();
Permanent Overlay of other WebElement over the WebElement of our interest :
If the overlay is a permanent one in this case we have to cast the WebDriver instance as JavascriptExecutor and perform the click operation as follows:
WebElement ele = driver.findElement(By.xpath("element_xpath"));
JavascriptExecutor executor = (JavascriptExecutor)driver;
executor.executeScript("arguments[0].click();", ele);
I got this because the element I wanted to interact with was covered by another element. In my case it was an opaque overlay to make everything r/o.
When trying to click an element UNDER another element we usualy get "... other Element would receive the click " but not always :.(
This Exception we get when the element is not in an interactable state. So we can use wait till the element is Located or become clickable.
Try using the Implicit wait:
driver.manage().timeouts().implicitlyWait(Time, TimeUnit.SECONDS);
If this is not working use Explicit wait:
WebDriverWait wait=new WebDriverWait(driver, 20);
WebElement input_userName;
input_userName = wait.until(ExpectedConditions.elementToBeClickable(By.tagName("input")));
input_userName.sendkeys("suryap");
You can use ExpectedCondition.visibilityOfElementLocated() as well.
You can increase the time, for example,
WebDriverWait wait=new WebDriverWait(driver, 90);
A solution to this for Javascript looks like this. You will have to modify the time to suit your need.
driver.manage().setTimeouts({ implicit: 30000 });
Hope this is helpful to someone.
see the docs for reference
Actually the Exception is Element Not Visible
The best practice is to use Implicit wait below driver Instantiation so it get sufficient time to find element throughout the exception
driver.get("http://www.testsite.com");
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
Still facing issue as some element require more time. Use ExplicitWait for individual element to satisfy certain condition
In your case you are facing element not visible exception then use wait condition in following way-
WebDriverWait wait = new WebDriverWait(driver, 120);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.your_Elemetnt));
In my case issue was because there is some animation, and that element is not visible for some duration. And hence exception was occurring.
For some reason I couldn't make ExpectedConditions.visibilityOfElementLocated work, so I created a code to wait for some hardcoded seconds before proceeding.
from selenium.webdriver.support.ui import WebDriverWait
def explicit_wait_predicate(abc):
return False
def explicit_wait(browser, timeout):
try:
Error = WebDriverWait(browser, timeout).until(explicit_wait_predicate)
except Exception as e:
None
And now I am calling this explicit_wait function wherever I want to wait for sometime e.g.
from selenium import webdriver
from selenium.webdriver.common.by import By
browser = webdriver.Safari()
browser.get('http://localhost')
explicit_wait(browser,5) # This will wait for 5 secs
elem_un = browser.find_element(By.ID, 'userName')

Not able to select element from drop down list

I am facing a problem that i am not able to select element from drop down list to proceed further.
The URL for reference site is "http://www.rechargeitnow.com/needrecharge.jspx"
I tried the code below but didn't got success.
//WebDriverWait wait = new WebDriverWait(driver, 10);
//WebElement element = wait.until(ExpectedConditions.elementToBeClickable(By.id("someid")));
WebDriverWait wait= new WebDriverWait(driver, 10);
WebElement element = wait.until(ExpectedConditions.elementToBeClickable(By.id("opId_div")));
//driver.findElement(By.cssSelector("select[id='operatorid']")).sendKeys("Airtel");;
//driver.findElement(By.linkText("mobile")).sendKeys("Airtel");
//driver.findElement(By.xpath("//*[#id='oprauto']")).click();
//driver.findElement(By.xpath("/html/body/div[2]/div/div[6]/div/div/div/div/div[2]/div/div/div/div/div[2]/select/option[5]")).findElement(By.name("Airtel"));
//operator.selectByIndex(1);
//driver.findElement(By.xpath("//*[#id='oprauto']")).sendKeys("Airtel");
driver.findElement(By.xpath("/html/body/div[2]/div/div[6]/div/div[3]/ul/li[3]/img")).click();
//Select operator=new Select(driver.findElement(By.id("operatorid")));
//operator.getOptions();
//operator.selectByVisibleText("Airtel");
driver.findElement(By.tagName(" mobile no. ")).sendKeys("9001785845");
driver.findElement(By.id("transSubscriptionNoID")).sendKeys("9001457868");
//driver.findElement(By.cssSelector("img[id='btn']")).submit();
//driver.findElement(By.id("btn")).submit();
driver.findElement(By.xpath("//*[#id='btn']"));
I am not familiar with Java but I was able to easily accomplish this in Ruby with the following code.
$driver.find_element(:xpath, ".//*[#id='input_dropdown']/div[1]/img").click
$driver.find_element(:link, "T24").click
You can replace "T24" with any of the other options available on the dropdown.
Hopefully this answers half of your question at least and someone will be able to translate this into Java.
So the combo drop down is not a select box, its an unordered list, wrapped around an input. You would need to click on the drop down icon and then click the element you want. Here is some dirty code that WORKS :). It selects "Idea" from the drop down.
WebDriver driver = new FirefoxDriver();
WebDriverWait wait = new WebDriverWait(driver, 300);
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
driver.get("http://www.rechargeitnow.com/needrecharge.jspx");
WebElement dropDownArrow = driver.findElement(By
.id("input_dropdown"));
dropDownArrow.click();
WebElement option = wait.until(ExpectedConditions
.elementToBeClickable(By.linkText("Idea")));
option.click();
The following code works. This is not what I wanted to provide you with as a code. But works none the less. You can replace Airtel with any other text present in the drop down.
driver.findElement(By.id("oprauto")).sendKeys("Airtel");
driver.findElement(By.xpath("//ul/li/a/strong[text() = 'Airtel']")).click();

Categories