The element does not exist in DOM anymore

Hi,

Appium throws intermittent error

selenium.common.exceptions.StaleElementReferenceException: Message: The element 'By.id: com.androidsample.generalstore:id/productPrice' does not exist in DOM anymore

Code:
driver.find_element_by_id("com.androidsample.generalstore:id/productPrice").is_displayed()

Test data:
Appium Version: 1.17.1
Python Version: 3.8
IDE: Pycharm

Kindly guide me to resolve above issue.

Best Regards,
Gaurav Valera

1 Like

Issue is fixed after applying Explicit Wait.In case some one is facing the same issue, do apply following steps:

            wait = WebDriverWait(self.driver, 8)
            wait.until(expected_conditions.presence_of_element_located((By.ID, "productPrice")))
            self.driver.find_element_by_id("productPrice").is_displayed()

Note: Import necessary packages too :slight_smile:

Which packages require to handle this exception?
@Gaurav_Valera

@Gaurav_Valera @Aleksei @KazuCocoa
Thanks for your code snippet. We had already implemented this wait feature of 20sec. But occasionally, or rather randomly this error still pops up. I could not figure out the reason. The code snippet for wait mechanism we use is as follows:

  • tapByElement(menuOptions.get(3), "Tap Devices Option");

  • public void tapByElement(WebElement e, String msg) {
              waitForVisibility(e);
              utils.log().info(msg);
              Rectangle elRect = e.getRect();
              Point point = new Point(
                      elRect.x + (int) (elRect.getWidth() / 2.0),
                      elRect.y + (int) (elRect.getHeight() / 2.0)
              );
              tapAtPoint(point);
          }
    
  • public boolean waitForVisibility(WebElement e) {
          WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(TestUtils.WAIT));
         return wait.until(ExpectedConditions.attributeContains(e, "enabled", String.valueOf(true)));
      }

it is cause you send element instead of it locator. plus your screen redraw during waiting.

Thanks Aleksei @Aleksei

Hello there!
I’m trying to catch the error in case the element doesn’t appear, because that’s how I need it. Is there any way to do it? With .size !=0 it acts as if it is always displayed, even though it is not.
Thanks in advance

first add example how you search for needed element.

Yes, sorry, this is my code

WebElement displayedError = driver.findElement(By.id(“com.example.prep:id/textinput_error”));
String errorText = driver.findElement(By.id(“com.example.prep:id/textinput_error”)).getText();

  driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(3));

  if (displayedError.isDisplayed()){
  	Assert.assertEquals(errorText, "Este teléfono no es válido.");
  	System.out.println(ANSI_YELLOW + "Aparece mensaje de error y texto es correcto" + ANSI_RESET);
  }
  
  else {
  	System.out.println(ANSI_YELLOW + "No aparece mensaje de error" + ANSI_RESET);
  }

lets change a bit your code:

        // this is FAST action by default if you need a bit more time use implicitlyWait before search element
        // driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(3)); // 3 sec wait for elements
        WebElement textErrorInput = driver.findElement(By.id("com.example.prep:id/textinput_error"));

        // check textErrorInput element appeared
        if (isLoaded(textErrorInput)) {
            Assert.assertEquals(textErrorInput.getText(), "Este teléfono no es válido.", "Text input error NOT correct");
            System.out.println(ANSI_YELLOW + "Aparece mensaje de error y texto es correcto" + ANSI_RESET);
        } else {
            System.out.println(ANSI_YELLOW + "No aparece mensaje de error" + ANSI_RESET);
        }

        public boolean isLoaded (WebElement el){
            boolean bool = false;
            try {
                bool = !((RemoteWebElement) el).getId().isEmpty();
            } catch (Exception ignored) {
            }
            return bool;
        }
1 Like

It works perfectly. I thank you very much.

Edit: Seemed to work but actually acts like it never found the item. I don’t understand what’s going on.

Edit again (sorry): I have corrected something that was wrong in my code and now I have the same problem as before.
I must point out that in the same test I have to do this check twice: in the first, the error should appear, in the second, not.
And it is in the second that Appium throws me the error:

FAILED: appiumTest.Login.Login

org.openqa.selenium.StaleElementReferenceException: The element ‘By.id: com.example.prep:id/textinput_error’ does not exist in DOM anymore

For documentation on this error, please visit: https://www.selenium.dev/documentation/webdriver/troubleshooting/errors#stale-element-reference-exception

Build info: version: ‘4.10.0’, revision: ‘c14d967899’

System info: os.name: ‘Windows 10’, os.arch: ‘amd64’, os.version: ‘10.0’, java.version: ‘17.0.6’

Driver info: io.appium.java_client.android.AndroidDriver

Command: [719e1b4b-35b7-4a2c-a5e3-8b7f1b02447a, getElementText {id=00000000-0000-0946-ffff-ffff0000007f}]

Capabilities {appium:app: C:\Users\elena\ecli…, appium:appPackage: com.example.prep, appium:automationName: UIAutomator2, appium:databaseEnabled: false, appium:desired: {app: C:\Users\elena\ecli…, automationName: UIAutomator2, deviceName: Pixel 6 API 33, platformName: ANDROID}, appium:deviceApiLevel: 33, appium:deviceManufacturer: Google, appium:deviceModel: sdk_gphone_x86_64, appium:deviceName: emulator-5554, appium:deviceScreenDensity: 420, appium:deviceScreenSize: 1080x2400, appium:deviceUDID: emulator-5554, appium:javascriptEnabled: true, appium:locationContextEnabled: false, appium:networkConnectionEnabled: true, appium:pixelRatio: 2.625, appium:platformVersion: 13, appium:statBarHeight: 128, appium:takesScreenshot: true, appium:viewportRect: {height: 2081, left: 0, top: 128, width: 1080}, appium:warnings: {}, appium:webStorageEnabled: false, platformName: ANDROID}

Element: [[AndroidDriver: on ANDROID (719e1b4b-35b7-4a2c-a5e3-8b7f1b02447a)] -> id: com.example.prep:id:id/textinput_error]

lets look all together

        // this is FAST action by default if you need a bit more time use implicitlyWait before search element
        // driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(3)); // 3 sec wait for elements
        WebElement textErrorInput = driver.findElement(By.id("com.example.prep:id/textinput_error"));

        // check textErrorInput element appeared
        if (isLoaded(textErrorInput)) {
            Assert.assertEquals(textErrorInput.getText(), "Este teléfono no es válido.", "Text input error NOT correct");
            System.out.println(ANSI_YELLOW + "Aparece mensaje de error y texto es correcto" + ANSI_RESET);
        } else {
            System.out.println(ANSI_YELLOW + "No aparece mensaje de error" + ANSI_RESET);
        }

       // ... here some your steps...
       
      // now need AGAIN to check. so you need AGAIN first find your element
      textErrorInput = driver.findElement(By.id("com.example.prep:id/textinput_error"));
      // only after this you can check if it appeared or not

Sorry for taking so long to respond, I was busy with other tasks during the summer.
I have tried this new code and I still get the same error. I don’t understand what is happening, since it recognizes that the text does not appear, but it does not consider it valid when it should, and the test fails.