Commit b677a089 by lmf

增加vendor目录至版本库

parent fd1210bc

Too many changes to show.

To preserve performance only 1000 of 1000+ files are displayed.

...@@ -10,4 +10,3 @@ errors ...@@ -10,4 +10,3 @@ errors
media media
opt opt
code code
vendor
memory_limit = 756M
max_execution_time = 18000
session.auto_start = off
suhosin.session.cryptua = off
\ No newline at end of file
<IfVersion < 2.4>
order allow,deny
deny from all
</IfVersion>
<IfVersion >= 2.4>
Require all denied
</IfVersion>
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: ''
assignees: ''
---
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Desktop (please complete the following information):**
- OS: [e.g. iOS]
- Browser [e.g. chrome, safari]
- Version [e.g. 22]
**Smartphone (please complete the following information):**
- Device: [e.g. iPhone6]
- OS: [e.g. iOS8.1]
- Browser [e.g. stock browser, safari]
- Version [e.g. 22]
**Additional context**
Add any other context about the problem here.
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: ''
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "daily"
labels:
- "type:dependencies"
- package-ecosystem: "composer"
directory: "/"
schedule:
interval: "daily"
labels:
- "type:dependencies"
name-template: '$NEXT_MINOR_VERSION'
tag-template: '$NEXT_MINOR_VERSION'
categories:
- title: '🚀 New Features'
labels:
- 'type:new feature'
- title: '🔬 Improvements'
labels:
- 'type:improvement'
- title: '🐞 Bug Fixes'
labels:
- 'type:bug'
- title: '⬆️ Dependency Updates'
labels:
- 'type:dependencies'
change-template: '* $TITLE (via #$NUMBER) - @$AUTHOR'
exclude-labels:
- 'type:internal'
template: |
$CHANGES
## 👀 Links
[Commits since $PREVIOUS_TAG](https://github.com/allure-framework/allure-codeception/compare/$PREVIOUS_TAG...master)
name: Build
on:
pull_request:
branches:
- '*'
push:
branches:
- 'master'
- 'hotfix-*'
jobs:
build71:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2.3.4
- uses: shivammathur/setup-php@2.11.0
with:
php-version: '7.1.3'
- name: Install
run: composer install
- name: Install
run: composer validate
- name: Test
run: composer test
build72:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2.3.4
- uses: shivammathur/setup-php@2.11.0
with:
php-version: '7.2'
- name: Install
run: composer install
- name: Install
run: composer validate
- name: Test
run: composer test
build73:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2.3.4
- uses: shivammathur/setup-php@2.11.0
with:
php-version: '7.3'
- name: Install
run: composer install
- name: Install
run: composer validate
- name: Test
run: composer test
build74:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2.3.4
- uses: shivammathur/setup-php@2.11.0
with:
php-version: '7.4'
- name: Install
run: composer install
- name: Install
run: composer validate
- name: Test
run: composer test
build80:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2.3.4
- uses: shivammathur/setup-php@2.11.0
with:
php-version: '8.0'
- name: Install
run: composer install
- name: Install
run: composer validate
- name: Test
run: composer test
name: Release Draft
on:
push:
branches:
- master
jobs:
update_draft_release:
runs-on: ubuntu-latest
steps:
- uses: toolmantim/release-drafter@v5.15.0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
name: "Verify type labels"
on:
pull_request:
types: [opened, labeled, unlabeled, synchronize]
jobs:
triage:
runs-on: ubuntu-latest
steps:
- uses: baev/match-label-action@master
with:
allowed: 'type:bug,type:new feature,type:improvement,type:dependencies,type:internal,type:invalid'
*.iml
.idea
vendor/*
composer.phar
composer.lock
/build/
.phpunit.result.cache
# Allure Codeception Adapter
[![Build](https://github.com/allure-framework/allure-codeception/actions/workflows/build.yml/badge.svg)](https://github.com/allure-framework/allure-codeception/actions/workflows/build.yml)
This is an official [Codeception](http://codeception.com) adapter for Allure Framework.
## What is this for?
The main purpose of this adapter is to accumulate information about your tests and write it out to a set of XML files: one for each test class. This adapter only generates XML files containing information about tests. See [wiki section](https://github.com/allure-framework/allure-core/wiki#generating-report) on how to generate report.
## Example project
Example project is located at: https://github.com/allure-examples/allure-codeception-example
## Installation and Usage
In order to use this adapter you need to add a new dependency to your **composer.json** file:
```
{
"require": {
"php": ">=5.4.0",
"allure-framework/allure-codeception": ">=1.1.0"
}
}
```
To enable this adapter in Codeception tests simply put it in "enabled" extensions section of **codeception.yml**:
```yaml
extensions:
enabled:
- Yandex\Allure\Codeception\AllureCodeception
config:
Yandex\Allure\Codeception\AllureCodeception:
deletePreviousResults: false
outputDirectory: allure-results
ignoredAnnotations:
- env
- dataprovider
```
`deletePreviousResults` will clear all `.xml` files from output directory (this
behavior may change to complete cleanup later). It is set to `false` by default.
`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`.
`ignoredAnnotations` is used to define extra custom annotations to ignore. It is empty by default.
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
default configuration):
```bash
allure generate --report-version 1.4.5 --report-path tests/_output/allure-report -- tests/_output/allure-results
```
Report will be generated in `tests/_output/allure-report`.
## Main features
See respective [PHPUnit](https://github.com/allure-framework/allure-phpunit#advanced-features) section.
namespace: Yandex\Allure\Codeception
suites:
unit:
path: .
settings:
lint: true
paths:
tests: test/codeception
output: build
support: test/codeception/_support
data: test/codeception
extensions:
enabled:
- Yandex\Allure\Codeception\AllureCodeception
config:
Yandex\Allure\Codeception\AllureCodeception:
deletePreviousResults: true
outputDirectory: allure-results
{
"name": "allure-framework/allure-codeception",
"keywords":["codeception", "testing", "report", "steps", "attachments", "cases", "allure"],
"description": "Allure Codeception integration",
"homepage": "http://allure.qatools.ru/",
"license": "Apache-2.0",
"authors": [
{
"name": "Ivan Krutov",
"email": "vania-pooh@aerokube.com",
"role": "Developer"
}
],
"support": {
"email": "allure@qameta.io",
"source": "https://github.com/allure-framework/allure-codeception"
},
"require": {
"php": ">=7.1.3",
"ext-json": "*",
"codeception/codeception": "^2.5 | ^3 | ^4",
"allure-framework/allure-php-api": "^1.3",
"symfony/filesystem": "^2.7 | ^3 | ^4 | ^5",
"symfony/finder": "^2.7 | ^3 | ^4 | ^5"
},
"require-dev": {
"ext-dom": "*",
"phpunit/phpunit": "^7.2 | ^8 | ^9"
},
"autoload": {
"psr-0": {
"Yandex": "src/"
}
},
"autoload-dev": {
"psr-4": {
"Yandex\\Allure\\Codeception\\": [
"test/report/",
"test/unit/"
]
}
},
"scripts": {
"test-report": [
"vendor/bin/codecept run --no-exit --report",
"vendor/bin/phpunit --testsuite=report"
],
"test": [
"@test-report"
]
}
}
<?xml version="1.0" encoding="UTF-8"?>
<phpunit
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/7.2/phpunit.xsd"
colors="true"
defaultTestSuite="unit">
<testsuites>
<testsuite name="report">
<directory>test/report/</directory>
</testsuite>
</testsuites>
</phpunit>
<?php
declare(strict_types=1);
namespace Yandex\Allure\Codeception;
use Codeception\Test\Unit;
use Yandex\Allure\Adapter\Annotation\Description;
use Yandex\Allure\Adapter\Annotation\Features;
use Yandex\Allure\Adapter\Annotation\Parameter;
use Yandex\Allure\Adapter\Annotation\Severity;
use Yandex\Allure\Adapter\Annotation\Stories;
use Yandex\Allure\Adapter\Annotation\Title;
use Yandex\Allure\Adapter\Model\DescriptionType;
use Yandex\Allure\Adapter\Model\ParameterKind;
use Yandex\Allure\Adapter\Model\SeverityLevel;
class AnnotationTest extends Unit
{
/**
* @Title ("Test title")
*/
public function testTitleAnnotation(): void
{
$this->expectNotToPerformAssertions();
}
/**
* @Description ("Test description with `markdown`", type = DescriptionType::MARKDOWN)
*/
public function testDescriptionAnnotation(): void
{
$this->expectNotToPerformAssertions();
}
/**
* @Severity (level = SeverityLevel::MINOR)
*/
public function testSeverityAnnotation(): void
{
$this->expectNotToPerformAssertions();
}
/**
* @Parameter (name = "foo", value = "bar", kind = ParameterKind::ARGUMENT)
*/
public function testParameterAnnotation(): void
{
$this->expectNotToPerformAssertions();
}
/**
* @Stories ("Story 1", "Story 2")
*/
public function testStoriesAnnotation(): void
{
$this->expectNotToPerformAssertions();
}
/**
* @Features ("Feature 1", "Feature 2")
*/
public function testFeaturesAnnotation(): void
{
$this->expectNotToPerformAssertions();
}
}
\ No newline at end of file
<?php
declare(strict_types=1);
namespace Yandex\Allure\Codeception;
use Codeception\Lib\ModuleContainer;
use Codeception\Scenario;
use Codeception\Step\Assertion;
use Codeception\Step\Comment;
use Codeception\Step\Meta;
use Codeception\Step\TryTo;
use Codeception\Test\Unit;
use Exception;
use PHPUnit\Framework\Assert;
class StepsTest extends Unit
{
public function testNoStepsSuccess(): void
{
$this->expectNotToPerformAssertions();
}
/**
* @throws Exception
*/
public function testNoStepsError(): void
{
throw new Exception('Error');
}
public function testNoStepsFailure(): void
{
self::fail('Failure');
}
public function testNoStepsSkipped(): void
{
self::markTestSkipped('Skipped');
}
public function testSingleSuccessfulStepWithTitle(): void
{
$this->expectNotToPerformAssertions();
$scenario = new Scenario($this);
$scenario->runStep(new Comment('Step 1 name'));
}
public function testTwoSuccessfulSteps(): void
{
$this->expectNotToPerformAssertions();
$scenario = new Scenario($this);
$scenario->runStep(new Comment('Step 1 name'));
$scenario->runStep(new Comment('Step 2 name'));
}
public function testTwoStepsFirstFails(): void
{
$this->expectNotToPerformAssertions();
$scenario = new Scenario($this);
$scenario->runStep($this->createFailingStep('Step 1 name', 'Failure'));
$scenario->runStep(new Comment('Step 2 name'));
}
public function testTwoStepsSecondFails(): void
{
$this->expectNotToPerformAssertions();
$scenario = new Scenario($this);
$scenario->runStep(new Comment('Step 1 name'));
$scenario->runStep($this->createFailingStep('Step 2 name', 'Failure'));
}
private function createFailingStep(string $name, string $failure): \Codeception\Step
{
return new class ($failure, $name) extends Meta {
private $failure;
public function __construct(string $failure, $action, array $arguments = [])
{
parent::__construct($action, $arguments);
$this->failure = $failure;
}
public function run(ModuleContainer $container = null)
{
$this->setFailed(true);
Assert::fail($this->failure);
}
};
}
}
<?php
declare(strict_types=1);
namespace Yandex\Allure\Codeception;
use DOMDocument;
use DOMXPath;
use PHPUnit\Framework\TestCase;
use RuntimeException;
use function is_file;
use function pathinfo;
use function scandir;
use function sprintf;
use const DIRECTORY_SEPARATOR;
use const PATHINFO_EXTENSION;
class ReportTest extends TestCase
{
/**
* @var string
*/
private $buildPath;
/**
* @var DOMXPath[]
*/
private $sources = [];
public function setUp(): void
{
$this->buildPath = __DIR__ . '/../../build/allure-results';
$files = scandir($this->buildPath);
foreach ($files as $fileName) {
$file = $this->buildPath . DIRECTORY_SEPARATOR . $fileName;
if (!is_file($file)) {
continue;
}
$extension = pathinfo($file, PATHINFO_EXTENSION);
if ('xml' == $extension) {
$dom = new DOMDocument();
$dom->load($file);
$path = new DOMXPath($dom);
$name = $path->query('/alr:test-suite/name')->item(0)->textContent;
if (isset($this->sources[$name])) {
throw new RuntimeException("Duplicate test suite: {$name}");
}
$this->sources[$name] = $path;
}
}
}
/**
* @param string $class
* @param string $xpath
* @param string $expectedValue
* @dataProvider providerSingleTextNode
*/
public function testSingleTextNode(string $class, string $xpath, string $expectedValue): void
{
self::assertArrayHasKey($class, $this->sources);
$actualValue = $this
->sources[$class]
->query($xpath)
->item(0)
->textContent;
self::assertSame($expectedValue, $actualValue);
}
public function providerSingleTextNode(): iterable
{
return [
'Test case title annotation' => [
'Yandex\Allure\Codeception.unit',
$this->buildTestXPath(
'testTitleAnnotation',
'/title'
),
'Test title',
],
'Test case severity annotation' => [
'Yandex\Allure\Codeception.unit',
$this->buildTestXPath(
'testSeverityAnnotation',
'/labels/label[@name="severity" and @value="minor"]'
),
'',
],
'Test case parameter annotation' => [
'Yandex\Allure\Codeception.unit',
$this->buildTestXPath(
'testParameterAnnotation',
'/parameters/parameter[@name="foo" and @value="bar" and @kind="argument"]'
),
'',
],
'Test case stories annotation: first story' => [
'Yandex\Allure\Codeception.unit',
$this->buildTestXPath(
'testStoriesAnnotation',
'/labels/label[@name="story" and @value="Story 1"]'
),
'',
],
'Test case stories annotation: second story' => [
'Yandex\Allure\Codeception.unit',
$this->buildTestXPath(
'testStoriesAnnotation',
'/labels/label[@name="story" and @value="Story 2"]'
),
'',
],
'Test case features annotation: first feature' => [
'Yandex\Allure\Codeception.unit',
$this->buildTestXPath(
'testFeaturesAnnotation',
'/labels/label[@name="feature" and @value="Feature 1"]'
),
'',
],
'Test case features annotation: second feature' => [
'Yandex\Allure\Codeception.unit',
$this->buildTestXPath(
'testFeaturesAnnotation',
'/labels/label[@name="feature" and @value="Feature 2"]'
),
'',
],
'Successful test case without steps' => [
'Yandex\Allure\Codeception.unit',
$this->buildTestXPath(
'testNoStepsSuccess',
'[@status="passed"]/name'
),
'testNoStepsSuccess',
],
'Error in test case without steps' => [
'Yandex\Allure\Codeception.unit',
$this->buildTestXPath(
'testNoStepsError',
'[@status="broken"]/failure/message'
),
'Error',
],
'Failure in test case without steps' => [
'Yandex\Allure\Codeception.unit',
$this->buildTestXPath(
'testNoStepsFailure',
'[@status="failed"]/failure/message'
),
'Failure',
],
'Test case without steps skipped' => [
'Yandex\Allure\Codeception.unit',
$this->buildTestXPath(
'testNoStepsSkipped',
'[@status="canceled"]/failure/message'
),
'Skipped',
],
'Successful test case with single step: name' => [
'Yandex\Allure\Codeception.unit',
$this->buildTestXPath(
'testSingleSuccessfulStepWithTitle',
'[@status="passed"]/steps/step[1][@status="passed"]/name'
),
'step 1 name ', // Codeception processes action internally
],
'Successful test case with two successful steps: step 2 name' => [
'Yandex\Allure\Codeception.unit',
$this->buildTestXPath(
'testTwoSuccessfulSteps',
'[@status="passed"]/steps/step[2][@status="passed"]/name'
),
'step 2 name ', // Codeception processes action internally
],
'First step in test case with two steps fails: failure' => [
'Yandex\Allure\Codeception.unit',
$this->buildTestXPath(
'testTwoStepsFirstFails',
'[@status="failed"]/failure/message'
),
'Failure',
],
'First step in test case with two steps fails: step 1 name' => [
'Yandex\Allure\Codeception.unit',
$this->buildTestXPath(
'testTwoStepsFirstFails',
'[@status="failed"]/steps/step[1][@status="failed"]/name'
),
'step 1 name ', // Codeception processes action internally
],
'Second step in test case with two steps fails: failure' => [
'Yandex\Allure\Codeception.unit',
$this->buildTestXPath(
'testTwoStepsSecondFails',
'[@status="failed"]/failure/message'
),
'Failure',
],
'Second step in test case with two steps fails: step 1 name' => [
'Yandex\Allure\Codeception.unit',
$this->buildTestXPath(
'testTwoStepsSecondFails',
'[@status="failed"]/steps/step[1][@status="passed"]/name'
),
'step 1 name ', // Codeception processes action internally
],
'Second step in test case with two steps fails: step 2 name' => [
'Yandex\Allure\Codeception.unit',
$this->buildTestXPath(
'testTwoStepsSecondFails',
'[@status="failed"]/steps/step[2][@status="failed"]/name'
),
'step 2 name ', // Codeception processes action internally
],
];
}
/**
* @param string $class
* @param string $xpath
* @dataProvider providerNodeNotExists
*/
public function testNodeNotExists(string $class, string $xpath): void
{
$testNode = $this
->sources[$class]
->query($xpath)
->item(0);
self::assertNull($testNode);
}
public function providerNodeNotExists(): iterable
{
return [
'Successful test case without steps: no steps' => [
'Yandex\Allure\Codeception.unit',
$this->buildTestXPath(
'testNoStepsSuccess',
'/steps'
)
],
'First step fails in test case with two steps: no second step' => [
'Yandex\Allure\Codeception.unit',
$this->buildTestXPath(
'testTwoStepsFirstFails',
'/steps/step[2]'
)
],
];
}
private function buildTestXPath(string $testName, string $tail): string
{
return sprintf('/alr:test-suite/test-cases/test-case[name="%s"]%s', $testName, $tail);
}
}
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: ''
assignees: ''
---
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Desktop (please complete the following information):**
- OS: [e.g. iOS]
- Browser [e.g. chrome, safari]
- Version [e.g. 22]
**Smartphone (please complete the following information):**
- Device: [e.g. iPhone6]
- OS: [e.g. iOS8.1]
- Browser [e.g. stock browser, safari]
- Version [e.g. 22]
**Additional context**
Add any other context about the problem here.
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: ''
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "daily"
labels:
- "type:dependencies"
- package-ecosystem: "composer"
directory: "/"
schedule:
interval: "daily"
labels:
- "type:dependencies"
name-template: '$NEXT_MINOR_VERSION'
tag-template: '$NEXT_MINOR_VERSION'
categories:
- title: '🚀 New Features'
labels:
- 'type:new feature'
- title: '🔬 Improvements'
labels:
- 'type:improvement'
- title: '🐞 Bug Fixes'
labels:
- 'type:bug'
- title: '⬆️ Dependency Updates'
labels:
- 'type:dependencies'
change-template: '* $TITLE (via #$NUMBER) - @$AUTHOR'
exclude-labels:
- 'type:internal'
template: |
$CHANGES
## 👀 Links
[Commits since $PREVIOUS_TAG](https://github.com/allure-framework/allure-php-api/compare/$PREVIOUS_TAG...master)
name: Build
on:
pull_request:
branches:
- '*'
push:
branches:
- 'master'
- 'hotfix-*'
jobs:
build71:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2.4.0
- uses: shivammathur/setup-php@2.15.0
with:
php-version: '7.1.3'
- name: Install
run: composer update
- name: Test
run: composer test-legacy
build72:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2.4.0
- uses: shivammathur/setup-php@2.15.0
with:
php-version: '7.2'
- name: Install
run: composer update
- name: Test
run: composer test-legacy
build73:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2.4.0
- uses: shivammathur/setup-php@2.15.0
with:
php-version: '7.3'
- name: Install
run: composer update
- name: Test
run: composer test
build74:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2.4.0
- uses: shivammathur/setup-php@2.15.0
with:
php-version: '7.4'
- name: Install
run: composer update
- name: Test
run: composer test
build80:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2.4.0
- uses: shivammathur/setup-php@2.15.0
with:
php-version: '8.0'
- name: Install
run: composer update
- name: Test
run: composer test
name: Release Draft
on:
push:
branches:
- master
jobs:
update_draft_release:
runs-on: ubuntu-latest
steps:
- uses: toolmantim/release-drafter@v5.15.0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
name: "Verify type labels"
on:
pull_request:
types: [opened, labeled, unlabeled, synchronize]
jobs:
triage:
runs-on: ubuntu-latest
steps:
- uses: zwaldowski/match-label-action@v2
with:
allowed: 'type:bug,type:new feature,type:improvement,type:dependencies,type:internal,type:invalid'
*.iml
.idea
nbproject
vendor/*
composer.phar
/composer.lock
.phpunit.result.cache
# Allure PHP API
[![Build](https://github.com/allure-framework/allure-php-api/actions/workflows/build.yml/badge.svg)](https://github.com/allure-framework/allure-php-api/actions/workflows/build.yml)
This repository contains PHP API for Allure framework. The main idea is to reuse this API when creating adapters for different test frameworks.
## Getting started
In order to use this API you simply need to add the following to **composer.json**:
```json
{
"require": {
"php": ">=5.4.0",
"allure-framework/allure-php-api": "~1.0.0"
}
}
```
Basic usage idiom is to fire an event like the following:
```php
Allure::lifecycle()->fire(new TestCaseFinishedEvent());
```
## Events
The following events are available right now:
* AddAttachmentEvent
* AddParameterEvent
* ClearStepStorageEvent
* ClearTestCaseStorageEvent
* RemoveAttachmentsEvent
* StepCanceledEvent
* StepEvent
* StepFailedEvent
* StepFinishedEvent
* StepStartedEvent
* TestCaseBrokenEvent
* TestCaseCanceledEvent
* TestCaseEvent
* TestCaseFailedEvent
* TestCaseFinishedEvent
* TestCasePendingEvent
* TestCaseStartedEvent
* TestCaseStatusChangedEvent
* TestSuiteEvent
* TestSuiteFinishedEvent
* TestSuiteStartedEvent
## Usage examples
See [allure-phpunit](https://github.com/allure-framework/allure-phpunit) project.
{
"name": "allure-framework/allure-php-api",
"keywords":["php", "report", "allure", "api"],
"description": "Allure PHP commons",
"homepage": "http://allure.qatools.ru/",
"license": "Apache-2.0",
"authors": [
{
"name": "Ivan Krutov",
"email": "vania-pooh@yandex-team.ru",
"role": "Developer"
}
],
"support": {
"email": "allure@qameta.io",
"source": "https://github.com/allure-framework/allure-php-api"
},
"require": {
"php": ">=7.1.3",
"jms/serializer": "^1 | ^2 | ^3",
"ramsey/uuid": "^3 | ^4",
"symfony/mime": "^4.3 | ^5"
},
"require-dev": {
"phpunit/phpunit": "^7 | ^8 | ^9"
},
"autoload": {
"psr-0": {
"Yandex": ["src/", "test/"]
}
},
"scripts": {
"test": "vendor/bin/phpunit",
"test-legacy": "vendor/bin/phpunit --configuration=phpunit.legacy.xml"
}
}
<?xml version="1.0" encoding="UTF-8"?>
<phpunit
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/7.0/phpunit.xsd"
bootstrap="phpunit.php"
colors="true"
defaultTestSuite="Allure PHP API Tests">
<testsuites>
<testsuite name="Allure PHP API Tests">
<directory>test/Yandex/Allure/Adapter/</directory>
</testsuite>
</testsuites>
<filter>
<whitelist>
<directory>src/</directory>
</whitelist>
</filter>
</phpunit>
\ No newline at end of file
<?php
use Doctrine\Common\Annotations\AnnotationRegistry;
require_once __DIR__ . '/vendor/autoload.php';
AnnotationRegistry::registerLoader('class_exists');
date_default_timezone_set('UTC');
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<phpunit
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd"
bootstrap="phpunit.php"
colors="true"
defaultTestSuite="Allure PHP API Tests">
<testsuites>
<testsuite name="Allure PHP API Tests">
<directory>test/Yandex/Allure/Adapter/</directory>
</testsuite>
</testsuites>
<coverage>
<include>
<directory>src/</directory>
</include>
</coverage>
</phpunit>
\ No newline at end of file
<?php
namespace Yandex\Allure\Adapter;
use Yandex\Allure\Adapter\Event\ClearStepStorageEvent;
use Yandex\Allure\Adapter\Event\ClearTestCaseStorageEvent;
use Yandex\Allure\Adapter\Event\Event;
use Yandex\Allure\Adapter\Event\StepEvent;
use Yandex\Allure\Adapter\Event\StepFinishedEvent;
use Yandex\Allure\Adapter\Event\StepStartedEvent;
use Yandex\Allure\Adapter\Event\Storage\StepStorage;
use Yandex\Allure\Adapter\Event\Storage\TestCaseStorage;
use Yandex\Allure\Adapter\Event\Storage\TestSuiteStorage;
use Yandex\Allure\Adapter\Event\TestCaseEvent;
use Yandex\Allure\Adapter\Event\TestCaseFinishedEvent;
use Yandex\Allure\Adapter\Event\TestCaseStartedEvent;
use Yandex\Allure\Adapter\Event\TestSuiteEvent;
use Yandex\Allure\Adapter\Event\TestSuiteFinishedEvent;
use Yandex\Allure\Adapter\Model\Provider;
use Yandex\Allure\Adapter\Model\Step;
use Yandex\Allure\Adapter\Model\TestSuite;
use Yandex\Allure\Adapter\Support\Utils;
class Allure
{
use Utils;
/**
* @var Allure
*/
private static $lifecycle;
private $stepStorage;
private $testCaseStorage;
private $testSuiteStorage;
/**
* @var Event
*/
private $lastEvent;
protected function __construct()
{
$this->stepStorage = new StepStorage();
$this->testCaseStorage = new TestCaseStorage();
$this->testSuiteStorage = new TestSuiteStorage();
}
/**
* @return Allure
*/
public static function lifecycle()
{
if (!isset(self::$lifecycle)) {
self::setDefaultLifecycle();
}
return self::$lifecycle;
}
public static function setLifecycle(Allure $lifecycle)
{
self::$lifecycle = $lifecycle;
}
public static function setDefaultLifecycle()
{
self::$lifecycle = new Allure();
}
public function fire(Event $event)
{
if ($event instanceof StepStartedEvent) {
$this->processStepStartedEvent($event);
} elseif ($event instanceof StepFinishedEvent) {
$this->processStepFinishedEvent($event);
} elseif ($event instanceof TestCaseStartedEvent) {
$this->processTestCaseStartedEvent($event);
} elseif ($event instanceof TestCaseFinishedEvent) {
$this->processTestCaseFinishedEvent($event);
} elseif ($event instanceof TestSuiteFinishedEvent) {
$this->processTestSuiteFinishedEvent($event);
} elseif ($event instanceof TestSuiteEvent) {
$this->processTestSuiteEvent($event);
} elseif ($event instanceof ClearStepStorageEvent) {
$this->processClearStepStorageEvent();
} elseif ($event instanceof ClearTestCaseStorageEvent) {
$this->processClearTestCaseStorageEvent();
} elseif ($event instanceof TestCaseEvent) {
$this->processTestCaseEvent($event);
} elseif ($event instanceof StepEvent) {
$this->processStepEvent($event);
} else {
throw new AllureException("Unknown event: " . get_class($event));
}
$this->lastEvent = $event;
}
protected function processStepStartedEvent(StepStartedEvent $event)
{
$step = new Step();
$event->process($step);
$this->getStepStorage()->put($step);
}
protected function processStepFinishedEvent(StepFinishedEvent $event)
{
$step = $this->getStepStorage()->pollLast();
$event->process($step);
$this->getStepStorage()->getLast()->addStep($step);
}
protected function processStepEvent(StepEvent $event)
{
$step = $this->getStepStorage()->getLast();
$event->process($step);
}
protected function processTestCaseStartedEvent(TestCaseStartedEvent $event)
{
//init root step if needed
$this->getStepStorage()->getLast();
$testCase = $this->getTestCaseStorage()->get();
$event->process($testCase);
$this->getTestSuiteStorage()->get($event->getSuiteUuid())->addTestCase($testCase);
}
protected function processTestCaseFinishedEvent(TestCaseFinishedEvent $event)
{
$testCase = $this->getTestCaseStorage()->get();
$event->process($testCase);
$rootStep = $this->getStepStorage()->pollLast();
foreach ($rootStep->getSteps() as $step) {
$testCase->addStep($step);
}
foreach ($rootStep->getAttachments() as $attachment) {
$testCase->addAttachment($attachment);
}
$this->getTestCaseStorage()->clear();
}
protected function processTestCaseEvent(TestCaseEvent $event)
{
$testCase = $this->getTestCaseStorage()->get();
$event->process($testCase);
}
protected function processTestSuiteEvent(TestSuiteEvent $event)
{
$uuid = $event->getUuid();
$testSuite = $this->getTestSuiteStorage()->get($uuid);
$event->process($testSuite);
}
protected function processTestSuiteFinishedEvent(TestSuiteFinishedEvent $event)
{
$suiteUuid = $event->getUuid();
$testSuite = $this->getTestSuiteStorage()->get($suiteUuid);
$event->process($testSuite);
$this->getTestSuiteStorage()->remove($suiteUuid);
$this->saveToFile($suiteUuid, $testSuite);
}
protected function saveToFile($testSuiteUuid, TestSuite $testSuite)
{
if ($testSuite->size() > 0) {
$xml = $testSuite->serialize();
$fileName = $testSuiteUuid . '-testsuite.xml';
$filePath = Provider::getOutputDirectory() . DIRECTORY_SEPARATOR . $fileName;
file_put_contents($filePath, $xml);
}
}
protected function processClearStepStorageEvent()
{
$this->getStepStorage()->clear();
}
protected function processClearTestCaseStorageEvent()
{
$this->getTestCaseStorage()->clear();
}
/**
* @return \Yandex\Allure\Adapter\Event\Storage\StepStorage
*/
public function getStepStorage()
{
return $this->stepStorage;
}
/**
* @return \Yandex\Allure\Adapter\Event\Storage\TestCaseStorage
*/
public function getTestCaseStorage()
{
return $this->testCaseStorage;
}
/**
* @return \Yandex\Allure\Adapter\Event\Storage\TestSuiteStorage
*/
public function getTestSuiteStorage()
{
return $this->testSuiteStorage;
}
/**
* @return \Yandex\Allure\Adapter\Event\Event
*/
public function getLastEvent()
{
return $this->lastEvent;
}
}
<?php
namespace Yandex\Allure\Adapter;
class AllureException extends \Exception
{
}
<?php
namespace Yandex\Allure\Adapter\Annotation;
use Doctrine\Common\Annotations\Annotation\Required;
/**
* @Annotation
* @Target({"METHOD"})
* @package Yandex\Allure\Adapter\Annotation
*/
class AllureId
{
/**
* @var string
* @Required
*/
public $value;
}
<?php
namespace Yandex\Allure\Adapter\Annotation;
use Yandex\Allure\Adapter\Event\TestCaseStartedEvent;
use Yandex\Allure\Adapter\Event\TestSuiteStartedEvent;
use Yandex\Allure\Adapter\Model;
use Yandex\Allure\Adapter\Model\ConstantChecker;
class AnnotationManager
{
/**
* @var string
*/
private $title;
/**
* @var Model\Description
*/
private $description;
/**
* @var array
*/
private $labels;
/**
* @var array
*/
private $parameters;
public function __construct(array $annotations)
{
$this->labels = [];
$this->parameters = [];
$this->processAnnotations($annotations);
}
private function processAnnotations(array $annotations)
{
foreach ($annotations as $annotation) {
if ($annotation instanceof AllureId) {
$this->labels[] = Model\Label::id($annotation->value);
} elseif ($annotation instanceof Title) {
$this->title = $annotation->value;
} elseif ($annotation instanceof Description) {
$this->description = new Model\Description(
$annotation->type,
$annotation->value
);
} elseif ($annotation instanceof Epics) {
foreach ($annotation->getEpicNames() as $epicName) {
$this->labels[] = Model\Label::epic($epicName);
}
} elseif ($annotation instanceof Features) {
foreach ($annotation->getFeatureNames() as $featureName) {
$this->labels[] = Model\Label::feature($featureName);
}
} elseif ($annotation instanceof Stories) {
foreach ($annotation->getStories() as $issueKey) {
$this->labels[] = Model\Label::story($issueKey);
}
} elseif ($annotation instanceof Issues) {
foreach ($annotation->getIssueKeys() as $issueKey) {
$this->labels[] = Model\Label::issue($issueKey);
}
} elseif ($annotation instanceof TestCaseId) {
foreach ($annotation->getTestCaseIds() as $testCaseId) {
$this->labels[] = Model\Label::testId($testCaseId);
}
} elseif ($annotation instanceof Severity) {
$this->labels[] = Model\Label::severity(
ConstantChecker::validate('Yandex\Allure\Adapter\Model\SeverityLevel', $annotation->level)
);
} elseif ($annotation instanceof TestType) {
$this->labels[] = Model\Label::testType($annotation->type);
} elseif ($annotation instanceof Parameter) {
$this->parameters[] = new Model\Parameter(
$annotation->name,
$annotation->value,
$annotation->kind
);
} elseif ($annotation instanceof Parameters) {
foreach ($annotation->parameters as $parameter) {
$this->parameters[] = new Model\Parameter(
$parameter->name,
$parameter->value,
$parameter->kind
);
}
} elseif ($annotation instanceof Label) {
foreach ($annotation -> values as $value) {
$this->labels[] = Model\Label::label($annotation->name, $value);
}
} elseif ($annotation instanceof Labels) {
foreach ($annotation -> labels as $label) {
foreach ($label -> values as $value) {
$this->labels[] = Model\Label::label($label->name, $value);
}
}
}
}
}
public function updateTestSuiteEvent(TestSuiteStartedEvent $event)
{
if ($this->isTitlePresent()) {
$event->setTitle($this->getTitle());
}
if ($this->isDescriptionPresent()) {
$event->setDescription($this->getDescription());
}
if ($this->areLabelsPresent()) {
$event->setLabels($this->getLabels());
}
}
public function updateTestCaseEvent(TestCaseStartedEvent $event)
{
if ($this->isTitlePresent()) {
$event->setTitle($this->getTitle());
}
if ($this->isDescriptionPresent()) {
$event->setDescription($this->getDescription());
}
if ($this->areLabelsPresent()) {
$event->setLabels(array_merge($event->getLabels(), $this->getLabels()));
}
if ($this->areParametersPresent()) {
$event->setParameters($this->getParameters());
}
}
/**
* @return Model\Description
*/
public function getDescription()
{
return $this->description;
}
/**
* @return array
*/
public function getLabels()
{
return $this->labels;
}
/**
* @return array
*/
public function getParameters()
{
return $this->parameters;
}
/**
* @return string
*/
public function getTitle()
{
return $this->title;
}
public function isTitlePresent()
{
return isset($this->title);
}
public function isDescriptionPresent()
{
return isset($this->description);
}
public function areLabelsPresent()
{
return !empty($this->labels);
}
public function areParametersPresent()
{
return !empty($this->parameters);
}
}
<?php
namespace Yandex\Allure\Adapter\Annotation;
use Doctrine\Common\Annotations\AnnotationReader;
use Doctrine\Common\Annotations\AnnotationRegistry;
use Doctrine\Common\Annotations\IndexedReader;
class AnnotationProvider
{
/**
* @var AnnotationReader
*/
private static $annotationReader;
/**
* @var IndexedReader
*/
private static $indexedReader;
/**
* Returns a list of class annotations
* @param $instance
* @return array
*/
public static function getClassAnnotations($instance)
{
$ref = new \ReflectionClass($instance);
return self::getIndexedReader()->getClassAnnotations($ref);
}
/**
* Returns a list of method annotations
* @param $instance
* @param $methodName
* @return array
*/
public static function getMethodAnnotations($instance, $methodName)
{
$ref = new \ReflectionMethod($instance, $methodName);
return self::getIndexedReader()->getMethodAnnotations($ref);
}
/**
* @return IndexedReader
*/
private static function getIndexedReader()
{
if (!isset(self::$indexedReader)) {
self::registerAnnotationNamespaces();
self::$indexedReader = new IndexedReader(self::getAnnotationReader());
}
return self::$indexedReader;
}
/**
* @return AnnotationReader
*/
private static function getAnnotationReader()
{
if (!isset(self::$annotationReader)) {
self::registerAnnotationNamespaces();
self::$annotationReader = new AnnotationReader();
}
return self::$annotationReader;
}
public static function registerAnnotationNamespaces()
{
AnnotationRegistry::registerUniqueLoader('class_exists');
}
/**
* Allows to ignore framework-specific annotations
* @param array $annotations
*/
public static function addIgnoredAnnotations(array $annotations)
{
foreach ($annotations as $annotation) {
self::getAnnotationReader()->addGlobalIgnoredName($annotation);
}
}
/**
* Remove the singleton instances. Useful in unit-testing.
*/
public static function tearDown()
{
static::$indexedReader = null;
static::$annotationReader = null;
}
}
<?php
namespace Yandex\Allure\Adapter\Annotation;
use Doctrine\Common\Annotations\Annotation\Required;
use Yandex\Allure\Adapter\Model\DescriptionType;
/**
* @Annotation
* @Target({"CLASS", "METHOD"})
* @package Yandex\Allure\Adapter\Annotation
*/
class Description
{
/**
* @var string
* @Required
*/
public $value;
/**
* @var string
*/
public $type = DescriptionType::TEXT;
}
<?php
namespace Yandex\Allure\Adapter\Annotation;
use Doctrine\Common\Annotations\Annotation\Required;
/**
* @Annotation
* @Target({"CLASS", "METHOD"})
* @package Yandex\Allure\Adapter\Annotation
*/
class Epics
{
/**
* @var array
* @Required
*/
public $epicNames;
/**
* @return array
*/
public function getEpicNames()
{
return $this->epicNames;
}
}
<?php
namespace Yandex\Allure\Adapter\Annotation;
use Doctrine\Common\Annotations\Annotation\Required;
/**
* @Annotation
* @Target({"CLASS", "METHOD"})
* @package Yandex\Allure\Adapter\Annotation
*/
class Features
{
/**
* @var array
* @Required
*/
public $featureNames;
/**
* @return array
*/
public function getFeatureNames()
{
return $this->featureNames;
}
}
<?php
namespace Yandex\Allure\Adapter\Annotation;
use Doctrine\Common\Annotations\Annotation\Required;
/**
* @Annotation
* @Target({"CLASS", "METHOD"})
* @package Yandex\Allure\Adapter\Annotation
*/
class Issues
{
/**
* @var array
* @Required
*/
public $issueKeys;
/**
* @return array
*/
public function getIssueKeys()
{
return $this->issueKeys;
}
}
<?php
namespace Yandex\Allure\Adapter\Annotation;
use Doctrine\Common\Annotations\Annotation\Required;
use Yandex\Allure\Adapter\Model\ParameterKind;
/**
* @Annotation
* @Target({"METHOD", "ANNOTATION"})
* @package Yandex\Allure\Adapter\Annotation
*/
class Label
{
/**
* @var string
* @Required
*/
public $name;
/**
* @var array
* @Required
*/
public $values;
}
<?php
namespace Yandex\Allure\Adapter\Annotation;
/**
* @Annotation
* @Target({"METHOD"})
* @package Yandex\Allure\Adapter\Annotation
*/
class Labels
{
/**
* @var array<Yandex\Allure\Adapter\Annotation\Label>
* @Required
*/
public $labels;
}
<?php
namespace Yandex\Allure\Adapter\Annotation;
use Doctrine\Common\Annotations\Annotation\Required;
use Yandex\Allure\Adapter\Model\ParameterKind;
/**
* @Annotation
* @Target({"METHOD", "ANNOTATION"})
* @package Yandex\Allure\Adapter\Annotation
*/
class Parameter
{
/**
* @var string
* @Required
*/
public $name;
/**
* @var string
* @Required
*/
public $value;
/**
* @var string
*/
public $kind = ParameterKind::ARGUMENT;
}
<?php
namespace Yandex\Allure\Adapter\Annotation;
use Doctrine\Common\Annotations\Annotation\Required;
/**
* @Annotation
* @Target({"METHOD"})
* @package Yandex\Allure\Adapter\Annotation
*/
class Parameters
{
/**
* @var array<Yandex\Allure\Adapter\Annotation\Parameter>
* @Required
*/
public $parameters;
}
<?php
namespace Yandex\Allure\Adapter\Annotation;
use Yandex\Allure\Adapter\Model\SeverityLevel;
/**
* @Annotation
* @Target({"METHOD"})
* @package Yandex\Allure\Adapter\Annotation
*/
class Severity
{
/**
* @var string
*/
public $level = SeverityLevel::NORMAL;
}
<?php
namespace Yandex\Allure\Adapter\Annotation;
use Doctrine\Common\Annotations\Annotation\Required;
/**
* @Annotation
* @Target({"CLASS", "METHOD"})
* @package Yandex\Allure\Adapter\Annotation
*/
class Stories
{
/**
* @var array
* @Required
*/
public $stories;
/**
* @return array
*/
public function getStories()
{
return $this->stories;
}
}
<?php
namespace Yandex\Allure\Adapter\Annotation;
use Doctrine\Common\Annotations\Annotation\Required;
/**
* @Annotation
* @Target({"CLASS", "METHOD"})
* @package Yandex\Allure\Adapter\Annotation
*/
class TestCaseId
{
/**
* @var array
* @Required
*/
public $testCaseIds;
/**
* @return array
*/
public function getTestCaseIds()
{
return $this->testCaseIds;
}
}
<?php
namespace Yandex\Allure\Adapter\Annotation;
/**
* @Annotation
* @Target({"METHOD"})
* @package Yandex\Allure\Adapter\Annotation
*/
class TestType
{
/**
* @var string
*/
public $type = "screenshotDiff";
}
<?php
namespace Yandex\Allure\Adapter\Annotation;
use Doctrine\Common\Annotations\Annotation\Required;
/**
* @Annotation
* @Target({"CLASS", "METHOD"})
* @package Yandex\Allure\Adapter\Annotation
*/
class Title
{
/**
* @var string
* @Required
*/
public $value;
}
<?php
namespace Yandex\Allure\Adapter\Event;
use Symfony\Component\Mime\MimeTypes;
use Yandex\Allure\Adapter\AllureException;
use Yandex\Allure\Adapter\Model\Attachment;
use Yandex\Allure\Adapter\Model\Entity;
use Yandex\Allure\Adapter\Model\Provider;
use Yandex\Allure\Adapter\Model\Step;
use Yandex\Allure\Adapter\Support\Utils;
const DEFAULT_FILE_EXTENSION = 'txt';
const DEFAULT_MIME_TYPE = 'text/plain';
class AddAttachmentEvent implements StepEvent
{
private $filePathOrContents;
private $caption;
private $type;
public function __construct($filePathOrContents, $caption, $type = null)
{
$this->filePathOrContents = $filePathOrContents;
$this->caption = $caption;
$this->type = $type;
}
public function process(Entity $context)
{
if ($context instanceof Step) {
$newFileName = $this->getAttachmentFileName($this->filePathOrContents, $this->type);
$attachment = new Attachment($this->caption, $newFileName, $this->type);
$context->addAttachment($attachment);
}
}
public function getAttachmentFileName($filePathOrContents, $type)
{
$filePath = $filePathOrContents;
if (!file_exists($filePath) || !is_file($filePath)) {
//Save contents to temporary file
$filePath = tempnam(sys_get_temp_dir(), 'allure-attachment');
if (!file_put_contents($filePath, $filePathOrContents)) {
throw new AllureException("Failed to save attachment contents to $filePath");
}
}
if (!isset($type)) {
$type = $this->guessFileMimeType($filePath);
$this->type = $type;
}
$fileExtension = $this->guessFileExtension($type);
$fileSha1 = sha1_file($filePath);
$outputPath = $this->getOutputPath($fileSha1, $fileExtension);
if (!copy($filePath, $outputPath)) {
throw new AllureException("Failed to copy attachment from $filePath to $outputPath.");
}
return $this->getOutputFileName($fileSha1, $fileExtension);
}
private function guessFileMimeType($filePath)
{
return MimeTypes::getDefault()->guessMimeType($filePath) ?? DEFAULT_MIME_TYPE;
}
private function guessFileExtension($mimeType)
{
$extensions = MimeTypes::getDefault()->getExtensions($mimeType);
return $extensions[0] ?? DEFAULT_FILE_EXTENSION;
}
public function getOutputFileName($sha1, $extension)
{
return $sha1 . '-attachment.' . $extension;
}
public function getOutputPath($sha1, $extension)
{
return Provider::getOutputDirectory() . DIRECTORY_SEPARATOR . $this->getOutputFileName($sha1, $extension);
}
/**
* @return mixed
*/
public function getCaption()
{
return $this->caption;
}
/**
* @return mixed
*/
public function getFilePathOrContents()
{
return $this->filePathOrContents;
}
/**
* @return mixed
*/
public function getType()
{
return $this->type;
}
}
<?php
namespace Yandex\Allure\Adapter\Event;
use Yandex\Allure\Adapter\Model\Entity;
use Yandex\Allure\Adapter\Model\Parameter;
use Yandex\Allure\Adapter\Model\ParameterKind;
use Yandex\Allure\Adapter\Model\TestCase;
class AddParameterEvent implements TestCaseEvent
{
private $name;
private $value;
private $kind;
public function __construct($name, $value, $kind = ParameterKind::SYSTEM_PROPERTY)
{
$this->name = $name;
$this->value = $value;
$this->kind = $kind;
}
public function process(Entity $context)
{
if ($context instanceof TestCase) {
$context->addParameter(new Parameter($this->name, $this->value, $this->kind));
}
}
}
<?php
namespace Yandex\Allure\Adapter\Event;
use Yandex\Allure\Adapter\Model\Entity;
class ClearStepStorageEvent implements StepEvent
{
public function process(Entity $context)
{
}
}
<?php
namespace Yandex\Allure\Adapter\Event;
use Yandex\Allure\Adapter\Model\Entity;
class ClearTestCaseStorageEvent implements TestCaseEvent
{
public function process(Entity $context)
{
}
}
<?php
namespace Yandex\Allure\Adapter\Event;
use Yandex\Allure\Adapter\Model\Entity;
interface Event
{
public function process(Entity $context);
}
<?php
namespace Yandex\Allure\Adapter\Event;
use Yandex\Allure\Adapter\Model\Attachment;
use Yandex\Allure\Adapter\Model\Entity;
use Yandex\Allure\Adapter\Model\Step;
class RemoveAttachmentsEvent implements StepEvent
{
private $pattern;
public function __construct($pattern)
{
$this->pattern = $pattern;
}
public function process(Entity $context)
{
if ($context instanceof Step) {
foreach ($context->getAttachments() as $index => $attachment) {
if ($attachment instanceof Attachment) {
$path = $attachment->getSource();
if (preg_match($this->pattern, $path)) {
if (file_exists($path) && is_writable($path)) {
unlink($path);
}
$context->removeAttachment($index);
}
}
}
}
}
}
<?php
namespace Yandex\Allure\Adapter\Event;
use Yandex\Allure\Adapter\Model\Entity;
use Yandex\Allure\Adapter\Model\Status;
use Yandex\Allure\Adapter\Model\Step;
class StepCanceledEvent implements StepEvent
{
public function process(Entity $context)
{
if ($context instanceof Step) {
$context->setStatus(Status::CANCELED);
}
}
}
<?php
namespace Yandex\Allure\Adapter\Event;
interface StepEvent extends Event
{
}
<?php
namespace Yandex\Allure\Adapter\Event;
use Yandex\Allure\Adapter\Model\Entity;
use Yandex\Allure\Adapter\Model\Status;
use Yandex\Allure\Adapter\Model\Step;
class StepFailedEvent implements StepEvent
{
public function process(Entity $context)
{
if ($context instanceof Step) {
$context->setStatus(Status::FAILED);
}
}
}
<?php
namespace Yandex\Allure\Adapter\Event;
use Yandex\Allure\Adapter\Model\Entity;
use Yandex\Allure\Adapter\Model\Step;
use Yandex\Allure\Adapter\Support\Utils;
class StepFinishedEvent implements StepEvent
{
use Utils;
public function process(Entity $context)
{
if ($context instanceof Step) {
$context->setStop(self::getTimestamp());
}
}
}
<?php
namespace Yandex\Allure\Adapter\Event;
use Yandex\Allure\Adapter\Model\Entity;
use Yandex\Allure\Adapter\Model\Status;
use Yandex\Allure\Adapter\Model\Step;
use Yandex\Allure\Adapter\Support\Utils;
class StepStartedEvent implements StepEvent
{
use Utils;
private $name;
private $title;
public function __construct($name)
{
$this->name = $name;
}
public function process(Entity $context)
{
if ($context instanceof Step) {
$context->setName($this->name);
$context->setStatus(Status::PASSED);
$context->setStart(self::getTimestamp());
$context->setTitle($this->title);
}
}
public function withTitle($title)
{
$this->title = $title;
return $this;
}
}
<?php
namespace Yandex\Allure\Adapter\Event\Storage;
use Yandex\Allure\Adapter\Model\Status;
use Yandex\Allure\Adapter\Model\Step;
use \SplStack;
use Yandex\Allure\Adapter\Support\Utils;
class StepStorage
{
use Utils;
const ROOT_STEP_NAME = 'root-step';
/**
* @var SplStack
*/
private $storage;
public function __construct()
{
$this->storage = new SplStack();
}
/**
* @return Step
*/
public function getLast()
{
if ($this->storage->isEmpty()) {
$this->put($this->getRootStep());
}
return $this->storage->top();
}
/**
* @return Step
*/
public function pollLast()
{
$step = $this->storage->pop();
if ($this->storage->isEmpty()) {
$this->storage->push($this->getRootStep());
}
return $step;
}
/**
* @param Step $step
*/
public function put(Step $step)
{
$this->storage->push($step);
}
public function clear()
{
$this->storage = new SplStack();
$this->put($this->getRootStep());
}
public function isEmpty()
{
return ($this->size() === 0) && $this->isRootStep($this->getLast());
}
public function size()
{
return $this->storage->count() - 1;
}
public function isRootStep(Step $step)
{
return $step->getName() === self::ROOT_STEP_NAME;
}
/**
* @return Step
*/
protected function getRootStep()
{
$step = new Step();
$step->setName(self::ROOT_STEP_NAME);
$step->setTitle(
"If you're seeing this then there's an error in step processing. "
. "Please send feedback to allure@yandex-team.ru. Thank you."
);
$step->setStart(self::getTimestamp());
$step->setStatus(Status::BROKEN);
return $step;
}
}
<?php
namespace Yandex\Allure\Adapter\Event\Storage;
use Yandex\Allure\Adapter\Model\TestCase;
class TestCaseStorage
{
/**
* @var TestCase
*/
private $case;
/**
* @return TestCase
*/
public function get()
{
if (!isset($this->case)) {
$this->case = new TestCase();
}
return $this->case;
}
/**
* @param TestCase $case
*/
public function put(TestCase $case)
{
$this->case = $case;
}
public function clear()
{
unset($this->case);
}
public function isEmpty()
{
return !isset($this->case);
}
}
<?php
namespace Yandex\Allure\Adapter\Event\Storage;
use Yandex\Allure\Adapter\Model\TestSuite;
class TestSuiteStorage
{
/**
* @var array
*/
private $storage;
public function __construct()
{
$this->clear();
}
/**
* @param string $uuid
* @return TestSuite
*/
public function get($uuid)
{
if (!array_key_exists($uuid, $this->storage)) {
$this->storage[$uuid] = new TestSuite();
}
return $this->storage[$uuid];
}
public function remove($uuid)
{
if (array_key_exists($uuid, $this->storage)) {
unset($this->storage[$uuid]);
}
}
public function clear()
{
$this->storage = [];
}
public function isEmpty()
{
return $this->size() === 0;
}
public function size()
{
return sizeof($this->storage);
}
}
<?php
namespace Yandex\Allure\Adapter\Event;
use Yandex\Allure\Adapter\Model\Status;
class TestCaseBrokenEvent extends TestCaseStatusChangedEvent
{
/**
* @return string
*/
protected function getStatus()
{
return Status::BROKEN;
}
}
<?php
namespace Yandex\Allure\Adapter\Event;
use Yandex\Allure\Adapter\Model\Status;
class TestCaseCanceledEvent extends TestCaseStatusChangedEvent
{
/**
* @return string
*/
protected function getStatus()
{
return Status::CANCELED;
}
}
<?php
namespace Yandex\Allure\Adapter\Event;
interface TestCaseEvent extends Event
{
}
<?php
namespace Yandex\Allure\Adapter\Event;
use Yandex\Allure\Adapter\Model\Status;
class TestCaseFailedEvent extends TestCaseStatusChangedEvent
{
/**
* @return string
*/
protected function getStatus()
{
return Status::FAILED;
}
}
<?php
namespace Yandex\Allure\Adapter\Event;
use Yandex\Allure\Adapter\Model\Entity;
use Yandex\Allure\Adapter\Model\TestCase;
use Yandex\Allure\Adapter\Support\Utils;
class TestCaseFinishedEvent implements TestCaseEvent
{
use Utils;
public function process(Entity $context)
{
if ($context instanceof TestCase) {
$context->setStop(self::getTimestamp());
}
}
}
<?php
namespace Yandex\Allure\Adapter\Event;
use Yandex\Allure\Adapter\Model\Status;
class TestCasePendingEvent extends TestCaseStatusChangedEvent
{
/**
* @return string
*/
protected function getStatus()
{
return Status::PENDING;
}
}
<?php
namespace Yandex\Allure\Adapter\Event;
use Yandex\Allure\Adapter\Model\Description;
use Yandex\Allure\Adapter\Model\Entity;
use Yandex\Allure\Adapter\Model\Status;
use Yandex\Allure\Adapter\Model\TestCase;
use Yandex\Allure\Adapter\Support\Utils;
class TestCaseStartedEvent implements TestCaseEvent
{
use Utils;
/**
* @var string
*/
private $suiteUuid;
/**
* @var string
*/
private $name;
/**
* @var string
*/
private $title;
/**
* @var Description
*/
private $description;
/**
* @var array
*/
private $labels;
/**
* @var array
*/
private $parameters;
public function __construct($suiteUuid, $name)
{
$this->suiteUuid = $suiteUuid;
$this->name = $name;
$this->labels = [];
$this->parameters = [];
}
public function process(Entity $context)
{
if ($context instanceof TestCase) {
$context->setName($this->getName());
$context->setStatus(Status::PASSED);
$context->setStart(self::getTimestamp());
$context->setTitle($this->getTitle());
$description = $this->getDescription();
if (isset($description)) {
$context->setDescription($description);
}
foreach ($this->getLabels() as $label) {
$context->addLabel($label);
}
foreach ($this->getParameters() as $parameter) {
$context->addParameter($parameter);
}
}
}
/**
* @param string $title
* @return $this
*/
public function withTitle($title)
{
$this->setTitle($title);
return $this;
}
/**
* @param Description $description
* @return $this
*/
public function withDescription(Description $description)
{
$this->setDescription($description);
return $this;
}
/**
* @param array $labels
* @return $this
*/
public function withLabels(array $labels)
{
$this->setLabels($labels);
return $this;
}
/**
* @param array $parameters
* @return $this
*/
public function withParameters(array $parameters)
{
$this->setParameters($parameters);
return $this;
}
/**
* @return string
*/
public function getSuiteUuid()
{
return $this->suiteUuid;
}
/**
* @param \Yandex\Allure\Adapter\Model\Description $description
*/
public function setDescription($description)
{
$this->description = $description;
}
/**
* @param array $labels
*/
public function setLabels(array $labels)
{
$this->labels = $labels;
}
/**
* @param string $title
*/
public function setTitle($title)
{
$this->title = $title;
}
/**
* @param array $parameters
*/
public function setParameters($parameters)
{
$this->parameters = $parameters;
}
/**
* @return \Yandex\Allure\Adapter\Model\Description
*/
public function getDescription()
{
return $this->description;
}
/**
* @return array
*/
public function getLabels()
{
return $this->labels;
}
/**
* @return array
*/
public function getParameters()
{
return $this->parameters;
}
/**
* @return string
*/
public function getTitle()
{
return $this->title;
}
/**
* @return string
*/
public function getName()
{
return $this->name;
}
}
<?php
namespace Yandex\Allure\Adapter\Event;
use Throwable;
use Yandex\Allure\Adapter\Model\Entity;
use Yandex\Allure\Adapter\Model\Failure;
use Yandex\Allure\Adapter\Model\TestCase;
abstract class TestCaseStatusChangedEvent implements TestCaseEvent
{
/**
* @var Throwable
*/
private $exception;
/**
* @var string
*/
private $message;
/**
* @return string
*/
abstract protected function getStatus();
public function process(Entity $context)
{
if ($context instanceof TestCase) {
$context->setStatus($this->getStatus());
$exception = $this->exception;
if (isset($exception)) {
$failure = new Failure($this->message);
$failure->setStackTrace($exception->getTraceAsString());
$context->setFailure($failure);
}
}
}
/**
* @param string $message
* @return $this
*/
public function withMessage($message)
{
$this->message = $message;
return $this;
}
/**
* @param Throwable $exception
* @return $this
*/
public function withException(Throwable $exception)
{
$this->exception = $exception;
return $this;
}
}
<?php
namespace Yandex\Allure\Adapter\Event;
interface TestSuiteEvent extends Event
{
/**
* @return string
*/
public function getUuid();
}
<?php
namespace Yandex\Allure\Adapter\Event;
use Yandex\Allure\Adapter\Model\Entity;
use Yandex\Allure\Adapter\Model\TestSuite;
use Yandex\Allure\Adapter\Support\Utils;
class TestSuiteFinishedEvent implements TestSuiteEvent
{
use Utils;
/**
* @var string
*/
private $uuid;
public function __construct($uuid)
{
$this->uuid = $uuid;
}
public function process(Entity $context)
{
if ($context instanceof TestSuite) {
$context->setStop(self::getTimestamp());
}
}
public function getUuid()
{
return $this->uuid;
}
}
<?php
namespace Yandex\Allure\Adapter\Event;
use Yandex\Allure\Adapter\Model\Description;
use Yandex\Allure\Adapter\Model\Entity;
use Yandex\Allure\Adapter\Model\TestSuite;
use Yandex\Allure\Adapter\Support\Utils;
class TestSuiteStartedEvent implements TestSuiteEvent
{
use Utils;
/**
* @var string
*/
private $name;
/**
* @var string
*/
private $title;
/**
* @var Description
*/
private $description;
/**
* @var array
*/
private $labels;
/**
* @var string
*/
private $uuid;
public function __construct($name)
{
$this->name = $name;
$this->labels = [];
}
public function process(Entity $context)
{
if ($context instanceof TestSuite) {
$context->setName($this->getName());
$context->setStart(self::getTimestamp());
$context->setTitle($this->getTitle());
$description = $this->getDescription();
if (isset($description)) {
$context->setDescription($this->getDescription());
}
foreach ($this->getLabels() as $label) {
$context->addLabel($label);
}
}
}
/**
* @param string $title
* @return $this
*/
public function withTitle($title)
{
$this->setTitle($title);
return $this;
}
/**
* @param Description $description
* @return $this
*/
public function withDescription(Description $description)
{
$this->setDescription($description);
return $this;
}
/**
* @param array $labels
* @return $this
*/
public function withLabels(array $labels)
{
$this->setLabels($labels);
return $this;
}
/**
* @param \Yandex\Allure\Adapter\Model\Description $description
*/
public function setDescription($description)
{
$this->description = $description;
}
/**
* @param array $labels
*/
public function setLabels($labels)
{
$this->labels = $labels;
}
/**
* @param string $name
*/
public function setName($name)
{
$this->name = $name;
}
/**
* @param string $title
*/
public function setTitle($title)
{
$this->title = $title;
}
/**
* @return \Yandex\Allure\Adapter\Model\Description
*/
public function getDescription()
{
return $this->description;
}
/**
* @return array
*/
public function getLabels()
{
return $this->labels;
}
/**
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* @return string
*/
public function getTitle()
{
return $this->title;
}
public function getUuid()
{
if (!isset($this->uuid)) {
$this->uuid = self::generateUUID();
}
return $this->uuid;
}
}
<?php
namespace Yandex\Allure\Adapter\Model;
use JMS\Serializer\Annotation\Type;
use JMS\Serializer\Annotation\XmlAttribute;
/**
* @package Yandex\Allure\Adapter\Model
*/
class Attachment implements Entity
{
/**
* @var string
* @Type("string")
* @XmlAttribute
*/
private $title;
/**
* @var string
* @Type("string")
* @XmlAttribute
*/
private $source;
/**
* @var string
* @Type("string")
* @XmlAttribute
*/
private $type;
public function __construct($title, $source, $type)
{
$this->source = $source;
$this->title = $title;
$this->type = $type;
}
/**
* @return string
*/
public function getSource()
{
return $this->source;
}
/**
* @return string
*/
public function getTitle()
{
return $this->title;
}
/**
* @return string
*/
public function getType()
{
return $this->type;
}
}
<?php
namespace Yandex\Allure\Adapter\Model;
use Yandex\Allure\Adapter\AllureException;
/**
* @package Yandex\Allure\Adapter\Model
*/
class ConstantChecker
{
/**
* Checks whether constant with the specified value is present. If it's present it's returned. An
* exception is thrown otherwise.
* @param $className
* @param $value
* @throws AllureException
* @return
*/
public static function validate($className, $value)
{
$ref = new \ReflectionClass($className);
foreach ($ref->getConstants() as $constantValue) {
if ($constantValue === $value) {
return $value;
}
}
throw new AllureException(
"Value \"$value\" is not present in class $className. You should use a constant from this class."
);
}
}
<?php
namespace Yandex\Allure\Adapter\Model;
use JMS\Serializer\Annotation\Type;
use JMS\Serializer\Annotation\XmlAttribute;
use JMS\Serializer\Annotation\XmlRoot;
use JMS\Serializer\Annotation\XmlValue;
/**
* @package Yandex\Allure\Adapter\Model
* @XmlRoot("description")
*/
class Description implements Entity
{
/**
* @Type("string")
* @XmlAttribute
*/
private $type;
/**
* @Type("string")
* @XmlValue
*/
private $value;
public function __construct($type, $value)
{
$this->type = ConstantChecker::validate('Yandex\Allure\Adapter\Model\DescriptionType', $type);
$this->value = $value;
}
/**
* @return string
*/
public function getType()
{
return $this->type;
}
/**
* @return string
*/
public function getValue()
{
return $this->value;
}
}
<?php
namespace Yandex\Allure\Adapter\Model;
/**
* Description type
* @package Yandex\Allure\Adapter\Model
*/
final class DescriptionType
{
const TEXT = 'text';
const HTML = 'html';
const MARKDOWN = 'markdown';
}
<?php
namespace Yandex\Allure\Adapter\Model;
/**
* Marker interface
* @package Yandex\Allure\Adapter\Model
*/
interface Entity
{
}
<?php
namespace Yandex\Allure\Adapter\Model;
use JMS\Serializer\Annotation\SerializedName;
use JMS\Serializer\Annotation\Type;
use JMS\Serializer\Annotation\XmlElement;
class Failure implements Entity
{
/**
* @var string
* @Type("string")
* @XmlElement(cdata=false)
*/
private $message;
/**
* @var string
* @Type("string")
* @XmlElement(cdata=false)
* @SerializedName("stack-trace")
*/
private $stackTrace;
public function __construct($message)
{
$this->message = $message;
}
/**
* @return string
*/
public function getMessage()
{
return $this->message;
}
/**
* @return string
*/
public function getStackTrace()
{
return $this->stackTrace;
}
/**
* @param string $stackTrace
*/
public function setStackTrace($stackTrace)
{
$this->stackTrace = $stackTrace;
}
}
<?php
namespace Yandex\Allure\Adapter\Model;
use JMS\Serializer\Annotation\Type;
use JMS\Serializer\Annotation\XmlAttribute;
use JMS\Serializer\Annotation\XmlRoot;
/**
* @package Yandex\Allure\Adapter\Model
* @XmlRoot("label")
*/
class Label implements Entity
{
/**
* @var string
* @Type("string")
* @XmlAttribute
*/
private $name;
/**
* @var string
* @Type("string")
* @XmlAttribute
*/
private $value;
public function __construct($name, $value)
{
$this->name = $name;
$this->value = $value;
}
/**
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* @return string
*/
public function getValue()
{
return $this->value;
}
/**
* @param $id
* @return Label
*/
public static function id($id)
{
return new Label(LabelType::ID, $id);
}
/**
* @param $epicName
* @return Label
*/
public static function epic($epicName)
{
return new Label(LabelType::EPIC, $epicName);
}
/**
* @param $featureName
* @return Label
*/
public static function feature($featureName)
{
return new Label(LabelType::FEATURE, $featureName);
}
/**
* @param $storyName
* @return Label
*/
public static function story($storyName)
{
return new Label(LabelType::STORY, $storyName);
}
/**
* @param $severityLevel
* @return Label
*/
public static function severity($severityLevel)
{
return new Label(LabelType::SEVERITY, $severityLevel);
}
/**
* @param $testType
* @return Label
*/
public static function testType($testType)
{
return new Label(LabelType::TEST_TYPE, $testType);
}
/**
* @param $issueKey
* @return Label
*/
public static function issue($issueKey)
{
return new Label(LabelType::ISSUE, $issueKey);
}
/**
* @param $testCaseId
*
* @return Label
*/
public static function testId($testCaseId)
{
return new Label(LabelType::TEST_ID, $testCaseId);
}
/**
* @param $name
* @param $value
*
* @return Label
*/
public static function label($name, $value)
{
return new Label($name, $value);
}
}
<?php
namespace Yandex\Allure\Adapter\Model;
class LabelType
{
const ID = 'AS_ID';
const EPIC = 'epic';
const FEATURE = 'feature';
const STORY = 'story';
const SEVERITY = 'severity';
const ISSUE = 'issue';
const TEST_ID = 'testId';
const TEST_TYPE = 'testType';
}
<?php
namespace Yandex\Allure\Adapter\Model;
use JMS\Serializer\Annotation\Type;
use JMS\Serializer\Annotation\XmlAttribute;
class Parameter implements Entity
{
/**
* @var string
* @Type("string")
* @XmlAttribute
*/
private $name;
/**
* @var string
* @Type("string")
* @XmlAttribute
*/
private $value;
/**
* @var string
* @Type("string")
* @XmlAttribute
*/
private $kind;
public function __construct($name, $value, $kind = ParameterKind::SYSTEM_PROPERTY)
{
$this->kind = ConstantChecker::validate('Yandex\Allure\Adapter\Model\ParameterKind', $kind);
$this->name = $name;
$this->value = $value;
}
/**
* @return string
*/
public function getKind()
{
return $this->kind;
}
/**
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* @return string
*/
public function getValue()
{
return $this->value;
}
}
<?php
namespace Yandex\Allure\Adapter\Model;
/**
* Parameter kind
* @package Yandex\Allure\Adapter\Model
*/
final class ParameterKind
{
const ARGUMENT = 'argument';
const SYSTEM_PROPERTY = 'system-property';
const ENVIRONMENT_VARIABLE = 'environment-variable';
}
<?php
namespace Yandex\Allure\Adapter\Model;
class Provider
{
/**
* @var string
*/
private static $outputDirectory;
/**
* @param string $outputDirectory
*/
public static function setOutputDirectory($outputDirectory)
{
self::$outputDirectory = $outputDirectory;
}
/**
* @return string
*/
public static function getOutputDirectory()
{
return self::$outputDirectory;
}
}
<?php
namespace Yandex\Allure\Adapter\Model;
/**
* Severity level
* @package Yandex\Allure\Adapter\Model
*/
final class SeverityLevel
{
const BLOCKER = 'blocker';
const CRITICAL = 'critical';
const NORMAL = 'normal';
const MINOR = 'minor';
const TRIVIAL = 'trivial';
}
<?php
namespace Yandex\Allure\Adapter\Model;
/**
* Step status
* @package Yandex\Allure\Adapter\Model
*/
final class Status
{
const FAILED = 'failed';
const BROKEN = 'broken';
const PASSED = 'passed';
const CANCELED = 'canceled';
const PENDING = 'pending';
}
<?php
namespace Yandex\Allure\Adapter\Model;
use JMS\Serializer\Annotation\Type;
use JMS\Serializer\Annotation\XmlAttribute;
use JMS\Serializer\Annotation\XmlList;
use JMS\Serializer\Annotation\XmlElement;
class Step implements Entity
{
/**
* @var int
* @Type("integer")
* @XmlAttribute
*/
private $start;
/**
* @var int
* @Type("integer")
* @XmlAttribute
*/
private $stop;
/**
* @var string
* @Type("string")
* @XmlElement
*/
private $name;
/**
* @var string
* @Type("string")
* @XmlElement
*/
private $title;
/**
* @var array
* @Type("array<Yandex\Allure\Adapter\Model\Step>")
* @XmlList(entry = "step")
*/
private $steps;
/**
* @var array
* @Type("array<Yandex\Allure\Adapter\Model\Attachment>")
* @XmlList(entry = "attachment")
*/
private $attachments;
/**
* @var Status
* @Type("string")
* @XmlAttribute
*/
private $status;
public function __construct()
{
$this->steps = [];
$this->attachments = [];
}
/**
* @param string $name
*/
public function setName($name)
{
$this->name = $name;
}
/**
* @param int $start
*/
public function setStart($start)
{
$this->start = $start;
}
/**
* @param int $stop
*/
public function setStop($stop)
{
$this->stop = $stop;
}
/**
* @param string $status
*/
public function setStatus($status)
{
$this->status = ConstantChecker::validate('Yandex\Allure\Adapter\Model\Status', $status);
}
/**
* @return array
*/
public function getAttachments()
{
return $this->attachments;
}
/**
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* @return int
*/
public function getStart()
{
return $this->start;
}
/**
* @return array
*/
public function getSteps()
{
return $this->steps;
}
/**
* @return int
*/
public function getStop()
{
return $this->stop;
}
/**
* @return string
*/
public function getTitle()
{
return $this->title;
}
/**
* @return string
*/
public function getStatus()
{
return $this->status;
}
/**
* @param string $title
*/
public function setTitle($title)
{
$this->title = $title;
}
/**
* @param \Yandex\Allure\Adapter\Model\Step $step
*/
public function addStep(Step $step)
{
$this->steps[] = $step;
}
/**
* @param \Yandex\Allure\Adapter\Model\Attachment $attachment
*/
public function addAttachment(Attachment $attachment)
{
$this->attachments[] = $attachment;
}
/**
* @param $index
*/
public function removeAttachment($index)
{
if (isset($this->attachments[$index])) {
unset($this->attachments[$index]);
}
}
}
<?php
namespace Yandex\Allure\Adapter\Model;
use JMS\Serializer\Annotation\Type;
use JMS\Serializer\Annotation\XmlAttribute;
use JMS\Serializer\Annotation\XmlElement;
use JMS\Serializer\Annotation\XmlList;
use JMS\Serializer\Annotation\XmlRoot;
/**
* @package Yandex\Allure\Adapter\Model
* @XmlRoot("test-case")
*/
class TestCase implements Entity
{
/**
* @var int
* @Type("integer")
* @XmlAttribute
*/
private $start;
/**
* @var int
* @Type("integer")
* @XmlAttribute
*/
private $stop;
/**
* @var string
* @Type("string")
* @XmlAttribute
*/
private $status = Status::PASSED;
/**
* @var string
* @Type("string")
* @XmlElement(cdata=false)
*/
private $name;
/**
* @var string
* @Type("string")
* @XmlElement
*/
private $title;
/**
* @var Description
* @Type("Yandex\Allure\Adapter\Model\Description")
*/
private $description;
/**
* @var Failure
* @Type("Yandex\Allure\Adapter\Model\Failure")
*/
private $failure;
/**
* @var array
* @Type("array<Yandex\Allure\Adapter\Model\Step>")
* @XmlList(entry = "step")
*/
private $steps;
/**
* @var array
* @Type("array<Yandex\Allure\Adapter\Model\Attachment>")
* @XmlList(entry = "attachment")
*/
private $attachments;
/**
* @Type("array<Yandex\Allure\Adapter\Model\Label>")
* @XmlList(entry = "label")
*/
private $labels;
/**
* @var array
* @Type("array<Yandex\Allure\Adapter\Model\Parameter>")
* @XmlList(entry = "parameter")
*/
private $parameters;
public function __construct()
{
$this->steps = [];
$this->labels = [];
$this->attachments = [];
$this->parameters = [];
}
/**
* @return array
*/
public function getAttachments()
{
return $this->attachments;
}
/**
* @return array
*/
public function getLabels()
{
return $this->labels;
}
/**
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* @return array
*/
public function getSteps()
{
return $this->steps;
}
/**
* @return string
*/
public function getTitle()
{
return $this->title;
}
/**
* @return int
*/
public function getStart()
{
return $this->start;
}
/**
* @return int
*/
public function getStop()
{
return $this->stop;
}
/**
* @return string
*/
public function getStatus()
{
return $this->status;
}
/**
* @return \Yandex\Allure\Adapter\Model\Description
*/
public function getDescription()
{
return $this->description;
}
/**
* @return \Yandex\Allure\Adapter\Model\Failure
*/
public function getFailure()
{
return $this->failure;
}
/**
* @return array
*/
public function getParameters()
{
return $this->parameters;
}
/**
* @param string $name
*/
public function setName($name)
{
$this->name = $name;
}
/**
* @param int $start
*/
public function setStart($start)
{
$this->start = $start;
}
/**
* @param int $stop
*/
public function setStop($stop)
{
$this->stop = $stop;
}
/**
* @param string $status
*/
public function setStatus($status)
{
$this->status = ConstantChecker::validate('Yandex\Allure\Adapter\Model\Status', $status);
}
/**
* @param \Yandex\Allure\Adapter\Model\Description $description
*/
public function setDescription($description)
{
$this->description = $description;
}
/**
* @param \Yandex\Allure\Adapter\Model\Failure $failure
*/
public function setFailure($failure)
{
$this->failure = $failure;
}
/**
* @param string $title
*/
public function setTitle($title)
{
$this->title = $title;
}
/**
* @param \Yandex\Allure\Adapter\Model\Label $label
*/
public function addLabel(Label $label)
{
$this->labels[] = $label;
}
/**
* @param \Yandex\Allure\Adapter\Model\Step $step
*/
public function addStep(Step $step)
{
$this->steps[] = $step;
}
/**
* @param \Yandex\Allure\Adapter\Model\Attachment $attachment
*/
public function addAttachment(Attachment $attachment)
{
$this->attachments[] = $attachment;
}
/**
* @param \Yandex\Allure\Adapter\Model\Parameter $parameter
*/
public function addParameter(Parameter $parameter)
{
$this->parameters[] = $parameter;
}
}
<?php
namespace Yandex\Allure\Adapter\Model;
use JMS\Serializer\Annotation\XmlElement;
use JMS\Serializer\Serializer;
use JMS\Serializer\SerializerBuilder;
use JMS\Serializer\Annotation\Exclude;
use JMS\Serializer\Annotation\ExclusionPolicy;
use JMS\Serializer\Annotation\SerializedName;
use JMS\Serializer\Annotation\Type;
use JMS\Serializer\Annotation\XmlAttribute;
use JMS\Serializer\Annotation\XmlList;
use JMS\Serializer\Annotation\XmlNamespace;
use JMS\Serializer\Annotation\XmlRoot;
/**
* @package Yandex\Allure\Adapter\Model
* @XmlNamespace(uri="urn:model.allure.qatools.yandex.ru", prefix="alr")
* @XmlRoot(name="alr:test-suite")
* @ExclusionPolicy("none")
*/
class TestSuite implements \Serializable, Entity
{
const DEFAULT_VERSION = '1.4.0';
/**
* @var int
* @Type("integer")
* @XmlAttribute
*/
private $start;
/**
* @var int
* @Type("integer")
* @XmlAttribute
*/
private $stop;
/**
* @var string
* @Type("string")
* @XmlAttribute
*/
private $version;
/**
* @var string
* @Type("string")
* @XmlElement(cdata=false)
*/
private $name;
/**
* @var string
* @Type("string")
* @XmlElement(cdata=false)
*/
private $title;
/**
* @var Description
* @Type("Yandex\Allure\Adapter\Model\Description")
*/
private $description;
/**
* @var array
* @Type("array<Yandex\Allure\Adapter\Model\TestCase>")
* @XmlList(entry = "test-case")
* @SerializedName("test-cases")
*/
private $testCases;
/**
* @var array
* @Type("array<Yandex\Allure\Adapter\Model\Label>")
* @XmlList(entry = "label")
*/
private $labels;
/**
* @var Serializer
* @Exclude
*/
private $serializer;
/**
* @var TestCase
* @Type("Yandex\Allure\Adapter\Model\TestCase")
* @Exclude
*/
private $currentTestCase;
public function __construct()
{
$this->testCases = [];
$this->labels = [];
$this->version = self::DEFAULT_VERSION;
}
/**
* @return Description
*/
public function getDescription()
{
return $this->description;
}
/**
* @return array
*/
public function getLabels()
{
return $this->labels;
}
/**
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* @return int
*/
public function getStart()
{
return $this->start;
}
/**
* @return int
*/
public function getStop()
{
return $this->stop;
}
/**
* @return string
*/
public function getVersion()
{
return $this->version;
}
/**
* @return int
*/
public function getTitle()
{
return $this->title;
}
/**
* @param int $start
*/
public function setStart($start)
{
$this->start = $start;
}
/**
* @param string $name
*/
public function setName($name)
{
$this->name = $name;
}
/**
* @param string $title
*/
public function setTitle($title)
{
$this->title = $title;
}
/**
* @param int $stop
*/
public function setStop($stop)
{
$this->stop = $stop;
}
/**
* @param string $version
*/
public function setVersion($version)
{
$this->version = $version;
}
/**
* @param \Yandex\Allure\Adapter\Model\Description $description
*/
public function setDescription(Description $description)
{
$this->description = $description;
}
/**
* @param \Yandex\Allure\Adapter\Model\TestCase $testCase
*/
public function addTestCase(TestCase $testCase)
{
$this->testCases[$testCase->getName()] = $testCase;
}
/**
* Returns test case by name
* @param string $name
* @return \Yandex\Allure\Adapter\Model\TestCase
*/
public function getTestCase($name)
{
return $this->testCases[$name];
}
/**
* Return total count of child elements (test cases or test suites)
* @return int
*/
public function size()
{
return count($this->testCases);
}
/**
* @param \Yandex\Allure\Adapter\Model\Label $label
*/
public function addLabel(Label $label)
{
$this->labels[] = $label;
}
/**
* @return string
*/
public function serialize()
{
return $this->getSerializer()->serialize($this, 'xml');
}
/**
* @param string $serialized
* @return mixed
*/
public function unserialize($serialized)
{
return $this->getSerializer()->deserialize($serialized, \Yandex\Allure\Adapter\Model\TestSuite::class, 'xml');
}
/**
+ * @return string
+ */
public function __serialize()
{
return $this->getSerializer()->serialize($this, 'xml');
}
/**
+ * @param string $serialized
+ * @return mixed
+ */
public function __unserialize($serialized)
{
return $this->getSerializer()->deserialize($serialized, \Yandex\Allure\Adapter\Model\TestSuite::class, 'xml');
}
/**
* @return Serializer
*/
private function getSerializer()
{
if (!isset($this->serializer)) {
$this->serializer = SerializerBuilder::create()->build();
}
return $this->serializer;
}
}
<?php
namespace Yandex\Allure\Adapter\Support;
use Yandex\Allure\Adapter\Allure;
use Yandex\Allure\Adapter\Event\AddAttachmentEvent;
use Yandex\Allure\Adapter\Model;
/**
* Use this trait in order to add Allure attachments support in your tests
* @package Yandex\Allure\Adapter\Support
*/
trait AttachmentSupport
{
/**
* Adds a new attachment to report
* @param string $filePathOrContents either a string with file contents or file path to copy
* @param $caption
* @param $type
*/
public function addAttachment($filePathOrContents, $caption, $type = null)
{
Allure::lifecycle()->fire(new AddAttachmentEvent($filePathOrContents, $caption, $type));
}
}
<?php
namespace Yandex\Allure\Adapter\Support;
use Exception;
use Yandex\Allure\Adapter\Allure;
use Yandex\Allure\Adapter\AllureException;
use Yandex\Allure\Adapter\Event\StepFailedEvent;
use Yandex\Allure\Adapter\Event\StepFinishedEvent;
use Yandex\Allure\Adapter\Event\StepStartedEvent;
const STEP_LOGIC_KEY = 'logic';
const STEP_TITLE_KEY = 'title';
const STEP_CHILD_STEPS_KEY = 'childSteps';
/**
* Use this trait in order to add Allure steps support
* @package Yandex\Allure\Adapter\Support
*/
trait StepSupport
{
use Utils;
/**
* Adds a simple step to current test case
* @param string $name step name
* @param callable $logic anonymous function containing the entire step logic.
* @param string $title an optional title for the step
* @return mixed
* @throws \Yandex\Allure\Adapter\AllureException
* @throws \Exception
*/
public function executeStep($name, $logic, $title = null)
{
$logicResult = null;
if (isset($name) && is_callable($logic)) {
$event = new StepStartedEvent($name);
if (isset($title)) {
$event->withTitle($title);
} else {
$event->withTitle($name);
}
Allure::lifecycle()->fire($event);
try {
$logicResult = $logic();
Allure::lifecycle()->fire(new StepFinishedEvent());
} catch (Exception $e) {
$stepFailedEvent = new StepFailedEvent();
Allure::lifecycle()->fire($stepFailedEvent);
Allure::lifecycle()->fire(new StepFinishedEvent());
throw $e;
}
} else {
throw new AllureException("Step name shouldn't be null and logic should be a callable.");
}
return $logicResult;
}
}
<?php
namespace Yandex\Allure\Adapter\Support;
use Ramsey\Uuid\Uuid;
trait Utils
{
/**
* @return float
*/
public static function getTimestamp()
{
return round(microtime(true) * 1000);
}
/**
* @return string
*/
public static function generateUUID()
{
return Uuid::uuid4()->toString();
}
}
<?php
namespace Yandex\Allure\Adapter;
use Doctrine\Common\Annotations\AnnotationRegistry;
use Yandex\Allure\Adapter\Event\ClearStepStorageEvent;
use Yandex\Allure\Adapter\Event\ClearTestCaseStorageEvent;
use Yandex\Allure\Adapter\Event\StepFinishedEvent;
use Yandex\Allure\Adapter\Event\StepStartedEvent;
use Yandex\Allure\Adapter\Event\TestCaseFinishedEvent;
use Yandex\Allure\Adapter\Event\TestCaseStartedEvent;
use Yandex\Allure\Adapter\Event\TestSuiteFinishedEvent;
use Yandex\Allure\Adapter\Model\Attachment;
use Yandex\Allure\Adapter\Model\Provider;
use Yandex\Allure\Adapter\Model\Step;
use Yandex\Allure\Adapter\Model\TestCase;
use Yandex\Allure\Adapter\Fixtures\GenericStepEvent;
use Yandex\Allure\Adapter\Fixtures\GenericTestCaseEvent;
use Yandex\Allure\Adapter\Fixtures\GenericTestSuiteEvent;
use PHPUnit\Framework\TestCase as PhpUnitTestCase;
class AllureTest extends PhpUnitTestCase
{
const STEP_NAME = 'step-name';
const TEST_CASE_NAME = 'test-case-name';
const TEST_SUITE_NAME = 'test-suite-name';
const TEST_SUITE_UUID = 'test-suite-uuid';
const STEP_ATTACHMENT_TITLE = 'step-attachment-caption';
const STEP_ATTACHMENT_SOURCE = 'step-attachment-source';
const STEP_ATTACHMENT_TYPE = 'text/plain';
public function testStepStorageClearEvent()
{
Allure::lifecycle()->getStepStorage()->clear();
Allure::lifecycle()->getStepStorage()->put(new Step());
Allure::lifecycle()->fire(new ClearStepStorageEvent());
$this->assertTrue(Allure::lifecycle()->getStepStorage()->isEmpty());
}
public function testTestCaseStorageClear()
{
Allure::lifecycle()->getTestCaseStorage()->clear();
Allure::lifecycle()->getTestCaseStorage()->put(new TestCase());
Allure::lifecycle()->fire(new ClearTestCaseStorageEvent());
$this->assertTrue(Allure::lifecycle()->getTestCaseStorage()->isEmpty());
}
public function testStepStartedEvent()
{
Allure::lifecycle()->getStepStorage()->clear();
$this->assertTrue(Allure::lifecycle()->getStepStorage()->isEmpty());
Allure::lifecycle()->fire(new StepStartedEvent(self::STEP_NAME));
$this->assertEquals(1, Allure::lifecycle()->getStepStorage()->size());
$step = Allure::lifecycle()->getStepStorage()->getLast();
$this->assertEquals(self::STEP_NAME, $step->getName());
}
public function testStepFinishedEvent()
{
$step = new Step();
$step->setName(self::STEP_NAME);
Allure::lifecycle()->getStepStorage()->put($step);
Allure::lifecycle()->fire(new StepFinishedEvent());
$step = Allure::lifecycle()->getStepStorage()->getLast();
$this->assertEquals(self::STEP_NAME, $step->getName());
}
public function testGenericStepEvent()
{
$step = new Step();
Allure::lifecycle()->getStepStorage()->clear();
Allure::lifecycle()->getStepStorage()->put($step);
Allure::lifecycle()->fire(new GenericStepEvent(self::STEP_NAME));
$this->assertEquals(self::STEP_NAME, $step->getName());
}
public function testTestCaseStarted()
{
Allure::lifecycle()->getTestCaseStorage()->clear();
Allure::lifecycle()->getTestSuiteStorage()->clear();
$this->assertTrue(Allure::lifecycle()->getTestCaseStorage()->isEmpty());
Allure::lifecycle()->fire(new TestCaseStartedEvent(self::TEST_SUITE_UUID, self::TEST_CASE_NAME));
$testCase = Allure::lifecycle()
->getTestSuiteStorage()
->get(self::TEST_SUITE_UUID)
->getTestCase(self::TEST_CASE_NAME);
$this->assertNotEmpty($testCase);
$this->assertEquals(self::TEST_CASE_NAME, $testCase->getName());
}
public function testTestCaseFinishedEvent()
{
Allure::lifecycle()->getStepStorage()->clear();
Allure::lifecycle()->getStepStorage()->getLast(); //To initialize root step
Allure::lifecycle()->getTestCaseStorage()->clear();
$step = new Step();
$step->setName(self::STEP_NAME);
$attachment = new Attachment(
self::STEP_ATTACHMENT_TITLE,
self::STEP_ATTACHMENT_SOURCE,
self::STEP_ATTACHMENT_TYPE
);
Allure::lifecycle()->getStepStorage()->getLast()->addStep($step);
Allure::lifecycle()->getStepStorage()->getLast()->addAttachment($attachment);
$testCaseFromStorage = Allure::lifecycle()->getTestCaseStorage()->get();
Allure::lifecycle()->fire(new TestCaseFinishedEvent());
//Checking that attachments were moved
$attachments = $testCaseFromStorage->getAttachments();
$this->assertEquals(1, sizeof($attachments));
$attachment = array_pop($attachments);
$this->assertTrue(
($attachment instanceof Attachment) &&
($attachment->getTitle() === self::STEP_ATTACHMENT_TITLE) &&
($attachment->getSource() === self::STEP_ATTACHMENT_SOURCE) &&
($attachment->getType() === self::STEP_ATTACHMENT_TYPE)
);
//Checking that steps were moved
$steps = $testCaseFromStorage->getSteps();
$this->assertEquals(1, sizeof($steps));
$stepFromStorage = array_pop($steps);
$this->assertTrue(
($stepFromStorage instanceof Step) &&
($stepFromStorage->getName() === self::STEP_NAME)
);
$this->assertTrue(Allure::lifecycle()->getTestCaseStorage()->isEmpty());
}
public function testGenericTestCaseEvent()
{
$testCase = new TestCase();
Allure::lifecycle()->getTestCaseStorage()->clear();
Allure::lifecycle()->getTestCaseStorage()->put($testCase);
Allure::lifecycle()->fire(new GenericTestCaseEvent(self::TEST_CASE_NAME));
$this->assertEquals(self::TEST_CASE_NAME, $testCase->getName());
}
public function testGenericTestSuiteEvent()
{
Allure::lifecycle()->getTestSuiteStorage()->clear();
$event = new GenericTestSuiteEvent(self::TEST_SUITE_NAME);
$testSuite = Allure::lifecycle()->getTestSuiteStorage()->get($event->getUuid());
Allure::lifecycle()->fire($event);
$this->assertEquals(self::TEST_SUITE_NAME, $testSuite->getName());
}
public function testTestSuiteFinishedEvent()
{
Allure::lifecycle()->getTestSuiteStorage()->clear();
$testSuite = Allure::lifecycle()->getTestSuiteStorage()->get(self::TEST_SUITE_UUID);
$testSuite->addTestCase(new TestCase());
$this->assertEquals(1, Allure::lifecycle()->getTestSuiteStorage()->size());
$outputDirectory = sys_get_temp_dir();
AnnotationRegistry::registerAutoloadNamespace(
'JMS\Serializer\Annotation',
__DIR__ . "/../../../../vendor/jms/serializer/src"
);
Provider::setOutputDirectory($outputDirectory);
$xmlFilePath = $outputDirectory . DIRECTORY_SEPARATOR . self::TEST_SUITE_UUID . '-testsuite.xml';
Allure::lifecycle()->fire(new TestSuiteFinishedEvent(self::TEST_SUITE_UUID));
$this->assertTrue(Allure::lifecycle()->getTestSuiteStorage()->isEmpty());
$this->assertTrue(file_exists($xmlFilePath));
}
}
<?php
namespace Yandex\Allure\Adapter\Annotation;
use PHPUnit\Framework\TestCase;
use Yandex\Allure\Adapter\Event\TestCaseStartedEvent;
use Yandex\Allure\Adapter\Event\TestSuiteStartedEvent;
use Yandex\Allure\Adapter\Model\DescriptionType;
use Yandex\Allure\Adapter\Model\ParameterKind;
use Yandex\Allure\Adapter\Model\SeverityLevel;
use Yandex\Allure\Adapter\Model\Label;
use Yandex\Allure\Adapter\Model\LabelType;
class AnnotationManagerTest extends TestCase
{
public function testUpdateTestSuiteStartedEvent(): void
{
$instance = new Fixtures\ExampleTestSuite();
$testSuiteAnnotations = AnnotationProvider::getClassAnnotations($instance);
$annotationManager = new AnnotationManager($testSuiteAnnotations);
$event = new TestSuiteStartedEvent('some-name');
$annotationManager->updateTestSuiteEvent($event);
$this->assertEquals('test-suite-title', $event->getTitle());
$this->assertEquals('test-suite-description', $event->getDescription()->getValue());
$this->assertEquals(DescriptionType::MARKDOWN, $event->getDescription()->getType());
$this->assertEquals(8, sizeof($event->getLabels()));
//Check features presence
$epics = $this->getLabelsByType($event->getLabels(), LabelType::EPIC);
$this->assertEquals(2, sizeof($epics));
$index = 1;
foreach ($epics as $epic) {
$this->assertInstanceOf('Yandex\Allure\Adapter\Model\Label', $epic);
$this->assertEquals("test-suite-epic$index", $epic->getValue());
$index++;
}
//Check features presence
$features = $this->getLabelsByType($event->getLabels(), LabelType::FEATURE);
$this->assertEquals(2, sizeof($features));
$index = 1;
foreach ($features as $feature) {
$this->assertInstanceOf('Yandex\Allure\Adapter\Model\Label', $feature);
$this->assertEquals("test-suite-feature$index", $feature->getValue());
$index++;
}
//Check stories presence
$stories = $this->getLabelsByType($event->getLabels(), LabelType::STORY);
$this->assertEquals(2, sizeof($stories));
$index = 1;
foreach ($stories as $story) {
$this->assertInstanceOf('Yandex\Allure\Adapter\Model\Label', $story);
$this->assertEquals("test-suite-story$index", $story->getValue());
$index++;
}
//Check issues presence
$issues = $this->getLabelsByType($event->getLabels(), LabelType::ISSUE);
$this->assertEquals(2, sizeof($issues));
$index = 1;
foreach ($issues as $issue) {
$this->assertInstanceOf('Yandex\Allure\Adapter\Model\Label', $issue);
$this->assertEquals("test-suite-issue$index", $issue->getValue());
$index++;
}
}
public function testUpdateTestCaseStartedEvent(): void
{
$instance = new Fixtures\ExampleTestSuite();
$testCaseAnnotations = AnnotationProvider::getMethodAnnotations($instance, 'exampleTestCase');
$annotationManager = new AnnotationManager($testCaseAnnotations);
$event = new TestCaseStartedEvent('some-uid', 'some-name');
$annotationManager->updateTestCaseEvent($event);
//Check scalar properties
$this->assertEquals('test-case-title', $event->getTitle());
$this->assertEquals('test-case-description', $event->getDescription()->getValue());
$this->assertEquals(DescriptionType::HTML, $event->getDescription()->getType());
$this->assertEquals(13, sizeof($event->getLabels()));
//Check id presence
$ids = $this->getLabelsByType($event->getLabels(), LabelType::ID);
$this->assertEquals(1, sizeof($ids));
$id = array_pop($ids);
$this->assertInstanceOf('Yandex\Allure\Adapter\Model\Label', $id);
$this->assertSame("123", $id->getValue());
//Check epic presence
$epics = $this->getLabelsByType($event->getLabels(), LabelType::EPIC);
$this->assertEquals(2, sizeof($epics));
$index = 1;
foreach ($epics as $epic) {
$this->assertInstanceOf('Yandex\Allure\Adapter\Model\Label', $epic);
$this->assertEquals("test-case-epic$index", $epic->getValue());
$index++;
}
//Check feature presence
$features = $this->getLabelsByType($event->getLabels(), LabelType::FEATURE);
$this->assertEquals(2, sizeof($features));
$index = 1;
foreach ($features as $feature) {
$this->assertInstanceOf('Yandex\Allure\Adapter\Model\Label', $feature);
$this->assertEquals("test-case-feature$index", $feature->getValue());
$index++;
}
//Check stories presence
$stories = $this->getLabelsByType($event->getLabels(), LabelType::STORY);
$this->assertEquals(2, sizeof($stories));
$index = 1;
foreach ($stories as $story) {
$this->assertInstanceOf('Yandex\Allure\Adapter\Model\Label', $story);
$this->assertEquals("test-case-story$index", $story->getValue());
$index++;
}
//Check issues presence
$issues = $this->getLabelsByType($event->getLabels(), LabelType::ISSUE);
$this->assertEquals(2, sizeof($issues));
$index = 1;
foreach ($issues as $issue) {
$this->assertInstanceOf('Yandex\Allure\Adapter\Model\Label', $issue);
$this->assertEquals("test-case-issue$index", $issue->getValue());
$index++;
}
//Check custom labels presence
$customs = $this->getLabelsByType($event->getLabels(), "custom-name");
$this->assertEquals(3, sizeof($customs));
$index = 1;
foreach ($customs as $custom) {
$this->assertInstanceOf('Yandex\Allure\Adapter\Model\Label', $custom);
$this->assertEquals("custom-value-$index", $custom->getValue());
$index++;
}
//Check severity presence
$severities = $this->getLabelsByType($event->getLabels(), LabelType::SEVERITY);
$this->assertEquals(1, sizeof($severities));
$severity = array_pop($severities);
$this->assertInstanceOf('Yandex\Allure\Adapter\Model\Label', $severity);
$this->assertSame(SeverityLevel::BLOCKER, $severity->getValue());
//Check parameter presence
$parameters = $event->getParameters();
$this->assertEquals(1, sizeof($parameters));
$parameter = array_pop($parameters);
$this->assertInstanceOf('Yandex\Allure\Adapter\Model\Parameter', $parameter);
$this->assertSame('test-case-param-name', $parameter->getName());
$this->assertSame('test-case-param-value', $parameter->getValue());
$this->assertSame(ParameterKind::ARGUMENT, $parameter->getKind());
}
private function getLabelsByType(array $labels, string $labelType): array
{
$filteredArray = array_filter(
$labels,
function ($element) use ($labelType) {
return ($element instanceof Label) && ($element->getName() === $labelType);
}
);
uasort(
$filteredArray,
function (Label $l1, Label $l2) {
$label1Value = $l1->getValue();
$label2Value = $l2->getValue();
if ($label1Value === $label2Value) {
return 0;
}
return ($label1Value < $label2Value) ? -1 : 1;
}
);
return $filteredArray;
}
}
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment