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

5

17

By default Selenium runs 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.

Rattigan answered 27/1, 2011 at 11:5 Comment(0)
C
25

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)
Carlotacarlotta answered 1/3, 2011 at 5:29 Comment(1)
thx for the hint! just in case page is not available, either include Capybara::DSL or replace it by Capybara.current_sessionNorby
B
6

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
Bragi answered 20/10, 2017 at 0:8 Comment(0)
R
3

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.

Reader answered 18/2, 2016 at 15:1 Comment(1)
@MischaMolhoek Use the code above and replace module ::Selenium::WebDriver::Firefox with module ::Selenium::WebDriver::Remote ! :D I'm currently using this w/ rspec features and have it in spec/support/throttle.rb calling set_speed :medium in my before block of my feature specs. Works great for when there's a lot of css and selenium is too fast for it. Thanks @phil for the update!Broncobuster
L
2

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.

Lizethlizette answered 25/7, 2017 at 8:10 Comment(0)
R
0

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!

Reichsmark answered 23/5, 2019 at 13:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.