From 3ec07614ba4b1a0320b7b0165b1b0f210cbb0608 Mon Sep 17 00:00:00 2001 From: Damyon Wiese Date: Wed, 18 Dec 2013 16:13:46 +0800 Subject: [PATCH 1/2] MDL-43439: Behat - new $CFG param - behat_screenshot_after_failure --- lib/tests/behat/behat_hooks.php | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/lib/tests/behat/behat_hooks.php b/lib/tests/behat/behat_hooks.php index 2478e7813d8..430ed4f13d5 100644 --- a/lib/tests/behat/behat_hooks.php +++ b/lib/tests/behat/behat_hooks.php @@ -278,6 +278,21 @@ class behat_hooks extends behat_base { } } + /** + * Take screenshot when step fails. + * Screenshot is saved at /tmp/ + * + * @AfterStep + */ + public function take_screenshot_after_failed_step(Behat\Behat\Event\StepEvent $event) { + global $CFG; + + if (!empty($CFG->behat_screenshot_after_failure) && + $event->getResult() === Behat\Behat\Event\StepEvent::FAILED) { + $this->saveScreenshot(); + } + } + /** * Waits for all the JS to be loaded. * From 5c0dfe32ebd85e5bf1e14e97f06be235acd3a7fd Mon Sep 17 00:00:00 2001 From: David Monllao Date: Mon, 6 Jan 2014 16:33:11 +0800 Subject: [PATCH 2/2] MDL-43439 behat: Save the screenshots to the specified location --- config-dist.php | 4 +++ lib/tests/behat/behat_hooks.php | 63 +++++++++++++++++++++++++++++---- 2 files changed, 60 insertions(+), 7 deletions(-) diff --git a/config-dist.php b/config-dist.php index 964a646a56c..6733547e12c 100644 --- a/config-dist.php +++ b/config-dist.php @@ -654,6 +654,10 @@ $CFG->admin = 'admin'; // Example: // $CFG->behat_additionalfeatures = array('/home/developer/code/wipfeatures'); // +// You can make behat save a screenshot when a scenario fails. +// Example: +// $CFG->behat_screenshots_path = '/my/path/to/save/screenshots'; +// //========================================================================= // 12. DEVELOPER DATA GENERATOR //========================================================================= diff --git a/lib/tests/behat/behat_hooks.php b/lib/tests/behat/behat_hooks.php index 430ed4f13d5..a4c76ac3f78 100644 --- a/lib/tests/behat/behat_hooks.php +++ b/lib/tests/behat/behat_hooks.php @@ -77,6 +77,13 @@ 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. + * + * @var The parent dir name + */ + protected static $screenshotsdirname = false; + /** * Gives access to moodle codebase, ensures all is ready and sets up the test lock. * @@ -134,6 +141,10 @@ class behat_hooks extends behat_base { // Store the initial browser session opening. 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'); + } } /** @@ -258,6 +269,13 @@ class behat_hooks extends behat_base { * @AfterStep @javascript */ public function after_step_javascript($event) { + global $CFG; + + // Save a screenshot if the step failed. + if (!empty($CFG->behat_screenshots_path) && + $event->getResult() === StepEvent::FAILED) { + $this->take_screenshot($event); + } try { $this->wait_for_pending_js(); @@ -279,18 +297,49 @@ class behat_hooks extends behat_base { } /** - * Take screenshot when step fails. - * Screenshot is saved at /tmp/ + * Getter for self::$screenshotsdirname * - * @AfterStep + * @return string */ - public function take_screenshot_after_failed_step(Behat\Behat\Event\StepEvent $event) { + protected function get_run_screenshots_dir() { + return self::$screenshotsdirname; + } + + /** + * Take screenshot when a step fails. + * + * @throws Exception + * @param StepEvent $event + */ + protected function take_screenshot(StepEvent $event) { global $CFG; - if (!empty($CFG->behat_screenshot_after_failure) && - $event->getResult() === Behat\Behat\Event\StepEvent::FAILED) { - $this->saveScreenshot(); + // 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('Y-m-d_Hi'); + + $dir = $CFG->behat_screenshots_path . DIRECTORY_SEPARATOR . $screenshotsdirname; + + if (!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.'); + } + } else { + // We will always need to know the full path. + $dir = $CFG->behat_screenshots_path . DIRECTORY_SEPARATOR . $screenshotsdirname; + } + + // The scenario title + the failed step text. + // We want a i-am-the-scenario-title_i-am-the-failed-step.png format. + $filename = $event->getStep()->getParent()->getTitle() . '_' . $event->getStep()->getText(); + $filename = preg_replace('/([^a-zA-Z0-9\_]+)/', '-', $filename) . '.png'; + + $this->saveScreenshot($filename, $dir); } /**