Skip to content

Commit

Permalink
Merge branch 'MDL-43911-master' of git://github.com/andrewnicols/moodle
Browse files Browse the repository at this point in the history
  • Loading branch information
stronk7 committed Feb 4, 2014
2 parents 845e114 + a964ead commit 5ecfa56
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 22 deletions.
6 changes: 4 additions & 2 deletions config-dist.php
Expand Up @@ -681,9 +681,11 @@
// Example:
// $CFG->behat_additionalfeatures = array('/home/developer/code/wipfeatures');
//
// You can make behat save a screenshot when a scenario fails.
// You can make behat save several dumps when a scenario fails. The dumps currently saved are:
// * a dump of the DOM in it's state at the time of failure; and
// * a screenshot (JavaScript is required for the screenshot functionality, so not all browsers support this option)
// Example:
// $CFG->behat_screenshots_path = '/my/path/to/save/screenshots';
// $CFG->behat_faildump_path = '/my/path/to/save/failure/dumps';
//
//=========================================================================
// 12. DEVELOPER DATA GENERATOR
Expand Down
85 changes: 65 additions & 20 deletions lib/tests/behat/behat_hooks.php
Expand Up @@ -78,11 +78,11 @@ class behat_hooks extends behat_base {
protected static $currentstepexception = null;

/**
* If we are saving screenshots on failures we should use the same parent dir during a run.
* If we are saving any kind of dump on failure we should use the same parent dir during a run.
*
* @var The parent dir name
*/
protected static $screenshotsdirname = false;
protected static $faildumpdirname = false;

/**
* Gives access to moodle codebase, ensures all is ready and sets up the test lock.
Expand Down Expand Up @@ -142,8 +142,8 @@ public static function before_suite($event) {
self::$lastbrowsersessionstart = time();
}

if (!empty($CFG->behat_screenshots_path) && !is_writable($CFG->behat_screenshots_path)) {
throw new Exception('You set $CFG->behat_screenshots_path to a non-writable directory');
if (!empty($CFG->behat_faildump_path) && !is_writable($CFG->behat_faildump_path)) {
throw new Exception('You set $CFG->behat_faildump_path to a non-writable directory');
}
}

Expand Down Expand Up @@ -272,7 +272,7 @@ public function after_step_javascript($event) {
global $CFG;

// Save a screenshot if the step failed.
if (!empty($CFG->behat_screenshots_path) &&
if (!empty($CFG->behat_faildump_path) &&
$event->getResult() === StepEvent::FAILED) {
$this->take_screenshot($event);
}
Expand All @@ -297,12 +297,29 @@ public function after_step_javascript($event) {
}

/**
* Getter for self::$screenshotsdirname
* Execute any steps required after the step has finished.
*
* This includes creating an HTML dump of the content if there was a failure.
*
* @AfterStep
*/
public function after_step($event) {
global $CFG;

// Save the page content if the step failed.
if (!empty($CFG->behat_faildump_path) &&
$event->getResult() === StepEvent::FAILED) {
$this->take_contentdump($event);
}
}

/**
* Getter for self::$faildumpdirname
*
* @return string
*/
protected function get_run_screenshots_dir() {
return self::$screenshotsdirname;
protected function get_run_faildump_dir() {
return self::$faildumpdirname;
}

/**
Expand All @@ -312,34 +329,61 @@ protected function get_run_screenshots_dir() {
* @param StepEvent $event
*/
protected function take_screenshot(StepEvent $event) {
global $CFG;

// Goutte can't save screenshots.
if (!$this->running_javascript()) {
return false;
}

// All the run screenshots in the same parent dir.
if (!$screenshotsdirname = self::get_run_screenshots_dir()) {
$screenshotsdirname = self::$screenshotsdirname = date('Ymd_His');
list ($dir, $filename) = $this->get_faildump_filename($event, 'png');
$this->saveScreenshot($filename, $dir);
}

/**
* Take a dump of the page content when a step fails.
*
* @throws Exception
* @param StepEvent $event
*/
protected function take_contentdump(StepEvent $event) {
list ($dir, $filename) = $this->get_faildump_filename($event, 'html');

$fh = fopen($dir . DIRECTORY_SEPARATOR . $filename, 'w');
fwrite($fh, $this->getSession()->getPage()->getContent());
fclose($fh);
}

/**
* Determine the full pathname to store a failure-related dump.
*
* This is used for content such as the DOM, and screenshots.
*
* @param StepEvent $event
* @param String $filetype The file suffix to use.
*/
protected function get_faildump_filename(StepEvent $event, $filetype) {
global $CFG;

// All the contentdumps should be in the same parent dir.
if (!$faildumpdir = self::get_run_faildump_dir()) {
$faildumpdir = self::$faildumpdirname = date('Ymd_His');

$dir = $CFG->behat_screenshots_path . DIRECTORY_SEPARATOR . $screenshotsdirname;
$dir = $CFG->behat_faildump_path . DIRECTORY_SEPARATOR . $faildumpdir;

if (!mkdir($dir, $CFG->directorypermissions, true)) {
if (!is_dir($dir) && !mkdir($dir, $CFG->directorypermissions, true)) {
// It shouldn't, we already checked that the directory is writable.
throw new Exception('No directories can be created inside $CFG->behat_screenshots_path, check the directory permissions.');
throw new Exception('No directories can be created inside $CFG->behat_faildump_path, check the directory permissions.');
}
} else {
// We will always need to know the full path.
$dir = $CFG->behat_screenshots_path . DIRECTORY_SEPARATOR . $screenshotsdirname;
$dir = $CFG->behat_faildump_path . DIRECTORY_SEPARATOR . $faildumpdir;
}

// The scenario title + the failed step text.
// We want a i-am-the-scenario-title_i-am-the-failed-step.png format.
// We want a i-am-the-scenario-title_i-am-the-failed-step.$filetype format.
$filename = $event->getStep()->getParent()->getTitle() . '_' . $event->getStep()->getText();
$filename = preg_replace('/([^a-zA-Z0-9\_]+)/', '-', $filename) . '.png';
$filename = preg_replace('/([^a-zA-Z0-9\_]+)/', '-', $filename) . '.' . $filetype;

$this->saveScreenshot($filename, $dir);
return array($dir, $filename);
}

/**
Expand Down Expand Up @@ -513,3 +557,4 @@ protected function throw_unknown_exception(UnknownError $exception) {
}

}

0 comments on commit 5ecfa56

Please sign in to comment.