@zest-pw/test 1.0.0 → 1.0.2

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.
Files changed (38) hide show
  1. package/README.md +10 -17
  2. package/dist/fixtures/fixtures.d.ts.map +1 -1
  3. package/dist/fixtures/fixtures.js +1 -8
  4. package/dist/types/types.d.ts +1 -0
  5. package/dist/types/types.d.ts.map +1 -0
  6. package/dist/types/types.js +0 -0
  7. package/dist/utils/enrich-test-results.d.ts +4 -2
  8. package/dist/utils/enrich-test-results.d.ts.map +1 -1
  9. package/dist/utils/enrich-test-results.js +17 -8
  10. package/dist/utils/parse-test-steps.d.ts +4 -4
  11. package/dist/utils/parse-test-steps.d.ts.map +1 -1
  12. package/dist/utils/parse-test-steps.js +5 -14
  13. package/dist/utils/save-json-report.d.ts.map +1 -1
  14. package/dist/utils/save-json-report.js +0 -6
  15. package/dist/utils/save-screenshots.d.ts +6 -5
  16. package/dist/utils/save-screenshots.d.ts.map +1 -1
  17. package/dist/utils/save-screenshots.js +9 -7
  18. package/dist/utils/take-screenshots.d.ts +11 -6
  19. package/dist/utils/take-screenshots.d.ts.map +1 -1
  20. package/dist/utils/take-screenshots.js +14 -16
  21. package/dist/utils/terminal-reporter.d.ts +3 -4
  22. package/dist/utils/terminal-reporter.d.ts.map +1 -1
  23. package/dist/utils/terminal-reporter.js +47 -44
  24. package/dist/utils/test-result-transformer.js +5 -18
  25. package/dist/utils/test-step-wrapper.d.ts +5 -7
  26. package/dist/utils/test-step-wrapper.d.ts.map +1 -1
  27. package/dist/utils/test-step-wrapper.js +15 -24
  28. package/dist/zephyr-api/get-results-from-json.d.ts +6 -0
  29. package/dist/zephyr-api/get-results-from-json.d.ts.map +1 -1
  30. package/dist/zephyr-api/get-results-from-json.js +11 -7
  31. package/dist/zephyr-api/update-execution-result.d.ts +4 -0
  32. package/dist/zephyr-api/update-execution-result.d.ts.map +1 -1
  33. package/dist/zephyr-api/update-execution-result.js +4 -1
  34. package/dist/zephyr-api/zephyr-api.d.ts +4 -3
  35. package/dist/zephyr-api/zephyr-api.d.ts.map +1 -1
  36. package/dist/zephyr-api/zephyr-api.js +6 -5
  37. package/package.json +53 -68
  38. package/scripts/install-config.js +0 -92
package/README.md CHANGED
@@ -13,6 +13,11 @@ Advanced Playwright test framework with automatic screenshots, custom reporting,
13
13
 
14
14
  ## 🚀 Quick Start
15
15
 
16
+ ### Requirements
17
+
18
+ - Node.js >= 18.0.0
19
+ - Playwright (peer dependency)
20
+
16
21
  ### 1. Install the Package
17
22
 
18
23
  ```bash
@@ -21,11 +26,7 @@ npm install --save-dev @zest-pw/test
21
26
 
22
27
  ### 2. Configuration
23
28
 
24
- The configuration file `zest.config.ts` will be automatically created in your project root after installation. If it wasn't created automatically, run:
25
-
26
- ```bash
27
- npx zest-pw-init
28
- ```
29
+ The configuration file `zest.config.ts` will be automatically created in your project root after installation.
29
30
 
30
31
  The default configuration:
31
32
 
@@ -170,13 +171,14 @@ Test results are automatically saved to `test-results/test-results.json`:
170
171
  {
171
172
  "tests": [
172
173
  {
174
+ "projectName": "chromium",
173
175
  "testTitle": "Check the title",
174
176
  "testCaseKey": "TC-001",
175
177
  "steps": [
176
178
  {
177
179
  "stepTitle": "Go to the playwright website",
178
180
  "actualResult": [...],
179
- "statusName": "passed"
181
+ "statusName": "pass"
180
182
  }
181
183
  ]
182
184
  }
@@ -281,9 +283,6 @@ tests/
281
283
  ## 💡 Commands
282
284
 
283
285
  ```bash
284
- # Initialize configuration (if not created automatically)
285
- npx zest-pw-init
286
-
287
286
  # Run all tests
288
287
  npx playwright test
289
288
 
@@ -349,15 +348,9 @@ export default defineZestConfig({
349
348
 
350
349
  ## 🐛 Troubleshooting
351
350
 
352
- ### Configuration file not created automatically
353
-
354
- If `zest.config.ts` wasn't created after installation, run:
355
-
356
- ```bash
357
- npx zest-pw-init
358
- ```
351
+ ### Configuration file setup
359
352
 
360
- Or create it manually using the template from the Configuration section.
353
+ The `zest.config.ts` file is automatically created when you install the package. If it wasn't created, you can create it manually using the template from the Configuration section.
361
354
 
362
355
  ### Screenshots not appearing in report
363
356
 
@@ -1 +1 @@
1
- {"version":3,"file":"fixtures.d.ts","sourceRoot":"","sources":["../../fixtures/fixtures.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,IAAI,6OAUf,CAAC;AASH,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC"}
1
+ {"version":3,"file":"fixtures.d.ts","sourceRoot":"","sources":["../../fixtures/fixtures.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,IAAI,6OAQf,CAAC;AAKH,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC"}
@@ -3,22 +3,15 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.expect = exports.test = void 0;
4
4
  const test_1 = require("@playwright/test");
5
5
  const test_step_wrapper_1 = require("../utils/test-step-wrapper");
6
- // Глобальна змінна для зберігання поточного контексту тесту
7
6
  let currentTestContext = null;
8
- // Розширюємо базовий test з кастомним fixture для зберігання контексту
9
7
  exports.test = test_1.test.extend({
10
8
  page: async ({ page }, use, testInfo) => {
11
- // Зберігаємо контекст перед використанням page
12
9
  currentTestContext = { testInfo, page };
13
10
  await use(page);
14
- // Очищаємо контекст після використання
15
11
  currentTestContext = null;
16
12
  },
17
13
  });
18
- // Застосовуємо обгортку до test.step для автоматичних скріншотів
14
+ // Apply wrapper to test.step for automatic screenshots
19
15
  (0, test_step_wrapper_1.wrapTestStepWithScreenshots)(exports.test, () => currentTestContext);
20
- // Примітка: Контекст тесту (page та testInfo) зберігається через custom fixture
21
- // Скріншоти створюються автоматично після кожного test.step()
22
- // Виведення результатів тестів відбувається через кастомний Reporter (custom-reporter.ts)
23
16
  var test_2 = require("@playwright/test");
24
17
  Object.defineProperty(exports, "expect", { enumerable: true, get: function () { return test_2.expect; } });
@@ -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
@@ -1,6 +1,8 @@
1
1
  /**
2
- * Збагачує результати тестів запланованими кроками з файлів
3
- * Додає кроки які не були виконані (наприклад після падіння тесту)
2
+ * Enriches test results with planned steps from files
3
+ * Adds steps that were not executed (e.g., after test failure)
4
+ * @param results - Test results object containing tests array
5
+ * @returns Enriched test results with planned steps included
4
6
  */
5
7
  export declare function enrichTestResultsWithPlannedSteps(results: any): any;
6
8
  //# sourceMappingURL=enrich-test-results.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"enrich-test-results.d.ts","sourceRoot":"","sources":["../../utils/enrich-test-results.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,wBAAgB,iCAAiC,CAAC,OAAO,EAAE,GAAG,GAAG,GAAG,CASnE"}
1
+ {"version":3,"file":"enrich-test-results.d.ts","sourceRoot":"","sources":["../../utils/enrich-test-results.ts"],"names":[],"mappings":"AAGA;;;;;GAKG;AACH,wBAAgB,iCAAiC,CAAC,OAAO,EAAE,GAAG,GAAG,GAAG,CASnE"}
@@ -37,8 +37,10 @@ exports.enrichTestResultsWithPlannedSteps = enrichTestResultsWithPlannedSteps;
37
37
  const path = __importStar(require("path"));
38
38
  const parse_test_steps_1 = require("./parse-test-steps");
39
39
  /**
40
- * Збагачує результати тестів запланованими кроками з файлів
41
- * Додає кроки які не були виконані (наприклад після падіння тесту)
40
+ * Enriches test results with planned steps from files
41
+ * Adds steps that were not executed (e.g., after test failure)
42
+ * @param results - Test results object containing tests array
43
+ * @returns Enriched test results with planned steps included
42
44
  */
43
45
  function enrichTestResultsWithPlannedSteps(results) {
44
46
  if (!results.tests || !Array.isArray(results.tests)) {
@@ -50,13 +52,14 @@ function enrichTestResultsWithPlannedSteps(results) {
50
52
  };
51
53
  }
52
54
  /**
53
- * Збагачує один тест запланованими кроками
55
+ * Enriches a single test with planned steps
56
+ * @param test - Test object containing steps and file path
57
+ * @returns Test object with enriched steps
54
58
  */
55
59
  function enrichTestWithPlannedSteps(test) {
56
60
  const userSteps = filterUserSteps(test.steps || []);
57
61
  const plannedSteps = getPlannedSteps(test);
58
62
  const allSteps = combineSteps(userSteps, plannedSteps);
59
- // Видаляємо _fullPath перед поверненням (використовувався тільки для getPlannedSteps)
60
63
  const { _fullPath, ...testWithoutFullPath } = test;
61
64
  return {
62
65
  ...testWithoutFullPath,
@@ -64,7 +67,9 @@ function enrichTestWithPlannedSteps(test) {
64
67
  };
65
68
  }
66
69
  /**
67
- * Фільтрує тільки користувацькі кроки (приховує системні хуки)
70
+ * Filters only user-defined steps (hides system hooks)
71
+ * @param steps - Array of test steps
72
+ * @returns Filtered array containing only user steps
68
73
  */
69
74
  function filterUserSteps(steps) {
70
75
  return steps.filter((step) => {
@@ -83,10 +88,11 @@ function filterUserSteps(steps) {
83
88
  });
84
89
  }
85
90
  /**
86
- * Отримує заплановані кроки з файлу тесту
91
+ * Gets planned steps from test file
92
+ * @param test - Test object containing _fullPath property
93
+ * @returns Array of planned step titles
87
94
  */
88
95
  function getPlannedSteps(test) {
89
- // Використовуємо _fullPath який створюється в transformTestCase
90
96
  const fullPath = test._fullPath;
91
97
  if (!fullPath) {
92
98
  return [];
@@ -97,7 +103,10 @@ function getPlannedSteps(test) {
97
103
  return (0, parse_test_steps_1.parsePlannedStepsFromFile)(testFilePath, test.testTitle);
98
104
  }
99
105
  /**
100
- * Об'єднує виконані та невиконані кроки
106
+ * Combines executed and unexecuted steps
107
+ * @param executedSteps - Array of executed step objects
108
+ * @param plannedSteps - Array of planned step titles
109
+ * @returns Combined array with executed steps and unexecuted steps marked as 'In Progress'
101
110
  */
102
111
  function combineSteps(executedSteps, plannedSteps) {
103
112
  const executedStepTitles = executedSteps.map((step) => step.stepTitle);
@@ -1,8 +1,8 @@
1
1
  /**
2
- * Парсить заплановані кроки тесту з файлу
3
- * @param filePath - Шлях до файлу тесту
4
- * @param testTitle - Назва тесту
5
- * @returns Масив назв запланованих кроків
2
+ * Parses planned test steps from file
3
+ * @param filePath - Path to test file
4
+ * @param testTitle - Test title
5
+ * @returns Array of planned step titles
6
6
  */
7
7
  export declare function parsePlannedStepsFromFile(filePath: string, testTitle: string): string[];
8
8
  //# sourceMappingURL=parse-test-steps.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"parse-test-steps.d.ts","sourceRoot":"","sources":["../../utils/parse-test-steps.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,CA4EvF"}
1
+ {"version":3,"file":"parse-test-steps.d.ts","sourceRoot":"","sources":["../../utils/parse-test-steps.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,CAmEvF"}
@@ -36,15 +36,14 @@ Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.parsePlannedStepsFromFile = parsePlannedStepsFromFile;
37
37
  const fs = __importStar(require("fs"));
38
38
  /**
39
- * Парсить заплановані кроки тесту з файлу
40
- * @param filePath - Шлях до файлу тесту
41
- * @param testTitle - Назва тесту
42
- * @returns Масив назв запланованих кроків
39
+ * Parses planned test steps from file
40
+ * @param filePath - Path to test file
41
+ * @param testTitle - Test title
42
+ * @returns Array of planned step titles
43
43
  */
44
44
  function parsePlannedStepsFromFile(filePath, testTitle) {
45
45
  const steps = [];
46
46
  try {
47
- // Перевіряємо, чи файл існує
48
47
  if (!fs.existsSync(filePath)) {
49
48
  return steps;
50
49
  }
@@ -54,16 +53,13 @@ function parsePlannedStepsFromFile(filePath, testTitle) {
54
53
  let insideTargetTest = false;
55
54
  let braceCount = 0;
56
55
  let testStartLine = -1;
57
- // Регулярні вирази для пошуку тестів та кроків
58
56
  const testTitleRegex = /\btest(\.only|\.skip|\.fixme)?\s*\(\s*(["'`])([^"'`]+)\2\s*,/;
59
57
  const stepRegex = /\b(?:test|await\s+test)\.step\s*\(\s*(["'`])([^"'`]+)\1\s*,/;
60
58
  for (let i = 0; i < lines.length; i++) {
61
59
  const line = lines[i];
62
- // Перевіряємо, чи це початок нового тесту
63
60
  const testMatch = line.match(testTitleRegex);
64
61
  if (testMatch) {
65
62
  const foundTitle = testMatch[3];
66
- // Якщо ми були всередині іншого тесту, скидаємо стан
67
63
  if (insideTargetTest && foundTitle !== testTitle) {
68
64
  insideTargetTest = false;
69
65
  braceCount = 0;
@@ -74,7 +70,6 @@ function parsePlannedStepsFromFile(filePath, testTitle) {
74
70
  steps.length = 0;
75
71
  testStartLine = i;
76
72
  braceCount = 0;
77
- // Починаємо рахувати відкриваючі дужки
78
73
  const openBraces = (line.match(/\{/g) || []).length;
79
74
  const closeBraces = (line.match(/\}/g) || []).length;
80
75
  braceCount += openBraces - closeBraces;
@@ -85,13 +80,10 @@ function parsePlannedStepsFromFile(filePath, testTitle) {
85
80
  continue;
86
81
  }
87
82
  }
88
- // Якщо ми знаходимось всередині потрібного тесту, шукаємо кроки
89
83
  if (insideTargetTest && currentTestTitle === testTitle) {
90
- // Рахуємо дужки для визначення меж тесту
91
84
  const openBraces = (line.match(/\{/g) || []).length;
92
85
  const closeBraces = (line.match(/\}/g) || []).length;
93
86
  braceCount += openBraces - closeBraces;
94
- // Якщо дужки закрилися, тест закінчився
95
87
  if (braceCount <= 0 && i > testStartLine) {
96
88
  break;
97
89
  }
@@ -103,8 +95,7 @@ function parsePlannedStepsFromFile(filePath, testTitle) {
103
95
  }
104
96
  }
105
97
  catch (error) {
106
- // Мовчки ігноруємо помилки парсингу
107
- console.error(`Помилка парсингу файлу ${filePath}:`, error);
98
+ console.error(`Error parsing file ${filePath}:`, error);
108
99
  }
109
100
  return steps;
110
101
  }
@@ -1 +1 @@
1
- {"version":3,"file":"save-json-report.d.ts","sourceRoot":"","sources":["../../utils/save-json-report.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,GAAG,EAAE,SAAS,GAAE,MAAuB,GAAG,MAAM,CAyB7F"}
1
+ {"version":3,"file":"save-json-report.d.ts","sourceRoot":"","sources":["../../utils/save-json-report.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,GAAG,EAAE,SAAS,GAAE,MAAuB,GAAG,MAAM,CAiB7F"}
@@ -53,18 +53,12 @@ const path = __importStar(require("path"));
53
53
  */
54
54
  function saveTestResultsToJson(result, outputDir = 'test-results') {
55
55
  try {
56
- // Build the full path to the results directory
57
56
  const resultsPath = path.join(process.cwd(), outputDir);
58
- // Create directory if it doesn't exist (recursive: true creates parent dirs too)
59
57
  if (!fs.existsSync(resultsPath)) {
60
58
  fs.mkdirSync(resultsPath, { recursive: true });
61
59
  }
62
- // Define the output filename
63
60
  const filename = `test-results.json`;
64
- // Build the full file path
65
61
  const filepath = path.join(resultsPath, filename);
66
- // Convert object to JSON string with pretty formatting (2 space indentation)
67
- // and save to file with UTF-8 encoding
68
62
  fs.writeFileSync(filepath, JSON.stringify(result, null, 2), 'utf-8');
69
63
  return filepath;
70
64
  }
@@ -1,9 +1,10 @@
1
1
  /**
2
- * Зберігає скріншот з base64 рядка
3
- * @param base64String - Base64 рядок скріншоту
4
- * @param filename - Назва файлу
5
- * @param outputDir - Базова директорія (за замовчуванням 'screenshots')
6
- * @param testTitle - Назва тесту (опціонально, створює підпапку для організації)
2
+ * Saves screenshot from base64 string to file
3
+ * @param base64String - Base64 encoded screenshot string
4
+ * @param filename - File name for the screenshot
5
+ * @param outputDir - Base output directory (default 'screenshots')
6
+ * @param testTitle - Optional test title, creates subdirectory for organization
7
+ * @returns Full path to the saved screenshot file
7
8
  */
8
9
  export declare function saveBase64Screenshot(base64String: string, filename: string, outputDir?: string, testTitle?: string): string;
9
10
  //# sourceMappingURL=save-screenshots.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"save-screenshots.d.ts","sourceRoot":"","sources":["../../utils/save-screenshots.ts"],"names":[],"mappings":"AAUA;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,YAAY,EAAE,MAAM,EACpB,QAAQ,EAAE,MAAM,EAChB,SAAS,GAAE,MAAsB,EACjC,SAAS,CAAC,EAAE,MAAM,GACjB,MAAM,CAkBR"}
1
+ {"version":3,"file":"save-screenshots.d.ts","sourceRoot":"","sources":["../../utils/save-screenshots.ts"],"names":[],"mappings":"AAYA;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAClC,YAAY,EAAE,MAAM,EACpB,QAAQ,EAAE,MAAM,EAChB,SAAS,GAAE,MAAsB,EACjC,SAAS,CAAC,EAAE,MAAM,GACjB,MAAM,CAiBR"}
@@ -37,21 +37,23 @@ exports.saveBase64Screenshot = saveBase64Screenshot;
37
37
  const fs = __importStar(require("fs"));
38
38
  const path = __importStar(require("path"));
39
39
  /**
40
- * Декодує base64 рядок в Buffer
40
+ * Decodes base64 string to Buffer
41
+ * @param base64String - Base64 encoded string
42
+ * @returns Buffer containing decoded data
41
43
  */
42
44
  function decodeBase64ToBuffer(base64String) {
43
45
  return Buffer.from(base64String, 'base64');
44
46
  }
45
47
  /**
46
- * Зберігає скріншот з base64 рядка
47
- * @param base64String - Base64 рядок скріншоту
48
- * @param filename - Назва файлу
49
- * @param outputDir - Базова директорія (за замовчуванням 'screenshots')
50
- * @param testTitle - Назва тесту (опціонально, створює підпапку для організації)
48
+ * Saves screenshot from base64 string to file
49
+ * @param base64String - Base64 encoded screenshot string
50
+ * @param filename - File name for the screenshot
51
+ * @param outputDir - Base output directory (default 'screenshots')
52
+ * @param testTitle - Optional test title, creates subdirectory for organization
53
+ * @returns Full path to the saved screenshot file
51
54
  */
52
55
  function saveBase64Screenshot(base64String, filename, outputDir = 'screenshots', testTitle) {
53
56
  let screenshotsPath = path.join(process.cwd(), outputDir);
54
- // Якщо вказано назву тесту, створюємо окрему підпапку
55
57
  if (testTitle) {
56
58
  const safeTestTitle = testTitle.replace(/[^a-z0-9]/gi, '_').toLowerCase();
57
59
  screenshotsPath = path.join(screenshotsPath, safeTestTitle);
@@ -1,13 +1,18 @@
1
1
  /**
2
- * Утиліта для створення скріншотів після кроків тесту
2
+ * Utility for creating screenshots after test steps
3
3
  */
4
4
  import type { Page, TestInfo } from "@playwright/test";
5
5
  /**
6
- * Робить скріншот після кожного кроку тесту (завжди, незалежно від результату)
6
+ * Takes a screenshot after each test step (always, regardless of result)
7
7
  *
8
- * Для збереження скріншотів на диск (з base64 результатів):
9
- * 1. Додайте в .env файл: SAVE_SCREENSHOTS=true
10
- * 2. Або передайте через команду: SAVE_SCREENSHOTS=true npx playwright test
8
+ * To save screenshots to disk (from base64 results):
9
+ * 1. Add to .env file: SAVE_SCREENSHOTS=true
10
+ * 2. Or pass via command: SAVE_SCREENSHOTS=true npx playwright test
11
+ *
12
+ * @param page - Playwright Page object
13
+ * @param stepInfo - Step information object
14
+ * @param testInfo - Playwright TestInfo object for attaching screenshots
15
+ * @param stepTitle - Optional step title for attachment name
11
16
  */
12
- 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>;
13
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;;;;;;GAMG;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,CAqBf"}
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"}
@@ -1,34 +1,32 @@
1
1
  "use strict";
2
2
  /**
3
- * Утиліта для створення скріншотів після кроків тесту
3
+ * Utility for creating screenshots after test steps
4
4
  */
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.takeScreenshotAfterStep = takeScreenshotAfterStep;
7
7
  /**
8
- * Робить скріншот після кожного кроку тесту (завжди, незалежно від результату)
8
+ * Takes a screenshot after each test step (always, regardless of result)
9
9
  *
10
- * Для збереження скріншотів на диск (з base64 результатів):
11
- * 1. Додайте в .env файл: SAVE_SCREENSHOTS=true
12
- * 2. Або передайте через команду: SAVE_SCREENSHOTS=true npx playwright test
10
+ * To save screenshots to disk (from base64 results):
11
+ * 1. Add to .env file: SAVE_SCREENSHOTS=true
12
+ * 2. Or pass via command: SAVE_SCREENSHOTS=true npx playwright test
13
+ *
14
+ * @param page - Playwright Page object
15
+ * @param stepInfo - Step information object
16
+ * @param testInfo - Playwright TestInfo object for attaching screenshots
17
+ * @param stepTitle - Optional step title for attachment name
13
18
  */
14
- async function takeScreenshotAfterStep(page, stepInfo, testInfo, stepTitle) {
19
+ async function takeScreenshotAfterStep(page, testInfo, stepTitle) {
15
20
  try {
16
21
  if (page && testInfo) {
17
- // Робимо скріншот без збереження на диск (тільки в буфер)
18
- const screenshotBuffer = await page.screenshot({
19
- fullPage: true
20
- });
21
- // Додаємо скріншот як attachment через testInfo
22
- // Attachment автоматично прикріплюється до поточного кроку як substep
23
- await testInfo.attach(stepTitle || stepInfo?.title || 'screenshot', {
22
+ const screenshotBuffer = await page.screenshot({ fullPage: true });
23
+ await testInfo.attach(stepTitle || 'screenshot', {
24
24
  body: screenshotBuffer,
25
25
  contentType: 'image/png',
26
26
  });
27
- // Примітка: Збереження на диск відбувається в terminal-reporter.ts (якщо PRINT_TEST_RESULTS=true)
28
- // або можна зберегти з JSON звіту вручну
29
27
  }
30
28
  }
31
29
  catch (error) {
32
- console.error('Помилка при створенні скріншота кроку:', error);
30
+ console.error('Error taking step screenshot:', error);
33
31
  }
34
32
  }
@@ -1,8 +1,7 @@
1
1
  /**
2
- * Форматує та виводить результати тестів після їх завершення
3
- * Вивід контролюється через змінну оточення PRINT_TEST_RESULTS
4
- *
5
- * Очікує що result вже збагачений запланованими кроками через enrichTestResultsWithPlannedSteps
2
+ * Formats and prints test results after completion
3
+ * Expects result to be enriched with planned steps via enrichTestResultsWithPlannedSteps
4
+ * @param result - Test results object containing tests array with steps information
6
5
  */
7
6
  export declare function printTestResults(result: any): void;
8
7
  //# sourceMappingURL=terminal-reporter.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"terminal-reporter.d.ts","sourceRoot":"","sources":["../../utils/terminal-reporter.ts"],"names":[],"mappings":"AAIA;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,GAAG,GAAG,IAAI,CAyBlD"}
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,CAsBlD"}
@@ -38,102 +38,105 @@ const path = __importStar(require("path"));
38
38
  const save_screenshots_1 = require("./save-screenshots");
39
39
  const config_1 = require("../config");
40
40
  /**
41
- * Форматує та виводить результати тестів після їх завершення
42
- * Вивід контролюється через змінну оточення PRINT_TEST_RESULTS
43
- *
44
- * Очікує що result вже збагачений запланованими кроками через enrichTestResultsWithPlannedSteps
41
+ * Formats and prints test results after completion
42
+ * Expects result to be enriched with planned steps via enrichTestResultsWithPlannedSteps
43
+ * @param result - Test results object containing tests array with steps information
45
44
  */
46
45
  function printTestResults(result) {
47
46
  if (!result.tests || !Array.isArray(result.tests)) {
48
47
  return;
49
48
  }
50
- console.log('\n=== Деталі по тестах та їх кроках ===');
51
49
  result.tests.forEach((test) => {
52
- printTestInfo(test);
53
- // test.steps вже містить всі кроки (виконані + заплановані) після enrichTestResultsWithPlannedSteps
54
50
  const allSteps = test.steps || [];
55
51
  const executedSteps = allSteps.filter((step) => step.statusName !== 'In Progress');
56
- // Створюємо outputDir точно як Playwright: test-results/{filename}-{test-title}-{project}
57
- // test.testCaseKey тепер без розширення (наприклад "TC-002")
58
52
  const testFileName = test.testCaseKey || 'test';
59
53
  const sanitizedTitle = test.testTitle.replace(/[^a-zA-Z0-9]+/g, '-').replace(/^-|-$/g, '');
60
- const outputDir = path.join('test-results', `${testFileName}-${sanitizedTitle}-chromium`);
54
+ const projectName = test.projectName || 'chromium';
55
+ const outputDir = path.join('test-results', `${testFileName}-${sanitizedTitle}-${projectName}`);
56
+ console.log('');
57
+ console.log('');
58
+ console.log(`\x1b[30m––––––––––––––––––––––––––––––––––\x1b[0m ${test.testCaseKey} \x1b[30m––––––––––––––––––––––––––––––––––\x1b[0m`);
59
+ printTestInfo(test);
61
60
  printTestSteps(executedSteps.length, allSteps, test.testTitle, outputDir);
61
+ console.log('');
62
62
  });
63
- console.log('\n=== Фінальне завершення ===');
64
63
  }
65
64
  /**
66
- * Виводить загальну інформацію про тест
65
+ * Prints general test information
66
+ * @param test - Test object containing testCaseKey and testTitle
67
67
  */
68
68
  function printTestInfo(test) {
69
- console.log(`\n${test.testCaseKey}: ${test.testTitle}`);
69
+ console.log(`\n\x1b[30mTEST CASE:\x1b[0m ${test.testTitle}`);
70
70
  }
71
71
  /**
72
- * Виводить інформацію про кроки тесту
72
+ * Prints test step information
73
+ * @param executedCount - Number of executed steps
74
+ * @param allSteps - Array of all steps (executed and planned)
75
+ * @param testTitle - Title of the test
76
+ * @param outputDir - Optional output directory path for saving screenshots
73
77
  */
74
78
  function printTestSteps(executedCount, allSteps, testTitle, outputDir) {
75
- if (allSteps.length === 0) {
76
- console.log(' Steps: none');
77
- return;
78
- }
79
79
  const totalCount = allSteps.length;
80
- console.log(` Steps (${executedCount}/${totalCount}):`);
80
+ console.log('');
81
81
  allSteps.forEach((step, stepIndex) => {
82
- const statusEmoji = step.statusName === 'passed' ? 'passed - ✅' : step.statusName === 'failed' ? 'failed - ❌' : step.statusName === 'In Progress' ? 'skipped - ⏭️' : '⏱️';
83
- console.log(` ${stepIndex + 1}. ${step.stepTitle}`);
84
- // Спочатку показуємо помилку, якщо є
82
+ const statusEmoji = step.statusName === 'pass' ? '\x1b[32mPASSED ✓\x1b[0m' : step.statusName === 'fail' ? '\x1b[31mFAILED ✗\x1b[0m' : step.statusName === 'In Progress' ? '\x1b[30mSKIPPED ⊘\x1b[0m' : '⏱️';
85
83
  if (step.error) {
86
- console.log(` ❌ Error: ${step.error.message}`);
87
- if (step.error.stack) {
88
- const stackLines = step.error.stack.split('\n').slice(0, 3);
89
- stackLines.forEach((line) => console.log(` ${line}`));
90
- }
84
+ console.log('\x1b[31m- - - - - - - - - - - - - ERROR - - - - - - - - - - - - -\x1b[0m');
85
+ console.log('');
91
86
  }
87
+ console.log(`\x1b[30mTest Step ${stepIndex + 1}:\x1b[0m ${step.stepTitle}`);
92
88
  printStepAttachments(step, testTitle, outputDir, stepIndex + 1);
93
- console.log(` Status: ${statusEmoji}`);
94
- // Додаємо порожній рядок після кожного кроку для кращої читабельності
95
89
  console.log('');
90
+ console.log(`\x1b[30mstatus:\x1b[0m ${statusEmoji}\x1b[0m`);
91
+ console.log('');
92
+ if (step.error) {
93
+ const stackLines = step.error.message.split('\n').slice(0, 4);
94
+ stackLines.forEach((line) => console.log(`${line}`));
95
+ console.log('');
96
+ console.log('\x1b[31m- - - - - - - - - - - - - ERROR - - - - - - - - - - - - -\x1b[0m');
97
+ console.log('');
98
+ }
96
99
  });
100
+ console.log('');
101
+ console.log(`\x1b[30mTotal results:\x1b[0m \x1b[32m${executedCount} passed,\x1b[0m \x1b[31m${totalCount - executedCount} failed\x1b[0m`);
102
+ console.log('');
97
103
  }
98
104
  /**
99
- * Виводить actualResult кроку
105
+ * Prints step attachments (screenshots, etc.)
106
+ * @param step - Step object containing actualResult with attachments
107
+ * @param testTitle - Title of the test
108
+ * @param outputDir - Optional output directory path for saving screenshots
109
+ * @param _stepNumber - Step number (unused, kept for compatibility)
100
110
  */
101
111
  function printStepAttachments(step, testTitle, outputDir, _stepNumber) {
102
112
  if (!step.actualResult || step.actualResult.length === 0) {
103
113
  return;
104
114
  }
105
- console.log(` Screenshot:`);
115
+ console.log(`\x1b[30mScreenshot:\x1b[0m`);
106
116
  step.actualResult.forEach((att) => {
107
117
  const isErrorScreenshot = att.fileName?.includes('ERROR');
108
118
  const emoji = isErrorScreenshot ? '💥' : att.image === 'image/png' ? '📸' : '📄';
109
- // Для консолі виводимо "Decode: Base64"
110
- const displayName = att.image === 'image/png' ? 'Decode: Base64' : att.fileName;
111
- console.log(` ${emoji} ${displayName}`);
119
+ const displayName = att.image === 'image/png' ? '\x1b[30mDecode:\x1b[0m Base64' : att.fileName;
120
+ console.log(` ${emoji} ${displayName}`);
112
121
  if (att.body && att.image === 'text/plain') {
113
- // Для текстових actualResult виводимо повний текст
114
- console.log(` ${att.body}`);
122
+ console.log(`${att.body}`);
115
123
  }
116
- // Зберігаємо скріншот на диск, якщо увімкнено в конфігурації або через змінну оточення
117
124
  const config = (0, config_1.getZestConfig)();
118
125
  const shouldSaveScreenshots = config.screenshots.saveToDisk || process.env.SAVE_SCREENSHOTS === 'true';
119
126
  if (att.body && shouldSaveScreenshots && att.image === 'image/png') {
120
127
  try {
121
- // Використовуємо fileName з actualResult
122
128
  const filename = att.fileName;
123
- // Використовуємо outputDir від Playwright або fallback на screenshots/
124
129
  if (outputDir) {
125
- // Зберігаємо в папку тесту, яку створив Playwright
126
130
  (0, save_screenshots_1.saveBase64Screenshot)(att.body, filename, outputDir);
127
131
  }
128
132
  else {
129
- // Fallback: зберігаємо в screenshots/ з підпапкою тесту
130
133
  (0, save_screenshots_1.saveBase64Screenshot)(att.body, filename, 'screenshots', testTitle);
131
134
  }
132
- console.log(` 💾 File saved: locally`);
133
- console.log(` 📄 File name: ${filename}`);
135
+ console.log(` \x1b[30m💾 File saved:\x1b[0m locally`);
136
+ console.log(` \x1b[30m📄 File name:\x1b[0m ${filename}`);
134
137
  }
135
138
  catch (error) {
136
- console.error(` ⚠️ Error saving screenshot: ${error}`);
139
+ console.error(` ⚠️ Error saving screenshot: ${error}`);
137
140
  }
138
141
  }
139
142
  });
@@ -22,26 +22,13 @@ function transformTestResults(_fullResult, testResults) {
22
22
  */
23
23
  function transformTestCase(test, result) {
24
24
  return {
25
+ projectName: test.parent.parent.title || 'chromium',
25
26
  testTitle: test.title,
26
- testCaseKey: transformLocation(test.location),
27
+ testCaseKey: test.parent.title.split('.')[0],
27
28
  _fullPath: test.location?.file, // Used in enrich-test-results.ts to find planned test steps
28
29
  steps: result.steps?.map(step => transformStep(step)) || []
29
30
  };
30
31
  }
31
- /**
32
- * Transforms test location information - returns file name as testCaseKey
33
- *
34
- * @param location - Location object containing file path information
35
- * @returns Test case key (file name without .spec.ts extension) or undefined
36
- */
37
- function transformLocation(location) {
38
- if (!location || !location.file) {
39
- return undefined;
40
- }
41
- // Extract only the file name from the full path and remove .spec.ts extension
42
- const fileName = location.file.split('/').pop();
43
- return fileName?.replace('.spec.ts', '');
44
- }
45
32
  /**
46
33
  * Transforms error information
47
34
  *
@@ -86,13 +73,13 @@ function transformStep(step) {
86
73
  * Determines step status
87
74
  *
88
75
  * @param step - Step object from test execution
89
- * @returns Step status ('failed' if has error, otherwise step.status or 'passed')
76
+ * @returns Step status ('fail' if has error, otherwise 'pass')
90
77
  */
91
78
  function determineStepStatus(step) {
92
79
  if (step.error) {
93
- return 'failed';
80
+ return 'fail';
94
81
  }
95
- return step.status || 'passed';
82
+ return 'pass';
96
83
  }
97
84
  /**
98
85
  * Transforms attachment (screenshot, video, etc.)
@@ -1,12 +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
- * Застосовує обгортку до test.step для автоматичного створення скріншотів
4
- * після кожного кроку тесту
5
- *
6
- * @param test - Об'єкт test з Playwright
7
- * @param getCurrentContext - Функція для отримання поточного контексту тесту
3
+ * Wraps test.step to automatically create screenshots after each test step
4
+ * @param test - Playwright test object
5
+ * @param getCurrentContext - Function to get current test context (testInfo and page)
8
6
  */
9
- export declare function wrapTestStepWithScreenshots(test: TestType<any, any>, getCurrentContext: () => {
7
+ export declare function wrapTestStepWithScreenshots(test: typeof base, getCurrentContext: () => {
10
8
  testInfo: TestInfo;
11
9
  page: Page;
12
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;;;;;;GAMG;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,CA2CN"}
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"}
@@ -3,46 +3,37 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.wrapTestStepWithScreenshots = wrapTestStepWithScreenshots;
4
4
  const take_screenshots_1 = require("./take-screenshots");
5
5
  /**
6
- * Застосовує обгортку до test.step для автоматичного створення скріншотів
7
- * після кожного кроку тесту
8
- *
9
- * @param test - Об'єкт test з Playwright
10
- * @param getCurrentContext - Функція для отримання поточного контексту тесту
6
+ * Wraps test.step to automatically create screenshots after each test step
7
+ * @param test - Playwright test object
8
+ * @param getCurrentContext - Function to get current test context (testInfo and page)
11
9
  */
12
10
  function wrapTestStepWithScreenshots(test, getCurrentContext) {
13
11
  const originalTestStep = test.step.bind(test);
14
- 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
+ };
15
22
  const stepWrapper = async function (title, body, options) {
16
23
  return originalTestStep(title, async (stepInfo) => {
17
24
  try {
18
- // Виконуємо крок
19
25
  const result = await body(stepInfo);
20
- // Робимо скріншот після успішного виконання кроку
21
- const context = getCurrentContext();
22
- if (context?.page && context?.testInfo) {
23
- await (0, take_screenshots_1.takeScreenshotAfterStep)(context.page, stepInfo, context.testInfo, title);
24
- }
26
+ await takeScreenshot(title);
25
27
  return result;
26
28
  }
27
29
  catch (error) {
28
- // Якщо крок падає, все одно робимо скріншот
29
- const context = getCurrentContext();
30
- if (context?.page && context?.testInfo) {
31
- try {
32
- await (0, take_screenshots_1.takeScreenshotAfterStep)(context.page, { ...stepInfo, error }, context.testInfo, title);
33
- }
34
- catch (screenshotError) {
35
- console.error('Помилка при створенні скріншота після помилки кроку:', screenshotError);
36
- }
37
- }
30
+ await takeScreenshot(title);
38
31
  throw error;
39
32
  }
40
33
  }, options);
41
34
  };
42
- // Додаємо метод skip, якщо він існує
43
35
  if (originalTestStepSkip) {
44
36
  stepWrapper.skip = originalTestStepSkip;
45
37
  }
46
- // Замінюємо оригінальний test.step на обгортку
47
38
  test.step = stepWrapper;
48
39
  }
@@ -1,2 +1,8 @@
1
+ /**
2
+ * Gets test results from JSON file and processes them for Zephyr
3
+ * Excludes testTitle and testCaseKey from each test, stepTitle from each step,
4
+ * and transforms tests array into an object with testCaseKey as keys
5
+ * @returns Processed test results object with testCaseKey as keys, or null if no results found
6
+ */
1
7
  export declare function getResultsFromJson(): Promise<any>;
2
8
  //# sourceMappingURL=get-results-from-json.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"get-results-from-json.d.ts","sourceRoot":"","sources":["../../zephyr-api/get-results-from-json.ts"],"names":[],"mappings":"AAsBA,wBAAsB,kBAAkB,iBAuBvC"}
1
+ {"version":3,"file":"get-results-from-json.d.ts","sourceRoot":"","sources":["../../zephyr-api/get-results-from-json.ts"],"names":[],"mappings":"AAqBA;;;;;GAKG;AACH,wBAAsB,kBAAkB,iBAoBvC"}
@@ -36,20 +36,26 @@ Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.getResultsFromJson = getResultsFromJson;
37
37
  const fs = __importStar(require("fs"));
38
38
  const path = __importStar(require("path"));
39
- // Допоміжна функція для читання результатів тестів
39
+ /**
40
+ * Helper function to read test results from JSON file
41
+ * @returns Test results object or null if file doesn't exist
42
+ */
40
43
  function readTestResults() {
41
- // Шлях до файлу з результатами тестів
42
44
  const testResultsPath = path.join(process.cwd(), 'test-results', 'test-results.json');
43
- // Перевіряємо, чи існує файл
44
45
  if (!fs.existsSync(testResultsPath)) {
45
46
  console.error('Test results file not found:', testResultsPath);
46
47
  return null;
47
48
  }
48
- // Читаємо та парсимо JSON файл
49
49
  const testResultsContent = fs.readFileSync(testResultsPath, 'utf-8');
50
50
  const testResults = JSON.parse(testResultsContent);
51
51
  return testResults;
52
52
  }
53
+ /**
54
+ * Gets test results from JSON file and processes them for Zephyr
55
+ * Excludes testTitle and testCaseKey from each test, stepTitle from each step,
56
+ * and transforms tests array into an object with testCaseKey as keys
57
+ * @returns Processed test results object with testCaseKey as keys, or null if no results found
58
+ */
53
59
  async function getResultsFromJson() {
54
60
  console.log('Getting results for Zephyr...');
55
61
  const testResults = readTestResults();
@@ -57,10 +63,8 @@ async function getResultsFromJson() {
57
63
  console.error('No test results found');
58
64
  return null;
59
65
  }
60
- // Виключаємо testTitle та testCaseKey з кожного тесту, stepTitle з кожного кроку
61
- // та перетворюємо масив тестів в об'єкт з ключами testCaseKey
62
66
  const processedResults = testResults.tests.reduce((acc, test) => {
63
- const { testTitle, testCaseKey, ...testData } = test;
67
+ const { projectName, testTitle, testCaseKey, ...testData } = test;
64
68
  acc[testCaseKey] = {
65
69
  ...testData,
66
70
  steps: test.steps.map(({ stepTitle, ...step }) => step)
@@ -1,2 +1,6 @@
1
+ /**
2
+ * Updates test execution results in Zephyr Scale
3
+ * Reads test results from JSON file and updates each test case in Zephyr
4
+ */
1
5
  export declare function updateTestResult(): Promise<void>;
2
6
  //# sourceMappingURL=update-execution-result.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"update-execution-result.d.ts","sourceRoot":"","sources":["../../zephyr-api/update-execution-result.ts"],"names":[],"mappings":"AAOA,wBAAsB,gBAAgB,kBAyBrC"}
1
+ {"version":3,"file":"update-execution-result.d.ts","sourceRoot":"","sources":["../../zephyr-api/update-execution-result.ts"],"names":[],"mappings":"AAOA;;;GAGG;AACH,wBAAsB,gBAAgB,kBAwBrC"}
@@ -3,6 +3,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.updateTestResult = updateTestResult;
4
4
  const get_results_from_json_1 = require("./get-results-from-json");
5
5
  const zephyr_api_1 = require("./zephyr-api");
6
+ /**
7
+ * Updates test execution results in Zephyr Scale
8
+ * Reads test results from JSON file and updates each test case in Zephyr
9
+ */
6
10
  async function updateTestResult() {
7
11
  console.log('Updating test result in Zephyr...');
8
12
  const testResults = await (0, get_results_from_json_1.getResultsFromJson)();
@@ -10,7 +14,6 @@ async function updateTestResult() {
10
14
  console.error('No test results found');
11
15
  return;
12
16
  }
13
- // Iterate over object with testCaseKey as keys
14
17
  for (const testCaseKey in testResults) {
15
18
  const steps = testResults[testCaseKey];
16
19
  const testCaseId = await (0, zephyr_api_1.getTestCaseId)(testCaseKey);
@@ -3,17 +3,18 @@
3
3
  * @param testCaseKey - Test case key (e.g., "TC-001")
4
4
  * @returns Test case ID or undefined in case of error
5
5
  */
6
- export declare function getTestCaseId(testCaseKey: string): Promise<string | undefined>;
6
+ export declare function getTestCaseId(testCaseKey: string): Promise<string>;
7
7
  /**
8
8
  * Gets test execution key from Zephyr by test case ID
9
9
  * @param testCaseId - Test case ID
10
10
  * @returns Test execution key or null in case of error
11
11
  */
12
- export declare function getTestExecutionKey(testCaseId: string): Promise<string | null>;
12
+ export declare function getTestExecutionKey(testCaseId: string): Promise<string>;
13
13
  /**
14
- * Puts test execution in Zephyr
14
+ * Updates test execution steps in Zephyr
15
15
  * @param testExecutionKey - Test execution key
16
16
  * @param steps - Array of test steps to update
17
+ * @throws Error if request fails
17
18
  */
18
19
  export declare function putTestExecution(testExecutionKey: string, steps: string[]): Promise<void>;
19
20
  //# sourceMappingURL=zephyr-api.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"zephyr-api.d.ts","sourceRoot":"","sources":["../../zephyr-api/zephyr-api.ts"],"names":[],"mappings":"AAQA;;;;GAIG;AACH,wBAAsB,aAAa,CAAC,WAAW,EAAE,MAAM,+BAmBtD;AAED;;;;GAIG;AACH,wBAAsB,mBAAmB,CAAC,UAAU,EAAE,MAAM,0BA2B3D;AAED;;;;GAIG;AACH,wBAAsB,gBAAgB,CAAC,gBAAgB,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,iBA2B/E"}
1
+ {"version":3,"file":"zephyr-api.d.ts","sourceRoot":"","sources":["../../zephyr-api/zephyr-api.ts"],"names":[],"mappings":"AAWA;;;;GAIG;AACH,wBAAsB,aAAa,CAAC,WAAW,EAAE,MAAM,mBAkBtD;AAED;;;;GAIG;AACH,wBAAsB,mBAAmB,CAAC,UAAU,EAAE,MAAM,mBA0B3D;AAED;;;;;GAKG;AACH,wBAAsB,gBAAgB,CAAC,gBAAgB,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,iBAyB/E"}
@@ -3,7 +3,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getTestCaseId = getTestCaseId;
4
4
  exports.getTestExecutionKey = getTestExecutionKey;
5
5
  exports.putTestExecution = putTestExecution;
6
- // Common headers for all requests
6
+ /**
7
+ * Gets common headers for all Zephyr API requests
8
+ * @returns Headers object with Content-Type and Authorization
9
+ */
7
10
  const getHeaders = () => {
8
11
  return {
9
12
  'Content-Type': 'application/json',
@@ -21,7 +24,6 @@ async function getTestCaseId(testCaseKey) {
21
24
  method: 'GET',
22
25
  headers: getHeaders(),
23
26
  });
24
- // Return only ID
25
27
  const data = await response.json();
26
28
  const id = data.id;
27
29
  console.log('------------------------------------------');
@@ -44,7 +46,6 @@ async function getTestExecutionKey(testCaseId) {
44
46
  method: 'GET',
45
47
  headers: getHeaders()
46
48
  });
47
- // Find object in array by testCase.id
48
49
  const data = await response.json();
49
50
  const testExecution = data.values.find((execution) => execution.testCase.id === testCaseId);
50
51
  if (testExecution) {
@@ -62,9 +63,10 @@ async function getTestExecutionKey(testCaseId) {
62
63
  }
63
64
  }
64
65
  /**
65
- * Puts test execution in Zephyr
66
+ * Updates test execution steps in Zephyr
66
67
  * @param testExecutionKey - Test execution key
67
68
  * @param steps - Array of test steps to update
69
+ * @throws Error if request fails
68
70
  */
69
71
  async function putTestExecution(testExecutionKey, steps) {
70
72
  try {
@@ -78,7 +80,6 @@ async function putTestExecution(testExecutionKey, steps) {
78
80
  });
79
81
  console.log('Successfully sent test steps to Zephyr ✅');
80
82
  console.log('------------------------------------------');
81
- // Add 3 second pause after updating steps
82
83
  console.log('Waiting 3 seconds before continuing... ⏳');
83
84
  await new Promise(resolve => setTimeout(resolve, 3000));
84
85
  }
package/package.json CHANGED
@@ -1,69 +1,54 @@
1
1
  {
2
- "name": "@zest-pw/test",
3
- "version": "1.0.0",
4
- "description": "Advanced Playwright test framework with automatic screenshots, custom reporting, and Zephyr Scale integration",
5
- "main": "dist/index.js",
6
- "types": "dist/index.d.ts",
7
- "exports": {
8
- ".": {
9
- "default": "./dist/index.js",
10
- "types": "./dist/index.d.ts"
11
- },
12
- "./reporter": "./dist/reporter/custom-reporter.js"
13
- },
14
- "files": [
15
- "dist",
16
- "scripts",
17
- "README.md",
18
- "LICENSE"
19
- ],
20
- "bin": {
21
- "zest-pw-init": "scripts/install-config.js"
22
- },
23
- "scripts": {
24
- "build": "tsc",
25
- "test": "playwright test",
26
- "prepublishOnly": "npm run build",
27
- "type-check": "tsc --noEmit",
28
- "postinstall": "node scripts/install-config.js",
29
- "install": "node scripts/install-config.js"
30
- },
31
- "keywords": [
32
- "playwright",
33
- "testing",
34
- "automation",
35
- "zephyr",
36
- "zephyr-scale",
37
- "screenshots",
38
- "test-framework",
39
- "test-reporter",
40
- "e2e",
41
- "end-to-end"
42
- ],
43
- "author": "",
44
- "license": "MIT",
45
- "repository": {
46
- "type": "git",
47
- "url": "https://github.com/Capuchin33/zest-pw.git"
48
- },
49
- "homepage": "https://github.com/Capuchin33/zest-pw#readme",
50
- "bugs": {
51
- "url": "https://github.com/Capuchin33/zest-pw/issues"
52
- },
53
- "engines": {
54
- "node": ">=16.0.0"
55
- },
56
- "peerDependencies": {
57
- "@playwright/test": "^1.40.0"
58
- },
59
- "peerDependenciesMeta": {
60
- "@playwright/test": {
61
- "optional": false
62
- }
63
- },
64
- "devDependencies": {
65
- "@playwright/test": "^1.40.0",
66
- "@types/node": "^20.0.0",
67
- "typescript": "^5.0.0"
68
- }
69
- }
2
+ "name": "@zest-pw/test",
3
+ "version": "1.0.2",
4
+ "description": "Advanced Playwright test framework with automatic screenshots, custom reporting, and Zephyr Scale integration",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "exports": {
8
+ ".": {
9
+ "default": "./dist/index.js",
10
+ "types": "./dist/index.d.ts"
11
+ },
12
+ "./reporter": "./dist/reporter/custom-reporter.js"
13
+ },
14
+ "files": [
15
+ "dist",
16
+ "README.md",
17
+ "LICENSE"
18
+ ],
19
+ "scripts": {
20
+ "build": "tsc",
21
+ "prepublishOnly": "npm run build",
22
+ "type-check": "tsc --noEmit"
23
+ },
24
+ "keywords": [
25
+ "playwright",
26
+ "testing",
27
+ "automation",
28
+ "zephyr",
29
+ "zephyr-scale",
30
+ "screenshots",
31
+ "test-framework",
32
+ "test-reporter",
33
+ "e2e",
34
+ "end-to-end"
35
+ ],
36
+ "author": "",
37
+ "license": "MIT",
38
+ "repository": {
39
+ "type": "git",
40
+ "url": "git+https://github.com/Capuchin33/zest-pw.git"
41
+ },
42
+ "homepage": "https://github.com/Capuchin33/zest-pw#readme",
43
+ "bugs": {
44
+ "url": "https://github.com/Capuchin33/zest-pw/issues"
45
+ },
46
+ "engines": {
47
+ "node": ">=18.0.0"
48
+ },
49
+ "devDependencies": {
50
+ "@playwright/test": "^1.40.0",
51
+ "@types/node": "^20.0.0",
52
+ "typescript": "^5.0.0"
53
+ }
54
+ }
@@ -1,92 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- /**
4
- * Post-install script to automatically create zest.config.ts in the project root
5
- * This script runs after npm install and creates a default configuration file
6
- * if it doesn't already exist.
7
- */
8
-
9
- const fs = require('fs');
10
- const path = require('path');
11
-
12
- const configTemplate = `import { defineZestConfig } from '@zest-pw/test';
13
-
14
- /**
15
- * Zest Playwright Configuration
16
- *
17
- * Configure test reporting, screenshots, and Zephyr integration
18
- */
19
- export default defineZestConfig({
20
- reporter: {
21
- // Save test results to JSON file
22
- saveJsonReport: true,
23
- // Output directory for reports
24
- outputDir: 'test-results',
25
- // Print test results to console
26
- printToConsole: true,
27
- // Verbose output (includes all step details)
28
- verbose: false,
29
- },
30
- screenshots: {
31
- // Enable screenshot capture
32
- enabled: true,
33
- // Include screenshots in JSON report
34
- includeInReport: true,
35
- // Capture screenshots only on failure
36
- onlyOnFailure: false,
37
- // Save screenshots to disk as files
38
- saveToDisk: false,
39
- },
40
- zephyr: {
41
- // Enable Zephyr Scale integration
42
- enabled: false,
43
- // Update test results in Zephyr after test run
44
- updateResults: false,
45
- // API credentials (uses environment variables by default)
46
- // apiUrl: process.env.ZEPHYR_API_URL,
47
- // apiKey: process.env.ZEPHYR_API_KEY,
48
- // testCycleKey: process.env.ZEPHYR_TEST_CYCLE_KEY,
49
- },
50
- });
51
- `;
52
-
53
- const configFileName = 'zest.config.ts';
54
-
55
- // When postinstall runs, process.cwd() is the project root where npm install was executed
56
- // This is the correct directory where we want to create zest.config.ts
57
- const projectRoot = process.cwd();
58
- const configPath = path.join(projectRoot, configFileName);
59
-
60
- // Skip if we're in the zest-pw package development directory itself
61
- // (when running npm install in the package repo)
62
- const packageJsonPath = path.join(projectRoot, 'package.json');
63
- if (fs.existsSync(packageJsonPath)) {
64
- try {
65
- const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
66
- if (packageJson.name === '@zest-pw/test') {
67
- // We're in the package development directory, skip
68
- process.exit(0);
69
- }
70
- } catch (e) {
71
- // If we can't read package.json, continue anyway
72
- }
73
- }
74
-
75
- // Перевіряємо, чи файл вже існує
76
- if (fs.existsSync(configPath)) {
77
- console.log(`[@zest-pw/test] ✓ ${configFileName} already exists, skipping...`);
78
- process.exit(0);
79
- }
80
-
81
- // Створюємо файл конфігурації
82
- try {
83
- fs.writeFileSync(configPath, configTemplate, 'utf8');
84
- console.log(`[@zest-pw/test] ✓ Created ${configFileName} in project root`);
85
- console.log(`[@zest-pw/test] Location: ${configPath}`);
86
- } catch (error) {
87
- // Don't break the installation process, but show the error
88
- console.error(`[@zest-pw/test] ⚠ Failed to create ${configFileName}:`, error.message);
89
- console.error(`[@zest-pw/test] Target directory: ${projectRoot}`);
90
- process.exit(0); // Exit with 0 to not break npm install
91
- }
92
-