Search code examples
seleniumselenium-webdrivertestunit

I want to know how long it takes to execute each test step


The test below runs great... I just want to know specifically how long each test step takes. The test was originally exported from the selenium firefox plugin to ruby.

My plan is to add one more additional step that verifies the 'average chute time' page has completely loaded. And I'd really like to know how long it takes from the moment that the test clicks on "average chute time" until the page is fully loaded.

 require "json"
    require "selenium-webdriver"
    gem "test-unit"
    require "test/unit"

    class LoginToChute< Test::Unit::TestCase

    def setup
        @driver = Selenium::WebDriver.for :chrome
        @base_url = "https://devdb5.esosuite.net/EsoSuiteHotfixDaily/"
        @accept_next_alert = true
        @driver.manage.timeouts.implicit_wait = 30
        @verification_errors = []
      end

      def teardown
        assert_equal [], @verification_errors
        @driver.quit
      end



      def test_login_to_chute
        @driver.get(@base_url)
        assert_equal "ESO Solutions :: NextGen", @driver.title
        @driver.find_element(:id, "UserName").clear
        @driver.find_element(:id, "UserName").send_keys "jenna"
        @driver.find_element(:id, "Password").clear
        @driver.find_element(:id, "Password").send_keys ".alice77."
        @driver.find_element(:id, "AgencyLoginId").clear
        @driver.find_element(:id, "AgencyLoginId").send_keys "wonderland"
        @driver.find_element(:id, "btnLogin").click
        @driver.find_element(:css, "img[alt=\"analytics\"]").click
        @driver.find_element(:xpath, "//div[text() = 'ePCR Reports']").click
        @driver.find_element(:xpath, "//div[text() = 'Operational Reports']").click
        @driver.find_element(:xpath, "//div[text() = 'Average Chute Time']").click



      end

      def element_present?(how, what)
        @driver.find_element(how, what)
        true
      rescue Selenium::WebDriver::Error::NoSuchElementError
        false
      end

      def alert_present?()
        @driver.switch_to.alert
        true
      rescue Selenium::WebDriver::Error::NoAlertPresentError
        false
      end

      def verify(&blk)
        yield
      rescue Test::Unit::AssertionFailedError => ex
        @verification_errors << ex
      end

      def close_alert_and_get_its_text(how, what)
        alert = @driver.switch_to().alert()
        alert_text = alert.text
        if (@accept_next_alert) then
          alert.accept()
        else
          alert.dismiss()
        end
        alert_text
      ensure
        @accept_next_alert = true
      end
    end

Solution

  • You should analyze this with a client side analysis like google dev tools. Determine what the last thing on the page is to actually load. This of course would give you a good analysis of performance itself, but going with the automated approach...

    You then take a system timestamp and save it as a variable before the @driver.find_element(:xpath, "//div[text() = 'Average Chute Time']").click line of your test. Execute all your code in your test and finish with a wait for the element you identified as the last to be loaded after your execution finishes. Right after the wait take a timestamp and get the difference between the two timestamps.

    Naturally this method would work for any duration you are wanting to measure you just need to organize your test accordingly so that you are measuring the exact step executions you want to measure. The waits for specific elements are important to ensure the client is finished rendering everything from a user standpoint. In general performance tricks are rendering the page and controls and then modifying the DOM via javascript so that it appears the page is there before all components and control contents are actually actionable to the user. So be careful what you are actually measuring and don't just measure a raw pageload.

    Repeat this for your specific loads and have separate measures for each. I have also implemented a wrapper that provides times for every step. Then have separate functions which I can start and stop a timer for groups of steps to measure. The choice is really up to what numbers you specifically want to capture.