Skip to content

Commit

Permalink
feat: add @fail decorator (#18)
Browse files Browse the repository at this point in the history
  • Loading branch information
SebastianSedzik committed Jul 20, 2023
1 parent f7bbe46 commit 4f13803
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 0 deletions.
31 changes: 31 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ class MyTestSuite {
#### Options
- `name` (optional) - name of the test suite. By default, name of the class.


### Creating a test: `@test(options?)`
Mark class method as test.
Under the hood, decorator creates a `test` block and runs the method inside it.
Expand All @@ -59,6 +60,7 @@ class MyTestSuite {
#### Options
- `name` (optional) - name of the test. By default, name of the method.


### Run method before all test in the suite: `@beforeAll()`
Mark method as `beforeAll` book.

Expand All @@ -74,6 +76,7 @@ class MyTestSuite {
}
```


### Run method before each test in the suite: `@beforeEach()`
Mark method as `beforeEach` book.

Expand All @@ -89,6 +92,7 @@ class MyTestSuite {
}
```


### Run method after all test in the suite: `@afterAll()`
Mark method as `afterAll` book.

Expand All @@ -104,6 +108,7 @@ class MyTestSuite {
}
```


### Run method after each test in the suite: `@afterEach()`
Mark method as `afterEach` book.

Expand All @@ -119,6 +124,7 @@ class MyTestSuite {
}
```


### Skip test or suite: `@skip(reason?: string)`
Skip single `@test` or `@suite`.

Expand All @@ -145,6 +151,29 @@ class MyTestSuite {
#### Options
- `reason` (optional) - reason of skipping. Will be displayed in the test report.


### Mark test as "should fail": `@fail(reason?: string)`
Mark single `@test` as "should fail".
Playwright Test runs this test and ensures that it is actually failing.
This is useful for documentation purposes to acknowledge that some functionality is broken until it is fixed.

```ts
import { suite, test, fail } from 'playwright-decorators';

@suite()
class MyTestSuite {
@fail() // <-- Decorate test with @fail()
@test()
async failingTest({ page }) {
// ...
}
}
```

#### Options
- `reason` (optional) - reason of marking as "should fail". Will be displayed in the test report.


### Mark test or suite as "slow": `@slow(reason?: string)`
Mark single `@test` or `@suite` as "slow".
Slow test will be given triple the default timeout.
Expand Down Expand Up @@ -172,6 +201,7 @@ class MyTestSuite {
#### Options
- `reason` (optional) - reason of marking as "slow". Will be displayed in the test report.


### Run only selected test(s) or suite(s): `@only()`
Declares a focused `@test` or `@suite`.
If there are some focused tests or suites, all of them will be run but nothing else.
Expand All @@ -196,6 +226,7 @@ class TestSuite {
}
```


### Run test(s) or suite(s) with certain tag(s): `@tag(tags: string[])`
Adds tags to `@test` or `@suite`.
You can later run test(s) or suite(s) with specific tag, using `npx playwright test --grep "@nameOfTag"` command.
Expand Down
13 changes: 13 additions & 0 deletions lib/fail.decorator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import {TestDecoratedMethod} from "./test.decorator";

/**
* Marks a @test as "should fail".
* Playwright Test runs this test and ensures that it is actually failing.
* This is useful for documentation purposes to acknowledge that some functionality is broken until it is fixed.
*/
export const fail = (reason?: string) => function(originalMethod: any, context?: any) {
if ((originalMethod as TestDecoratedMethod)?.testDecorator) {
originalMethod.testDecorator.fail = reason || true;
return;
}
}
1 change: 1 addition & 0 deletions lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export { afterEach } from './afterEach.decorator';
// annotations
export { skip } from './skip.decorator';
export { slow } from './slow.decorator';
export { fail } from './fail.decorator';
export { only } from './only.decorator';
// helpers
export { tag } from './tag.decorator';
20 changes: 20 additions & 0 deletions lib/test.decorator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@ interface TestDecoratorOptions {
* Slow test will be given triple the default timeout.
*/
slow?: string | boolean;
/**
* Marks a test as "should fail".
* Playwright Test runs this test and ensures that it is actually failing.
* This is useful for documentation purposes to acknowledge that some functionality is broken until it is fixe
*/
fail?: string | boolean
/**
* Declares a focused test.
* If there are some focused @test(s) or @suite(s), all of them will be run but nothing else.
Expand All @@ -26,6 +32,7 @@ class TestDecorator implements TestDecoratorOptions {
name: string;
skip: string | boolean = false;
slow: string | boolean = false;
fail: string | boolean = false;
only = false;

constructor(private testMethod: any, options: TestDecoratorOptions) {
Expand Down Expand Up @@ -58,13 +65,26 @@ class TestDecorator implements TestDecoratorOptions {
return playwright.slow();
}

private handleFail() {
if (this.fail === false) {
return;
}

if (typeof this.fail === 'string') {
return playwright.fail(true, this.fail);
}

return playwright.fail();
}

/**
* Run playwright.test function using all collected data.
*/
run(executionContext: any) {
const decoratedTest: TestDecoratorFunction = (testFunction) => (...args) => {
this.handleSkip();
this.handleSlow();
this.handleFail();

// set correct executionContext (test class)
return testFunction.call(executionContext, ...args);
Expand Down
23 changes: 23 additions & 0 deletions tests/fail.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import playwright, {expect} from "@playwright/test";
import {suite, test, fail} from "../lib";

playwright.describe('@fail decorator', () => {
playwright.describe('with @test', () => {
const called: string[] = [];

@suite()
class FocusedSuite {
@fail()
@test()
failingTest() {
called.push('failingTest');
expect(true).toBe(false);
}
}

playwright('@fail decorator should not throw error when test fails', () => {
// is called and not throw error
expect(called).toEqual(['failingTest']);
});
});
});

0 comments on commit 4f13803

Please sign in to comment.