@zest-pw/test 1.0.1 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../types/types.ts"],"names":[],"mappings":""}
File without changes
@@ -14,5 +14,5 @@ import type { Page, TestInfo } from "@playwright/test";
14
14
  * @param testInfo - Playwright TestInfo object for attaching screenshots
15
15
  * @param stepTitle - Optional step title for attachment name
16
16
  */
17
- export declare function takeScreenshotAfterStep(page: Page, stepInfo: any, testInfo: TestInfo, stepTitle?: string): Promise<void>;
17
+ export declare function takeScreenshotAfterStep(page: Page, testInfo: TestInfo, stepTitle?: string): Promise<void>;
18
18
  //# sourceMappingURL=take-screenshots.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"take-screenshots.d.ts","sourceRoot":"","sources":["../../utils/take-screenshots.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEvD;;;;;;;;;;;GAWG;AACH,wBAAsB,uBAAuB,CAC3C,IAAI,EAAE,IAAI,EACV,QAAQ,EAAE,GAAG,EACb,QAAQ,EAAE,QAAQ,EAClB,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,IAAI,CAAC,CAef"}
1
+ {"version":3,"file":"take-screenshots.d.ts","sourceRoot":"","sources":["../../utils/take-screenshots.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEvD;;;;;;;;;;;GAWG;AACH,wBAAsB,uBAAuB,CAC3C,IAAI,EAAE,IAAI,EACV,QAAQ,EAAE,QAAQ,EAClB,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,IAAI,CAAC,CAaf"}
@@ -16,13 +16,11 @@ exports.takeScreenshotAfterStep = takeScreenshotAfterStep;
16
16
  * @param testInfo - Playwright TestInfo object for attaching screenshots
17
17
  * @param stepTitle - Optional step title for attachment name
18
18
  */
19
- async function takeScreenshotAfterStep(page, stepInfo, testInfo, stepTitle) {
19
+ async function takeScreenshotAfterStep(page, testInfo, stepTitle) {
20
20
  try {
21
21
  if (page && testInfo) {
22
- const screenshotBuffer = await page.screenshot({
23
- fullPage: true
24
- });
25
- await testInfo.attach(stepTitle || stepInfo?.title || 'screenshot', {
22
+ const screenshotBuffer = await page.screenshot({ fullPage: true });
23
+ await testInfo.attach(stepTitle || 'screenshot', {
26
24
  body: screenshotBuffer,
27
25
  contentType: 'image/png',
28
26
  });
@@ -1 +1 @@
1
- {"version":3,"file":"terminal-reporter.d.ts","sourceRoot":"","sources":["../../utils/terminal-reporter.ts"],"names":[],"mappings":"AAIA;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,GAAG,GAAG,IAAI,CAoBlD"}
1
+ {"version":3,"file":"terminal-reporter.d.ts","sourceRoot":"","sources":["../../utils/terminal-reporter.ts"],"names":[],"mappings":"AAIA;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,GAAG,GAAG,IAAI,CAuClD"}
@@ -47,22 +47,38 @@ function printTestResults(result) {
47
47
  return;
48
48
  }
49
49
  result.tests.forEach((test) => {
50
- printTestInfo(test);
51
50
  const allSteps = test.steps || [];
52
51
  const executedSteps = allSteps.filter((step) => step.statusName !== 'In Progress');
53
52
  const testFileName = test.testCaseKey || 'test';
54
53
  const sanitizedTitle = test.testTitle.replace(/[^a-zA-Z0-9]+/g, '-').replace(/^-|-$/g, '');
55
54
  const projectName = test.projectName || 'chromium';
56
55
  const outputDir = path.join('test-results', `${testFileName}-${sanitizedTitle}-${projectName}`);
56
+ const testTitle = `${projectName} › ${testFileName} › ${test.testTitle}`;
57
+ const remainder = (63 - testTitle.length) < 0 ? 0 : (63 - testTitle.length);
58
+ const spaces = '\x1b[40m \x1b[0m'.repeat(remainder);
59
+ console.log(`\n\x1b[40m${testTitle}${spaces}\x1b[0m`);
57
60
  printTestSteps(executedSteps.length, allSteps, test.testTitle, outputDir);
58
61
  });
59
- }
60
- /**
61
- * Prints general test information
62
- * @param test - Test object containing testCaseKey and testTitle
63
- */
64
- function printTestInfo(test) {
65
- console.log(`\n${test.testCaseKey}: ${test.testTitle}`);
62
+ let passedCount = 0;
63
+ let failedCount = 0;
64
+ let skippedCount = 0;
65
+ result.tests.forEach((test) => {
66
+ for (const step of test.steps) {
67
+ switch (step.statusName) {
68
+ case 'pass':
69
+ passedCount++;
70
+ break;
71
+ case 'fail':
72
+ failedCount++;
73
+ break;
74
+ case 'In Progress':
75
+ skippedCount++;
76
+ break;
77
+ }
78
+ }
79
+ });
80
+ console.log(`\x1b[30mTotal results:\x1b[0m \x1b[32m${passedCount} passed\x1b[0m\x1b[30m,\x1b[0m \x1b[31m${failedCount} failed\x1b[0m\x1b[30m,\x1b[0m \x1b[30m${skippedCount} skipped\x1b[0m`);
81
+ console.log('\n');
66
82
  }
67
83
  /**
68
84
  * Prints test step information
@@ -72,25 +88,35 @@ function printTestInfo(test) {
72
88
  * @param outputDir - Optional output directory path for saving screenshots
73
89
  */
74
90
  function printTestSteps(executedCount, allSteps, testTitle, outputDir) {
75
- if (allSteps.length === 0) {
76
- console.log(' Steps: none');
77
- return;
78
- }
79
- const totalCount = allSteps.length;
80
- console.log(` Steps (${executedCount}/${totalCount}):`);
91
+ console.log('');
81
92
  allSteps.forEach((step, stepIndex) => {
82
- const statusEmoji = step.statusName === 'pass' ? 'passed - ✅' : step.statusName === 'failed' ? 'fail - ❌' : step.statusName === 'In Progress' ? 'skipped - ⏭️' : '⏱️';
83
- console.log(` ${stepIndex + 1}. ${step.stepTitle}`);
84
- if (step.error) {
85
- console.log(` ❌ Error: ${step.error.message}`);
86
- if (step.error.stack) {
87
- const stackLines = step.error.stack.split('\n').slice(0, 3);
88
- stackLines.forEach((line) => console.log(` ${line}`));
89
- }
93
+ if (step.statusName === 'In Progress') {
94
+ return;
95
+ }
96
+ let stepTitle;
97
+ switch (step.statusName) {
98
+ case 'fail':
99
+ stepTitle = `\x1b[31m ${step.stepTitle}\x1b[0m`;
100
+ break;
101
+ default:
102
+ stepTitle = step.stepTitle;
103
+ break;
90
104
  }
105
+ const statusEmoji = step.statusName === 'pass' ? '\x1b[32mPASSED ✓\x1b[0m' : step.statusName === 'fail' ? '\x1b[31mFAILED ✗\x1b[0m' : step.statusName === 'In Progress' ? '\x1b[30mSKIPPED ⊘\x1b[0m' : '⏱️';
106
+ console.log(`\x1b[30mSTEP ${stepIndex + 1}:\x1b[0m ${stepTitle}`);
91
107
  printStepAttachments(step, testTitle, outputDir, stepIndex + 1);
92
- console.log(` Status: ${statusEmoji}`);
93
- console.log('');
108
+ if (step.error) {
109
+ const stackLines = step.error.message.split('\n').slice(0, 4);
110
+ console.log('\n\n\x1b[41m ERROR \x1b[0m\n');
111
+ stackLines.forEach((line) => console.log(`${line}`));
112
+ console.log('\n\x1b[41m ERROR \x1b[0m\n\n');
113
+ }
114
+ ;
115
+ if (!step.error) {
116
+ console.log(`\n\x1b[30mstatus:\x1b[0m ${statusEmoji}\x1b[0m`);
117
+ console.log('\x1b[30m‾ ‾ ‾ ‾ ‾ ‾ ‾ ‾ ‾ ‾ ‾ ‾ ‾ ‾ ‾ ‾ ‾ ‾ ‾ ‾ ‾ ‾ ‾ ‾ ‾ ‾ ‾ ‾ ‾ ‾ ‾ ‾\x1b[0m\n\n');
118
+ }
119
+ ;
94
120
  });
95
121
  }
96
122
  /**
@@ -104,14 +130,14 @@ function printStepAttachments(step, testTitle, outputDir, _stepNumber) {
104
130
  if (!step.actualResult || step.actualResult.length === 0) {
105
131
  return;
106
132
  }
107
- console.log(` Screenshot:`);
133
+ console.log(`\x1b[30mscreenshot:\x1b[0m`);
108
134
  step.actualResult.forEach((att) => {
109
135
  const isErrorScreenshot = att.fileName?.includes('ERROR');
110
136
  const emoji = isErrorScreenshot ? '💥' : att.image === 'image/png' ? '📸' : '📄';
111
- const displayName = att.image === 'image/png' ? 'Decode: Base64' : att.fileName;
112
- console.log(` ${emoji} ${displayName}`);
137
+ const displayName = att.image === 'image/png' ? '\x1b[30mDecode:\x1b[0m Base64' : att.fileName;
138
+ console.log(` ${emoji} ${displayName}`);
113
139
  if (att.body && att.image === 'text/plain') {
114
- console.log(` ${att.body}`);
140
+ console.log(`${att.body}`);
115
141
  }
116
142
  const config = (0, config_1.getZestConfig)();
117
143
  const shouldSaveScreenshots = config.screenshots.saveToDisk || process.env.SAVE_SCREENSHOTS === 'true';
@@ -124,11 +150,11 @@ function printStepAttachments(step, testTitle, outputDir, _stepNumber) {
124
150
  else {
125
151
  (0, save_screenshots_1.saveBase64Screenshot)(att.body, filename, 'screenshots', testTitle);
126
152
  }
127
- console.log(` 💾 File saved: locally`);
128
- console.log(` 📄 File name: ${filename}`);
153
+ console.log(` \x1b[30m💾 saved:\x1b[0m Locally`);
154
+ console.log(` \x1b[30m📄 name:\x1b[0m ${filename}`);
129
155
  }
130
156
  catch (error) {
131
- console.error(` ⚠️ Error saving screenshot: ${error}`);
157
+ console.error(` ⚠️ Error saving screenshot: ${error}`);
132
158
  }
133
159
  }
134
160
  });
@@ -1,10 +1,10 @@
1
- import type { TestInfo, TestType, Page } from '@playwright/test';
1
+ import type { TestInfo, Page, test as base } from '@playwright/test';
2
2
  /**
3
3
  * Wraps test.step to automatically create screenshots after each test step
4
4
  * @param test - Playwright test object
5
5
  * @param getCurrentContext - Function to get current test context (testInfo and page)
6
6
  */
7
- export declare function wrapTestStepWithScreenshots(test: TestType<any, any>, getCurrentContext: () => {
7
+ export declare function wrapTestStepWithScreenshots(test: typeof base, getCurrentContext: () => {
8
8
  testInfo: TestInfo;
9
9
  page: Page;
10
10
  } | null): void;
@@ -1 +1 @@
1
- {"version":3,"file":"test-step-wrapper.d.ts","sourceRoot":"","sources":["../../utils/test-step-wrapper.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAGjE;;;;GAIG;AACH,wBAAgB,2BAA2B,CACzC,IAAI,EAAE,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC,EACxB,iBAAiB,EAAE,MAAM;IAAE,QAAQ,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE,IAAI,CAAA;CAAE,GAAG,IAAI,GACjE,IAAI,CAsCN"}
1
+ {"version":3,"file":"test-step-wrapper.d.ts","sourceRoot":"","sources":["../../utils/test-step-wrapper.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAgB,IAAI,IAAI,IAAI,EAAY,MAAM,kBAAkB,CAAC;AAG7F;;;;GAIG;AACH,wBAAgB,2BAA2B,CACzC,IAAI,EAAE,OAAO,IAAI,EACjB,iBAAiB,EAAE,MAAM;IAAE,QAAQ,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE,IAAI,CAAA;CAAE,GAAG,IAAI,GACjE,IAAI,CAmCN"}
@@ -9,27 +9,25 @@ const take_screenshots_1 = require("./take-screenshots");
9
9
  */
10
10
  function wrapTestStepWithScreenshots(test, getCurrentContext) {
11
11
  const originalTestStep = test.step.bind(test);
12
- const originalTestStepSkip = test.step.skip?.bind(test);
12
+ const originalTestStepSkip = test.step.skip.bind(test);
13
+ const takeScreenshot = async (title) => {
14
+ const context = getCurrentContext();
15
+ try {
16
+ await (0, take_screenshots_1.takeScreenshotAfterStep)(context.page, context.testInfo, title);
17
+ }
18
+ catch (screenshotError) {
19
+ console.error('Error taking screenshot after step error:', screenshotError);
20
+ }
21
+ };
13
22
  const stepWrapper = async function (title, body, options) {
14
23
  return originalTestStep(title, async (stepInfo) => {
15
24
  try {
16
25
  const result = await body(stepInfo);
17
- const context = getCurrentContext();
18
- if (context?.page && context?.testInfo) {
19
- await (0, take_screenshots_1.takeScreenshotAfterStep)(context.page, stepInfo, context.testInfo, title);
20
- }
26
+ await takeScreenshot(title);
21
27
  return result;
22
28
  }
23
29
  catch (error) {
24
- const context = getCurrentContext();
25
- if (context?.page && context?.testInfo) {
26
- try {
27
- await (0, take_screenshots_1.takeScreenshotAfterStep)(context.page, { ...stepInfo, error }, context.testInfo, title);
28
- }
29
- catch (screenshotError) {
30
- console.error('Error taking screenshot after step error:', screenshotError);
31
- }
32
- }
30
+ await takeScreenshot(title);
33
31
  throw error;
34
32
  }
35
33
  }, options);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zest-pw/test",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
4
4
  "description": "Advanced Playwright test framework with automatic screenshots, custom reporting, and Zephyr Scale integration",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",