diff --git a/README.md b/README.md index 75aae84..11b43bf 100644 --- a/README.md +++ b/README.md @@ -8,11 +8,6 @@ Behat 3 extension for generating HTML reports from your test results. ![Twig Screenshot](http://i.imgur.com/o0zCqiB.png) -### Behat 2 report - -![Behat2 Screenshot](http://i57.tinypic.com/287g942.jpg) - - ## How? * The tool can be installed easily with composer. diff --git a/src/Classes/Scenario.php b/src/Classes/Scenario.php index 7d422a7..869e326 100644 --- a/src/Classes/Scenario.php +++ b/src/Classes/Scenario.php @@ -198,14 +198,24 @@ public function getScreenshotPath() /** * Gets relative path for screenshot. * - * @return bool|string + * @return string */ public function getRelativeScreenshotPath() { - if (!file_exists($this->screenshotPath)) { - return false; + if (!$this->hasScreenshot()) { + return ''; } - return '.'.substr($this->screenshotPath, strpos($this->screenshotPath, '/assets/screenshots')); + return $this->hasScreenshotData() ? $this->screenshotPath : 'data:image/png;base64,' . base64_encode(file_get_contents($this->screenshotPath)); + } + + public function hasScreenshot() + { + return $this->hasScreenshotData() || file_exists($this->screenshotPath); + } + + public function hasScreenshotData() + { + return substr($this->screenshotPath, 0, 10) === 'data:image'; } } diff --git a/src/Context/ScreenshotContext.php b/src/Context/ScreenshotContext.php index 66546bc..4de41b2 100644 --- a/src/Context/ScreenshotContext.php +++ b/src/Context/ScreenshotContext.php @@ -6,22 +6,16 @@ class ScreenshotContext extends RawMinkContext { - private $currentScenario; - private $screenshotDir; - + private static $screenshotPath; + public function __construct($screenshotDir) { - $this->screenshotDir = $screenshotDir; + // $this->screenshotDir = $screenshotDir; } - /** - * @BeforeScenario - * - * @param BeforeScenarioScope $scope - */ - public function setUpTestEnvironment($scope) + public static function setScreenshotPath($screenshotPath) { - $this->currentScenario = $scope->getScenario(); + self::$screenshotPath = $screenshotPath; } /** @@ -35,18 +29,22 @@ public function afterStep($scope) if ($scope->getTestResult()->isPassed()) { return; } + if (!self::$screenshotPath) { + echo 'Screenshot path is empty!'; + return; + } // create filename string - $featureFolder = preg_replace('/\W/', '', $scope->getFeature()->getTitle()); - - $scenarioName = $this->currentScenario->getTitle(); - $fileName = preg_replace('/\W/', '', $scenarioName).'.png'; + $fileName = basename(self::$screenshotPath); + $screenshotDir = str_replace('/' . $fileName, '', self::$screenshotPath); // create screenshots directory if it doesn't exist - if (!file_exists($this->screenshotDir.'/'.$featureFolder)) { - mkdir($this->screenshotDir.'/'.$featureFolder); + if (!file_exists($screenshotDir)) { + mkdir($screenshotDir); } - $this->saveScreenshot($fileName, $this->screenshotDir.'/'.$featureFolder.'/'); + $this->saveScreenshot($fileName, $screenshotDir); + $file = $screenshotDir . '/' . $fileName; + echo file_exists($file) ? "Saved screenshot: $file" : "Cannot save screenshot: $file"; } } diff --git a/src/Formatter/BehatHTMLFormatter.php b/src/Formatter/BehatHTMLFormatter.php index 5514455..678d1c5 100644 --- a/src/Formatter/BehatHTMLFormatter.php +++ b/src/Formatter/BehatHTMLFormatter.php @@ -15,15 +15,16 @@ use Behat\Testwork\Counter\Memory; use Behat\Testwork\Counter\Timer; use Behat\Testwork\EventDispatcher\Event\AfterExerciseCompleted; -use Behat\Testwork\EventDispatcher\Event\AfterSuiteTested; use Behat\Testwork\EventDispatcher\Event\BeforeExerciseCompleted; use Behat\Testwork\EventDispatcher\Event\BeforeSuiteTested; +use Behat\Testwork\EventDispatcher\Event\SuiteTested; use Behat\Testwork\Output\Formatter; use Behat\Testwork\Output\Printer\OutputPrinter; use emuse\BehatHTMLFormatter\Classes\Feature; use emuse\BehatHTMLFormatter\Classes\Scenario; use emuse\BehatHTMLFormatter\Classes\Step; use emuse\BehatHTMLFormatter\Classes\Suite; +use emuse\BehatHTMLFormatter\Context\ScreenshotContext; use emuse\BehatHTMLFormatter\Printer\FileOutputPrinter; use emuse\BehatHTMLFormatter\Renderer\BaseRenderer; @@ -431,9 +432,9 @@ public function onBeforeSuiteTested(BeforeSuiteTested $event) } /** - * @param AfterSuiteTested $event + * @param SuiteTested $event */ - public function onAfterSuiteTested(AfterSuiteTested $event) + public function onAfterSuiteTested(SuiteTested $event) { $this->suites[] = $this->currentSuite; @@ -487,11 +488,11 @@ public function onBeforeScenarioTested(BeforeScenarioTested $event) $scenario->setLine($event->getScenario()->getLine()); $scenario->setScreenshotName($event->getScenario()->getTitle()); $scenario->setScreenshotPath( - $this->printer->getOutputPath(). - '/assets/screenshots/'. + '/tmp/'. preg_replace('/\W/', '', $event->getFeature()->getTitle()).'/'. preg_replace('/\W/', '', $event->getScenario()->getTitle()).'.png' ); + ScreenshotContext::setScreenshotPath($scenario->getScreenshotPath()); $this->currentScenario = $scenario; $print = $this->renderer->renderBeforeScenario($this); @@ -536,6 +537,12 @@ public function onBeforeOutlineTested(BeforeOutlineTested $event) $scenario->setName($event->getOutline()->getTitle()); $scenario->setTags($event->getOutline()->getTags()); $scenario->setLine($event->getOutline()->getLine()); + $scenario->setScreenshotName($event->getOutline()->getTitle()); + $scenario->setScreenshotPath( + '/tmp/'. + preg_replace('/\W/', '', $event->getFeature()->getTitle()).'/'. + preg_replace('/\W/', '', $event->getOutline()->getTitle()).'.png' + ); $this->currentScenario = $scenario; $print = $this->renderer->renderBeforeOutline($this); diff --git a/src/Printer/FileOutputPrinter.php b/src/Printer/FileOutputPrinter.php index 1289a3a..9cd88ee 100644 --- a/src/Printer/FileOutputPrinter.php +++ b/src/Printer/FileOutputPrinter.php @@ -39,7 +39,7 @@ public function __construct($rendererList, $filename, $base_path) foreach ($rendererList as $renderer) { if ('generated' == $filename) { $date = date('YmdHis'); - $this->rendererFiles[$renderer] = $renderer.'_'.$date; + $this->rendererFiles[$renderer] = $renderer . '_' . $date; } else { $this->rendererFiles[$renderer] = $filename; } @@ -60,22 +60,22 @@ public function setOutputPath($path) if (!file_exists($outpath)) { if (!mkdir($outpath, 0755, true)) { throw new BadOutputPathException( - sprintf( - 'Output path %s does not exist and could not be created!', - $outpath - ), - $outpath - ); + sprintf( + 'Output path %s does not exist and could not be created!', + $outpath + ), + $outpath + ); } } else { if (!is_dir(realpath($outpath))) { throw new BadOutputPathException( - sprintf( - 'The argument to `output` is expected to the a directory, but got %s!', - $outpath - ), - $outpath - ); + sprintf( + 'The argument to `output` is expected to the a directory, but got %s!', + $outpath + ), + $outpath + ); } } $this->outputPath = $outpath; @@ -155,7 +155,7 @@ public function write($messages = array()) { //Write it for each message = each renderer foreach ($messages as $key => $message) { - $file = $this->outputPath.DIRECTORY_SEPARATOR.$this->rendererFiles[$key].'.html'; + $file = $this->outputPath . DIRECTORY_SEPARATOR . $this->rendererFiles[$key] . '.html'; file_put_contents($file, $message); $this->copyAssets($key); } @@ -170,7 +170,7 @@ public function writeln($messages = array()) { //Write it for each message = each renderer foreach ($messages as $key => $message) { - $file = $this->outputPath.DIRECTORY_SEPARATOR.$this->rendererFiles[$key].'.html'; + $file = $this->outputPath . DIRECTORY_SEPARATOR . $this->rendererFiles[$key] . '.html'; file_put_contents($file, $message, FILE_APPEND); } } @@ -184,9 +184,9 @@ public function writeBeginning($messages = array()) { //Write it for each message = each renderer foreach ($messages as $key => $message) { - $file = $this->outputPath.DIRECTORY_SEPARATOR.$this->rendererFiles[$key].'.html'; + $file = $this->outputPath . DIRECTORY_SEPARATOR . $this->rendererFiles[$key] . '.html'; $fileContents = file_get_contents($file); - file_put_contents($file, $message.$fileContents); + file_put_contents($file, $message . $fileContents); } } @@ -199,17 +199,20 @@ public function copyAssets($renderer) { // If the assets folder doesn' exist in the output path for this renderer, copy it $source = realpath(dirname(__FILE__)); - $assets_source = realpath($source.'/../../assets/'.$renderer); + $assets_source = realpath($source . '/../../assets/' . $renderer); if (false === $assets_source) { //There is no assets to copy for this renderer return; } //first create the assets dir - $destination = $this->outputPath.DIRECTORY_SEPARATOR.'assets'; - @mkdir($destination); + $destination = $this->outputPath . DIRECTORY_SEPARATOR . 'assets'; - $this->recurse_copy($assets_source, $destination.DIRECTORY_SEPARATOR.$renderer); + if (!file_exists($destination)) { + mkdir($destination); + } + + $this->recurse_copy($assets_source, $destination . DIRECTORY_SEPARATOR . $renderer); } /** @@ -221,13 +224,16 @@ public function copyAssets($renderer) private function recurse_copy($src, $dst) { $dir = opendir($src); - @mkdir($dst); + if (!file_exists($dst)) { + mkdir($dst); + } + while (false !== ($file = readdir($dir))) { if (('.' != $file) && ('..' != $file)) { - if (is_dir($src.'/'.$file)) { - $this->recurse_copy($src.'/'.$file, $dst.'/'.$file); + if (is_dir($src . '/' . $file)) { + $this->recurse_copy($src . '/' . $file, $dst . '/' . $file); } else { - copy($src.'/'.$file, $dst.'/'.$file); + copy($src . '/' . $file, $dst . '/' . $file); } } } diff --git a/src/Renderer/TwigRenderer.php b/src/Renderer/TwigRenderer.php index c86659d..baf2436 100644 --- a/src/Renderer/TwigRenderer.php +++ b/src/Renderer/TwigRenderer.php @@ -3,8 +3,8 @@ namespace emuse\BehatHTMLFormatter\Renderer; use emuse\BehatHTMLFormatter\Formatter\BehatHTMLFormatter; -use Twig_Environment; -use Twig_Loader_Filesystem; +use Twig\Environment; +use Twig\Loader\FilesystemLoader; /** * Twig renderer for Behat report. @@ -35,8 +35,8 @@ public function renderBeforeExercise(BehatHTMLFormatter $obj) public function renderAfterExercise(BehatHTMLFormatter $obj) { $templatePath = dirname(__FILE__).'/../../templates'; - $loader = new Twig_Loader_Filesystem($templatePath); - $twig = new Twig_Environment($loader, array()); + $loader = new FilesystemLoader($templatePath); + $twig = new Environment($loader, array()); $print = $twig->render('index.html.twig', array( 'suites' => $obj->getSuites(), diff --git a/templates/index.html.twig b/templates/index.html.twig index 57e2505..1926a8a 100644 --- a/templates/index.html.twig +++ b/templates/index.html.twig @@ -193,7 +193,7 @@ {% for tag in scenario.tags %} {{ tag }} {% endfor %} - {% if scenario.getRelativeScreenshotPath() %} + {% if scenario.hasScreenshot() %} Screenshot {% endif %}