Home > Enterprise >  StaleElement exception error when asserting data in a table
StaleElement exception error when asserting data in a table

Time:10-04

I am trying to add data to a table and then asserting that data is added by collecting table data in a list but every time it throws me a StaleElement exception error, now I guess it is happening because the list is getting refreshed, so I am not sure how do I handle it.

Here is my implementation

    private static List<WebElement> listOfJobs = 
    driver.findElements(By.xpath(("//*[@id='resultTable']//tbody/tr//a")));

    public static List<WebElement> getListOfJobs() 
        {
            try 
            {
                return listOfJobs;
            } 
            catch (Exception e) 
            {
                e.printStackTrace();
            }
            return null;
        }

    public static String generateName()
        {
            String AlphaNumericString = "abcdefghijklmnopqrstuvxyz";
            StringBuilder sb = new StringBuilder(9);
    
            for (int i = 0; i < 9; i  ) 
            {
                int index = (int)(AlphaNumericString.length() * Math.random());
                sb.append(AlphaNumericString.charAt(index));
            }
            return sb.toString() "digi";
        }
    
    @SuppressWarnings({ "null" })
        public static List<String> listOfJobs()
        {
            List<String> jobs = null;
            for(int i=0; i < OrangeHRMAddJobCategories.getListOfJobs().size(); i  )
            {
                jobs.add(OrangeHRMAddJobCategories.getListOfJobs().get(i).getText());
            }
            return jobs;
        }

    OrangeHRMAddJobCategories jobCategories = new OrangeHRMAddJobCategories();
            jobCategories.clickJobTab().clickJobCategoires().clickAdd().setJobCategoryName(UsefulFunctionUtils.generateName()).saveJobCategory();   

    Assertions.assertThat(UsefulFunctionUtils.listOfJobs().contains("digi"));

I feel that the listOfJobs should be reinjected somewhere but not sure where exactly do I put it because refreshing the page did not work.

Complete stacktrace


    org.openqa.selenium.StaleElementReferenceException: stale element reference: element is not attached to the page document
      (Session info: chrome=94.0.4606.61)
    For documentation on this error, please visit: https://www.seleniumhq.org/exceptions/stale_element_reference.html
    Build info: version: '3.141.59', revision: 'e82be7d358', time: '2018-11-14T08:17:03'
    System info: host: 'DESKTOP-R3JT7MO', ip: '192.168.0.103', os.name: 'Windows 10', os.arch: 'amd64', os.version: '10.0', java.version: '16.0.1'
    Driver info: org.openqa.selenium.chrome.ChromeDriver
    Capabilities {acceptInsecureCerts: false, browserName: chrome, browserVersion: 94.0.4606.61, chrome: {chromedriverVersion: 94.0.4606.61 (418b78f5838ed..., userDataDir: C:\Users\CHINMA~1\AppData\L...}, goog:chromeOptions: {debuggerAddress: localhost:62489}, javascriptEnabled: true, networkConnectionEnabled: false, pageLoadStrategy: normal, platform: WINDOWS, platformName: WINDOWS, proxy: Proxy(), setWindowRect: true, strictFileInteractability: false, timeouts: {implicit: 0, pageLoad: 300000, script: 30000}, unhandledPromptBehavior: dismiss and notify, webauthn:extension:credBlob: true, webauthn:extension:largeBlob: true, webauthn:virtualAuthenticators: true}
    Session ID: 8b68238ee73ae8190f250fa15fbb41f1
        at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:78)
        at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
        at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499)
        at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:480)
        at org.openqa.selenium.remote.http.W3CHttpResponseCodec.createException(W3CHttpResponseCodec.java:187)
        at org.openqa.selenium.remote.http.W3CHttpResponseCodec.decode(W3CHttpResponseCodec.java:122)
        at org.openqa.selenium.remote.http.W3CHttpResponseCodec.decode(W3CHttpResponseCodec.java:49)
        at org.openqa.selenium.remote.HttpCommandExecutor.execute(HttpCommandExecutor.java:158)
        at org.openqa.selenium.remote.service.DriverCommandExecutor.execute(DriverCommandExecutor.java:83)
        at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:552)
        at org.openqa.selenium.remote.RemoteWebElement.execute(RemoteWebElement.java:285)
        at org.openqa.selenium.remote.RemoteWebElement.getText(RemoteWebElement.java:166)
        at com.digicorp.utils.UsefulFunctionUtils.listOfJobs(UsefulFunctionUtils.java:45)
        at com.digicorp.testcases.TC_AddJobCategory.testAddJobCategory(TC_AddJobCategory.java:26)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:78)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:567)
        at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:133)
        at org.testng.internal.TestInvoker.invokeMethod(TestInvoker.java:598)
        at org.testng.internal.TestInvoker.invokeTestMethod(TestInvoker.java:173)
        at org.testng.internal.MethodRunner.runInSequence(MethodRunner.java:46)
        at org.testng.internal.TestInvoker$MethodInvocationAgent.invoke(TestInvoker.java:824)
        at org.testng.internal.TestInvoker.invokeTestMethods(TestInvoker.java:146)
        at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:146)
        at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:128)
        at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
        at org.testng.TestRunner.privateRun(TestRunner.java:794)
        at org.testng.TestRunner.run(TestRunner.java:596)
        at org.testng.SuiteRunner.runTest(SuiteRunner.java:377)
        at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:371)
        at org.testng.SuiteRunner.privateRun(SuiteRunner.java:332)
        at org.testng.SuiteRunner.run(SuiteRunner.java:276)
        at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:53)
        at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:96)
        at org.testng.TestNG.runSuitesSequentially(TestNG.java:1212)
        at org.testng.TestNG.runSuitesLocally(TestNG.java:1134)
        at org.testng.TestNG.runSuites(TestNG.java:1063)
        at org.testng.TestNG.run(TestNG.java:1031)
        at org.testng.remote.AbstractRemoteTestNG.run(AbstractRemoteTestNG.java:115)
        at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:251)
        at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:77)

CodePudding user response:

As per the convo with OP, it's getting stale at this point

jobs.add(OrangeHRMAddJobCategories.getListOfJobs().get(i).getText());

It could be because he is calling getListOfJobs which returns a List of WebElement. and when you call again, they are no longer available to page dom, cause you might have interacted with web element/elements in first iteration. There are few fixes, such as using Explicit wait staleness or redefining the elements again and again for next iteration.

Fix 1 :

private static List<WebElement> listOfJobs = driver.findElements(By.xpath(("//*[@id='resultTable']//tbody/tr//a")));

public static List<WebElement> getListOfJobs(int j) 
 {
     try 
     {
         List<WebElement> listOfJobs = driver.findElements(By.xpath("(//*[@id='resultTable']//tbody/tr//a)['" j "']"));
         return listOfJobs;
     } 
     catch (Exception e) 
     {
         e.printStackTrace();
     }
     return null;
 }
 
 
    @SuppressWarnings({ "null" })
    public static List<String> listOfJobs()
    {
        int j = 1;
        List<String> jobs = null;
        for(int i=0; i < listOfJobs.size(); i  )
        {
            jobs.add(OrangeHRMAddJobCategories.getListOfJobs(j).get(i).getText());
            j  ;
        }
        return jobs;
    }

CodePudding user response:

org.openqa.selenium.StaleElementReferenceException: stale element reference: element is not attached to the page document

Indicates that a reference to an element is now "stale" --- the element no longer appears on the DOM of the page. The reason for this expectation is may be your DOM got updated or refreshed. For an example, after performing an action like click() your DOM may get updated or refreshed. In this time when you are trying to find an element on DOM you will experience this error.

You have to re-find that element in updated or refreshed DOM

try{
    jobs.add(OrangeHRMAddJobCategories.getListOfJobs().get(i).getText());
   }catch(org.openqa.selenium.StaleElementReferenceException e){
     new WebDriverWait(driver, 10).until(ExpectedConditions.visibilityOf(OrangeHRMAddJobCategories.getListOfJobs().get(i)));
     jobs.add(OrangeHRMAddJobCategories.getListOfJobs().get(i).getText());
   }

CodePudding user response:

You are doing the operation before the element is loaded in the webpage, so please add the wait conditions and then do your operation.

By divCss = By.xpath(("//*[@id='resultTable']//tbody/tr//a"));
wait.until(ExpectedConditions.elementToBeClickable(divCss));
wait.until(ExpectedConditions.presenceOfAllElementsLocatedBy(divCss));
  • Related