How can I run Selenium (used through Capybara) at

2019-02-01 01:35发布

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.

4条回答
Rolldiameter
2楼-- · 2019-02-01 01:46

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.

查看更多
The star\"
3楼-- · 2019-02-01 01:51

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)
查看更多
放荡不羁爱自由
4楼-- · 2019-02-01 01:51

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.

查看更多
趁早两清
5楼-- · 2019-02-01 02:00

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
查看更多
登录 后发表回答