Search code examples
seleniumcapybaraselenium-chromedriverrspec-rails

How to get capybara chrome headless to open sweetalert2 modals for Rspec tests


I'm currently using

selenium-webdriver 3.141.0 chromedriver-helper 2.1.0

gem 'rails-assets-sweetalert2', source: 'https://rails-assets.org' gem 'sweet-alert2-rails'

With Rails 5.2

My Capybara setup:

RSpec.configure do |config| 
  config.before(:each, type: :system) do
    driven_by :rack_test 
  end
  config.before(:each, type: :system, js: true) do 
    driven_by :selenium_chrome_headless
  end 
end
require "capybara-screenshot/rspec"

#Use the following to set the screen size for tests
Capybara.register_driver :selenium_chrome_headless do |app|
  options = Selenium::WebDriver::Chrome::Options.new

  [
    "headless",
    "window-size=1280x1280",
    "disable-gpu" # https://developers.google.com/web/updates/2017/04/headless-chrome
  ].each { |arg| options.add_argument(arg) }

  Capybara::Selenium::Driver.new(app, browser: :chrome, options: options)
end

I run the following test:

    require 'rails_helper'

    RSpec.describe 'deleting a proofread document using ajax', js: true do

      let(:job)  { create(:proofreading_job, title: 'Internal Job') }
      let(:user) { job.proofreader.user }

      it 'can delete a proofread document' do
        visit root_path
        click_on 'Login'
        fill_in  'Email', with: user.email
        fill_in  'Password', with: user.password
        click_on 'Sign In'
        click_on 'Dashboard'
        click_on 'Proofreading Jobs'
        click_on 'Current'
        click_on 'Internal Job'
        click_on 'Upload Proofread Document'
        attach_file(I18n.t('proofreader.proofread_document.upload'), Rails.root + 'spec/test_documents/proofread_document/1.docx' , make_visible: true)
        accept_alert do
           find_button('Upload', disabled: false).click
        end
        expect(page).to_not have_button('Delete')

     end
   end
 end

However the test fails with Rspec informing me that:

 Capybara::ModalNotFound:
   Unable to find modal dialog

However, I have manually used the webpage and the modal does show and work properly.

How can I get Capybara Selenium Chrome Headless Driver to open the modal in the tests?


Solution

  • accept_alert is for dealing with system modals (those the browser creates by default when calling window.alert that don't actually add elements to the page). Sweetalert2 is a JS library that inserts elements to the page to create more stylish "modals". You don't use accept_alert with those, you just interact with them as if they were any other HTML elements on the page. That would mean something along the lines of

    ....
    attach_file(...)
    click_button('Upload', disabled: false) # Not sure why you're passing `disabled: false` here since that's the default
    within('.swal2-actions') { click_button('the text of the button to accept the "modal"') }
    expect(page)....
    

    Update: As discovered in the comments - an additional cause of this issue was the assets not being compiled, in the OPs setup, so the JS wasn't firing at all. This would be immediately clear when running in non-headless mode and seeing that no "modal" was ever being displayed. The fix for that depends on what asset pipeline is being used and how it's configured, which goes beyond the scope of this question.