开发者

How can I run Selenium (used through Capybara) at a lower speed?

By default Selenium r开发者_运维技巧uns as fast as possible through the scenarios I defined using Cucumber. I would like to set it to run at a lower speed, so I am able to capture a video of the process.

I figured out that an instance of Selenium::Client::Driver has a set_speed method. Which corresponds with the Java API.

How can I obtain an instance of the Selenium::Client::Driver class? I can get as far as page.driver, but that returns an instance of Capybara::Driver::Selenium.


Thanks to http://groups.google.com/group/ruby-capybara/msg/6079b122979ffad2 for a hint.

Just a note that this uses Ruby's sleep, so it's somewhat imprecise - but should do the job for you. Also, execute is called for everything so that's why it's sub-second waiting. The intermediate steps - wait until ready, check field, focus, enter text - each pause.

Create a "throttle.rb" in your features/support directory (if using Cucumber) and fill it with:

require 'selenium-webdriver'
module ::Selenium::WebDriver::Firefox
  class Bridge
    attr_accessor :speed

    def execute(*args)
      result = raw_execute(*args)['value']
      case speed
        when :slow
          sleep 0.3
        when :medium
          sleep 0.1
      end
      result
    end
  end
end

def set_speed(speed)
  begin
    page.driver.browser.send(:bridge).speed=speed
  rescue
  end
end

Then, in a step definition, call:

set_speed(:slow)

or:

set_speed(:medium)

To reset, call:

set_speed(:fast)


This will work, and is less brittle (for some small value of "less")

require 'selenium-webdriver'
module ::Selenium::WebDriver::Remote
  class Bridge
    alias_method :old_execute, :execute
    def execute(*args)
      sleep(0.1)
      old_execute(*args)
    end
  end
end


As an update, the execute method in that class is no longer available. It is now here only:

module ::Selenium::WebDriver::Remote

I needed to throttle some tests in IE and this worked.


The methods mentioned in this thread no longer work with Selenium Webdriver v3.

You'll instead need to add a sleep to the execution command.

module Selenium::WebDriver::Remote
  class Bridge
    def execute(command, opts = {}, command_hash = nil)
      verb, path = commands(command) || raise(ArgumentError, "unknown command: #{command.inspect}")
      path = path.dup

      path[':session_id'] = session_id if path.include?(':session_id')

      begin
        opts.each { |key, value| path[key.inspect] = escaper.escape(value.to_s) }
      rescue IndexError
        raise ArgumentError, "#{opts.inspect} invalid for #{command.inspect}"
      end

      Selenium::WebDriver.logger.info("-> #{verb.to_s.upcase} #{path}")
      res = http.call(verb, path, command_hash)
      sleep(0.1) # <--- Add your sleep here.
      res
    end
  end
end

Note this is a very brittle way to slow down the tests since you're monkey patching a private API.


I wanted to slow down the page load speeds in my Capybara test suite to see if I could trigger some intermittently failing tests. I achieved this by creating an nginx reverse proxy container and sitting it between my test container and the phantomjs container I was using as a headless browser. The speed was limited by using the limit_rate directive. It didn't help me to achieve my goal in the end, but it did work and it may be a useful strategy for others to use!

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜