Search code examples
ruby-on-railsselenium-webdrivercapybaraapparition

Capybara, possible to access Selenium actions?


ANSWER: Turns out all that needed to be done is to add the .perform action. This is what the resulting code looks like:

start_x = 450
start_y = 450
offset = 50
page.driver.browser.action
  .move_to_location(start_x, start_y)
  .pointer_down(:left)
  .move_by(offset, offset)
  .pointer_up(:left)
  .perform

Special thanks to @Thomas_Walpole for his help! :)


UPDATE: Here's what I'm trying now, thanks to @Thomas Walpole's comments. I'm trying to access the Selenium API actions in the test, using Capybara with the Selenium WebDriver and the Apparition javascript_driver:

start_x = 450
start_y = 450
offset = 50
page.driver.browser.action
  .move_to_location(start_x, start_y)
  .pointer_down(:left)
  .move_by(offset, offset)
  .pointer_up(:left)

And another attempt using .find_element

target = page.driver.browser.find_element(:css, '.cropper-canvas')
puts "#{target}" 
  => #<Selenium::WebDriver::ELement:0x0000557b0ef5bf48
offset = 50
page.driver.browser.action
  .move_to(target)
  .pointer_down(:left)
  .move_by(offset, offset)
  .pointer_up(:left)

In either case, the tests seem to complete but nothing actually happens (there's a whole slew of things that trigger in a live browser once a crop area has been drawn).

What am I doing wrong?


I'm trying to access some of Selenium's actions, to try and fill in the gap for a few things not offered in Capybara. Is this possible?

For example, I'm trying to test a click-and-drag action to simulate the user selecting a crop area on an image, but as far as I'm aware that type of functionality does not exist within Capybara. It does, however, seem to exist within the Selenium Webdriver itself (as outlined here), but I can't seem to find the right methods/syntax structure to bring it into play.

NOTE: I'm currently using Rails 6 and Capybara with the Apparition driver. ~~From what I can tell, Apparition is designed to be Selenium+Extras. So that's why I'm asking specifically about Selenium, and~~ I can change back to Selenium if it helps with my question.

My understanding thusfar is that the driver methods can be accessed within the system test *.rb file with page.driver,

cropper_canvas = find('.cropper-canvas')
x_offset = 20
y_offset = 20
page.driver.browser.drag_and_drop_by(cropper_canvas, x_offset, y_offset)

I've also tried to recreate a click and drag with

page.driver.browser.click_and_hold(cropper_canvas).move_by_offset(x_offset, y_offset).release

But neither of these approaches are going through. I suspect this has to do with the fact that the active page.driver is not a "true" Selenium::Webdriver but instead contained within Capybara, ala Capybara::Selenium::Driver

Is there anything I can do to use these Selenium-related methods/actions in my Rails system tests? If not with Capybara, then is there another approach I could try?

Thanks in advance for any help or insights! I'm just now learning about system tests, so my apologies if I'm not referring to things correctly or have my wires a bit crossed.

test_helper.rb

require_relative '../config/environment'
require 'rails/test_help'
...
require 'capybara/rails'
require 'capybara/minitest'
require 'capybara-screenshot/minitest'
require 'capybara/apparition'
...
Capybara.default_driver = :selenium_chrome
Capybara.javascript_driver = :apparition

Capybara.register_driver :apparition do |app|
  size = [1366,768]
  options = {
    headless: false,
    windows_size: size,
    screen_size: size,
    timeout: 10,
  }

  Capybara::Apparition::Driver.new(app, options)
end
...
Class ActionDispatch::IntegrationTest
  ...
  include Capybara::DSL
  include Capybara::Minitest::Assertions
end

Solution

  • Apparition is most definitely NOT selenium + extras. It, in fact, started more as a combination of the Poltergeist and capybara-webkit APIs. Apparition implements the Capybara required driver API but does not implement any other Seleniums APIs so the short answer is that you cannot access Selenium actions if you're using Apparition.

    You may be able to do what you want via methods like

    page.driver.browser.current_page.mouse.<xxxx>
    

    where the available mouse methods are defined at https://github.com/twalpole/apparition/blob/master/lib/capybara/apparition/page/mouse.rb but you'd be using private APIs which could break on any release