diff --git a/src/Codeception/Step.php b/src/Codeception/Step.php index 95ed38580c..035d1ed7d1 100644 --- a/src/Codeception/Step.php +++ b/src/Codeception/Step.php @@ -79,6 +79,9 @@ public function getAction() return $this->action; } + /** + * @deprecated To be removed in Codeception 5.0 + */ public function getLine() { if ($this->line && $this->file) { @@ -86,6 +89,20 @@ public function getLine() } } + public function getFilePath() + { + if ($this->file) { + return codecept_relative_path($this->file); + } + } + + public function getLineNumber() + { + if ($this->line) { + return $this->line; + } + } + public function hasFailed() { return $this->failed; diff --git a/src/Codeception/Subscriber/Console.php b/src/Codeception/Subscriber/Console.php index ba54264eaf..30bb167b63 100644 --- a/src/Codeception/Subscriber/Console.php +++ b/src/Codeception/Subscriber/Console.php @@ -165,7 +165,7 @@ public function startTest(TestEvent $e) $this->printedTest = $test; $this->message = null; - if (!$this->output->isInteractive() and !$this->isDetailed($test)) { + if (!$this->output->isInteractive() && !$this->isDetailed($test)) { return; } $this->writeCurrentTest($test); @@ -207,7 +207,7 @@ public function afterStep(StepEvent $e) public function afterResult(PrintResultEvent $event) { $result = $event->getResult(); - if ($result->skippedCount() + $result->notImplementedCount() > 0 and $this->options['verbosity'] < OutputInterface::VERBOSITY_VERBOSE) { + if ($result->skippedCount() + $result->notImplementedCount() > 0 && $this->options['verbosity'] < OutputInterface::VERBOSITY_VERBOSE) { $this->output->writeln("run with `-v` to get more info about skipped or incomplete tests"); } foreach ($this->reports as $message) { @@ -303,7 +303,7 @@ public function beforeStep(StepEvent $e) return; } $metaStep = $e->getStep()->getMetaStep(); - if ($metaStep and $this->metaStep != $metaStep) { + if ($metaStep && $this->metaStep != $metaStep) { $this->message(' ' . $metaStep->getPrefix()) ->style('bold') ->append($metaStep->__toString()) @@ -316,7 +316,7 @@ public function beforeStep(StepEvent $e) private function printStep(Step $step) { - if ($step instanceof Comment and $step->__toString() == '') { + if ($step instanceof Comment && $step->__toString() == '') { return; // don't print empty comments } $msg = $this->message(' '); @@ -356,8 +356,22 @@ public function printFail(FailEvent $e) $this->output->write($e->getCount() . ") "); $this->writeCurrentTest($failedTest, false); $this->output->writeln(''); + + // Clickable `editorUrl`: + if (isset($this->options['editorUrl']) && is_string($this->options['editorUrl'])) { + $filePath = codecept_absolute_path(Descriptor::getTestFileName($failedTest)); + $line = 1; + foreach ($fail->getTrace() as $trace) { + if (isset($trace['file']) && $filePath === $trace['file'] && isset($trace['line'])) { + $line = $trace['line']; + } + } + $message = str_replace(['%%file%%', '%%line%%'], [$filePath, $line], $this->options['editorUrl']); + } else { + $message = codecept_relative_path(Descriptor::getTestFullName($failedTest)); + } $this->message(" Test ") - ->append(codecept_relative_path(Descriptor::getTestFullName($failedTest))) + ->append($message) ->write(); if ($failedTest instanceof ScenarioDriven) { @@ -492,7 +506,14 @@ public function printExceptionTrace($e) $message->writeln(); continue; } - $message->append($step['file'] . ':' . $step['line']); + + // Clickable `editorUrl`: + if (isset($this->options['editorUrl']) && is_string($this->options['editorUrl'])) { + $lineString = str_replace(['%%file%%', '%%line%%'], [$step['file'], $step['line']], $this->options['editorUrl']); + } else { + $lineString = $step['file'] . ':' . $step['line']; + } + $message->append($lineString); $message->writeln(); } @@ -536,9 +557,17 @@ public function printScenarioTrace(ScenarioDriven $failedTest) $message->style('bold'); } - $line = $step->getLine(); - if ($line and (!$step instanceof Comment)) { - $message->append(" at $line"); + if (!$step instanceof Comment) { + $filePath = $step->getFilePath(); + if ($filePath) { + // Clickable `editorUrl`: + if (isset($this->options['editorUrl']) && is_string($this->options['editorUrl'])) { + $lineString = str_replace(['%%file%%', '%%line%%'], [codecept_absolute_path($step->getFilePath()), $step->getLineNumber()], $this->options['editorUrl']); + } else { + $lineString = $step->getFilePath() . ':' . $step->getLineNumber(); + } + $message->append(" at $lineString"); + } } $stepNumber--; @@ -587,7 +616,7 @@ private function isWin() */ protected function writeCurrentTest(\PHPUnit\Framework\SelfDescribing $test, $inProgress = true) { - $prefix = ($this->output->isInteractive() and !$this->isDetailed($test) and $inProgress) ? '- ' : ''; + $prefix = ($this->output->isInteractive() && !$this->isDetailed($test) && $inProgress) ? '- ' : ''; $testString = Descriptor::getTestAsString($test); $testString = preg_replace('~^([^:]+):\s~', "$1{$this->chars['of']} ", $testString);