1

I have the following webdriver function:

this.clickButton = async function () {
  try {
    var buttonElement = await driver.findElement(By.className('button-class'));
    await buttonElement.click();
  }
  catch (err) {
    console.log(err);
  }
}

This sometimes gives a Stale Element exception.

I sometimes get that exception even if I change it to:

this.clickButton = async function () {
  try {
    await driver.findElement(By.className('button-class')).click();
  }
  catch (err) {
    console.log(err);
  }
}

My questions are:

  1. Is it normal / expected that a Stale Reference exception can occur in this function, where I get the element reference, then use it on the very next line, or even the same line, doing nothing else with the page? (I could understand getting an 'element not found' exception, if no element of 'button-class' existed, but it doesn't make sense to me that the element exists at the time which I'm searching for it, but it's gone by the time the next line of code is reached.)

  2. If the answer to question 1 is yes, then how is that possible? The element found is immediately acted upon, as it is in this case? As you can see, I am not reusing locators / elements; the function searches for the element each time it is called, and ends immediately after the click.

  3. Is it relevant that clicking the button removes itself from the page? That is, could I be getting this exception because the button is gone after the click?

Phil
  • 348
  • 1
  • 15
  • https://stackoverflow.com/questions/43471166/selenium-with-async-await-in-js-find-and-click-on-element Please check the answer in this page.He mentioned 'it is attempting to await on (click()) is never called, because a Promise does not have a click() function' – Sudha Velan Oct 04 '19 at 06:40
  • I don't think the linked answer is exactly on point. In that one, the asker was getting a 'not a function' error. In my case, regardless of whether I use the 1 or 2 line version of the function, I sometimes get a Stale Element exception. – Phil Oct 07 '19 at 17:12
  • StaleElementRefernce sometime occurs if stale DOM is loaded and because of it more than one elements are present with the same finder. For example, once I tested a web app, which kept DOM of 3 pages loaded, and I had a button with the same finder ref on all three pages. My code worked perfectly for page 1 button, but I got StaleElementRefernce on the 2nd page as DOM of the first page was loaded too and I was getting the button of page 1 instead of page 2. Just to debug try using exact xpath to find the element or another unique finder. – sameeksha sahib Oct 11 '19 at 13:43
  • @sameeksha sahib that is a good thing to be looking for, but in this case, what I am searching for is already unique within the page, unless it is very quickly being added and removed or something. – Phil Oct 11 '19 at 17:28
  • check the answer of Ardesco her https://stackoverflow.com/questions/16166261/selenium-webdriver-how-to-resolve-stale-element-reference-exception (and use try/catch to find the element again in case stale element is thrown) – Mr Cas Oct 17 '19 at 14:52

1 Answers1

0

You must use the wait-until-clickable operator of selenium,this error occurred because it is still not appeared in DOM or still not clickable. Example Code:

var webDriver= new ChromeDriver(Constants.DriverPath);
WebDriverWait wait = new WebDriverWait(webDriver, TimeSpan.FromSeconds(5));
            wait.Until(SeleniumExtras.WaitHelpers.ExpectedConditions.ElementToBeClickable(By.ClassName('button-class')));

Then after that you can do your operation:

var buttonElement = await webDriver.FindElement(By.ClassName('button-class'));
    await buttonElement.Click();

In JavaScript there is no clickable but you can check for visible and enable state like :

driver.findElement(webdriver.By.name('q')).then(function (element) {
    driver.wait(function () {
        return element.isDisplayed().then(function (displayed) {
            if (!displayed)
                return false;

            return element.isEnabled();
        });
    });
    element.sendKeys('webdriver');
});
  • Unfortunately, all of my test automation is in JavaScript, and it looks like this answer is specific to .Net / C# (at least, all references I found online to SeleniumExtras were for that environment). – Phil Oct 13 '19 at 17:16
  • There is no different between them you can find this classes also in JavaScript,the logic is the same waiting until clack-able,and of I;m sure there is same method as in Javascript – Mortaza Ghahremani Oct 13 '19 at 20:23
  • Where have you seen this functionality? I've been looking at what I thought was the official documentation for JavaScript webdriver (https://seleniumhq.github.io/selenium/docs/api/javascript/module/selenium-webdriver/), and I didn't see SeleniumExtras, ExpectedConditions, or ElementToBeClickable listed there. Is there documentation elsewhere that you know of which is more up to date? – Phil Oct 13 '19 at 21:36