I am working with Selenium C# .NET.
What I want to accomplish is elegant, extendable page load time logging within my page object architecture. Most new pages are loaded as the result of some action, such as a click on a previous page. The problem is that when an action is performed, the WebDriver does not give control back to the Selenium code until the page has loaded. This causes the reported time elapsed to be much less than it actually is from a user perspective.
Here is some code that represents what I'm trying to do.
class LoginPage : Page
{
public WelcomePage Login()
{
EnterUserName();
EnterPassword();
// Really DON'T want to start a timer here and then access it in the Page constructor, if possible.
ClickContinueButton(); // Performs driver.FindElement(continueButtonLocator).Click();
return new WelcomePage();
}
}
class WelcomePage : Page
{
public override void WaitForLoad()
{
// Wait until some element exists to indicate page has completely loaded.
}
}
abstract class Page
{
long loadTime;
// Base constructor
// Start a timer, verify page load, and stop the timer.
public Page()
{
// This isn't called until the browser loading indicator has stopped.
timer = StopWatch.StartNew();
WaitForLoad();
loadTime = timer.EllapsedMilliseconds;
}
protected abstract void WaitForLoad();
}
Has anyone else come up with a solution to this problem?
The next-best solution I can think of right now is to have a global timer that restarts whenever an action like a click is performed. On the base Page class, I have generic methods for performing those actions, so one of those might look like this:
public void ClickElement(By locator)
{
IWebElement element = driver.FindElement(locator);
GlobalTimer.Restart();
element.Click();
}
And then the Page constructor would just access that after verifying load completion:
public Page()
{
WaitForLoad();
loadTime = GlobablTimer.EllapsedMilliseconds;
}
I feel like there has to be a better way of doing this, but I haven't come across a well-defined pattern in my searching.