最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

.net core - Cannot return a Web Element to its prior state after testing in Selenium - Stack Overflow

programmeradmin3浏览0评论

Specific issue -- I get the stale element exception when trying to re-access the element and set it back to Active or Inactive.

I'm using Selenium to get an IReadOnlyCollection of all its entries. When an unchecked (inactive) date is Posted, its checkbox will show as checked. When a checked (active) date is Deactivated, it will show as unchecked:

Deactivate reverses the process:

A related but really unanswered post from 5 years ago suggests to get a list of the Ids and loop through those. But there's no solution I can find that shows how to do this.

Here is the Intellisense showing the Element Ids:

I think looping through the Ids, not the Elements, might work. But getting that list of Ids is elusive. Any attempt to get at the Ids list only exposes the API for getting the Element properties (Text, etc.)

It seems this is an array of Id strings. Should be simple enough to get the length, dynamically set a string[] object and iterate over it. (I hope)

This all said, I have to test Post and its related dialogs, then uncheck the element. And of course, test Deactivate and its related dialogs then re-check the checkbox. Trying to do this in a single test instance throws the stale element exception.

I'm not able to find an example that does this.

Thanks for any ideas.

For DeLaphante's code:

Here is my code, I know there's a way to prettify c#, I fet how to do that:

public void SelectSpecificProgrammaticDate(IReadOnlyCollection<IWebElement> programmaticList, string programmaticDate)
    {
        foreach (IWebElement el in programmaticList)
        {
            try
            {
                string elDate = el.FindElement(By.CssSelector(
                    CommonXpathStrings.adminManageProgrammaticDateRow)).Text;
                if (elDate == programmaticDate)
                {
                    el.Click();
                    break;
                }
            }
            catch
            {
                string elDate = el.FindElement(By.CssSelector(
                    CommonXpathStrings.adminManageProgrammaticDateRow)).Text;
                if (elDate == programmaticDate)
                {
                    el.Click();
                    break;
                }
            }
        }
    }

Even though I'm catching the exception, upon working again to get the element, the exception is yet thrown again in the catch.

I'm thinking I need to re-create the list again.

Here's a bit more explanation -- the entire 71 elements are captured in the collection. The first unchecked one is found. Post is used to activate it at which time it's checked and Deactivate will need to be used on that date element to uncheck it, putting it back into its pre-test state.

It may be the ENTIRE list is stale once ANY element is acted upon. I didn't consider that before so I'll try that angle.

Specific issue -- I get the stale element exception when trying to re-access the element and set it back to Active or Inactive.

I'm using Selenium to get an IReadOnlyCollection of all its entries. When an unchecked (inactive) date is Posted, its checkbox will show as checked. When a checked (active) date is Deactivated, it will show as unchecked:

Deactivate reverses the process:

A related but really unanswered post from 5 years ago suggests to get a list of the Ids and loop through those. But there's no solution I can find that shows how to do this.

Here is the Intellisense showing the Element Ids:

I think looping through the Ids, not the Elements, might work. But getting that list of Ids is elusive. Any attempt to get at the Ids list only exposes the API for getting the Element properties (Text, etc.)

It seems this is an array of Id strings. Should be simple enough to get the length, dynamically set a string[] object and iterate over it. (I hope)

This all said, I have to test Post and its related dialogs, then uncheck the element. And of course, test Deactivate and its related dialogs then re-check the checkbox. Trying to do this in a single test instance throws the stale element exception.

I'm not able to find an example that does this.

Thanks for any ideas.

For DeLaphante's code:

Here is my code, I know there's a way to prettify c#, I fet how to do that:

public void SelectSpecificProgrammaticDate(IReadOnlyCollection<IWebElement> programmaticList, string programmaticDate)
    {
        foreach (IWebElement el in programmaticList)
        {
            try
            {
                string elDate = el.FindElement(By.CssSelector(
                    CommonXpathStrings.adminManageProgrammaticDateRow)).Text;
                if (elDate == programmaticDate)
                {
                    el.Click();
                    break;
                }
            }
            catch
            {
                string elDate = el.FindElement(By.CssSelector(
                    CommonXpathStrings.adminManageProgrammaticDateRow)).Text;
                if (elDate == programmaticDate)
                {
                    el.Click();
                    break;
                }
            }
        }
    }

Even though I'm catching the exception, upon working again to get the element, the exception is yet thrown again in the catch.

I'm thinking I need to re-create the list again.

Here's a bit more explanation -- the entire 71 elements are captured in the collection. The first unchecked one is found. Post is used to activate it at which time it's checked and Deactivate will need to be used on that date element to uncheck it, putting it back into its pre-test state.

It may be the ENTIRE list is stale once ANY element is acted upon. I didn't consider that before so I'll try that angle.

Share Improve this question edited Mar 11 at 16:11 user1585204 asked Mar 11 at 12:23 user1585204user1585204 9871 gold badge11 silver badges20 bronze badges 5
  • I'm afraid the question isn't going deep enough into the dynamics of your test... if you carefully read the SO answer you cited, there's a comment saying the reason is: when you come "back" to the first page, the DOM will be rewritten, causing your previously fetched webElement references to become stale and a link to the StaleElementReferenceException saying that thing in broader terms – Diego D Commented Mar 11 at 12:58
  • so the problem is that you are acting over an element that was fetched before the DOM changed.. you should show those details to understand how to better deal with that scenario. – Diego D Commented Mar 11 at 12:59
  • You need to post the current code you are using so we can see potential problems and offer solutions along with some of the HTML for a few dates in the activated and deactivated states. The "ids" you are talking about are the GUIDs of the WebElements and are not static. They are not related to HTML IDs. If the page refreshes, those ids will change so this is not a viable option. – JeffC Commented Mar 11 at 13:57
  • Is the same date listed twice in the list? e.g. is "03/11/25" in the list twice? I'm assuming it's not. You should be able to easily find locators for those dates specifically. Without knowing anything about the page, I would probably grab a list of all elements, then grab the dates in each element and store that in a list, then loop through the list of dates doing your test on each one. – JeffC Commented Mar 11 at 13:59
  • Jeff and Diego, thanks. I did see that the other post involved a return to the page. Since I was getting the same exception, however, considered the suggestions of getting the Ids to be right. DeLephante gave another idea, will check it out. Jeff, are the GUIDs an option if the page isn't refreshed? I'm tending to lean toward the proposed answer below but am interested in how one would snag the GUIDs. – user1585204 Commented Mar 11 at 14:40
Add a comment  | 

2 Answers 2

Reset to default 0

You need to create a wrapper or method that will catch the exception and locate the element again as shown below:

Recreating an entire list of dates with a framework that can be quite slow loading, like Ext JS 3.x, sounds counter intuitive. But that's how to resolve this.

I copied my Browser Fixture properties that create the the first Programmatic List. And named these as Secondary Programmatic Dates, etc.

One saves the date whether it is going to be Post(ed) (activated, checked) or Deactivated (unchecked). Then using the secondary list, the date is returned to its pre-test value.

Working with the already existing list seems much faster an approach but IReadOnlyCollection is just that.

Jeff C, Diego, DeLaphante, thanks for the input.

发布评论

评论列表(0)

  1. 暂无评论