/** * 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; }