0

I am using Angular Material Tab, and all my elements become stale after switching to different tab (which has a clone grid). Instead of doing this for all 20 elements on my grid, is there a way to Refresh ALL elements on page, so my references are not stale?

We are trying to acquire values on the grid.

private By JobIdHeaderGrid => By.XPath("//span[text() = 'Process ID']");

stale element reference: element is not attached to the page document

try {
    WebElement date = driver.findElement(By.linkText(Utility.getSheetData(path, 7, 1, 2)));
    date.click();
}
catch(org.openqa.selenium.StaleElementReferenceException ex)
{
    WebElement date = driver.findElement(By.linkText(Utility.getSheetData(path, 7, 1, 2)));
    date.click();
}

enter image description here

mattsmith5
  • 540
  • 4
  • 29
  • 67
  • is this line causing stale element reference `date.click();` ? – cruisepandey May 13 '21 at 17:22
  • it is getting stale, when I try to Find/get the element @cruisepandey – mattsmith5 May 13 '21 at 17:23
  • try to reload the UI using selenium and see if that works ? – cruisepandey May 13 '21 at 17:24
  • that would work, however manager wants to verify tabs, without reload @cruisepandey – mattsmith5 May 13 '21 at 17:24
  • Can you post few element from both the tabs as HTML in text format ? – cruisepandey May 13 '21 at 17:25
  • you're probably instantiating the page too soon. Try to wait until it's fully loaded. – DMart May 13 '21 at 18:11
  • find won't throw stale element... only when you call a method on that webreference will a stale element error be thrown. If the click() is throwing that error this page is either still in the process of updating or is constantly updating somewhere in the DOM. (like a timer element) Is this somewhat random? – pcalkins May 13 '21 at 18:56
  • check the answer here for a possible workaround: https://stackoverflow.com/a/66820707/4744568 An alternative is to functionize the call and re-call if stale element is thrown. (with a sanity count = 2X timeout of webdriverwait... wait is a 1/2 second polling loop) – pcalkins May 13 '21 at 18:58

1 Answers1

1

The short answer is no, there is no way to automatically refresh stale elements. Basically a stale element is one that is no longer attached to the DOM. That could be for multiple reasons... the page reloads, the browser is navigated away from and back to the page, etc. In your case, when you switch tabs, it sounds like it's treated like a page change which wipes out all of your references.

I would recommend not storing references but instead create methods that fetch and then use the element, e.g. click.

public void ClickDate()
{
    driver.findElement(By.linkText(Utility.getSheetData(path, 7, 1, 2))).click();
}

That way you should get rid of all your stale elements because you aren't fetching them, switching tabs and then back again, and then clicking the stored reference. You always fetch and then click immediately.

JeffC
  • 22,180
  • 5
  • 32
  • 55
  • there is a way, but you're not refreshing the stale element, you're refreshing the reference to the element. In this case it sounds like the previous action is causing an update to the DOM which is taking a little bit. So it finds the element, but by the time the click happens since the DOM is still updating that reference has gone bad. Putting this into one line would not help you still have to get the reference and then call the method on it. You also need a webdriverwait for this. – pcalkins May 13 '21 at 19:36
  • @pcalkins As to your first few sentences, your description does not match up with OP's description of what is happening. He stated he gets 20 references, clicks a tab, and then all references become stale... it's not a timing issue as you are claiming. The rest I'm not sure what you are saying... are you saying my answer is right/wrong/other? – JeffC May 13 '21 at 19:39
  • The only way that my code could result in a stale element is if in the few ms between the time it gets the reference and clicks the element, it goes stale... possible but highly, highly unlikely. I have code like this all over my projects that I've been using for years and don't have those issues. – JeffC May 13 '21 at 19:45
  • It would depend on how the site works. If the DOM is updated via javascript a webdriverwait is needed.... however that will only wait until the element is there... it won't know if the element is there but the DOM is still being updated. That's why the Stale Element exception was created. To let you know so that you can re-get the element. To be honest I didn't read his post very carefully (I was just looking at the code he posted), but the answer is still the same. Use WebDriverWait/Expected Conditions and catch Stale Elements if those are still being thrown. – pcalkins May 13 '21 at 19:49
  • So basically after a get()/navigate() Selenium waits for the page to load... or a non-javascript updating site's click. If the click doesn't generate a standard page load, but instead generates a JS action which results in a DOM update a webdriverwait is needed and it will only wait as long as necessary for that element to appear and/or meet the expected condition. – pcalkins May 13 '21 at 20:06
  • @pcalkins You really need to actually read the question. You are talking about something that has nothing to do with what he asled. Adding a WebDriverWait doesn't fix an existing element reference that goes stale. – JeffC May 13 '21 at 20:46
  • my apologies, I misunderstood and thought the code he posted was throwing the exception. I think I'd have to read the cross-post question to understand this properly, but yeah, you can't use webelement references that point to objects no longer in the DOM. – pcalkins May 13 '21 at 22:42