Testing IMCE Wysiwyg Integration in Drupal Using Behat and Mink

by Aaron Froehlich

Over the past few months we've been using Behat and Mink for acceptance testing on a large Drupal distribution we're building (further background reading here). Overall, the transition from our comfy rails testing tools like RSpec and capybara-webkit has gone pretty smoothly, and we look forward to more articles about what we've learned in the coming weeks.

Last week, however, I hit a roadblock when testing IMCE integration with the Wysiwyg module. When a user clicks on the "Browser Server" button, IMCE opens a new window, but the Mink context does not automatically shift to the new window. Luckily, Mink provides the solution for this exact problem with its
session->switchToWindow(name) method (documentation). Unfortunately, CKEditor doesn't name the window when it opens, so it is impossible to target the window using the built-in method.

The problem presents an interesting dilemma. Patches are a good solution for bugs in modules/libraries, but leaving out an optional attribute isn't really a bug. Also, the minified javascript code makes it really hard to even write a patch that would work correctly when applied. Finally, it hardly makes sense to patch a file simply for the test suite.

To solve the dilemma, we simply needed to figure out where CKEditor was creating that window, and then utilize Behat's @BeforeSuite and @AfterSuite1 hooks to add a window name before the suite runs, and remove it after the tests finish running. In this case, we created a static method called strReplaceFile

private function strReplaceFile($file, $find, $replace) {
    $str = file_get_contents($file);
    $str = str_replace($find, $replace, $str);
    file_put_contents($file, $str);

After isolating the correct window.open function in CKEditor.js (where they are indeed passing null as the window name), we were able to run our handy method to give the window a name:


On teardown, we simply reverse it:


Our handy use of str_replace now allows us to create step definitions like the following (using the selenium driver):

 * @Given /^I choose the file "([^"]*)" in the "([^"]*)" folder$/
public function chooseTheFileInTheFolder($filename, $folder)
  sleep(1); //Solves intermittent timeout issues
  $el = $this->page->find('xpath', '//span[text()="'. $filename .'"]');
  $this->getSession()->switchToWindow(null); // Switches back to the main window

1Note that if the tests fail to complete for some reason, the ckeditor.js file will remain in it's edited state.
Are you passionate about programming and making the world a better place with your code? We want to hear from you!