0

I did a little research here and here, however when I apply the given examples with this random url: https://www.ibm.com/support/pages/it-possible-use-upper-or-lowercase-function-xpath-expression I get the error below with Selenium WebDriver for .NET:

OpenQA.Selenium.StaleElementReferenceException: 'The element reference of {script src="https://example.com/"} is stale; either the element is no longer attached to the DOM, it is not in the current frame context, or the document has been refreshed'

My purpose is to get all the elements on the current web-page in this universal function:

Function FindElementsByText(drv As IWebDriver, text As String, 
                            stringComparison As StringComparison) As ReadOnlyCollection(Of IWebElement)

    Return (From element As IWebElement In drv.FindElements(By.CssSelector("*"))
            Where element.Text.Equals(text, stringComparison)
           ).ToList().AsReadOnly()

End Function

Where drv.FindElements(By.CssSelector("*")) (or drv.FindElementsByXPath("//*")) is what is causing the exception above after I instruct the driver to navigate to the url that I specified at the beginning.

The function above would be a great improvement for this other universal function limited by the translate function of XPath 1.0:

Function FindElementsByText(drv As RemoteWebDriver, text As String, 
                            ignoreCase As Boolean) As ReadOnlyCollection(Of IWebElement)

    Const translateUpperText As String = "ABCDEFGHIJKLMNOPQRSTUVWXYZÁÉÍÓÚÀÈÌÒÙÄËÏÖÜÂÊÎÔÛÑÇ"
    Const translateLowerText As String = "abcdefghijklmnopqrstuvwxyzáéíóúàèìòùäëïöüâêîôûñç"

    If ignoreCase Then
        Return drv.FindElementsByXPath($"//*[contains(translate(text(), {translateUpperText}, {translateLowerText}),'{text.ToLower()}')]")

    Else
        Return drv.FindElementsByXPath("//*[contains(text(),'{text}')]")

    End If

End Function

My question is: how can I get rid of the error I'm getting to get all the elements in a web-page in the proper way?.

6
  • You can use a try/catch to capture the exception but really I'm wondering: What is your actual goal in capturing all webelements? Commented Nov 19, 2020 at 17:30
  • As you can see in the sample code that I provided I can't just add a try/catch block since I'm using a LINQ query that with or without a try/catch the exception will interrupt the return of the query. As explained in my question, the idea is to analyze the text of every element in the current webpage to match an element by its text. Commented Nov 19, 2020 at 19:51
  • you're simply trying to find 1 webelement based on known text? Commented Nov 19, 2020 at 20:07
  • if the DOM is still being updated while you iterate your loop you will receive a stale element exception at this line: element.Text... (the reference to the DOM will be stale.) Commented Nov 19, 2020 at 20:28
  • 1
    a .get() call will wait... except for "lazy loading" type sites. Seems like for your use-case you can craft an xpath that will work. For times when you need to wait, use a webdriverwait with find_elements. Try/catch the find_elements call. If you receive a stale element exception, run the find again. (functionize the call so you can re-call it inside the method) A java example of this technique is here: github.com/pcalkins/browsermator/blob/master/src/browsermator/… Commented Nov 19, 2020 at 23:52

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.