Question

I have a standard rails application with a delete link. This delete link comes up with a browser popup modal (using rails confirm option).

I am currently attempting to test the delete function with Cucumber, Selenium-Webdriver (or Watir-Webdriver, still haven't decided), and the page-object gem.

Once the modal has been triggered, anything I do on the page gives me the following error:

Modal dialog present (Selenium::WebDriver::Error::UnhandledAlertError)

I have been looking all over, but cannot find a way to handle this condition. If possible, I would like to continue using the PageFactory module in the page-object gem.

How can I dismiss/accept the modal?

Was it helpful?

Solution

I figured out a way to do this, but haven't decided upon the exact implementation.

In Javascript you can overwrite any function, which means you can overwrite the confirm

This means that you can run the following code to disable any popups.

def disable_popups
  # don't return anything for alert
  browser.execute_script("window.alert = function() {}")

  # return some string for prompt to simulate user entering it
  browser.execute_script("window.prompt = function() {return 'my name'}")

  # return null for prompt to simulate clicking Cancel
  browser.execute_script("window.prompt = function() {return null}")

  # return true for confirm to simulate clicking OK
  browser.execute_script("window.confirm = function() {return true}")

  # return false for confirm to simulate clicking Cancel
  browser.execute_script("window.confirm = function() {return false}")
end

If you put this inside the initalize_page function of a page-object then the dialogs are automatically removed.

def initialize_page
    disable_popups
end

Or you could do it right before the pop is triggered

def delete
  disable_popups
  delete_link # => clicks the link
end

References:

OTHER TIPS

The page object gem has methods to handle javascript popups - see the original page-object gem post. In your case, I believe you want the confirm method::

(String) confirm(response, frame = nil, &block)

Override the normal confirm popup so it does not occurr.

Examples:

message = @popup.confirm(true) do
   @page.button_that_causes_confirm
end

Parameters:

  • what (bool) — response you want to return back from the confirm popup
  • frame (defaults to: nil) — optional parameter used when the confirm is nested within a frame
  • block — a block that has the call that will cause the confirm to display

Returns:

(String) — the message that was prompted in the confirm

There is similar for the alert and prompt popups.

In your page-object, I would define:

class MyPage
  link(:delete_link, :id=>'delete')

  def delete()
    confirm(true){ delete_link }
  end
end 

Then when you call page.delete, it will click the link and confirm the popup.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top