Skip to content

Commit a404a8e

Browse files
added capability to save playwright trace (#18)
added capability to save playwright trace
1 parent c7e851a commit a404a8e

File tree

7 files changed

+80
-11
lines changed

7 files changed

+80
-11
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
## 0.0.8
22
- :beetle: fixed issue that opens page from browser, not from context
33
- :rocket: added mock steps
4+
- :rocket: added playwright traces
45

56
## 0.0.7
67
- :rocket: added capability to connect via CDP

README.md

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ const App = require('./page_object');
1313
module.exports = {
1414
default: {
1515
require: [
16-
'@qavajs/steps-playwright'
16+
'node_modules/@qavajs/steps-playwright'
1717
],
1818
browser: {
1919
timeout: {
@@ -66,3 +66,17 @@ module.exports = {
6666
}
6767
}
6868
```
69+
70+
## Playwright traces
71+
@qavajs support capturing playwright traces. https://playwright.dev/docs/next/trace-viewer-intro
72+
```typescript
73+
{
74+
browser: {
75+
trace: {
76+
event: 'onFail', // Event to save trace. Possible value onFail or AfterScenario
77+
dir: 'dirToStoreTraces' // Dir to store traces. Default is traces/
78+
attach: true // Define if trace need to be attached to cucumber report. Default false
79+
}
80+
}
81+
}
82+
```

src/hooks.ts

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
import { After, AfterStep, Before, BeforeStep, Status } from '@cucumber/cucumber';
1+
import { After, AfterStep, Before, BeforeStep } from '@cucumber/cucumber';
22
import defaultTimeouts from './defaultTimeouts';
33
import { Browser, BrowserContext, Page } from 'playwright';
44
import { po } from '@qavajs/po-playwright';
5-
import { ScreenshotEvent } from './screenshotEvent';
65
import { driverProvider } from './driverProvider';
6+
import { saveScreenshotAfterStep, saveScreenshotBeforeStep, saveTrace, traceArchive } from './utils/utils';
7+
import { readFile } from 'fs/promises';
78

89
declare global {
910
var browser: Browser;
@@ -19,16 +20,23 @@ Before(async function () {
1920
defaultTimeouts,
2021
...driverConfig.timeout
2122
}
22-
global.browser = await driverProvider(driverConfig);
23+
config.driverConfig = driverConfig;
24+
global.browser = await driverProvider(config.driverConfig);
2325
global.context = await browser.newContext({ viewport: null });
26+
if (config.driverConfig.trace) {
27+
await context.tracing.start({
28+
screenshots: true,
29+
snapshots: true
30+
})
31+
}
2432
global.page = await context.newPage();
2533
global.driver = global.browser;
26-
po.init(page, { timeout: driverConfig.timeout.present });
34+
po.init(page, { timeout: config.driverConfig.timeout.present });
2735
po.register(config.pageObject);
2836
});
2937

3038
BeforeStep(async function () {
31-
if (config.screenshot === ScreenshotEvent.BEFORE_STEP) {
39+
if (saveScreenshotBeforeStep(config)) {
3240
try {
3341
this.attach(await page.screenshot(), 'image/png');
3442
} catch (err) {
@@ -39,18 +47,23 @@ BeforeStep(async function () {
3947

4048
AfterStep(async function (step) {
4149
try {
42-
if (
43-
(config.screenshot === ScreenshotEvent.ON_FAIL && step.result.status === Status.FAILED) ||
44-
config.screenshot === ScreenshotEvent.AFTER_STEP
45-
) {
50+
if (saveScreenshotAfterStep(config, step)) {
4651
this.attach(await page.screenshot(), 'image/png');
4752
}
4853
} catch (err) {
4954
console.warn(err)
5055
}
5156
});
5257

53-
After(async function () {
58+
After(async function (scenario) {
59+
if (saveTrace(config.driverConfig, scenario)) {
60+
const path = traceArchive(config.driverConfig, scenario);
61+
await context.tracing.stop({ path });
62+
if (config.driverConfig?.trace.attach) {
63+
const zipBuffer: Buffer = await readFile(path);
64+
this.attach(zipBuffer.toString('base64'), 'base64:application/zip');
65+
}
66+
}
5467
if (global.browser) {
5568
await browser.close();
5669
}
File renamed without changes.

src/utils/traceEvent.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
export enum TraceEvent {
2+
ON_FAIL = 'onFail',
3+
AFTER_SCENARIO = 'afterScenario'
4+
}

src/utils/utils.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { ScreenshotEvent } from './screenshotEvent';
2+
import { TraceEvent } from './traceEvent';
3+
import { Status, ITestStepHookParameter, ITestCaseHookParameter } from '@cucumber/cucumber';
4+
import { join } from 'path';
5+
6+
export function saveScreenshotAfterStep(config: any, step: ITestStepHookParameter): boolean {
7+
return (config.screenshot === ScreenshotEvent.ON_FAIL && step.result.status === Status.FAILED) ||
8+
config.screenshot === ScreenshotEvent.AFTER_STEP
9+
}
10+
11+
export function saveScreenshotBeforeStep(config: any): boolean {
12+
return config.screenshot === ScreenshotEvent.BEFORE_STEP
13+
}
14+
15+
export function saveTrace(driverConfig: any, scenario: ITestCaseHookParameter): boolean {
16+
return driverConfig?.trace && (
17+
(driverConfig?.trace.event === TraceEvent.AFTER_SCENARIO) ||
18+
(scenario.result?.status === Status.FAILED && driverConfig?.trace.event === TraceEvent.ON_FAIL)
19+
)
20+
}
21+
22+
function normalizeScenarioName(name: string): string {
23+
return name.replace(/\W/g, '-')
24+
}
25+
26+
export function traceArchive(driverConfig: any, scenario: ITestCaseHookParameter): string {
27+
return join(
28+
driverConfig.trace?.dir ?? 'traces',
29+
`${normalizeScenarioName(scenario.pickle.name)}-${scenario.testCaseStartedId}.zip`
30+
)
31+
}

test-e2e/webui.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ const common = {
1414
}
1515
},
1616
format: [
17+
'json:test-e2e/report.json',
1718
'@qavajs/xunit-formatter:test-e2e/report.xml'
1819
],
1920
memory: new Memory(),
@@ -35,6 +36,11 @@ export const debug = {
3536
capabilities: {
3637
browserName: 'chromium',
3738
headless: false
39+
},
40+
trace: {
41+
event: 'onFail',
42+
dir: 'customDir',
43+
attach: true
3844
}
3945
}
4046
}

0 commit comments

Comments
 (0)