Selenium Stale Element Reference Exception - java

Everytime got StaleElementReferenceException exception.
Here is a method, pls help.
private void selectAndClickRow(String elementName, boolean doubleClick) {
try {
String elementXpath = "//tr//td//div[contains(text(),'" + elementName + "')]";
new WebDriverWait(Init.getWebDriver(), Init.getTimeOutInSeconds()).until(ExpectedConditions.visibilityOf(Init.getDriverExtensions().waitUntilElementAppearsInDom(By.xpath(elementXpath))));
WebElement row = table.findElements(By.xpath(elementXpath)).get(0);
row.click();
if (doubleClick) {
row.click();
}
Init.getDriverExtensions().waitUntilElementAppearsInDom(By.xpath("//tr//td[contains(#class,'selected')]//div[contains(text(),'" + elementName + "')]"));
} catch (StaleElementReferenceException e) {
freeze(1);
selectAndClickRow(elementName, doubleClick);
}
waitToLoad();
}
public WebElement waitUntilElementAppearsInDom(By by) {
Wait wait = new WebDriverWait(Init.getWebDriver(), (long)Init.getTimeOutInSeconds());
wait.until(ExpectedConditions.presenceOfElementLocated(by));
return Init.getWebDriver().findElement(by);
}
I already added an element research and waiting for a second. It doesn't help.

I guess, you are trying to double click on a element. You can use actions class as given below instead of clicking twice on a element.
private void selectAndClickRow(String elementName, boolean doubleClick) {
try {
String elementXpath = "//tr//td//div[contains(text(),'" + elementName + "')]";
new WebDriverWait(Init.getWebDriver(), Init.getTimeOutInSeconds()).until(ExpectedConditions.visibilityOf(Init.getDriverExtensions().waitUntilElementAppearsInDom(By.xpath(elementXpath))));
WebElement row = table.findElements(By.xpath(elementXpath)).get(0);
new Actions(driver).doubleClick(row).perform();
} catch (StaleElementReferenceException e) {
//freeze(1);
//selectAndClickRow(elementName, doubleClick);
}
waitToLoad();
}

Related

Selenium click until the attirbute show

How can I create click method which can be click in the button until the attribute shows? Something like loop until but with timer (if it's not found attribute after 10 seconds, display an error). I have created something like that, but code give me NullPointerException when not found attribute:
wait.until(new ExpectedCondition<Boolean>() {
public Boolean apply(WebDriver driver) {
WebElement button = driver.findElement(By.xpath("xpath"));
String attribute = button.getAttribute("disabled");
button.click();
if(attribute .equals("true"))
return true;
else
return false;
}
});
I got similar problem and my solution was to write a function that tries to click on the object and when it is not present it waits a second and tries once again. After 10 times of trying it returns null.
It works beautifully for me. Goes like this:
WebElement tryfind(WebDriver browser, By id)
{
WebElement ttwel=null;
for (int i=0;i<10;i++)
{
try
{
ttwel=browser.findElement(id);
break;
}
catch (NoSuchElementException ex)
{
sleep(1000);
}
}
return ttwel;
}
void sleep(int mills)
{
try
{
Thread.sleep(mills);
}
catch (InterruptedException ex)
{
}
}
You might add waiting for disabled attribute to this method, something like:
for (int i=0;i<10;i++)
{
try
{
ttwel=browser.findElement(id);
String attribute = button.getAttribute("disabled");
if (attribute==null) sleep(1000);
else break;
}
catch (NoSuchElementException ex)
{
sleep(1000);
}
}
Why don't you add a try catch block like this below to catch the NullPointerException and return false in that case
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(30));
wait.until(new ExpectedCondition<Boolean>() {
public Boolean apply(WebDriver driver) {
WebElement button = driver.findElement(By.xpath("xpath"));
try {
String attribute = button.getAttribute("disabled");
button.click();
if (attribute.equals("true")) {
return true;
}
} catch (NullPointerException e) {
return false;
}
return false;
}
});

Cucumber with Java Selenium framework

I am working as a manual tester now recently I shifted to Selenium, in my company now they are telling me to create Cucumber Java Selenium framework for a project from scratch. My requirement is I need to create a class which it consists of all the methods of selenium like, sendKeys, Click, dragAndDrop, mouseHover like that all selenium related actions I need to put in one class...I'm facing very difficulty.
Does anyone have such type of class which has all Selenium actions?
You can use webdriver methods like the following. For the full list please check https://seleniumhq.github.io/selenium/docs/api/rb/method_list.html
get()
getCurrentUrl()
findElement(By, by) and click()
isEnabled()
findElement(By, by) with sendKeys()
findElement(By, by) with getText()
Submit()
findElements(By, by)
You don't need a class with all of those actions; Selenium provides them out of the box. This can be achieved simply by instantiating a new instance of the driver:
WebDriver driver = new ChromeDriver();
And then calling the functions you require:
driver.getElement(By.id("element")).click();
Creating a new class to wrap an existing function is terrible terrible practice. If you're looking for a good design pattern for Selenium tests, look up the 'Page Object Model'.
I hope this methods will be helpful to you
public static void wait(int secs) {
try {
Thread.sleep(1000 * secs);
} catch (InterruptedException e) {
}
}
/**
* Generates the String path to the screenshot taken.
* Within the method, the screenshot is taken and is saved into FileUtils.
* The String return will have a unique name destination of the screenshot itself.
*
* #param name Test name passed in as a String
* #return unique String representation of the file's location / path to file
*/
public static String getScreenshot(String name) {
// name the screenshot with the current date time to avoid duplicate name
//for windows users or if you cannot get a screenshot
String date = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy_MMdd_hh_mm_ss_a"));
// TakesScreenshot ---> interface from selenium which takes screenshots
TakesScreenshot ts = (TakesScreenshot) Driver.getDriver();
File source = ts.getScreenshotAs(OutputType.FILE);
// full path to the screenshot location
String target = System.getProperty("user.dir") + "/test-output/Screenshots/" + name + date + ".png";
//if screenshot doesn't work
//try to provide hardcoded path
// String target = "/Users/studio2/IdeaProjects/Spring2019FinalTestNGFramework/screenshots/" + name + date + ".png";
File finalDestination = new File(target);
// save the screenshot to the path given
try {
FileUtils.copyFile(source, finalDestination);
} catch (IOException e) {
e.printStackTrace();
}
return target;
}
/*
* switches to new window by the exact title
* returns to original window if windows with given title not found
*/
public static void switchToWindow(String targetTitle) {
String origin = Driver.getDriver().getWindowHandle();
for (String handle : Driver.getDriver().getWindowHandles()) {
Driver.getDriver().switchTo().window(handle);
if (Driver.getDriver().getTitle().equals(targetTitle)) {
return;
}
}
Driver.getDriver().switchTo().window(origin);
}
public static void hover(WebElement element) {
Actions actions = new Actions(Driver.getDriver());
actions.moveToElement(element).perform();
}
/**
* return a list of string from a list of elements
* text
*
* #param list of webelements
* #return
*/
public static List<String> getElementsText(List<WebElement> list) {
List<String> elemTexts = new ArrayList<>();
for (WebElement el : list) {
if (!el.getText().isEmpty()) {
elemTexts.add(el.getText());
}
}
return elemTexts;
}
/**
* Extracts text from list of elements matching the provided locator into new List<String>
*
* #param locator
* #return list of strings
*/
public static List<String> getElementsText(By locator) {
List<WebElement> elems = Driver.getDriver().findElements(locator);
List<String> elemTexts = new ArrayList<>();
for (WebElement el : elems) {
if (!el.getText().isEmpty()) {
elemTexts.add(el.getText());
}
}
return elemTexts;
}
public static WebElement waitForVisibility(WebElement element, int timeToWaitInSec) {
WebDriverWait wait = new WebDriverWait(Driver.getDriver(), timeToWaitInSec);
return wait.until(ExpectedConditions.visibilityOf(element));
}
public static WebElement waitForVisibility(By locator, int timeout) {
WebDriverWait wait = new WebDriverWait(Driver.getDriver(), timeout);
return wait.until(ExpectedConditions.visibilityOfElementLocated(locator));
}
public static WebElement waitForClickability(WebElement element, int timeout) {
WebDriverWait wait = new WebDriverWait(Driver.getDriver(), timeout);
return wait.until(ExpectedConditions.elementToBeClickable(element));
}
public static WebElement waitForClickability(By locator, int timeout) {
WebDriverWait wait = new WebDriverWait(Driver.getDriver(), timeout);
return wait.until(ExpectedConditions.elementToBeClickable(locator));
}
public static Boolean waitForURL(String actualURL, int timeout) {
WebDriverWait wait = new WebDriverWait(Driver.getDriver(), 5);
return wait.until(ExpectedConditions.urlToBe(actualURL));
}
public static void waitForPageToLoad(long timeOutInSeconds) {
ExpectedCondition<Boolean> expectation = new ExpectedCondition<Boolean>() {
public Boolean apply(WebDriver driver) {
return ((JavascriptExecutor) driver).executeScript("return document.readyState").equals("complete");
}
};
try {
Logger logger = Logger.getLogger(UtilsBrowser.class);
logger.info("Waiting for page to load...");
WebDriverWait wait = new WebDriverWait(Driver.getDriver(), timeOutInSeconds);
wait.until(expectation);
} catch (Throwable error) {
System.out.println(
"Timeout waiting for Page Load Request to complete after " + timeOutInSeconds + " seconds");
}
}
public static WebElement fluentWait(final WebElement webElement, int timeinsec) {
FluentWait<WebDriver> wait = new FluentWait<WebDriver>(Driver.getDriver())
.withTimeout(Duration.ofSeconds(timeinsec))
.pollingEvery(Duration.ofMillis(500))
.ignoring(NoSuchElementException.class);
WebElement element = wait.until(new Function<WebDriver, WebElement>() {
public WebElement apply(WebDriver driver) {
return webElement;
}
});
return element;
}
/**
* Verifies whether the element matching the provided locator is displayed on page
*
* #param by
* #throws AssertionError if the element matching the provided locator is not found or not displayed
*/
public static void verifyElementDisplayed(By by) {
try {
assertTrue("Element not visible: " + by, Driver.getDriver().findElement(by).isDisplayed());
} catch (NoSuchElementException e) {
e.printStackTrace();
Assert.fail("Element not found: " + by);
}
}
/**
* Verifies whether the element matching the provided locator is NOT displayed on page
*
* #param by
* #throws AssertionError the element matching the provided locator is displayed
*/
public static void verifyElementNotDisplayed(By by) {
try {
Assert.assertFalse("Element should not be visible: " + by, Driver.getDriver().findElement(by).isDisplayed());
} catch (NoSuchElementException e) {
e.printStackTrace();
}
}
/**
* Verifies whether the element is displayed on page
*
* #param element
* #throws AssertionError if the element is not found or not displayed
*/
public static void verifyElementDisplayed(WebElement element) {
try {
assertTrue("Element not visible: " + element, element.isDisplayed());
} catch (NoSuchElementException e) {
e.printStackTrace();
Assert.fail("Element not found: " + element);
}
}
/**
* Waits for element to be not stale
*
* #param element
*/
public void waitForStaleElement(WebElement element) {
int y = 0;
while (y <= 15) {
if (y == 1)
try {
element.isDisplayed();
break;
} catch (StaleElementReferenceException st) {
y++;
try {
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
} catch (WebDriverException we) {
y++;
try {
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
/**
* Selects a random value from a dropdown list and returns the selected Web Element
*
* #param select
* #return
*/
public static WebElement selectRandomTextFromDropdown(Select select) {
Random random = new Random();
List<WebElement> weblist = select.getOptions();
int optionIndex = 1 + random.nextInt(weblist.size() - 1);
select.selectByIndex(optionIndex);
return select.getFirstSelectedOption();
}
/**
* Clicks on an element using JavaScript
*
* #param element
*/
public void clickWithJS(WebElement element) {
((JavascriptExecutor) Driver.getDriver()).executeScript("arguments[0].scrollIntoView(true);", element);
((JavascriptExecutor) Driver.getDriver()).executeScript("arguments[0].click();", element);
}
/**
* Scrolls down to an element using JavaScript
*
* #param element
*/
public void scrollToElement(WebElement element) {
((JavascriptExecutor) Driver.getDriver()).executeScript("arguments[0].scrollIntoView(true);", element);
}
/**
* Performs double click action on an element
*
* #param element
*/
public void doubleClick(WebElement element) {
new Actions(Driver.getDriver()).doubleClick(element).build().perform();
}
/**
* Changes the HTML attribute of a Web Element to the given value using JavaScript
*
* #param element
* #param attributeName
* #param attributeValue
*/
public void setAttribute(WebElement element, String attributeName, String attributeValue) {
((JavascriptExecutor) Driver.getDriver()).executeScript("arguments[0].setAttribute(arguments[1], arguments[2]);", element, attributeName, attributeValue);
}
public String[] fromListToString(List<WebElement> x) {
String[] trans = new String[x.size()];
for (WebElement xx : x) {
int count = 0;
trans[count] = xx.getText();
count++;
}
Arrays.sort(trans);
return trans;
}
/**
* Highlighs an element by changing its background and border color
*
* #param element
*/
public static void highlight(WebElement element) {
((JavascriptExecutor) Driver.getDriver()).executeScript("arguments[0].setAttribute('style', 'background: yellow; border: 2px solid red;');", element);
wait(1);
((JavascriptExecutor) Driver.getDriver()).executeScript("arguments[0].removeAttribute('style', 'background: yellow; border: 2px solid red;');", element);
}
/**
* Checks or unchecks given checkbox
*
* #param element
* #param check
*/
public static void selectCheckBox(WebElement element, boolean check) {
if (check) {
if (!element.isSelected()) {
element.click();
}
} else {
if (element.isSelected()) {
element.click();
}
}
}
public static void grabHold(WebDriver driver) {
/* /NOTE: Be sure to set -> String parentHandle=driver.getWindowHandle(); prior to the action preceding method deployment */
String parentHandle = driver.getWindowHandle();
Set<String> windows = driver.getWindowHandles();
for (String window : windows) {
if (window != parentHandle)
driver.switchTo().window(window);
}
}
public static void waitUntilTitleEquals(int timeout, String x) {
WebDriverWait wait = new WebDriverWait(Driver.getDriver(), timeout);
wait.until(ExpectedConditions.titleContains(x));
}
public static int getRandomNumInRange(int low, int high) {
Random random = new Random();
return random.nextInt(high - low) + low;
}
public void waitForPresenceOfElementByCss(String css) {
WebDriverWait wait = new WebDriverWait(Driver.getDriver(),
Long.parseLong(ConfigurationReader.getProperties("timeout")));
wait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector(css)));
}
public void hitEnterUsingRobot() {
Robot rb;
try {
rb = new Robot();
rb.keyPress(KeyEvent.VK_ENTER);
rb.keyRelease(KeyEvent.VK_ENTER);
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
public boolean verifyAlertPresent() {
try {
Driver.getDriver().switchTo().alert();
return true;
} catch (NoAlertPresentException Ex) {
// System.out.println("Alert is not presenet");
}
return false;
}
public boolean isElementVisible(By arg0) {
boolean elementVisible = false;
try {
(new WebDriverWait(Driver.getDriver(), 60)).until(ExpectedConditions.visibilityOfElementLocated(arg0));
elementVisible = true;
} catch (TimeoutException ex) {
elementVisible = false;
}
return elementVisible;
}
public static boolean isElementNotVisible(By arg0) {
boolean elementVisible = false;
try {
//these two waitinf for webelement to be gone
// (new WebDriverWait(Driver.getDriver(), 60)).until(ExpectedConditions.invisibilityOfElementLocated(arg0));
(new WebDriverWait(Driver.getDriver(), 60)).until(ExpectedConditions.not(ExpectedConditions.presenceOfAllElementsLocatedBy(arg0)));
elementVisible = true;
} catch (NullPointerException ex) {
elementVisible = false;
}
return elementVisible;
}

how can i compare value from the list of webElement and click on the required value from the list

I am using below code:
public static void main(String[] args)
{System.setProperty("webdriver.gecko.driver","C:\\geckodriver-v0.17.0-win64\\geckodriver.exe");
WebDriver driver = new FirefoxDriver();
driver.get("https://www.makemytrip.com/flights");
driver.manage().timeouts().implicitlyWait(10,TimeUnit.MILLISECONDS);
driver.manage().window().maximize();
driver.findElement(By.id("hp-widget__sfrom")).click();
driver.findElement(By.id("hp-widget__sfrom")).clear();
List<WebElement> Cities = driver.findElements(By.xpath("//div[#class='autoCompleteItem']"));
for (WebElement size1 : Cities )
{
String str = size1.getText();
System.out.println(str);
if(size1.getText().equals("LON"))
{
size1.click();
break;
}
else
{
System.out.println("match not found");
}
}
}
}
Use below code :
driver.get("https://www.makemytrip.com/flights");
driver.findElement(By.id("hp-widget__sfrom")).click();
driver.findElement(By.id("hp-widget__sfrom")).clear();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
driver.findElement(By.id("hp-widget__sfrom")).sendKeys("LON");
List<WebElement> Cities = driver.findElements(By.xpath("//div[#class='autoCompleteItem']//span[contains(.,'London, UK - All Airports')]"));
for (WebElement size1 : Cities )
{
String str = size1.getText();
if(size1.getText().equalsIgnoreCase("London, UK - All Airports"))
{
System.out.println(size1.getText());
size1.click();
break;
}
else
{
System.out.println("match not found");
}
}
}
}
If your value in below in dropdown then need to focus that element first.
if you only wants to check for text then you could simple form an xpath and avoid this loop.
try{
WebElement city =driver.findElement(By.xpath("//div[#class='autoCompleteItem' and text()='LON']");
city.click();
}catch (NoSuchElementException ex){
System.out.print("Element not Found");
}

How to click on mail using selenium webdriver?

I want to open the mail by clicking on it, after receiving the activation mail.
For that I am using keyword driven framework.
So can anyone please let me know that how can we click on element without using List<>.
Because in my coding structure I am returning the object of Webelement instead of List<> object.
Note: Please suggest the solution without using JavaMail Api or if suggest please let me know according to the keyword driven framework.
Way of code structure where I find the elements in one method and in another method after getting an element perform the operations:
private boolean operateWebDriver(String operation, String Locator,
String value, String objectName) throws Exception {
boolean testCaseStep = false;
try {
System.out.println("Operation execution in progress");
WebElement temp = getElement(Locator, objectName);
System.out.println("Get Element ::"+temp);
driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
//For performing click event on any of the button, radio button, drop-down etc.
if (operation.equalsIgnoreCase("Click")) {
temp.click();
}
/*Trying to click on subject line of "Email"*/
if (operation.equalsIgnoreCase("Click_anElement")) {
Thread.sleep(6000L);
Select select = new Select(temp);
List<WebElement> options= select.getOptions();
for(WebElement option:options){
System.out.println(option.getText());
}
/*try
{
if(temp.getText().equals(value)){
temp.click();
}
}
catch(Exception e){
System.out.println(e.getCause());
}*/
/*if (value != null) {
temp.click();
}*/
}
}
testCaseStep = true;
} catch (Exception e) {
System.out.println("Exception occurred operateWebDriver"
+ e.getMessage());
System.out.println("Taking Screen Shot");
TakesScreenshot ts=(TakesScreenshot)driver;
File source=ts.getScreenshotAs(OutputType.FILE);
FileUtils.copyFile(source, new File("./Screenshots/"+screenshotName+".png"));
System.out.println("Screenshot taken");
}
return testCaseStep;
}
public WebElement getElement(String locator, String objectName) throws Exception {
WebElement temp = null;
System.out.println("Locator-->" + locator);
if (locator.equalsIgnoreCase("id")) {
temp = driver.findElement(By.id(objectName));
} else if (locator.equalsIgnoreCase("xpath")) {
temp = driver.findElement(By.xpath(objectName));
System.out.println("xpath temp ----->" + temp);
} else if (locator.equalsIgnoreCase("name")) {
temp = driver.findElement(By.name(objectName));
}else if (locator.equalsIgnoreCase("cssSelector")) {
temp = driver.findElement(By.cssSelector(objectName));
}
return temp;
}

JavaScript button can only be clicked once with selenium Webdriver

I am trying to use Selenium with JUnit and I am having trouble completing my tests because it seems like my button execution is only occurring once. here's some of the code:
JQueryUITab navTab = new JQueryUITab(driver.findElement(By.cssSelector("nav ul.tabs")));
try {
navTab.selectTab("Tab1");
} catch (Exception e) {
e.printStackTrace();
}
try {
navTab.selectTab("Tab2");
} catch (Exception e) {
e.printStackTrace();
}
System.out.print(navTab.getSelectedTab());
the console print out will read "Tab1". this JQueryUITab object is a custom object. here are the inner workings:
public String getSelectedTab() {
List<WebElement> tabs = jQueryUITab.findElements(By.cssSelector("li.tab"));
for (WebElement tab : tabs) {
if (tab.getAttribute("class").equals("tab selected")) {
return tab.getText();
}
}
return null;
}
public void selectTab(String tabName) throws Exception {
boolean found = false;
List<WebElement> tabs = jQueryUITab.findElements(By.cssSelector("li.tab"));
for (WebElement tab : tabs) {
if(tabName.equals(tab.getText().toString())) {
tab.click();
found = true;
break;
}
}
if (!found) {
throw new Exception("Could not find tab '" + tabName + "'");
}
}
There are no exceptions thrown. At least pertaining before or at this part of the code.
There were a couple problems wrong with my implementation. Firstly, it could have been improved by selecting not the li.tab object, but the a class inside of it. From there, there were 2 solutions that worked for me. First was using
webElement.sendKeys(Keys.ENTER);
and the second (imho more elegant solution) was to get the instance of the selenium driver object controlling the object and then get it to execute the command to click the tab. Here's the full corrected method.
public void selectTab(String tabName) throws Exception {
boolean found = false;
List<WebElement> tabs = jQueryUITab.findElements(By.cssSelector("li.tab a"));
for (WebElement tab : tabs) {
if(tabName.equals(tab.getText().toString())) {
// tab.sendKeys(Keys.ENTER);
WrapsDriver wrappedElement = (WrapsDriver) jQueryUITab;
JavascriptExecutor driver = (JavascriptExecutor) wrappedElement.getWrappedDriver();
driver.executeScript("$(arguments[0]).click();", tab);
found = true;
break;
}
}
if (!found) {
throw new Exception("Could not find tab '" + tabName + "'");
}
}

Categories