diff --git a/README.md b/README.md index 7ef0772..2565292 100644 --- a/README.md +++ b/README.md @@ -22,12 +22,13 @@ default: suites: default: contexts: - - IntegratedExperts\BehatScreenshot\ScreenshotContext: - - - dir: %paths.base%/screenshots - fail: true - purge: false - - FeatureContext + - IntegratedExperts\BehatScreenshot\ScreenshotContext + - FeatureContext + extensions: + IntegratedExperts\BehatScreenshot\ScreenshotExtension: + dir: %paths.base%/screenshots + fail: true + purge: false ``` In your feature: diff --git a/behat.yml b/behat.yml index dfbcf84..837d137 100644 --- a/behat.yml +++ b/behat.yml @@ -7,11 +7,7 @@ default: - IntegratedExperts\BehatPhpServer\PhpServerContext: - docroot: %paths.base%/tests/behat/features/fixtures - - IntegratedExperts\BehatScreenshot\ScreenshotContext: - - - dir: %paths.base%/screenshots - fail: false - purge: true + - IntegratedExperts\Behat\Screenshot\Context\ScreenshotContext - FeatureContext: - screenshot_dir: %paths.base%/screenshots @@ -21,3 +17,7 @@ default: files_path: %paths.base%/tests/behat/features/fixtures selenium2: ~ browser_name: chrome + IntegratedExperts\Behat\Screenshot\ScreenshotExtension: + dir: %paths.base%/screenshots + fail: false + purge: true \ No newline at end of file diff --git a/circle.yml b/circle.yml index cebcef9..b5ea999 100644 --- a/circle.yml +++ b/circle.yml @@ -18,4 +18,3 @@ test: override: - composer cs - composer test - - BEHAT_SCREENSHOT_DIR=$CIRCLE_ARTIFACTS/behat composer test diff --git a/composer.json b/composer.json index 96fe5d5..03a8de0 100644 --- a/composer.json +++ b/composer.json @@ -29,7 +29,7 @@ }, "autoload": { "psr-0": { - "IntegratedExperts\\BehatScreenshot": "src/" + "IntegratedExperts\\Behat\\Screenshot": "src/" } }, "scripts": { diff --git a/src/IntegratedExperts/Behat/Screenshot/Context/Initializer/ScreenshotContextInitializer.php b/src/IntegratedExperts/Behat/Screenshot/Context/Initializer/ScreenshotContextInitializer.php new file mode 100644 index 0000000..5fc4ae2 --- /dev/null +++ b/src/IntegratedExperts/Behat/Screenshot/Context/Initializer/ScreenshotContextInitializer.php @@ -0,0 +1,90 @@ +toPurge = true; + $this->dir = $dir; + $this->fail = $fail; + $this->purge = $purge; + } + + /** + * {@inheritdoc} + */ + public function initializeContext(Context $context) + { + if ($context instanceof ScreenshotContextInterface) { + $context->setParameters($this->dir, $this->fail); + // Calling clearing screenshot directory function. + if ($this->purge && $this->toPurge) { + $this->purgeFilesInDir(); + $this->toPurge = false; + } + } + } + + /** + * Remove files in directory. + */ + protected function purgeFilesInDir() + { + $fs = new Filesystem(); + $finder = new Finder(); + if ($fs->exists($this->dir)) { + $fs->remove($finder->files()->in($this->dir)); + } + } +} diff --git a/src/IntegratedExperts/BehatScreenshot/ScreenshotContext.php b/src/IntegratedExperts/Behat/Screenshot/Context/ScreenshotContext.php similarity index 53% rename from src/IntegratedExperts/BehatScreenshot/ScreenshotContext.php rename to src/IntegratedExperts/Behat/Screenshot/Context/ScreenshotContext.php index eceed12..aea591c 100644 --- a/src/IntegratedExperts/BehatScreenshot/ScreenshotContext.php +++ b/src/IntegratedExperts/Behat/Screenshot/Context/ScreenshotContext.php @@ -5,7 +5,7 @@ * Behat context to enable Screenshot support in tests. */ -namespace IntegratedExperts\BehatScreenshot; +namespace IntegratedExperts\Behat\Screenshot\Context; use Behat\Behat\Context\SnippetAcceptingContext; use Behat\Behat\Hook\Scope\AfterStepScope; @@ -13,15 +13,12 @@ use Behat\Behat\Hook\Scope\BeforeStepScope; use Behat\Mink\Driver\Selenium2Driver; use Behat\MinkExtension\Context\RawMinkContext; -use Behat\Testwork\Hook\Scope\BeforeSuiteScope; use Symfony\Component\Filesystem\Filesystem; -use Symfony\Component\Finder\Finder; -use Symfony\Component\Yaml\Exception\RuntimeException; /** * Class ScreenshotContext. */ -class ScreenshotContext extends RawMinkContext implements SnippetAcceptingContext +class ScreenshotContext extends RawMinkContext implements SnippetAcceptingContext, ScreenshotContextInterface { /** @@ -39,51 +36,28 @@ class ScreenshotContext extends RawMinkContext implements SnippetAcceptingContex protected $stepLine; /** - * Directory where screenshots are stored. + * Screenshot directory name. * * @var string */ - protected $dir; + private $dir; /** - * Flag to create a screenshot when test fails. + * Makes screenshot when fail. * * @var bool */ - protected $onFail; + private $fail; /** - * Initializes context. - * - * Every scenario gets its own context instance. - * You can also pass arbitrary arguments to the context constructor through - * behat.yml. - * - * @param array $parameters Get parameters for construct test. - */ - public function __construct($parameters = []) - { - $this->dir = $this->extractParameterFromEnv('BEHAT_SCREENSHOT_DIR', $parameters['dir']); - $this->onFail = isset($parameters['fail']) ? $parameters['fail'] : true; - } - - /** - * Init function before tests run. - * - * @param BeforeSuiteScope $scope - * - * @BeforeSuite + * {@inheritdoc} */ - public static function beforeSuitInit(BeforeSuiteScope $scope) + public function setParameters($dir, $fail) { - $contextSettings = self::getSettingsFromScope($scope); + $this->dir = $dir; + $this->fail = $fail; - $dir = self::extractParameterFromEnv('BEHAT_SCREENSHOT_DIR', $contextSettings['dir']); - $purge = self::extractParameterFromEnv('BEHAT_SCREENSHOT_PURGE', $contextSettings['purge'], false); - - if ($purge) { - self::purgeFilesInDir($dir); - } + return $this; } /** @@ -124,8 +98,8 @@ public function beforeStepInit(BeforeStepScope $scope) */ public function printLastResponseOnError(AfterStepScope $event) { - if ($this->onFail && !$event->getTestResult()->isPassed()) { - $this->saveDebugScreenshot(); + if ($this->fail && !$event->getTestResult()->isPassed()) { + $this->iSaveScreenshot(); } } @@ -137,7 +111,7 @@ public function printLastResponseOnError(AfterStepScope $event) * @When save screenshot * @When I save screenshot */ - public function saveDebugScreenshot() + public function iSaveScreenshot() { $data = null; $driver = $this->getSession()->getDriver(); @@ -155,28 +129,24 @@ public function saveDebugScreenshot() } } - protected function saveScreenshotData($filename, $data) - { - $this->prepareDir($this->dir); - file_put_contents($this->dir.DIRECTORY_SEPARATOR.$filename, $data); - } - /** - * Make screenshot filename. - * - * Format: microseconds.featurefilename_linenumber.ext - * - * @param string $ext File extension without dot. + * Save screenshot data into a file. * - * @return string Unique file name. + * @param string $filename + * File name to write. + * @param string $data + * Data to write into a file. */ - protected function makeFileName($ext) + protected function saveScreenshotData($filename, $data) { - return sprintf('%01.2f.%s_[%s].%s', microtime(true), basename($this->featureFile), $this->stepLine, $ext); + $this->prepareDir($this->dir); + file_put_contents($this->dir.DIRECTORY_SEPARATOR.$filename, $data); } /** * Prepare directory. + * + * @param string $dir Name of preparing directory. */ protected function prepareDir($dir) { @@ -185,49 +155,16 @@ protected function prepareDir($dir) } /** - * Remove files in directory. + * Make screenshot filename. * - * @param string $dir Directory name. - */ - protected static function purgeFilesInDir($dir) - { - $fs = new Filesystem(); - $finder = new Finder(); - if ($fs->exists($dir)) { - $fs->remove($finder->files()->in($dir)); - } - } - - /** - * Extract parameter from the list of provided parameters. - */ - protected static function extractParameterFromEnv() - { - $candidates = func_get_args(); - $candidates[0] = getenv($candidates[0]) === false ? null : getenv($candidates[0]); - - foreach ($candidates as $candidate) { - if (isset($candidate)) { - return $candidate; - } - } - - throw new RuntimeException('One of the parameters was not provided'); - } - - /** - * Extarct settings from scope. + * Format: microseconds.featurefilename_linenumber.ext + * + * @param string $ext File extension without dot. + * + * @return string Unique file name. */ - protected static function getSettingsFromScope(BeforeSuiteScope $scope) + protected function makeFileName($ext) { - $settings = null; - foreach ($scope->getSuite()->getSetting('contexts') as $context) { - if (is_array($context) && isset($context['IntegratedExperts\BehatScreenshot\ScreenshotContext'][0])) { - $settings = $context['IntegratedExperts\BehatScreenshot\ScreenshotContext'][0]; - break; - } - } - - return $settings; + return sprintf('%01.2f.%s_[%s].%s', microtime(true), basename($this->featureFile), $this->stepLine, $ext); } } diff --git a/src/IntegratedExperts/Behat/Screenshot/Context/ScreenshotContextInterface.php b/src/IntegratedExperts/Behat/Screenshot/Context/ScreenshotContextInterface.php new file mode 100644 index 0000000..5a4213f --- /dev/null +++ b/src/IntegratedExperts/Behat/Screenshot/Context/ScreenshotContextInterface.php @@ -0,0 +1,27 @@ +children() + ->scalarNode('dir')->cannotBeEmpty()->end() + ->scalarNode('fail')->cannotBeEmpty()->end() + ->scalarNode('purge')->cannotBeEmpty()->end(); + } + + /** + * {@inheritdoc} + */ + public function load(ContainerBuilder $container, array $config) + { + if (!isset($config['dir'])) { + throw new RuntimeException('Parameter dir is not determine in behat config.'); + } elseif (!isset($config['fail'])) { + throw new RuntimeException('Parameter fail is not determine in behat config.'); + } elseif (!isset($config['purge'])) { + throw new RuntimeException('Parameter purge is not determine in behat config.'); + } else { + $definition = new Definition('IntegratedExperts\Behat\Screenshot\Context\Initializer\ScreenshotContextInitializer', [ + $config['dir'], + $config['fail'], + $config['purge'], + ]); + $definition->addTag(ContextExtension::INITIALIZER_TAG, ['priority' => 0]); + $container->setDefinition('integratedexperts_screenshot.screenshot_context_initializer', $definition); + } + } +} diff --git a/tests/behat/bootstrap/FeatureContext.php b/tests/behat/bootstrap/FeatureContext.php index 80101cf..a22a003 100644 --- a/tests/behat/bootstrap/FeatureContext.php +++ b/tests/behat/bootstrap/FeatureContext.php @@ -13,6 +13,7 @@ */ class FeatureContext extends MinkContext implements Context { + /** * @var string $screenshotDir Directory where screenshots are stored. */