Skip to content

Commit

Permalink
feat: @step, @attachment, @FileAttachment decorators (#13)
Browse files Browse the repository at this point in the history
  • Loading branch information
noomorph authored Oct 14, 2023
1 parent da9f017 commit f3a447b
Show file tree
Hide file tree
Showing 32 changed files with 525 additions and 134 deletions.
4 changes: 4 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,18 @@ module.exports = {
"unicorn/consistent-function-scoping": "off",
"unicorn/filename-case": "off",
"unicorn/no-array-callback-reference": "off",
"unicorn/no-array-method-this-argument": "off",
"unicorn/no-array-reduce": "off",
"unicorn/no-null": "off",
"unicorn/no-this-assignment": "off",
"unicorn/prefer-event-target": "off",
"unicorn/prefer-module": "off",
"import/no-extraneous-dependencies": ["error", {
devDependencies: false,
optionalDependencies: false,
}],
"@typescript-eslint/consistent-type-imports": "error",
"@typescript-eslint/no-this-alias": "off",
"@typescript-eslint/no-unused-vars": [
"error",
{
Expand Down
8 changes: 4 additions & 4 deletions docs/docs/introduction/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ It provides several **entry points**:
<dl>
<dt><code>jest-allure2-reporter</code></dt>
<dd>The reporter itself, which is responsible for collecting test results and generating a report.</dd>
<dt><code>jest-allure2-reporter</code></dt>
<dd>A set of functions and decorators to add additional metadata to your tests.</dd>
<dd>DSL to add additional metadata to your test definitions: <code>$Link</code>, <code>$Owner</code>.</dd>
<dd>`allure` runtime API to use inside your tests: <code>allure.step</code>, <code>allure.attachment</code>.</dd>
<dt>
<b>Environment packages</b>, to enable the annotations, media attachments and provide additional test data:
</dt>
Expand All @@ -43,8 +43,8 @@ It provides several **entry points**:
<dd>For Node.js tests.</dd>
<dt><code>jest-allure2-reporter/environment-jsdom</code></dt>
<dd>For browser tests.</dd>
<dt><code>jest-allure2-reporter/environment-extend</code></dt>
<dd>For advanced use cases where you need to extend your already customized test environment.</dd>
<dt><code>jest-allure2-reporter/environment-decorator</code></dt>
<dd>For advanced use cases where you need to extend an already customized test environment.</dd>
</dl>
</dd>
</dl>
Expand Down
4 changes: 4 additions & 0 deletions e2e/fixtures/invalid-email.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<validation result="failed">
<error message="Invalid e-mail format" />
</validation>
4 changes: 2 additions & 2 deletions e2e/jest.config.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
const PRESET = process.env.ALLURE_PRESET ?? 'default';
const ALLURE_PRESET = process.env.ALLURE_PRESET ?? 'default';

module.exports = require(`./configs/${PRESET}`);
module.exports = require(`./configs/${ALLURE_PRESET}`);
6 changes: 4 additions & 2 deletions e2e/src/programmatic/grouping/client/auth/LoginScreen.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { $Epic, $Feature, $Story, $Tag } from 'jest-allure2-reporter';
import LoginHelper from '../../../../utils/LoginHelper';

$Tag('client');
$Epic('Authentication');
Expand All @@ -13,8 +14,9 @@ describe('Login screen', () => {

$Story('Validation');
describe('Form Submission', () => {
it('should show error on invalid e-mail format', () => {
// ...
it('should show error on invalid e-mail format', async () => {
await LoginHelper.typeEmail('someone#example.com');
expect(LoginHelper.getValidationSummary()).toBe('fixtures/invalid-email.xml');
});

it('should show error on short or invalid password format', () => {
Expand Down
14 changes: 6 additions & 8 deletions e2e/src/simple.not-test.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
import path from 'node:path';
import {
allure,
$Description,
$Owner,
$Severity,
$Link,
} from 'jest-allure2-reporter';
import {LoginHelper} from "./utils/LoginHelper";

$Description('Sanity test for Allure reporter');
$Owner('Yaroslav Serhieiev <[email protected]>');
describe('Simple suite', () => {
beforeAll(() => {
console.log('beforeAll');
allure.fileAttachment(
allure.createFileAttachment(
'Project Logo',
'/home/x/Projects/wix-incubator/jest-allure2-reporter/docs/img/logo.svg',
path.resolve('../docs/img/logo.svg'),
'image/svg+xml',
);
});
Expand All @@ -32,12 +34,8 @@ describe('Simple suite', () => {
});

allure.step('Inner step 2', () => {
allure.attachment(
'Some code',
'console.log("Hello, World!");',
'text/plain',
);
expect(true).toBe(false);
const helper = new LoginHelper();
expect(helper.typeEmail('[email protected]')).toBe('Entered: [email protected]');
});
});
});
Expand Down
16 changes: 16 additions & 0 deletions e2e/src/utils/LoginHelper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import {Attachment, FileAttachment, Step} from 'jest-allure2-reporter';

class LoginHelper {
@Step('Type e-mail', ['E-mail'])
@Attachment('email.txt')
async typeEmail(email: string) {
return 'Entered: ' + email;
}

@FileAttachment('summary.xml', 'text/xml')
getValidationSummary() {
return 'fixtures/invalid-email.xml';
}
}

export default new LoginHelper();
1 change: 1 addition & 0 deletions e2e/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"compilerOptions": {
"module": "node16",
"ignoreDeprecations": "5.0",
"experimentalDecorators": true,
"noEmit": true
}
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@
"dependencies": {
"@noomorph/allure-js-commons": "^2.3.0",
"ci-info": "^3.8.0",
"jest-metadata": "^1.0.2",
"jest-metadata": "^1.1.1",
"pkg-up": "^3.1.0",
"rimraf": "^4.3.1",
"strip-ansi": "^6.0.0"
Expand Down
3 changes: 3 additions & 0 deletions src/constants.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
export const PREFIX = 'allure2' as const;

export const OUT_DIR = [PREFIX, 'config', 'outDir'] as const;

export const CODE = [PREFIX, 'code'] as const;
export const WORKER_ID = [PREFIX, 'workerId'] as const;
export const HIDDEN = [PREFIX, 'hidden'] as const;

export const START = [PREFIX, 'start'] as const;

Expand Down
20 changes: 18 additions & 2 deletions src/decorators/Attachment.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
export function Attachment() {
// TODO: Implement
import realm from '../realms';

const allure = realm.runtime;

export function Attachment(filename: string, contentType?: string) {
return function (
_target: object,
_propertyName: string,
descriptor: TypedPropertyDescriptor<(...arguments_: any[]) => any>,

Check warning on line 9 in src/decorators/Attachment.ts

View workflow job for this annotation

GitHub Actions / Sanity

Unexpected any. Specify a different type

Check warning on line 9 in src/decorators/Attachment.ts

View workflow job for this annotation

GitHub Actions / Sanity

Unexpected any. Specify a different type
) {
descriptor.value = allure.createAttachment(
filename,
descriptor.value!,

Check warning on line 13 in src/decorators/Attachment.ts

View workflow job for this annotation

GitHub Actions / Sanity

Forbidden non-null assertion
contentType,
);

return descriptor;
};
}
20 changes: 18 additions & 2 deletions src/decorators/FileAttachment.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
export function FileAttachment() {
// TODO: Implement
import realm from '../realms';

const allure = realm.runtime;

export function FileAttachment(fileName: string, contentType: string) {
return function (
_target: object,
_propertyName: string,
descriptor: TypedPropertyDescriptor<(...arguments_: any[]) => any>,

Check warning on line 9 in src/decorators/FileAttachment.ts

View workflow job for this annotation

GitHub Actions / Sanity

Unexpected any. Specify a different type

Check warning on line 9 in src/decorators/FileAttachment.ts

View workflow job for this annotation

GitHub Actions / Sanity

Unexpected any. Specify a different type
) {
descriptor.value = allure.createFileAttachment(
fileName,
descriptor.value!,

Check warning on line 13 in src/decorators/FileAttachment.ts

View workflow job for this annotation

GitHub Actions / Sanity

Forbidden non-null assertion
contentType,
);

return descriptor;
};
}
19 changes: 17 additions & 2 deletions src/decorators/Step.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,18 @@
export function Step() {
// TODO: Implement
import realm from '../realms';
import type { ParameterOrString } from '../utils/types';

const allure = realm.runtime;

export function Step(name: string, arguments_?: ParameterOrString[]) {
return function (
_target: object,
_propertyName: string,
descriptor: TypedPropertyDescriptor<(...arguments_: any[]) => Promise<any>>,

Check warning on line 10 in src/decorators/Step.ts

View workflow job for this annotation

GitHub Actions / Sanity

Unexpected any. Specify a different type

Check warning on line 10 in src/decorators/Step.ts

View workflow job for this annotation

GitHub Actions / Sanity

Unexpected any. Specify a different type
) {
descriptor.value = arguments_
? allure.createStep(name, arguments_, descriptor.value!)

Check warning on line 13 in src/decorators/Step.ts

View workflow job for this annotation

GitHub Actions / Sanity

Forbidden non-null assertion
: allure.createStep(name, descriptor.value!);

Check warning on line 14 in src/decorators/Step.ts

View workflow job for this annotation

GitHub Actions / Sanity

Forbidden non-null assertion

return descriptor;
};
}
20 changes: 11 additions & 9 deletions src/environment/decorator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,16 +49,18 @@ export function WithAllure2<E extends WithEmitter>(
event,
}: ForwardedCircusEvent<Circus.Event & { name: 'add_hook' }>) {
const sourceCode = event.fn.toString();
if (
!sourceCode.includes(
"during setup, this cannot be null (and it's fine to explode if it is)",
)
) {
const metadata = {
code: [sourceCode],
} as AllureTestStepMetadata;
state.currentMetadata.assign(PREFIX, metadata);
const hidden = sourceCode.includes(
"during setup, this cannot be null (and it's fine to explode if it is)",
);

const metadata = {
code: [sourceCode],
} as AllureTestStepMetadata;
if (hidden) {
delete metadata.code;
metadata.hidden = true;
}
state.currentMetadata.assign(PREFIX, metadata);
}

#addTest({
Expand Down
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@ export { JestAllure2Reporter } from './reporter/JestAllure2Reporter';
export { JestAllure2Reporter as default } from './reporter/JestAllure2Reporter';
export { ReporterOptions } from './options/ReporterOptions';
export * from './annotations';
export * from './decorators';

export const allure = realm.runtime;
20 changes: 9 additions & 11 deletions src/metadata/MetadataSquasher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,8 @@ import type { AllureTestCaseMetadata } from './metadata';
export class MetadataSquasher {
protected readonly testInvocationConfig: MetadataSquasherConfig<AllureTestCaseMetadata>;

constructor(flat: boolean) {
this.testInvocationConfig = flat
? MetadataSquasher.flatConfig()
: MetadataSquasher.deepConfig();
constructor() {
this.testInvocationConfig = MetadataSquasher.flatConfig();
}

testInvocation(metadata: TestInvocationMetadata): AllureTestCaseMetadata {
Expand Down Expand Up @@ -78,13 +76,13 @@ export class MetadataSquasher {
};
}

private static deepConfig(): MetadataSquasherConfig<AllureTestCaseMetadata> {
return {
...this.flatConfig(),
attachments: chain(['testEntry', 'testInvocation']),
parameters: chain(['testEntry', 'testInvocation']),
};
}
// private static deepConfig(): MetadataSquasherConfig<AllureTestCaseMetadata> {
// return {
// ...this.flatConfig(),
// attachments: chain(['testEntry', 'testInvocation']),
// parameters: chain(['testEntry', 'testInvocation']),
// };
// }
}

export type MetadataSquasherConfig<T extends object> = {
Expand Down
17 changes: 11 additions & 6 deletions src/metadata/StepExtractor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,27 @@ import type {
TestFnInvocationMetadata,
} from 'jest-metadata';

import { PREFIX } from '../constants';
import { HIDDEN, PREFIX } from '../constants';

import type { AllureTestStepMetadata } from './metadata';

export class StepExtractor {
constructor(protected readonly flat: boolean) {}

public extractFromInvocation(
metadata: HookInvocationMetadata<any> | TestFnInvocationMetadata,
): AllureTestStepMetadata {
): AllureTestStepMetadata | null {
const definition = metadata.definition as HookDefinitionMetadata;
const hidden = metadata.get(HIDDEN, definition.get(HIDDEN, false));
if (hidden) {
return null;
}

const hookType = definition.hookType;
const data = {
name: (metadata.definition as HookDefinitionMetadata).hookType ?? 'test',
name: hookType,
...(metadata.get([PREFIX]) as AllureTestStepMetadata),
};

if (this.flat) {
if (!hookType) {
delete data.attachments;
delete data.parameters;
}
Expand Down
9 changes: 5 additions & 4 deletions src/metadata/metadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ import type {

export interface AllureTestStepMetadata {
steps?: AllureTestStepMetadata[];
hidden?: boolean;
/**
* Source code of the test case, test step or a hook.
*/
code?: string[];

name?: string;
status?: Status;
Expand All @@ -34,10 +39,6 @@ export interface AllureTestCaseMetadata extends AllureTestStepMetadata {
* @see {import('@noomorph/allure-js-commons').LabelName.THREAD}
*/
workerId?: string;
/**
* Source code of the test case, glued from all hooks and test function itself.
*/
code?: string[];
/**
* Only steps can have names.
*/
Expand Down
15 changes: 13 additions & 2 deletions src/options/defaultOptions.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import path from 'node:path';

import type { TestCaseResult } from '@jest/reporters';
import type { StatusDetails } from '@noomorph/allure-js-commons';
import type { Attachment, StatusDetails } from '@noomorph/allure-js-commons';
import { Stage, Status } from '@noomorph/allure-js-commons';

import { stripStatusDetails } from '../metadata/utils';
Expand Down Expand Up @@ -38,7 +38,8 @@ export function defaultOptions(): ReporterConfig {
stage: ({ testCase }) => getTestCaseStage(testCase),
status: ({ testCase }) => getTestCaseStatus(testCase),
statusDetails: ({ testCase }) => getTestCaseStatusDetails(testCase),
attachments: ({ testCaseMetadata }) => testCaseMetadata.attachments ?? [],
attachments: ({ config, testCaseMetadata }) =>
(testCaseMetadata.attachments ?? []).map(relativizeAttachment, config),
parameters: ({ testCaseMetadata }) => testCaseMetadata.parameters ?? [],
labels: aggregateLabelCustomizers({
package: last,
Expand Down Expand Up @@ -140,3 +141,13 @@ function getTestCaseStatusDetails(
})
: undefined;
}

function relativizeAttachment(
this: ReporterConfig,
attachment: Attachment,
): Attachment {
return {
...attachment,
source: path.relative(this.resultsDir, attachment.source),
};
}
Loading

0 comments on commit f3a447b

Please sign in to comment.