3

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.

  • What are you going todo with the data? Benchmark? – Niels van Reijmersdal Sep 20 '17 at 11:57
  • Yes, collecting data for benchmark comparisons is the primary goal. Ultimately the data will be stored to and accessed from a logging database so that comparisons can be easily made via query. Once I have a reasonable amount of historical data, regression tests will be marked as failed if performance has degraded. – VanderLinden Sep 20 '17 at 16:52
2

The browser already collects performance data, not sure you need to collect your own. You can retrieve it with the JavaScript Executor by returning the object window.performance.

PerformanceTiming.domInteractive: This property can be used to measure the speed of loading Web sites that users feels.

https://developer.mozilla.org/en-US/docs/Web/API/PerformanceTiming/domInteractive

This article has an C# example how to collect and process this data.

This is not perfect as the DOMStates stop measuring after the onLoad is called I think. If you have a complex UI or single page application and you want to benchmark individual workflows. Also if you are serious about collecting such performance data from the front-end, I would ask the developers to also implement their own performance objects which you can collect, instead of hacking something into your tests.

The simplest way to benchmark test performance with tests is to just record the test run-time length at the end of the test. I would think if the tests become slower overtime you would get the same signal. If your tests execute good isolated workflows I do not think you need to record individual drawn elements.

Don't re-invite the wheel:

So yes it is technically possible to use Selenium to benchmark performance. Still I think this is a too complex way doing it.

Rather research tools like NewRelic, which records actual data from users from the loading of the UI till requests of the database and back. You can even set it up to show you which function calls happened and how long they took and show it in graphs over time. The nice thing here is these are tools monitor performance of real users not tests.

If you do want to know performance difference before you release to production. Run the full Selenium regression test-suite against an environment which records performance data with something like NewRelic. Analyse after the run, possibly automated.

Also read this "What is Application Performance Management?" blog.

  • I think window.performance is exactly the kind of thing I'm looking for. This is a short-term solution; in the long term, I will advocate for implementing a tool like NewRelic (thanks for pointing me to that). " I would ask the developers to also implement their own performance objects" - this is something I completely agree with as well, but in my organization, things of this nature are met with resistance. – VanderLinden Sep 20 '17 at 18:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.