I get this error when running my tests:
org.openqa.selenium.StaleElementReferenceException: Element is no longer attached to the DOM
any idea on how to solve the above exception?
this happen in my grid
which has a ref Xpath expression which is dynamic
I ran across this same problem and could not find any solutions. Came up with a solution and posting it here, hope this helps someone with the same problem. I created a class to handle stale elements depending on their type, cssselector, id, etc and simply call it like I would any other page object.
public void StaleElementHandleByID (String elementID)
{
int count = 0;
boolean clicked = false;
while (count < 4 && !clicked)
{
try
{
WebElement yourSlipperyElement= driver.findElement(By.id(elementID));
yourSlipperyElement.click();
clicked = true;
}
catch (StaleElementReferenceException e)
{
e.toString();
System.out.println("Trying to recover from a stale element :" + e.getMessage());
count = count+1;
}
}
}
I'd recommend only using this on elements you know cause problems for WebDriver.
We get around this issue by doing something called WebdriverWrapper and WebElementWrapper.
What these wrappers do is handle the StaleElementException within and then use the locator to re-evaluate and get the new WebElement object. This way, you need to spread the code handling the exception all over your codebase and localize it to one class.
I will look into open sourcing just these couple of classes soon and add a link here if you folk are interested.
That exception is thrown when you try to use a method of a WebElement that is not longer on the page. If your grid is dynamically loading data and you refresh the grid, any references to elements on that grid would be 'stale'. Double check that the element you're trying to reference is on the page in your tests, and you may need to re-instantiate the object.
It also encountered this issue, It looks very obvious the modal panel loading falls into a race condition and keeps waiting till time out.
I have tried many times, and found the solution is to hold the modal panel loading till it can be exactly found by webDriver and at the same time keep refresh the webDriver instance , then try to find WebElements within the modal panel.
So the solution is like follows:
e.g. MyModalPanel is your ModalPanel Id, then do the following
page.openModalPanel();
Assert.assertTrue(page.waitTillDisplay( "MyModalPanelContentDiv"), Wait.MODAL_PANEL));
page.fillInFormInModalpanel(formObj);
and the waitTillDisplay code can be found on WebDriver website, I will just paste my code here for your reference:
public Boolean waitTillDisplay(final String id, int waitSeconds){
WebDriverWait wait = new WebDriverWait(driver, waitSeconds);
Boolean displayed = wait.until(new ExpectedCondition<Boolean>() {
public Boolean apply(WebDriver driver) {
return driver.findElement(By.id(id)).isDisplayed();
}
});
return displayed;
}
You might be trying to get any of element properties after clicking an element.
I had the same issue, I was trying to getText() of button after it was clicked. In my case, once button is clicked, new window comes.
I used a FluentWait and also the ExpectedCondition apply override: https://gist.github.com/djangofan/5112655 . This one handles the exception inside the finalized block, unlike how other people answer this, and allows the successive tries to be wrapped in that block. I think this is more elegant.
public static void clickByLocator( final By locator ) {
final long startTime = System.currentTimeMillis();
driver.manage().timeouts().implicitlyWait( 5, TimeUnit.SECONDS );
Wait<WebDriver> wait = new FluentWait<WebDriver>( driver )
.withTimeout(90000, TimeUnit.MILLISECONDS)
.pollingEvery(5500, TimeUnit.MILLISECONDS);
//.ignoring( StaleElementReferenceException.class );
wait.until( new ExpectedCondition<Boolean>() {
#Override
public Boolean apply( WebDriver webDriver ) {
try {
webDriver.findElement( locator ).click();
return true;
} catch ( StaleElementReferenceException e ) { // try again
return false;
}
}
} );
driver.manage().timeouts().implicitlyWait( DEFAULT_IMPLICIT_WAIT, TimeUnit.SECONDS );
long endTime = System.currentTimeMillis();
long totalTime = endTime - startTime;
log("Finished click after waiting for " + totalTime + " milliseconds.");
}
public static Boolean executeElementSendKeys
(WebDriver driver, WebElement element, String sInputParameters) throws Exception {
return (Boolean) executeElementMaster
(driver, element, "sendKeys", sInputParameters, 30, true);
}
public static Boolean executeElementClear
(WebDriver driver, WebElement element) throws Exception {
return (Boolean) executeElementMaster (driver, element, "clear", "", 30, true);
}
public static String executeElementGetText
(WebDriver driver, WebElement element) throws Exception {
return (String) executeElementMaster (driver, element, "getText", "", 30, true);
}
public static Boolean executeElementClick
(WebDriver driver, WebElement element) throws Exception {
return (Boolean) executeElementMaster (driver, element, "click", "", 30, true);
}
public static boolean executeElementIsDisplayed
(WebDriver driver, WebElement element) throws Exception {
return (Boolean) executeElementMaster (driver, element, "isDisplayed", "", 30, true);
}
public static String executeElementGetAttribute
(WebDriver driver, WebElement element, String sInputParameters) throws Exception {
return (String) executeElementMaster
(driver, element, "getAttribute", sInputParameters, 30, true);
}
// And below is the master method that handles the StaleElementReferenceException and other exceptions.
// In the catch section, replace (Exception e) with (StaleElementReferenceException e) if you want this method to retry actions (like click, sendkeys etc.) for only StaleElementReferenceException and not other exceptions.
private static Object executeElementMaster(WebDriver driver, WebElement element, String sExecuteAction, String sInputParametersOptional, int MaxTimeToWait,
boolean bExpectedElementState) throws Exception {
try {
// Local variable declaration
String sElementString = "";
String sElementXpath = "";
Object ReturnValue = "";
int Index = 0;
boolean bCurrentElementState = true;
boolean bWebDriverWaitUntilElementClickableFlag = false;
System.out.println("**** Execute method '" + sExecuteAction + "' on '" + sElementString + "' - Expected : '" + bExpectedElementState + "'");
System.out.println("**** MaxTimeToWait ='" + MaxTimeToWait + "' seconds");
// Set browser timeout to 1 second. Will be reset to default later
driver.manage().timeouts().implicitlyWait(1, TimeUnit.SECONDS);
// Keep trying until 'MaxTimeToWait' is reached
for (int i = 0; i < MaxTimeToWait; i++) {
try {
// Get element xPath - and find element again
if (element != null && i < 2 && sElementString == "") {
sElementString = (element).toString();
if (sElementString.contains("xpath: ")) {
// Retrieve xPath from element, if available
Index = sElementString.indexOf("xpath: ");
sElementXpath = sElementString.substring(Index + 7, sElementString.length());
}
}
// Find Element again
if (sElementXpath != "" && i > 0) {
element = driver.findElement(By.xpath(sElementXpath));
}
// Execute the action requested
switch (sExecuteAction) {
case ("isDisplayed"):
// Check if element is displayed and save in bCurrentElementState variable
ReturnValue = element.isDisplayed();
bCurrentElementState = (Boolean) ReturnValue;
bWebDriverWaitUntilElementClickableFlag = true;
break;
case ("getText"):
ReturnValue = element.getText();
bCurrentElementState = true;
bWebDriverWaitUntilElementClickableFlag = false;
break;
case ("sendKeys"):
// Scroll element into view before performing any action
element.sendKeys(sInputParametersOptional);
ReturnValue = true;
bCurrentElementState = true;
bWebDriverWaitUntilElementClickableFlag = false;
break;
case ("clear"):
// Scroll element into view before performing any action
element.clear();
ReturnValue = true;
bCurrentElementState = true;
bWebDriverWaitUntilElementClickableFlag = false;
break;
case ("click"):
// Scroll element into view before performing any action
element.click();
ReturnValue = true;
bCurrentElementState = true;
bWebDriverWaitUntilElementClickableFlag = false;
break;
default:
ReturnValue = element.getAttribute(sInputParametersOptional);
bCurrentElementState = true;
break;
}
} catch (Exception e) {
Thread.sleep(500);
bCurrentElementState = false;
ReturnValue = false;
}
if (bCurrentElementState == bExpectedElementState) {
// If element's actual and expected states match, log result and return value
System.out.println("**** PASSED: Execute method '" + sExecuteAction + "' on '" + sElementString + "' - Returned '" + ReturnValue + "' **** \n"
+ "Actual element status: '" + bCurrentElementState + "' Expected element status: '" + bExpectedElementState + "'");
break;
} else {
// If element's actual and expected states do NOT match, loop until they match or timeout is reached
Thread.sleep(500);
}
}
// Reset browser timeout to default
driver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
// Return value before exiting
if (bCurrentElementState != bExpectedElementState) {
// If element's actual and expected states do NOT match, log result and return value
System.out.println("**** FAILED: Execute method '" + sExecuteAction + "' on '" + sElementString + "' - Returned '" + ReturnValue + "' **** \n"
+ "Actual element status: '" + bCurrentElementState + "' Expected element status: '" + bExpectedElementState + "'");
if (sExecuteAction.equalsIgnoreCase("findElement")) {
ReturnValue = null;
}
}
return ReturnValue;
} catch (Exception e) {
System.out.println("Exception in executeElementMaster - " + e.getMessage());
throw (e);
}
}
I made some changes to be more flexible:
delegate void StaleFunction(IWebElement elt);
private static void StaleElementHandleByID(By by, StaleFunction func )
{
int count = 0;
while (count < 4)
{
try
{
IWebElement yourSlipperyElement = Driver.FindElement(by);
func(yourSlipperyElement);
count = count + 4;
}
catch (StaleElementReferenceException e)
{
count = count + 1;
}
}
}
StaleElementHandleByID(By.Id("identDdl"),
delegate(IWebElement elt)
{
SelectElement select = new SelectElement(elt);
select.SelectByText(tosave.ItemEquipamentoCem.CodigoCne.ToString());
});
a quick & dirty solution:
el.click()
time.sleep(1)
then continue to parse in iteration way
In this case, the tests are looking for an element that is not yet loaded, or has been refreshed. As a result, the StaleElementException. A simple solution would be to add a fluentWait.
#netz75 : Thank you. Had this problem when a click redirects to second page.
This worked for me:
//.. (first page asserts)
//...
element.Click();
Thread.Sleep(200);
//.. (second page asserts)
//...
Related
Problem: Using Selenium Java I want to automate a table that contains a price list and a price calculator
Another little problem: I can't click on the "Analysis" (Filter) button, because I have to double-click, which I could do in this case
What I want: I'm trying to find a method so that when I run the program, the program will click on another analysis (on another + button) Now with the help of a selector, I can only click on the first (+). But I want each time, the program to test, randomly other analyzes (other buttons +).
What I do
#FindBy(xpath = "//*[#id='footable_501']/thead/tr[2]/th[1]")
WebElement analizaSort;
#FindBy(xpath = "//*[#id='footable_501']/thead/tr[2]/th[2]")
WebElement pretSort;
#FindBy(xpath = "//*[#id='calculator']/div[1]/div[2]/div[2]")
WebElement total;
public void checkCalculator()
{
add.click();
add2.click();
}
public void checkFilter()
{
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("window.scrollBy(0,500)"); //Scroll vertically down by 1000 pixels
analizaSort.click();
analizaSort.click();
pretSort.click();
}
Link: https://www.poliana.ro/analize-preturi/
I've added below the code to click on a random analyze and to calculate the total:
#FindBy(css = "th.footable-sortable[class*='pret']") // css locator is faster than xpath
WebElement pretSort;
#FindBy(css = "th.footable-sortable[class*='analiza']")
WebElement analizaSort;
#FindBy(css = "tr[class*='row'] td[class*='pret']")
List<WebElement> analyzePriceList;
#FindBy(css = "#calculator .total .right")
WebElement total;
public void checkCalculator() {
int elementListSize = analyzePriceList.size();
assertTrue("No analyze was found in the table", elementListSize != 0); // replace here with the specific of your testing framework
int elementIndex = getRandomNumber(elementListSize - 1);
scrollElementToTheMiddle(analyzePriceList.get(elementIndex));
int expectedTotal = getTextAsInt(analyzePriceList.get(elementIndex));
analyzePriceList.get(elementIndex).click();
String totalAsString = total.getText().replace("lei", "");
int actualTotal = getInt(totalAsString);
assertEquals(expectedTotal, actualTotal);
}
public void checkFilter() {
scrollElementToTheMiddle(analizaSort);
analizaSort.click();
analizaSort.click(); // if you need double click, please see the below method
pretSort.click();
}
private void doubleClick(WebElement element) {
Actions act = new Actions(driver);
act.doubleClick(element).build().perform();
}
private int getTextAsInt(WebElement element) {
String text = element.getText();
return getInt(text);
}
private int getInt(String text) {
assertTrue("The " + text + " text was expected to be numeric", isNumeric(text)); // replace here with the specific of your testing framework
return Integer.parseInt(text);
}
private boolean isNumeric(String possibleNumberAsString) {
Pattern pattern = Pattern.compile("-?\\d+(\\.\\d+)?\n");
if (possibleNumberAsString == null) {
return false;
}
return pattern.matcher(possibleNumberAsString.trim()).matches();
}
private int getRandomNumber(int maximum) {
return ThreadLocalRandom.current().nextInt(0, maximum);
}
private void scrollElementToTheMiddle(WebElement element) {
String scrollElementIntoMiddle = "var viewPortHeight = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);"
+ "var elementTop = arguments[0].getBoundingClientRect().top;"
+ "window.scrollBy(0, elementTop-(viewPortHeight/2));";
((JavascriptExecutor) driver).executeScript(scrollElementIntoMiddle, element);
}
I have a JTextPane with an extended DefaultStyledDocument. Updating the document takes about 2 minutes. Currently I am breaking it up into steps and updating on the swing thread with InvokeAndWait for each step. I have a progress bar and a cancel button. The cancel button only triggers when there is a break between steps. Each step takes about 10 seconds so I need to wait up to 10 seconds to stop the processing of the document. Is there anyway to make this more responsive? I am displaying a JFrame with the JTextPane in a JScrollPane when it is done. When it is finally rendered the scroll is very responsive and I can view the whole document. I do not want to display the JFrame until the document is updated yet I want to continue to show the progress of the update. Any ideas on how to update the document and have Swing and/or the cancel button more responsive?
====== Edit in response to comments ======
In styled document using the append(text) method - setting styles for each line before appending.
public void append(String text)
{
append(text, textStyle, paragraphStyle);
}
public void append(String text, Style ts, Style ps)
{
try
{
int start = this.getLength();
int end = this.getLength()+text.length();
this.insertString(start, text, ts);
this.setParagraphAttributes(start, end, ps, true);
}
catch (BadLocationException e)
{
LOG.log(Level.SEVERE, "Bad location in append", e);
}
}
======== Edit ========
This is what my document update method looks like.
public void writeTextOutsideOfSwing(StatusDialog status, float statusPercentage)
{
final StringBuilder letter = new StringBuilder();
final ArrayList<IndexTextEntry>list = new ArrayList<>();
LOG.log(Level.INFO, "Updating document: {0}", entries.length);
setText("");
int step = (int)((status.getMaximum() * statusPercentage) / (double)entries.length);
for(int j = 0; j < entries.length; j++)
{
if(status.cancel) break;
final int index = j;
list.add(entries[j]);
if(list.size() == 100 || index == entries.length -1)
{
int first = index - list.size() + 2;
int last = index + 1;
status.setStatusBarText("Writing Concordance: Processing " + first + " - " + last + " of " + entries.length);
try
{
SwingUtilities.invokeAndWait(()->
{
for(int k = 0; k < list.size(); k++)
{
int i = index-list.size() + k;
if(!letter.toString().equals(list.get(k).getSortLetter()))
{
letter.setLength(0);
letter.append(list.get(k).getSortLetter());
String title = list.get(k).getSortLetterTitle(letter.toString());
appendLetter(title, i == 0);
}
else if(i > 0)
{
if(cf.getLineBetweenEntries())
{
clearTextAreaStyles();
setFontSize(cf.getLineBetweenEntriesFontSize());
append(" \n");
}
}
float indent = appendEntry(0, list.get(k));
appendSubEntries(indent, list.get(k));
}
});
}
catch(InterruptedException | InvocationTargetException ex)
{ LOG.log(Level.SEVERE, "Writing Concorder Interrupted", ex); }
list.clear();
}
status.increment(step);
}
LOG.info("Done updating docuemnt");
}
And these methods go with the write method:
private void appendSubEntries(float indent, IndexTextEntry entry)
{
for (IndexTextEntry subEntry : entry.getSubEntries())
{
float ind = appendEntry(indent, subEntry);
appendSubEntries(ind, subEntry);
}
}
private float appendEntry(float indent, IndexTextEntry entry)
{
setFontFamily(cf.getWordFormat().getFontFamily());
setFontSize(cf.getWordFormat().getFontSize());
setFontBold(cf.getWordFormat().getBold());
setFontItalic(cf.getWordFormat().getItalic());
switch (cf.getWordFormat().getAlignment())
{
case TextFormat.ALIGN_CENTER:
setFontAlignment(EnhancedTextArea.ALIGN_CENTER);
break;
case TextFormat.ALIGN_RIGHT:
setFontAlignment(EnhancedTextArea.ALIGN_RIGHT);
break;
default:
setFontAlignment(EnhancedTextArea.ALIGN_LEFT);
break;
}
float wi = indent + cf.getWordFormat().getIndentJAVA();
setLeftIndent(wi);
setFontColor(cf.getWordFormat().getColor());
append(entry.getConcordance().getTitle());
append("\n");
float li = 0;
for(ConcordanceLine line : entry.getConcordance().getLines())
li = appendLine(wi, line);
return li;
}
private float appendLine(float indent, ConcordanceLine line)
{
setFontFamily(cf.getLineFormat().getFontFamily());
setFontSize(cf.getLineFormat().getFontSize());
switch (cf.getLineFormat().getAlignment())
{
case TextFormat.ALIGN_CENTER:
setFontAlignment(EnhancedTextArea.ALIGN_CENTER);
break;
case TextFormat.ALIGN_RIGHT:
setFontAlignment(EnhancedTextArea.ALIGN_RIGHT);
break;
default:
setFontAlignment(EnhancedTextArea.ALIGN_LEFT);
break;
}
float li = indent + cf.getLineFormat().getIndentJAVA();
setLeftIndent(li);
setFontColor(cf.getLineFormat().getColor());
setFontBold(cf.getPageBold());
setFontItalic(cf.getPageItalic());
append(line.page + " ");
setFontBold(cf.getLineBold());
setFontItalic(cf.getLineItalic());
append(line.lead);
setFontBold(cf.getWordBold());
setFontItalic(cf.getWordItalic());
append(line.word);
setFontBold(cf.getLineBold());
setFontItalic(cf.getLineItalic());
append(line.trail);
append("\n");
return li;
}
ALL VARIABLES are resolved before get methods
I am automating a page where I must choose two prices, when choosing the first price the page goes down the scroll and that's where the test fails, I get the error, I've already tried with explicit waits and thread.sleep but it does not work. any ideas?
this is the error:
net.thucydides.core.webdriver.exceptions.ElementShouldBeVisibleException: Expected condition failed: waiting for [[RemoteWebDriver: chrome on XP (e64b73bc32012e0506c1b2816cbc2ac2)] -> xpath: //div[#id='divAvailabilityOut']//span[#data-bind='html: Price']] to be displayed (tried for 50 second(s) with 100 milliseconds interval)
and this is my code:
public void escogerPreioMasCaro() throws InterruptedException {
List<WebElementFacade> listPreciosCaros = findAll(
"//div[#class='availabilityIn box']//span[#data-bind='html: Price']");
String[] strVectorCaros = new String[listPreciosCaros.size()];
int i = 0;
for (WebElementFacade listado : listPreciosCaros) {
System.out.println("Lista Precios Caros" + listado.getText());
strVectorCaros[i] = listado.getText().replaceAll("COP", " ").trim();
i++;
}
System.out.println(Arrays.toString(strVectorCaros).trim());
double[] vec1 = new double[strVectorCaros.length];
for (int g = 0; g < strVectorCaros.length; g++) {
try {
vec1[g] = Double.parseDouble(strVectorCaros[g]);
} catch (NumberFormatException ex) {
System.err.println("Ilegal input");
}
}
// System.out.println(Arrays.toString(vec1));
double precioMayor = vec1[0];
for (int x = 0; x < vec1.length; x++) {
// System.out.println(nombres[i] + " " + sueldos[i]);
if (vec1[x] > precioMayor) { //
precioMayor = vec1[x];
}
}
System.out.println("PrecioCaro" + precioMayor);
String precioMayorString = String.valueOf(precioMayor);
System.out.println("string " + precioMayorString);
for (WebElementFacade listado2 : listPreciosCaros) {
if (listado2.getText().contains(precioMayorString)) {
System.out.println(precioMayorString);
listado2.click();
}
}
Thread.sleep(2000);
}
What I am doing is to go through the series of prices and separate them to choose only the number, then pass them to double type vector to be able to compare their prices and choose the most expensive one
this is the page of the automation, the error presents it after choosing the destination and dates of travel
https://www.vivaair.com/co/flight/reserva
As I understood you try to find and select ticket with max price.
Here code sample to find and select max price for From and To figths:
driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
List<Double> pricesDouble = new ArrayList<>();
//Get all prices without currency of FROM Flight section
List<WebElement> fromPrices = driver.findElements(By.cssSelector("#divAvailabilityOut span[data-bind='html: PriceWithoutCurrencySymbol']"));
//To get all prices without currency of TO Flight section use code below
//List<WebElement> toPrices = driver.findElements(By.cssSelector("#availabilityLoadingIn span[data-bind='html: PriceWithoutCurrencySymbol']"));
fromPrices.forEach(e -> {
try {
pricesDouble.add(Double.parseDouble(e.getAttribute("innerText")));
} catch (NumberFormatException ex) {
System.err.println("Ilegal input");
}
});
//Assert.assertTrue(pricesDouble.size()>0, "Get at least one price");
int indexOfMaxPrice = pricesDouble.indexOf(Collections.max(pricesDouble););
//Get clickable element with max price
fromPrices.get(indexOfMaxPrice).findElement(By.xpath("ancestor::div[#class='totalPrice']")).click();
Here helpful links:
https://www.w3schools.com/cssref/css_selectors.asp
https://www.w3schools.com/xml/xpath_intro.asp
This is my code:
click(By.id("job-description-help"), MOUSE_LEFT, 2);
click(By.id("job-description-help"), MOUSE_LEFT, 2);
click(By.id("title"), MOUSE_LEFT, 2);
sendKeys(By.id("title"), "ttttt", true, 4);
click(By.xpath(".//*[#id='editor']/span[5]/a[1]"), MOUSE_LEFT, 7);
public void click(By locator, int mouseButton, String combinedControlKeys, int timeoutInSeconds) throws Exception {
Boolean success = false;
long timeoutInMillies = timeoutInSeconds * 1000;
WebElement elm = null;
// indicate whether the element is an <option> tag on Firefox browser
Boolean isOptionTagOnFireFox = false;
// time spent counters
long timeSpentInMillis = 0;
// try to click on the element until wait timout reached
while ((success == false) && (timeSpentInMillis <= timeoutInMillies)) {
try {
// find the element and calculate time spent
long startFinding = System.currentTimeMillis();
elm = findElement(locator, 1);
timeSpentInMillis += System.currentTimeMillis() - startFinding;
if (elm != null) {
// get tag name of the element
String tag = elm.getTagName();
// check whether the element is <option> tag on Firefox browser
isOptionTagOnFireFox = isFirefoxDriver && (0 == elm.getTagName().compareToIgnoreCase("option"));
// press control keys (Ctrl, Alt, Shift, Meta), if any
pressControlKeys(combinedControlKeys);
if (mouseButton == MOUSE_LEFT) {
// click on the element
elm.click();
}
else if (mouseButton == MOUSE_RIGHT) {
Actions action = new Actions(driver);
action.contextClick(elm);
action.build().perform();
}
// release control keys (Ctrl, Alt, Shift, Meta)
releaseControlKeys(combinedControlKeys);
// successfully clicked on element, turn on the flag to escape the loop
success = true;
}
} catch (Exception e) {
releaseControlKeys(combinedControlKeys);
// probably the element is not present yet or it is non-clickable
System.out.println(e.getMessage());
// if element is found and we reached to the timeout, try to click on it with JavaScript
if ((elm != null) && (timeSpentInMillis > timeoutInMillies)) {
// press control keys (Ctrl, Alt, Shift, Meta), if any
pressControlKeys(combinedControlKeys);
JavascriptExecutor js = (JavascriptExecutor) this.driver;
js.executeScript("arguments[0].click();", elm);
releaseControlKeys(combinedControlKeys);
// successfully clicked on element, turn on the flag to escape the loop
success = true;
}
}
}
if (success) {
// if element is <option> tag on Firefox browser,
// perform a workaround to support MOUSE_LEFT
if (isOptionTagOnFireFox)
{
robot.keyPress(KeyEvent.VK_ENTER);
robot.delay(300);
robot.keyRelease(KeyEvent.VK_ENTER);
}
}
else { // failed
if (elm == null) {
throw new NoSuchElementException("Element not found.");
} else {
throw new Exception("Failed to click on the element");
}
}
}
public void sendKeys(By locator, String keys, boolean clearTextBeforeSendingKeys, int timeoutInSeconds) throws Exception {
WebElement elm = findElement(locator, timeoutInSeconds);
if (clearTextBeforeSendingKeys) elm.clear();
elm.sendKeys(keys);
}
The error
invalid element state: Element is not currently interactable and may not be manipulated
start at
sendKeys(By.id("title"), "ttttt", true, 4);
I'm using Eclipse and ChromeDriver 2.27
Not sure why but the input field is visible. Can't move forward because of error. Any Idea how to solve this error?
When I start my tests I want to see an Exception, but programm just stay on the one line "mobileTelephony.driver" and don't throught exception. I don't understand why?
#Test(groups = {"non-basic"})
#Parameters({"idCategory"})
public void checkSearchForm(int idCategory) throws InterruptedException {
String categoryName;
int location = 1;
StackOfCategories sub1Stack = TestSuiteMobileTelephony.sub1Stack;
boolean isItSubCategory;
basePage.getBasePage();
basePage.clickCategoryName(idCategory);
MobileTelephonyPage mobileTelephony = PageFactory.initElements(basePage.driver, MobileTelephonyPage.class);
while (location <= 3) {
mobileTelephony.clickChangeLocation(location);
for(int i = 1; i <= sub1Stack.size(); i++) {
if (location == 1) {
categoryName = sub1Stack.getCategory(i).getNameEn();
} else if (location == 2) {
categoryName = sub1Stack.getCategory(i).getNameRu();
} else {
categoryName = sub1Stack.getCategory(i).getNameUk();
}
mobileTelephony.writeInSearchFormAndClick(categoryName);
try {
mobileTelephony.driver.findElement(By.xpath(".//div[#id='breadcrumbs']/span1"));
} catch(Exception e){
e.printStackTrace();
mobileTelephony.back();
}
isItSubCategory = true;
AssertMessage.assertTrueNavigateSubCategory(categoryName, isItSubCategory);
mobileTelephony.back();
}
location++;
}
}
Mobail Telefony code
public class MobileTelephonyPage extends BasePage {
public void clickAndWriteNumber(String number) throws AWTException {
String[] numsArray = number.split("");
number1.clear();
number1.click();
Robot robot = new Robot();
// Constryction
for(int i = 0; i < numsArray.length; i++) {
switch(Integer.parseInt(numsArray[i])) {
case 0 :
robot.keyPress(KeyEvent.VK_0);
break;
case 1 :
robot.keyPress(KeyEvent.VK_1);
break;
case 2 :
robot.keyPress(KeyEvent.VK_2);
break;
case 3 :
robot.keyPress(KeyEvent.VK_3);
break;
case 4 :
robot.keyPress(KeyEvent.VK_4);
break;
case 5 :
robot.keyPress(KeyEvent.VK_5);
break;
case 6 :
robot.keyPress(KeyEvent.VK_6);
break;
case 7 :
robot.keyPress(KeyEvent.VK_7);
break;
case 8 :
robot.keyPress(KeyEvent.VK_8);
break;
case 9 :
robot.keyPress(KeyEvent.VK_9);
break;
}
}
}
public MobileTelephonyPage(WebDriver driver) {
super(driver);
}
public int getHeightImg(int number) {
int height = driver.findElement(By.xpath("(.//div[#class='icon']/img)[" + number + "]")).getSize().getHeight();
return height;
}
public int getWidthImg(int number) {
int width = driver.findElement(By.xpath("(.//div[#class='icon']/img)[" + number + "]")).getSize().getWidth();
return width;
}
public MobileTelephonyPage back() {
driver.navigate().back();
return this;
}
public String getCurrentURL() {
return driver.getCurrentUrl();
}
public void clickOperator(String linkText) {
driver.findElement(By.linkText(linkText)).click();
}
}
in debug program stop in the next snipet of code(class HttpCommandExecutor)
this.log("profiler", new HttpProfilerLogEntry(command.getName(), true));
HttpResponse e = this.client.execute(httpRequest, true);
this.log("profiler", new HttpProfilerLogEntry(command.getName(), false));
No Exception is thrown.
Probably the code needs a long time to be executed or it is in a livelock.
A livelock is a situation when a function is executed but never ends. For example because in a for loop you loose to update a variable so the test is always true
Edited after new informations
From the javadoc of WebDriver:
This method is affected by the 'implicit wait' times in force at the
time of execution. The findElement(..) invocation will return a
matching row, or try again repeatedly until the configured timeout is
reached. findElement should not be used to look for non-present
elements, use findElements(By) and assert zero length response
instead.
As you can see the the function could not returns exactly as mentioned on the first two lines of my post.