Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 28 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,42 @@ extensions:
enabled:
- Qameta\Allure\Codeception\AllureCodeception
config:
Qameta\Allure\Codeception\AllureCodeception:
Qameta\Allure\Codeception\AllureCodeception:
outputDirectory: allure-results
linkTemplates:
issue: https://example.org/issues/%s
setipHook: My\SetupHook
```

`outputDirectory` is used to store Allure results and will be calculated
relatively to Codeception output directory (also known as `paths: log` in
codeception.yml) unless you specify an absolute path. You can traverse up using
`..` as usual. `outputDirectory` defaults to `allure-results`.

`linkTemplates` is used to process links and generate URLs for them. You can put
here an `sprintf()`-like template or a name of class to be constructed; such class
must implement `Qameta\Allure\Setup\LinkTemplateInterface`.

`setupHook` allows to execute some bootstrapping code during initialization. You can
put here a name of the class that implements magic `__invoke()` method - and that method
will be called. For example, it can be used to ignore unnecessary docblock annotations:

```php
<?php

namespace My;

use Doctrine\Common\Annotations\AnnotationReader;

class SetupHook
{
public function __invoke(): void
{
AnnotationReader::addGlobalIgnoredName('annotationToIgnore');
}
}
```

To generate report from your favourite terminal,
[install](https://github.com/allure-framework/allure-cli#installation)
allure-cli and run following command (assuming you're in project root and using
Expand Down
4 changes: 2 additions & 2 deletions codeception.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,5 @@ extensions:
config:
Qameta\Allure\Codeception\AllureCodeception:
outputDirectory: allure-results


linkTemplates:
issue: https://example.org/issues/%s
7 changes: 3 additions & 4 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,15 @@
"php": "^8",
"ext-json": "*",
"codeception/codeception": "^4.1",
"allure-framework/allure-php-commons": "2.0.0-rc3"
"allure-framework/allure-php-commons": "^2"
},
"require-dev": {
"ext-dom": "*",
"phpunit/phpunit": "^9",
"psalm/plugin-phpunit": "^0.16.1",
"remorhaz/php-json-data": "^0.5.3",
"remorhaz/php-json-path": "^0.7.7",
"squizlabs/php_codesniffer": "^3.6.1",
"vimeo/psalm": "^4.10"
"squizlabs/php_codesniffer": "^3.6.2",
"vimeo/psalm": "^4.20"
},
"conflict": {
"codeception/phpunit-wrapper": "<9.0.1"
Expand Down
51 changes: 39 additions & 12 deletions src/AllureCodeception.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,22 @@
use Codeception\Step;
use Qameta\Allure\Allure;
use Qameta\Allure\Allure as QametaAllure;
use Qameta\Allure\Attribute\LinkTemplateInterface;
use Qameta\Allure\Codeception\Internal\DefaultThreadDetector;
use Qameta\Allure\Codeception\Internal\SuiteInfo;
use Qameta\Allure\Codeception\Internal\TestLifecycle;
use Qameta\Allure\Codeception\Internal\TestLifecycleInterface;
use Qameta\Allure\Codeception\Setup\ThreadDetectorInterface;
use Qameta\Allure\Model\LinkType;
use Qameta\Allure\Model\Status;
use Qameta\Allure\Model\StatusDetails;
use Qameta\Allure\Setup\DefaultStatusDetector;
use Qameta\Allure\Setup\LinkTemplate;
use Qameta\Allure\Setup\LinkTemplateInterface;
use Throwable;

use function class_exists;
use function is_a;
use function is_array;
use function is_callable;
use function is_string;
use function trim;
Expand All @@ -35,9 +39,9 @@

final class AllureCodeception extends Extension
{

private const SETUP_HOOK_PARAMETER = 'setupHook';
private const OUTPUT_DIRECTORY_PARAMETER = 'outputDirectory';
private const LINK_TEMPLATES_PARAMETER = 'linkTemplates';

private const DEFAULT_RESULTS_DIRECTORY = 'allure-results';

Expand All @@ -55,11 +59,6 @@ final class AllureCodeception extends Extension
Events::STEP_AFTER => 'stepAfter'
];

/**
* @var array<string, LinkTemplateInterface>
*/
private array $linkTemplates = [];

private ?ThreadDetectorInterface $threadDetector = null;

private ?TestLifecycleInterface $testLifecycle = null;
Expand All @@ -76,9 +75,12 @@ public function _initialize(): void
parent::_initialize();
QametaAllure::reset();
QametaAllure::getLifecycleConfigurator()
->setStatusDetector(new StatusDetector(new DefaultStatusDetector()));
->setStatusDetector(new StatusDetector(new DefaultStatusDetector()))
->setOutputDirectory($this->getOutputDirectory());
foreach ($this->getLinkTemplates() as $linkType => $linkTemplate) {
QametaAllure::getLifecycleConfigurator()->addLinkTemplate($linkType, $linkTemplate);
}
$this->callSetupHook();
QametaAllure::setOutputDirectory($this->getOutputDirectory());
}

private function callSetupHook(): void
Expand Down Expand Up @@ -115,6 +117,31 @@ private function getOutputDirectory(): string
return Configuration::outputDir() . ($outputLocal ?? self::DEFAULT_RESULTS_DIRECTORY) . DIRECTORY_SEPARATOR;
}

/**
* @psalm-suppress MoreSpecificReturnType
* @return iterable<LinkType, LinkTemplate>
*/
private function getLinkTemplates(): iterable
{
/**
* @var mixed $templatesConfig
* @psalm-var array $this->config
*/
$templatesConfig = $this->config[self::LINK_TEMPLATES_PARAMETER] ?? [];
if (!is_array($templatesConfig)) {
$templatesConfig = [];
}
foreach ($templatesConfig as $linkTypeName => $linkConfig) {
if (!is_string($linkConfig) || !is_string($linkTypeName)) {
continue;
}
yield LinkType::fromOptionalString($linkTypeName) =>
class_exists($linkConfig) && is_a($linkConfig, LinkTemplateInterface::class, true)
? new $linkConfig()
: new LinkTemplate($linkConfig);
}
}

/**
* @psalm-suppress MissingDependency
*/
Expand Down Expand Up @@ -270,10 +297,10 @@ private function getTestLifecycle(): TestLifecycleInterface
{
return $this->testLifecycle ??= new TestLifecycle(
Allure::getLifecycle(),
Allure::getResultFactory(),
Allure::getStatusDetector(),
Allure::getConfig()->getResultFactory(),
Allure::getConfig()->getStatusDetector(),
$this->getThreadDetector(),
$this->linkTemplates,
Allure::getConfig()->getLinkTemplates(),
);
}
}
5 changes: 3 additions & 2 deletions src/Internal/ArgumentAsString.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use Stringable;

use function array_map;
use function class_exists;
use function is_a;
use function is_array;
use function is_object;
Expand All @@ -22,7 +23,6 @@
*/
final class ArgumentAsString implements Stringable
{

public function __construct(
private mixed $argument,
) {
Expand Down Expand Up @@ -75,7 +75,8 @@ private function prepareObject(object $argument): string
return (string) $argument;
}

if (is_a($argument, 'Facebook\WebDriver\WebDriverBy')) {
$webdriverByClass = '\Facebook\WebDriver\WebDriverBy';
if (class_exists($webdriverByClass) && is_a($argument, $webdriverByClass)) {
return Locator::humanReadableString($argument);
}

Expand Down
1 change: 0 additions & 1 deletion src/Internal/CeptInfoBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@

final class CeptInfoBuilder implements TestInfoBuilderInterface
{

public function __construct(
private Cept $test,
) {
Expand Down
30 changes: 13 additions & 17 deletions src/Internal/CeptProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
namespace Qameta\Allure\Codeception\Internal;

use Codeception\Test\Cept;
use Qameta\Allure\Attribute\LinkTemplateInterface;
use Qameta\Allure\Setup\LinkTemplateCollectionInterface;
use Qameta\Allure\Model\Label;
use Qameta\Allure\Model\Link;
use Qameta\Allure\Model\LinkType;
Expand All @@ -27,7 +27,6 @@
*/
final class CeptProvider implements ModelProviderInterface
{

private bool $isLoaded = false;

/**
Expand All @@ -45,21 +44,21 @@ final class CeptProvider implements ModelProviderInterface
private ?string $legacyDescription = null;

/**
* @param Cept $test
* @param array<string, LinkTemplateInterface> $linkTemplates
* @param Cept $test
* @param LinkTemplateCollectionInterface $linkTemplates
*/
public function __construct(
private Cept $test,
private array $linkTemplates = [],
private LinkTemplateCollectionInterface $linkTemplates,
) {
}

/**
* @param Cept $test
* @param array<string, LinkTemplateInterface> $linkTemplates
* @param Cept $test
* @param LinkTemplateCollectionInterface $linkTemplates
* @return list<ModelProviderInterface>
*/
public static function createForChain(Cept $test, array $linkTemplates): array
public static function createForChain(Cept $test, LinkTemplateCollectionInterface $linkTemplates): array
{
return [new self($test, $linkTemplates)];
}
Expand All @@ -83,14 +82,6 @@ public function getParameters(): array
return [];
}

/**
* @deprecated Please use {@see getDisplayName()} method
*/
public function getTitle(): ?string
{
return $this->getDisplayName();
}

public function getDisplayName(): ?string
{
$this->loadLegacyModels();
Expand All @@ -107,6 +98,11 @@ public function getDisplayName(): ?string
: null;
}

public function getFullName(): ?string
{
return (string) $this->test->getSignature();
}

public function getDescription(): ?string
{
$this->loadLegacyModels();
Expand Down Expand Up @@ -179,7 +175,7 @@ private function loadLegacyModels(): void
$this->getLegacyAnnotations('Stories'),
),
];
$linkTemplate = $this->linkTemplates[(string) LinkType::issue()] ?? null;
$linkTemplate = $this->linkTemplates->get(LinkType::issue()) ?? null;
$this->legacyLinks = array_map(
fn (string $value): Link => Link::issue($value, $linkTemplate?->buildUrl($value)),
$this->getLegacyAnnotations('Issues'),
Expand Down
1 change: 0 additions & 1 deletion src/Internal/CestInfoBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@

final class CestInfoBuilder implements TestInfoBuilderInterface
{

public function __construct(
private Cest $test,
) {
Expand Down
22 changes: 9 additions & 13 deletions src/Internal/CestProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

use Codeception\Test\Cest;
use Qameta\Allure\Attribute\AttributeParser;
use Qameta\Allure\Attribute\LinkTemplateInterface;
use Qameta\Allure\Setup\LinkTemplateCollectionInterface;
use Qameta\Allure\Model\ModelProviderInterface;
use Qameta\Allure\Model\Parameter;
use ReflectionException;
Expand All @@ -24,19 +24,18 @@
*/
final class CestProvider implements ModelProviderInterface
{

public function __construct(
private Cest $test,
) {
}

/**
* @param Cest $test
* @param array<string, LinkTemplateInterface> $linkTemplates
* @param Cest $test
* @param LinkTemplateCollectionInterface $linkTemplates
* @return list<ModelProviderInterface>
* @throws ReflectionException
*/
public static function createForChain(Cest $test, array $linkTemplates = []): array
public static function createForChain(Cest $test, LinkTemplateCollectionInterface $linkTemplates): array
{
/** @var mixed $testClass */
$testClass = $test->getTestClass();
Expand Down Expand Up @@ -86,14 +85,6 @@ public function getParameters(): array
);
}

/**
* @deprecated Please, use {@see getDisplayName()} method
*/
public function getTitle(): ?string
{
return $this->getDisplayName();
}

public function getDisplayName(): ?string
{
/** @psalm-var mixed $displayName */
Expand All @@ -113,4 +104,9 @@ public function getDescriptionHtml(): ?string
{
return null;
}

public function getFullName(): ?string
{
return null;
}
}
1 change: 0 additions & 1 deletion src/Internal/DefaultThreadDetector.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@

final class DefaultThreadDetector implements ThreadDetectorInterface
{

private string|false|null $host = null;

public function getHost(): ?string
Expand Down
1 change: 0 additions & 1 deletion src/Internal/GherkinInfoBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@

final class GherkinInfoBuilder implements TestInfoBuilderInterface
{

public function __construct(
private Gherkin $test,
) {
Expand Down
Loading