"Unable to locate element" exception with WebDriver - java

I'm getting an "Unable to locate element" exception while running the below code. My expected output is First Page of GoogleResults.
public static void main(String[] args) {
WebDriver driver;
driver = new FirefoxDriver();
driver.get("http://www.google.com");
driver.manage().timeouts().implicitlyWait(45, TimeUnit.SECONDS);
WebElement oSearchField = driver.findElement(By.name("q"));
oSearchField.sendKeys("Selenium");
WebElement oButton = driver.findElement(By.name("btnG"));
oButton.click();
//String oNext = "//td[#class='b navend']/a[#id='pnnext']";
WebElement oPrevious;
oPrevious = driver.findElement(By.xpath("//td[#class='b navend']/a[#id='pnprev']"));
if (!oPrevious.isDisplayed()){
System.out.println("First Page of GoogleResults");
}
}
If I run the above code I get "Unable to Locate Element Exception". I know the Previous Button Element is not in the first page of the Google Search Results page, but I want to suppress the exception and get the output of the next step if condition.

Logical mistake -
oPrevious = driver.findElement(By.xpath("//td[#class='b navend']/a[#id='pnprev']"));
will fail or give error if WebDriver can't locate the element.
Try using something like -
public boolean isElementPresent(By by) {
try {
driver.findElement(by);
return true;
} catch (NoSuchElementException e) {
return false;
}
}
You can pass the xpath to the function like
boolean x = isElementPresent(By.xpath("//td[#class='b navend']/a[#id='pnprev']"));
if (!x){
System.out.println("First Page of GoogleResults");
}

Related

Explicit wait not getting applied

I am trying to write following code but I am getting NoSuchElementException. I see that the explicit wait is not getting applied.
WebDriver driver = WebDriverManager.chromedriver().create();
driver.manage().window().maximize();
driver.get("abc");
driver.findElement(By.id("-signin-username")).sendKeys("pratik.p#feg.com");
driver.findElement(By.id("-signin-password")).sendKeys("abcdf");
driver.findElement(By.id("-signin-submit")).click();
// wait(100);
waitForElementToLoad(driver, driver.findElement(By.cssSelector("portal-application[title='AW Acc']")), 100);
Below is the 'Explicit Wait' method.
public static void waitForElementToLoad(WebDriver driver, WebElement element,int seconds) {
WebDriverWait wait = new WebDriverWait(driver, seconds);
wait.until(ExpectedConditions.visibilityOf(element));
}
Using forced wait Thread.sleep() the code works but I don't want any forced wait in the code as it slows down the execution. Can anyone help? I am getting this in the console:
Exception in thread "main" org.openqa.selenium.NoSuchElementException: no such element: Unable to locate element: {"method":"css selector","selector":"portal-application[title='AW Acc']"}
(Session info: chrome=102.0.5005.115)
Try:
...
driver.findElement(By.id("-signin-submit")).click();
WebDriverWait wait = new WebDriverWait(driver, 20);
wait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("portal-application[title='AW Acc']")));
You catch exception because webdriver tries to find element before checking it's visibility. So what it does is:
Find element by css selector portal-application[title='AW Acc']
Wait for element to be visible (it's height and width more than 0)
and it fails on step 1 because element is not in the DOM yet.
If it doesn't work, then try Fluent Waits:
Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
.withTimeout(Duration.ofSeconds(10))
.pollingEvery(Duration.ofSeconds(10))
.ignoring(NoSuchElementException.class);
WebElement element = wait.until(new Function<WebDriver, WebElement>() {
public WebElement apply(WebDriver driver) {
return driver.findElement(By.cssSelector("portal-application[title='AW Acc']"));
}
});
Also, just in case you decide you want it, there is a dirty way that works in any case:
public static WebElement findMyElement(WebDriver driver, By by, int timeoutSeconds) throws Exception {
long timeout = System.currentTimeMillis() + (timeoutSeconds * 1000);
while (true) {
try {
return driver.findElement(by);
} catch (NoSuchElementException nEx) {
Thread.sleep(50);
if (System.currentTimeMillis() > timeout) {
throw new RuntimeException("Still can't find the element..");
}
}
}
}
...
WebElement element = findMyElement(driver, By.cssSelector("portal-application[title='AW Acc']"), 20);

Prompting user input in selenium web driver before launching URL

I am trying to take user input then stored into the variable and i want to use that input into my program .
Here is my code , code is asking for user input but not loading the URL . It is just initiating the driver. Please someone correct me .
Current behavior:
Initiating the driver (IE shows the message " This is the Initial start page for wendriver server"
Asking for prompt .I gave my input in the prompt and click OK.
thats it .. after that code is not getting executed. Please help me
enter image description here
public class app{
public static void main(String[] args) throws Throwable
{
System.setProperty("webdriver.ie.driver", "C:\\Automation\\IEDriverServer.exe");
WebDriver driver = new InternetExplorerDriver();
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("window.promptResponse=prompt('Please enter the USER ID')");
if(isAlertPresent(driver)) {
// switch to alert
Alert alert = driver.switchTo().alert();
// sleep to allow user to input text
Thread.sleep(10000);
// this doesn't seem to work
alert.accept();
String ID = (String) js.executeScript("return window.promptResponse");
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
driver.get("my application URL");
driver.findElement(By.name("USERID")).sendKeys("username");
driver.findElement(By.name("user_pwd")).sendKeys("mypwd");
driver.findElement(By.name("submit")).submit();
.......
......
// some more code which is doing my application fucntionality
.......
......
........
private static boolean isAlertPresent(WebDriver driver) {
try
{
driver.switchTo().alert();
return true;
} // try
catch (NoAlertPresentException Ex)
{
return false;
}
}
}
If you need to take input (ie. URL) from promp then you may use JOptionPane's showInputDialog() method from Java Swing.
Code snippet:
String URL =JOptionPane.showInputDialog(null,"Enter URL");
Try following code; it should serve your purpose:
public class app{
public static void main(String[] args) throws Throwable
{
System.setProperty("webdriver.ie.driver", "C:\\Automation\\IEDriverServer.exe");
WebDriver driver = new InternetExplorerDriver();
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("window.promptResponse=prompt('Please enter the USER ID')");
isAlertPresent(driver);
String ID = (String) js.executeScript("return window.promptResponse");
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
driver.get("my application URL");
driver.findElement(By.name("USERID")).sendKeys("username");
driver.findElement(By.name("user_pwd")).sendKeys("mypwd");
driver.findElement(By.name("submit")).submit();
}
private static void isAlertPresent(WebDriver driver) {
try
{
driver.switchTo().alert();
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); // even though not needed
isAlertPresent(driver);
} // try
catch (NoAlertPresentException Ex)
{
}
}
}

How can I extract the text from a variable with Selenium WebDriver?

If I use "Inspect Element" on FireFox, I see this:
<span class="stock-number-value ng-binding">17109 </span>
When I use driver.getSource(), that 17109 is replaced by "vehicle.attributes.stockNumber".
My main goal is to use the driver to get whatever value is stored by vehicle.attributes.stockNumber, but I can't figure out how to get the contents of that variable using Selenium.
I suspect you are getting the source too early in the process while the angular is not yet ready and the bindings are not yet data-feeded. I'd use a custom wait condition function to wait for the "stock" to have a numeric value:
WebDriverWait wait = new WebDriverWait(webDriver, 510);
WebElement stock = wait.until(waitForStock(By.cssSelector(".stock-number-value")));
System.out.println(stock.getText());
where waitForStock is something along these lines:
public static ExpectedCondition<Boolean> waitForStock(final By locator) {
return new ExpectedCondition<Boolean>() {
#Override
public Boolean apply(WebDriver driver) {
try {
WebElement elm = driver.findElement(locator);
return elm.getText().trim().matches("[0-9]+");
} catch (NoSuchElementException e) {
return false;
} catch (StaleElementReferenceException e) {
return false;
}
}
#Override
public String toString() {
return "stock is not yet loaded";
}
};
}

I am getting nullpointer exception when I perform click() for the same WebElement which I have performed earlier in my Code

I am getting some good handson on my Java ans Selenium. When I use the same "Input_Search_Box" Webelement to perform click method it throws a nullpointer exception. I have googled and tried few work around like adding Thread, adding Explicit wait but still no clue where i miss. Any suggestion would be greatly appreciated.
Here is my Code:
public class Testclass {
WebElement Input_Search_Box;
WebDriver driver;
#Test
public void openBrowser() throws Exception{
System.setProperty("webdriver.chrome.driver","E:\\Ecilpse\\chromedriver_win32\\chromedriver.exe");
driver = new ChromeDriver();
driver.get("https://en.wikipedia.org/wiki/Main_Page");
driver.manage().timeouts().implicitlyWait(20,TimeUnit.SECONDS);
driver.manage().window().maximize();
JavascriptExecutor jse = (JavascriptExecutor)driver;
jse.executeScript("window.scrollBy(0,500)");
WebElement Click_Create_Book = driver.findElement(By.xpath(".//*[#id='coll-create_a_book']/a"));
Click_Create_Book.click();
WebElement Start_Book_Creator_Btn = driver.findElement(By.xpath(".//*[#id='mw-content-text']/form/div/div[1]/button"));
Start_Book_Creator_Btn.click();
Input_Search_Box = driver.findElement(By.xpath(".//*[#id='searchInput']"));
Input_Search_Box.click();
Input_Search_Box.sendKeys("Selenium",Keys.ENTER);
for(int i =0;i<=8;i++){
try{
if(driver.findElement(By.xpath(".//*[#id='siteNotice']/div[2]/div[2]/div")).isDisplayed())
break;
}
catch(Exception e){
jse.executeScript("window.scrollBy(0,2500)");
}
}
for(int j=0;j<=5;j++){
if(driver.findElement(By.id("coll-add_article")).isDisplayed()) {
System.out.println("If Executed");
break;
}else
{
WebElement Book_Remove = driver.findElement(By.xpath(".//*[#id='coll-remove_article']"));
Book_Remove.click();
}
}
WebElement Add_This_Book = driver.findElement(By.xpath(".//*[#id='coll-add_article']"));
Add_This_Book.click();
Thread.sleep(3000);
for(int k =0;k<=6;k++){
jse.executeScript("window.scrollBy(0,-2500)");
Thread.sleep(3000);
}
Thread.sleep(4000);
System.out.println("Sctipr on hold for 4k seconds");
//Here is the Nullpointer error occuring
Input_Search_Box.click();
Input_SearchBox.sendKeys("JSCRIPT",Keys.ENTER);
}
}
If the page has changed/reloaded then you need to use find again.
Sometimes on user actions the page can trigger calls that can change the page that can change the state of the page and the current found objects are lost this can results in a stale element exception or null exception.

In frame, how to find username textbox's xpath with webdriver

I want to sign in to http://www.timesjobs.com/. Upon signing in a pop-up appears (it is the css lightbox). Cannot find the exact xpath for the username on this sign-in box. I iterated over each and every frame and tried to use firefox generated xpath for username textbox. I got exception as:
org.openqa.selenium.NoSuchElementException: Unable to locate element: {"method":"xpath","selector":"//html/body//input[#name='j_username']"}.
Tried below code but no luck:
public static void main(String[] args) throws InterruptedException {
// TODO Auto-generated method stub
WebDriver driver = new FirefoxDriver();
driver.manage().timeouts().implicitlyWait(6, TimeUnit.SECONDS);
driver.get("http://www.timesjobs.com");
driver.findElement(By.linkText("Sign In")).click();
Thread.sleep(10000L);
List<WebElement> frames = driver.findElements(By.tagName("iframe"));
System.out.println("Total Frames: " + frames.size());
int k =0;
while(k<=frames.size()){
try{driver.switchTo().defaultContent();
driver.switchTo().frame(k);
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
WebElement we1 = driver.findElement(By.xpath("//html/body//input[#name='j_username']"));
we1.sendKeys("xyzusername#xyzcompany.com");
System.out.println("in try BLOCK:"+k);
}catch(Exception e){
e.printStackTrace();
System.out.println("in catch: "+k);
}finally{
k++;}
}
System.out.println("end of the program");
}
Try the following code. It works.
Your username Field is contained within GB_Frame which is contained under GB_Frame1. So we have to switch to GB_Frame1 and then to GB_Frame. Username field has a name, so better use it over xpath.
public static void main(String[] args) throws InterruptedException {
WebDriver driver = new FirefoxDriver();
driver.get("http://www.timesjobs.com");
driver.findElement(By.linkText("Sign In")).click();
Thread.sleep(10000);
driver.switchTo().frame("GB_frame1");
driver.switchTo().frame("GB_frame");
WebElement we1 = driver.findElement(By.name("j_username"));
we1.sendKeys("xyzusername#xyzcompany.com");
}
I dont understand what difficulty you had in identifying the frames. It was pretty clear from the page source. Let me know if this helps you.

Categories

Resources