I'm trying to speed up some slow code by separating page loads from page analysis, but it seems that this breaks some rules that Selenium usually follows. As I understand it (found here) when you find something, Selenium stores references to it, not the actual thing you've found.
The result of this behaviour is that you can't load another page before processing the things you found. ie this sequential example works:
myDriver.Navigate.GoToUrl("mysite")
myVar = myDriver.FindElementsByClassName("upperContainer")
thisPN(i) = Trim(myVar.FindElement(By.ClassName("partNumber")).Text)
myDriver.Navigate.GoToUrl("http://www.google.com")
In order to make it faster though, I'm trying to pass the found items to a new thread for processing while the driver does other page loads.
This is illustrated by the below code which throws an exception An unhandled exception of type 'OpenQA.Selenium.StaleElementReferenceException' occurred in WebDriver.dll Additional information: stale element reference: element is not attached to the page document
sub main()
myDriver.Navigate.GoToUrl("mysite")
myVar = myDriver.FindElementsByClassName("upperContainer")
Dim myThread As New Thread(Sub() ripitems(myVar))
myThread.Start() 'this line kicks off the sub
myDriver.Navigate.GoToUrl("anothersite") ' and then this line changes the page before the sub has got going
end sub
sub ripitems(ByVal elementCollection As System.Collections.ObjectModel.ReadOnlyCollection(Of IWebElement))
for i = 0 to 100
thisPN(i) = Trim(elementCollection.FindElement(By.ClassName("partNumber")).Text)
next i
end sub
I can cure this exception by adding an arbitrary Threading.Thread.Sleep(500)
in after myThread.Start()
. So I know it's the page change, not the threading that breaks things.
Is there any function that copies the found HTML into the result variable, so that I can use it even after the page I'm looking at has changed. Something along the lines of:
myVar = **ByVal** myDriver.FindElementsByClassName("upperContainer")