nattfodd
nattfodd

Reputation: 1890

Capybara/Selenium - force to reload Selenium Driver on each call

I have a solution to parse some data from a remote websites using Firefox(46) + Capybara + Selenium. I pass path_to_firefox_profile argument on initialize, which is some real Firefox profile folder.

The problem is that if I execute this code:

a = MyParser.new(profile_a)
a.parse_something
b = MyParser.new(profile_b)
b.parse_something

... the instance b will have profile A loaded despite I specified another profile.

But, if I run these 2 lines in a separate processes, I'll get what I want. So I assume one of them - either Capybara or Selenium - stores profiles settings once per ruby process, and won't change it on demand.

Are there are ideas how to change profile within the same process?

I tries to .quit Firefox, but it doesn't help, on visiting new URL Selenium opens another Firefox window with the exact same profile instead of new one.

class MyParser
  def initialize(path_to_firefox_profile)
    Capybara.register_driver(:selenium) do |app|
      client = Selenium::WebDriver::Remote::Http::Default.new
      client.timeout = 150
      Capybara::Selenium::Driver.new(app,
        profile: path_to_firefox_profile,
        http_client: client)
    end
  end

  def parse_something
    # perform some parsings & return result
  end
end

Upvotes: 0

Views: 353

Answers (1)

Thomas Walpole
Thomas Walpole

Reputation: 49870

Capybara's register_driver registers the driver by the name you assign globally, and will use those drivers (by name) in its sessions. It will also automatically manage sessions in a manner designed for ease of use by people testing web-apps. The issue here is that a new session with the newly registered driver isn't being created. This is because you're not really using Capybara for what it was designed, and therefore need to pick up a bit more of the weight of session management. If you're ever going to have more than 2 of your MyParser objects around you probably should be creating a new session per MyParser instance you create and then using that session in all of the MyParser methods. Since you're using different driver settings per MyParser instance you should probably also be naming each driver registered differently.

class MyParser
  def initialize(path_to_firefox_profile)
    Capybara.register_driver(self.object_id.to_s) do |app|
      client = Selenium::WebDriver::Remote::Http::Default.new
      client.timeout = 150
      Capybara::Selenium::Driver.new(app,
        profile: path_to_firefox_profile,
        http_client: client)
    end
    @session = Capybara::Session.new(self.object_id.to_s)
  end

  def parse_something
    @session.visit("some url")
    @session.find(...)  # perform some parsings & return result
  end
end

You will also need to handle cleaning up the session when you're done with each MyParser instance.

Upvotes: 1

Related Questions