Search code examples
drupalbehatgherkin

How can I handle modal dialogs with Behat and Goutte?


I'm testing a functionnality on a website that allows the user to fill a form. At a moment, the users needs to click on a button, which triggers an Ajax loaded modal that allows him to upload a file. However, when I trigger the button, Behat doesn't seem to "see" the modal window.

Maybe I should precise I'm in a Drupal 8 environment, but I don't know if this changed anything

Just so we're clear, I'm not talking about an alert, but this kind of modal

So far my tests looks like this:

Scenario: Creates a stage test with two sessions
    Given I am on "/user/login"
    And I fill in "[email protected]" for "name"
    And I fill in "password" for "pass"
    And I press "Log in"
    Then I should get a "200" HTTP response
    And I should see "User Name"
    When I go to "/node/add/stage"
    Then I should get a "200" HTTP response
    And I should see "Add content CISIA Stage"
    When I fill in "Test Cisia Stage" for "edit-title-0-value"
    And I press "Select files"
    Then I should see "Upload files" <-- fails
    And I should see "Click or drop files here to upload them" <-- gets ignored but is likely to fail too

I can't find anything modal-related on SO or Google in general, only about small message alerts, and people talk about objects or functions I don't have (such as getWebDriver())

I also tried to find the modal's content by myself by doing so:

public function iShouldSeeAModalWindow() {

    $element = $this->getSession()->getPage();
    $modal = $element->find('css', sprintf('div:contains("%s")', 'Upload files'));

    if($modal) {
      exit('Yaaaay!');
    }

    else {
      throw new Exception("No modal found");
    }
}

However I got no luck so far.

What should I do?


Solution

  • You have an iframe and you need to switch to it.

    Use something like this:

    $this->getSession()->getDriver()->switchToIFrame('iframe_name');
    

    I think you should also consider to write your scenario on a high level basis and also use page objects extension to avoid getting long scenarios that are hard to maintain and unreadable and also to reuse as much code as possible.

    Follow Behavior Driven Development methodology.