/**
  * Executes provided step definition.
  *
  * If the result is not a failure then take a screenshot and compare for differences.
  *
  * @param StepNode $step
  * @param DefinitionInterface $definition
  * @throws PerceptualDiffException If there are differences compared to the baseline
  */
 protected function executeStepDefinition(StepNode $step, DefinitionInterface $definition)
 {
     parent::executeStepDefinition($step, $definition);
     $session = $this->context->getSession();
     // give JavaScript time to trigger additional ajax requests after onload
     $session->wait(100);
     // Wait for an ajax request to complete, but only for a maximum of X seconds to avoid deadlocks
     $session->wait(5000, "(typeof window.__ajaxStatus !== 'undefined' ? window.__ajaxStatus() : 'no ajax') !== 'waiting'");
     // The 'sleep' config setting will be respected in the comparator logic,
     // and is required to be at least ~200ms to give the browser a chance to finish rendering
     $diff = $this->screenshotComparator->takeScreenshot($this->context, $step);
     if ($diff > 0 && $this->failOnDiff) {
         // There were differences between the two screenshots
         throw new PerceptualDiffException(sprintf('There was a perceptual difference of %d', $diff));
     }
 }
 /**
  * Takes a screenshot if the step passes and compares it to the baseline
  *
  * @param ContextInterface $context
  * @param StepNode $step
  */
 public function takeScreenshot(ContextInterface $context, StepNode $step)
 {
     // Increment the step number
     $this->stepNumber++;
     if ($this->sleep > 0) {
         // Convert seconds to microseconds
         usleep($this->sleep * 1000000);
     }
     $screenshotPath = $this->getScreenshotPath();
     $screenshotFile = $screenshotPath . $this->getFilepath($step);
     $this->ensureDirectoryExists($screenshotFile);
     // Save the screenshot
     file_put_contents($screenshotFile, $context->getSession()->getScreenshot());
     // Comparison
     $baselinePath = $this->getBaselinePath();
     $diffPath = $this->getDiffPath();
     $baselineFile = str_replace($screenshotPath, $baselinePath, $screenshotFile);
     if (!is_file($baselineFile)) {
         $this->ensureDirectoryExists($baselineFile);
         // New step, move into the baseline but return as there is no need for a comparison
         copy($screenshotFile, $baselineFile);
         return;
     }
     // Output the comparison to a temp file
     $tempFile = $this->path . '/temp.png';
     // Run the comparison
     $output = array();
     exec($this->getCompareCommand($baselineFile, $screenshotFile, $tempFile), $output, $return);
     if ($return === 0 || $return === 1) {
         // Check that there are some differences
         if ($return === 1) {
             $diffFile = str_replace($screenshotPath, $diffPath, $screenshotFile);
             $this->ensureDirectoryExists($diffFile);
             // Store the diff
             rename($tempFile, $diffFile);
             // Record the diff for output
             $this->diffs[spl_object_hash($step)] = $this->getFilepath($step);
         } elseif (is_file($tempFile)) {
             // Clean up the temp file
             unlink($tempFile);
         }
         return $output[0];
     }
     return false;
 }