芝麻web文件管理V1.00
编辑当前文件:/home2/sdektunc/xmintal-back/vendor/codeception/codeception/ext/Recorder.php
login(); * $I->amOnUrl('https://codeception.com'); * } * ``` * */ class Recorder extends \Codeception\Extension { /** @var array */ protected $config = [ 'delete_successful' => true, 'module' => 'WebDriver', 'template' => null, 'animate_slides' => true, 'ignore_steps' => [], 'success_color' => 'success', 'failure_color' => 'danger', 'error_color' => 'dark', 'delete_orphaned' => false, 'include_microseconds' => false, ]; /** @var string */ protected $template = <<
Recorder Result
Recorded Tests
{{feature}}
{{test}}
{{indicators}}
{{slides}}
Previous
Next
EOF; /** @var string */ protected $indicatorTemplate = <<
EOF; /** @var string */ protected $indexTemplate = <<
Recorder Results Index
Recorded Tests
Record #{{seed}}
{{records}}
EOF; /** @var string */ protected $slidesTemplate = <<
{{caption}}
Step finished at
"{{timeStamp}}"
EOF; /** @var array */ public static $events = [ Events::SUITE_BEFORE => 'beforeSuite', Events::SUITE_AFTER => 'afterSuite', Events::TEST_BEFORE => 'before', Events::TEST_ERROR => 'persist', Events::TEST_FAIL => 'persist', Events::TEST_SUCCESS => 'cleanup', Events::STEP_AFTER => 'afterStep', ]; /** @var WebDriver */ protected $webDriverModule; /** @var string */ protected $dir; /** @var array */ protected $slides = []; /** @var int */ protected $stepNum = 0; /** @var string */ protected $seed; /** @var array */ protected $seeds; /** @var array */ protected $recordedTests = []; /** @var array */ protected $skipRecording = []; /** @var array */ protected $errorMessages = []; /** @var bool */ protected $colors; /** @var bool */ protected $ansi; /** @var array */ protected $timeStamps = []; /** @var string */ private $dateFormat; public function beforeSuite() { $this->webDriverModule = null; if (!$this->hasModule($this->config['module'])) { $this->writeln('Recorder is disabled, no available modules'); return; } $this->seed = uniqid(); $this->seeds[] = $this->seed; $this->webDriverModule = $this->getModule($this->config['module']); $this->skipRecording = []; $this->errorMessages = []; $this->dateFormat = $this->config['include_microseconds'] ? 'Y-m-d\TH:i:s.uP' : DATE_ATOM; $this->ansi = !isset($this->options['no-ansi']); $this->colors = !isset($this->options['no-colors']); if (!$this->webDriverModule instanceof ScreenshotSaver) { throw new ExtensionException( $this, 'You should pass module which implements ' . ScreenshotSaver::class . ' interface' ); } $this->writeln( sprintf( '⏺
Recording
⏺ step-by-step screenshots will be saved to
%s
', codecept_output_dir() ) ); $this->writeln("Directory Format:
record_{$this->seed}_{filename}_{testname}
----"); } public function afterSuite() { if (!$this->webDriverModule) { return; } $links = ''; if (count($this->slides)) { foreach ($this->recordedTests as $suiteName => $suite) { $links .= "
{$suiteName}
"; foreach ($suite as $fileName => $tests) { $links .= "
{$fileName}
"; foreach ($tests as $test) { $links .= in_array($test['path'], $this->skipRecording, true) ? "
config['error_color']}\">{$test['name']}
\n" : '
{$test['name']}
\n"; } $links .= '
'; } $links .= '
'; } $indexHTML = (new Template($this->indexTemplate)) ->place('seed', $this->seed) ->place('records', $links) ->produce(); try { file_put_contents(codecept_output_dir() . 'records.html', $indexHTML); } catch (\Exception $exception) { $this->writeln( "⏺ An exception occurred while saving records.html:
{$exception->getMessage()}
" ); } $this->writeln('⏺ Records saved into:
file://' . codecept_output_dir() . 'records.html
'); } foreach ($this->errorMessages as $message) { $this->writeln($message); } } /** * @param TestEvent $e */ public function before(TestEvent $e) { if (!$this->webDriverModule) { return; } $this->dir = null; $this->stepNum = 0; $this->slides = []; $this->timeStamps = []; $this->dir = codecept_output_dir() . "record_{$this->seed}_{$this->getTestName($e)}"; $testPath = codecept_relative_path(Descriptor::getTestFullName($e->getTest())); try { !is_dir($this->dir) && !mkdir($this->dir) && !is_dir($this->dir); } catch (\Exception $exception) { $this->skipRecording[] = $testPath; $this->appendErrorMessage( $testPath, "⏺ An exception occurred while creating directory:
{$this->dir}
" ); } } /** * @param TestEvent $e */ public function cleanup(TestEvent $e) { if ($this->config['delete_orphaned']) { $recordingDirectories = []; $directories = new \DirectoryIterator(codecept_output_dir()); // getting a list of currently present recording directories foreach ($directories as $directory) { preg_match('/^record_(.*?)_[^\n]+.php_[^\n]+$/', $directory->getFilename(), $match); if (isset($match[1])) { $recordingDirectories[$match[1]][] = codecept_output_dir() . $directory->getFilename(); } } // removing orphaned recording directories foreach (array_diff(array_keys($recordingDirectories), $this->seeds) as $orphanedSeed) { foreach ($recordingDirectories[$orphanedSeed] as $orphanedDirectory) { FileSystem::deleteDir($orphanedDirectory); } } } if (!$this->webDriverModule || !$this->dir) { return; } if (!$this->config['delete_successful']) { $this->persist($e); return; } // deleting successfully executed tests FileSystem::deleteDir($this->dir); } /** * @param TestEvent $e */ public function persist(TestEvent $e) { if (!$this->webDriverModule) { return; } $indicatorHtml = ''; $slideHtml = ''; $testName = $this->getTestName($e); $testPath = codecept_relative_path(Descriptor::getTestFullName($e->getTest())); $dir = codecept_output_dir() . "record_{$this->seed}_$testName"; $status = 'success'; if (strcasecmp($this->dir, $dir) !== 0) { $filename = str_pad(0, 3, '0', STR_PAD_LEFT) . '.png'; try { !is_dir($dir) && !mkdir($dir) && !is_dir($dir); $this->dir = $dir; } catch (\Exception $exception) { $this->skipRecording[] = $testPath; $this->appendErrorMessage( $testPath, "⏺ An exception occurred while creating directory:
{$dir}
" ); } $this->slides = []; $this->timeStamps = []; $this->slides[$filename] = new Step\Action('encountered an unexpected error prior to the test execution'); $this->timeStamps[$filename] = (new \DateTime())->format($this->dateFormat); $status = 'error'; try { if ($this->webDriverModule->webDriver === null) { throw new ExtensionException($this, 'Failed to save screenshot as webDriver is not set'); } $this->webDriverModule->webDriver->takeScreenshot($this->dir . DIRECTORY_SEPARATOR . $filename); } catch (\Exception $exception) { $this->appendErrorMessage( $testPath, "⏺ Unable to capture a screenshot for
{$testPath}/before
" ); } } if (!in_array($testPath, $this->skipRecording, true)) { foreach ($this->slides as $i => $step) { /** @var Step $step */ if ($step->hasFailed()) { $status = 'failure'; } $indicatorHtml .= (new Template($this->indicatorTemplate)) ->place('step', (int)$i) ->place('isActive', (int)$i ? '' : 'active') ->produce(); $slideHtml .= (new Template($this->slidesTemplate)) ->place('image', $i) ->place('caption', $step->getHtml('#3498db')) ->place('isActive', (int)$i ? '' : 'active') ->place('isError', $status === 'success' ? '' : 'error') ->place('timeStamp', $this->timeStamps[$i]) ->produce(); } $html = (new Template($this->template)) ->place('indicators', $indicatorHtml) ->place('slides', $slideHtml) ->place('feature', ucfirst($e->getTest()->getFeature())) ->place('test', Descriptor::getTestSignature($e->getTest())) ->place('carousel_class', $this->config['animate_slides'] ? ' slide' : '') ->produce(); $indexFile = $this->dir . DIRECTORY_SEPARATOR . 'index.html'; $environment = $e->getTest()->getMetadata()->getCurrent('env') ?: ''; $suite = ucfirst(basename(\dirname($e->getTest()->getMetadata()->getFilename()))); $testName = basename($e->getTest()->getMetadata()->getFilename()); try { file_put_contents($indexFile, $html); } catch (\Exception $exception) { $this->skipRecording[] = $testPath; $this->appendErrorMessage( $testPath, "⏺ An exception occurred while saving index.html for
{$testPath}: " . "{$exception->getMessage()}
" ); } $this->recordedTests["{$suite} ({$environment})"][$testName][] = [ 'name' => $e->getTest()->getMetadata()->getName(), 'path' => $testPath, 'status' => $status, 'index' => substr($indexFile, strlen(codecept_output_dir())), ]; } } /** * @param StepEvent $e */ public function afterStep(StepEvent $e) { if ($this->webDriverModule === null || $this->dir === null) { return; } if ($e->getStep() instanceof CommentStep) { return; } // only taking the ignore step into consideration if that step has passed if ($this->isStepIgnored($e) && !$e->getStep()->hasFailed()) { return; } $filename = str_pad($this->stepNum, 3, '0', STR_PAD_LEFT) . '.png'; try { if ($this->webDriverModule->webDriver === null) { throw new ExtensionException($this, 'Failed to save screenshot as webDriver is not set'); } $this->webDriverModule->webDriver->takeScreenshot($this->dir . DIRECTORY_SEPARATOR . $filename); } catch (\Exception $exception) { $testPath = codecept_relative_path(Descriptor::getTestFullName($e->getTest())); $this->appendErrorMessage( $testPath, "⏺ Unable to capture a screenshot for
{$testPath}/{$e->getStep()->getAction()}
" ); } $this->stepNum++; $this->slides[$filename] = $e->getStep(); $this->timeStamps[$filename] = (new \DateTime())->format($this->dateFormat); } /** * @param StepEvent $e * * @return bool */ protected function isStepIgnored(StepEvent $e) { $configIgnoredSteps = $this->config['ignore_steps']; $annotationIgnoredSteps = $e->getTest()->getMetadata()->getParam('skipRecording'); $ignoredSteps = array_unique( array_merge( $configIgnoredSteps, is_array($annotationIgnoredSteps) ? $annotationIgnoredSteps : [] ) ); foreach ($ignoredSteps as $stepPattern) { $stepRegexp = '/^' . str_replace('*', '.*?', $stepPattern) . '$/i'; if (preg_match($stepRegexp, $e->getStep()->getAction())) { return true; } if ($e->getStep()->getMetaStep() !== null && preg_match($stepRegexp, $e->getStep()->getMetaStep()->getAction()) ) { return true; } } return false; } /** * @param StepEvent|TestEvent $e * * @return string */ private function getTestName($e) { return basename($e->getTest()->getMetadata()->getFilename()) . '_' . preg_replace('/[^A-Za-z0-9\-\_]/', '_', $e->getTest()->getMetadata()->getName()); } /** * @param string $message */ protected function writeln($message) { parent::writeln( $this->ansi ? $message : trim(preg_replace('/[ ]{2,}/', ' ', str_replace('⏺', '', $message))) ); } /** * @param string $testPath * @param string $message */ private function appendErrorMessage($testPath, $message) { $this->errorMessages[$testPath] = array_merge( array_key_exists($testPath, $this->errorMessages) ? $this->errorMessages[$testPath]: [], [$message] ); } }