From ecba2084a0ac85c61f985228d0b6e9d57198857a Mon Sep 17 00:00:00 2001 From: Oleksandr Pelykh Date: Mon, 13 Jan 2025 07:38:18 +0200 Subject: [PATCH 1/9] upd build script for package.json --- build/scripts/edit-package-json.js | 68 +++++++++++++++--------------- src/reporter.js | 4 +- 2 files changed, 37 insertions(+), 35 deletions(-) diff --git a/build/scripts/edit-package-json.js b/build/scripts/edit-package-json.js index b1a7f3e2..60440e34 100755 --- a/build/scripts/edit-package-json.js +++ b/build/scripts/edit-package-json.js @@ -1,40 +1,42 @@ -// import fs from 'fs'; -// import path from 'path'; +import fs from 'fs'; +import path from 'path'; -// // This script updates "type" to "commonjs" and "chalk" version to "^4.1.2" in package.json file. -// // Because chalk 5+ works only with ESM. +// This script updates "type" to "commonjs" and "chalk" version to "^4.1.2" in package.json file. +// Because chalk 5+ works only with ESM. -// // Define the file path -// const filePath = path.join(process.cwd(), 'lib/package.json'); +// Define the file path +const filePath = path.join(process.cwd(), 'lib/package.json'); -// // Read the file content -// fs.readFile(filePath, 'utf8', (err, data) => { -// if (err) { -// console.error('Error reading the file:', err); -// return; -// } +// Read the file content +fs.readFile(filePath, 'utf8', (err, data) => { + if (err) { + console.error('No package.json file. Creating...'); + // create file if not exists + fs.writeFileSync(filePath, '{}', 'utf8'); + data = data || '{}'; + } -// // Parse the JSON content -// let packageJson; -// try { -// packageJson = JSON.parse(data); -// } catch (parseErr) { -// console.error('Error parsing JSON:', parseErr); -// return; -// } + // Parse the JSON content + let packageJson; + try { + packageJson = JSON.parse(data); + } catch (parseErr) { + console.error('Error parsing JSON:', parseErr); + return; + } -// // Update the "type" -// packageJson.type = 'commonjs'; + // Update the "type" + packageJson.type = 'commonjs'; -// // Convert the JSON object back to a string -// const updatedData = JSON.stringify(packageJson, null, 2); + // Convert the JSON object back to a string + const updatedData = JSON.stringify(packageJson, null, 2); -// // Write the updated content back to the file -// fs.writeFile(filePath, updatedData, 'utf8', (err) => { -// if (err) { -// console.error('Error writing the file:', err); -// return; -// } -// console.log(`Updated 'type' to 'commonjs' in ${filePath}`); -// }); -// }); \ No newline at end of file + // Write the updated content back to the file + fs.writeFile(filePath, updatedData, 'utf8', (err) => { + if (err) { + console.error('Error writing the file:', err); + return; + } + console.log(`Updated 'type' to 'commonjs' in ${filePath}`); + }); +}); \ No newline at end of file diff --git a/src/reporter.js b/src/reporter.js index 3a2a38bc..133dcbcb 100644 --- a/src/reporter.js +++ b/src/reporter.js @@ -1,5 +1,5 @@ -import TestomatClient from './client.js'; -import * as TRConstants from './constants.js'; +// import TestomatClient from './client.js'; +// import * as TRConstants from './constants.js'; import { services } from './services/index.js'; import reporterFunctions from './reporter-functions.js'; From 07b066fe2bb74cb210abf4e98fa9d325b37aed59 Mon Sep 17 00:00:00 2001 From: Oleksandr Pelykh Date: Wed, 15 Jan 2025 19:08:32 +0200 Subject: [PATCH 2/9] rm testomat functions support for Playwright --- docs/functions.md | 2 +- src/adapter/playwright.js | 15 --------------- 2 files changed, 1 insertion(+), 16 deletions(-) diff --git a/docs/functions.md b/docs/functions.md index ea0c7d91..0cb6ff87 100644 --- a/docs/functions.md +++ b/docs/functions.md @@ -128,5 +128,5 @@ Supported frameworks: - 🟢 Cucumber - 🟢 Jest - 🟢 Mocha -- 🟢 Playwright +- 🔴 Playwright (use native functionality instead) - 🟢 WDIO (everything, except artifacts) \ No newline at end of file diff --git a/src/adapter/playwright.js b/src/adapter/playwright.js index bfc99200..f50c762f 100644 --- a/src/adapter/playwright.js +++ b/src/adapter/playwright.js @@ -233,19 +233,4 @@ function getTestContextName(test) { return `${test._requireFile || ''}_${test.title}`; } -async function initPlaywrightForStorage() { - try { - // @ts-ignore-next-line - // eslint-disable-next-line import/no-extraneous-dependencies - const { test } = await import('@playwright/test'); - // eslint-disable-next-line no-empty-pattern - test.beforeEach(async ({}, testInfo) => { - global.testomatioTestTitle = `${testInfo.file || ''}_${testInfo.title}`; - }); - } catch (e) { - // ignore - } -} - export default PlaywrightReporter; -export { initPlaywrightForStorage }; From 1484c265e89da6219ed52c9b392999f4fafff0b0 Mon Sep 17 00:00:00 2001 From: Oleksandr Pelykh Date: Wed, 15 Jan 2025 19:08:45 +0200 Subject: [PATCH 3/9] fix client artifacts logging --- src/client.js | 133 ++++++++++++++++++++++++-------------------------- 1 file changed, 63 insertions(+), 70 deletions(-) diff --git a/src/client.js b/src/client.js index 47d03fde..50d2130a 100644 --- a/src/client.js +++ b/src/client.js @@ -305,88 +305,81 @@ class Client { .then(() => { if (!this.uploader.isEnabled) return; + const filesizeStrMaxLength = 7; + if (this.uploader.successfulUploads.length) { + debug('\n', APP_PREFIX, `🗄️ ${this.uploader.successfulUploads.length} artifacts uploaded to S3 bucket`); + const uploadedArtifacts = this.uploader.successfulUploads.map(file => ({ + relativePath: file.path.replace(process.cwd(), ''), + link: file.link, + sizePretty: prettyBytes(file.size, { round: 0 }).toString(), + })); + + uploadedArtifacts.forEach(upload => { + debug( + `🟢Uploaded artifact`, + `${upload.relativePath},`, + 'size:', + `${upload.sizePretty},`, + 'link:', + `${upload.link}`, + ); + }); + } + + if (this.uploader.failedUploads.length) { console.log( APP_PREFIX, - `🗄️ ${this.uploader.successfulUploads.length} artifacts ${ - process.env.TESTOMATIO_PRIVATE_ARTIFACTS ? 'privately' : pc.bold('publicly') - } 🟢uploaded to S3 bucket`, + `🗄️ ${this.uploader.failedUploads.length} artifacts 🔴${pc.bold('failed')} to upload`, ); + const failedUploads = this.uploader.failedUploads.map(file => ({ + relativePath: file.path.replace(process.cwd(), ''), + sizePretty: prettyBytes(file.size, { round: 0 }).toString(), + })); - const filesizeStrMaxLength = 7; - - if (this.uploader.successfulUploads.length) { - debug('\n', APP_PREFIX, `🗄️ ${this.uploader.successfulUploads.length} artifacts uploaded to S3 bucket`); - const uploadedArtifacts = this.uploader.successfulUploads.map(file => ({ - relativePath: file.path.replace(process.cwd(), ''), - link: file.link, - sizePretty: prettyBytes(file.size, { round: 0 }).toString(), - })); - - uploadedArtifacts.forEach(upload => { - debug( - `🟢Uploaded artifact`, - `${upload.relativePath},`, - 'size:', - `${upload.sizePretty},`, - 'link:', - `${upload.link}`, - ); - }); - } + const pathPadding = Math.max(...failedUploads.map(upload => upload.relativePath.length)) + 1; - if (this.uploader.failedUploads.length) { + failedUploads.forEach(upload => { console.log( - APP_PREFIX, - `🗄️ ${this.uploader.failedUploads.length} artifacts 🔴${pc.bold('failed')} to upload`, + ` ${pc.gray('|')} 🔴 ${upload.relativePath.padEnd(pathPadding)} ${pc.gray( + `| ${upload.sizePretty.padStart(filesizeStrMaxLength)} |`, + )}`, ); - const failedUploads = this.uploader.failedUploads.map(file => ({ - relativePath: file.path.replace(process.cwd(), ''), - sizePretty: prettyBytes(file.size, { round: 0 }).toString(), - })); - - const pathPadding = Math.max(...failedUploads.map(upload => upload.relativePath.length)) + 1; - - failedUploads.forEach(upload => { - console.log( - ` ${pc.gray('|')} 🔴 ${upload.relativePath.padEnd(pathPadding)} ${pc.gray( - `| ${upload.sizePretty.padStart(filesizeStrMaxLength)} |`, - )}`, - ); - }); - } + }); + } - if (this.uploader.skippedUploads.length) { + if (this.uploader.skippedUploads.length) { + console.log( + '\n', + APP_PREFIX, + `🗄️ ${pc.bold(this.uploader.skippedUploads.length)} artifacts uploading 🟡${pc.bold( + 'skipped', + )}`, + ); + const skippedUploads = this.uploader.skippedUploads.map(file => ({ + relativePath: file.path.replace(process.cwd(), ''), + sizePretty: file.size === null ? 'unknown' : prettyBytes(file.size, { round: 0 }).toString(), + })); + const pathPadding = Math.max(...skippedUploads.map(upload => upload.relativePath.length)) + 1; + skippedUploads.forEach(upload => { console.log( - '\n', - APP_PREFIX, - `🗄️ ${pc.bold(this.uploader.skippedUploads.length)} artifacts uploading 🟡${pc.bold( - 'skipped', + ` ${pc.gray('|')} 🟡 ${upload.relativePath.padEnd(pathPadding)} ${pc.gray( + `| ${upload.sizePretty.padStart(filesizeStrMaxLength)} |`, )}`, ); - const skippedUploads = this.uploader.skippedUploads.map(file => ({ - relativePath: file.path.replace(process.cwd(), ''), - sizePretty: file.size === null ? 'unknown' : prettyBytes(file.size, { round: 0 }).toString(), - })); - const pathPadding = Math.max(...skippedUploads.map(upload => upload.relativePath.length)) + 1; - skippedUploads.forEach(upload => { - console.log( - ` ${pc.gray('|')} 🟡 ${upload.relativePath.padEnd(pathPadding)} ${pc.gray( - `| ${upload.sizePretty.padStart(filesizeStrMaxLength)} |`, - )}`, - ); - }); - } - - if (this.uploader.skippedUploads.length || this.uploader.failedUploads.length) { - const command = `TESTOMATIO= TESTOMATIO_RUN=${ - this.runId - } npx @testomatio/reporter upload-artifacts`; - console.log( - APP_PREFIX, - `Run "${pc.magenta(command)}" with valid S3 credentials to upload skipped & failed artifacts`, - ); - } + }); + } + + if (this.uploader.skippedUploads.length || this.uploader.failedUploads.length) { + const command = `TESTOMATIO= TESTOMATIO_RUN=${ + this.runId + } npx @testomatio/reporter upload-artifacts`; + const numberOfNotUploadedArtifacts = this.uploader.skippedUploads.length + this.uploader.failedUploads.length; + console.log( + APP_PREFIX, + `${numberOfNotUploadedArtifacts} artifacts were not uploaded. + Run "${pc.magenta(command)}" with valid S3 credentials to upload skipped & failed artifacts`, + ); } }) .catch(err => console.log(APP_PREFIX, err)); From 195d93a327ce358e447480f724189fd2e32e2937 Mon Sep 17 00:00:00 2001 From: Oleksandr Pelykh Date: Wed, 15 Jan 2025 19:08:59 +0200 Subject: [PATCH 4/9] upd reporter functions: remove playwright --- src/reporter-functions.js | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/src/reporter-functions.js b/src/reporter-functions.js index 0dbc2320..df4e0dd2 100644 --- a/src/reporter-functions.js +++ b/src/reporter-functions.js @@ -1,40 +1,48 @@ import { services } from './services/index.js'; -import { initPlaywrightForStorage } from './adapter/playwright.js'; - -(async () => { - if (process.env.PLAYWRIGHT_TEST_BASE_URL) initPlaywrightForStorage(); -})(); /** * Stores path to file as artifact and uploads it to the S3 storage * @param {string | {path: string, type: string, name: string}} data - path to file or object with path, type and name */ function saveArtifact(data, context = null) { + if (process.env.IS_PLAYWRIGHT) + throw new Error('This function is not available in Playwright framework. Playwright supports artifacts out of the box'); if (!data) return; services.artifacts.put(data, context); } /** * Attach log message(s) to the test report - * @param {...any} args + * @param string */ function logMessage(...args) { + if (process.env.IS_PLAYWRIGHT) throw new Error('This function is not available in Playwright framework'); services.logger._templateLiteralLog(...args); } /** * Similar to "log" function but marks message in report as a step - * @param {*} message + * @param {string} message */ function addStep(message) { + if (process.env.IS_PLAYWRIGHT) + throw new Error('This function is not available in Playwright framework. Use playwright steps'); + services.logger.step(message); } /** * Add key-value pair(s) to the test report - * @param {*} keyValue + * @param {{[key: string]: string} | string} keyValue object { key: value } (multiple props allowed) or key (string) + * @param {string?} value */ -function setKeyValue(keyValue) { +function setKeyValue(keyValue, value = null) { + if (process.env.IS_PLAYWRIGHT) + throw new Error('This function is not available in Playwright framework. Use test tag instead.'); + + if (typeof keyValue === 'string') { + keyValue = { [keyValue]: value } + } services.keyValues.put(keyValue); } From 852e1e1ecb87202c6a2f296cfb2eae39a2671d00 Mon Sep 17 00:00:00 2001 From: Oleksandr Pelykh Date: Wed, 15 Jan 2025 19:09:09 +0200 Subject: [PATCH 5/9] add types for reporter --- src/reporter.js | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/reporter.js b/src/reporter.js index 133dcbcb..87b9d429 100644 --- a/src/reporter.js +++ b/src/reporter.js @@ -3,6 +3,20 @@ import { services } from './services/index.js'; import reporterFunctions from './reporter-functions.js'; + +export const artifact = reporterFunctions.artifact; +export const log = reporterFunctions.log; +export const logger = services.logger; +export const meta = reporterFunctions.keyValue; +export const step = reporterFunctions.step; + +/** + * @typedef {import('./reporter-functions.js')} artifact + * @typedef {import('./reporter-functions.js')} log + * @typedef {import('./services/index.js')} logger + * @typedef {import('./reporter-functions.js')} meta + * @typedef {import('./reporter-functions.js')} step + */ export default { /** * @deprecated Use `log` or `testomat.log` @@ -18,9 +32,3 @@ export default { // TestomatClient, // TRConstants, }; - -export const artifact = reporterFunctions.artifact; -export const log = reporterFunctions.log; -export const logger = services.logger; -export const meta = reporterFunctions.keyValue; -export const step = reporterFunctions.step; From 85fd3f01d668a8b8ead85b27fbb2e1c5bb9ca1a0 Mon Sep 17 00:00:00 2001 From: Oleksandr Pelykh Date: Wed, 15 Jan 2025 19:09:17 +0200 Subject: [PATCH 6/9] upd type for meta --- src/services/key-values.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/services/key-values.js b/src/services/key-values.js index ec972d67..ec3e831b 100644 --- a/src/services/key-values.js +++ b/src/services/key-values.js @@ -18,7 +18,7 @@ class KeyValueStorage { /** * Stores key-value pair and passes it to reporter - * @param {{key: string}} keyValue - key-value pair(s) as object + * @param {{[key: string]: string}} keyValue - key-value pair(s) as object * @param {*} context - full test title */ put(keyValue, context = null) { From 0ee8a6afb82b2834e233cae0da840a56d5314875 Mon Sep 17 00:00:00 2001 From: Oleksandr Pelykh Date: Wed, 15 Jan 2025 19:09:27 +0200 Subject: [PATCH 7/9] xml reader minor fix by davert --- src/xmlReader.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/xmlReader.js b/src/xmlReader.js index c005703d..09343b7b 100644 --- a/src/xmlReader.js +++ b/src/xmlReader.js @@ -47,7 +47,7 @@ class XmlReader { title: TESTOMATIO_TITLE, env: TESTOMATIO_ENV, group_title: TESTOMATIO_RUNGROUP_TITLE, - detach: !!TESTOMATIO_MARK_DETACHED, + detach: TESTOMATIO_MARK_DETACHED, // batch uploading is implemented for xml already isBatchEnabled: false, }; From 1e7813cce5af2ee306f2adbec66a1ed887fddefe Mon Sep 17 00:00:00 2001 From: Oleksandr Pelykh Date: Sun, 19 Jan 2025 15:23:07 +0200 Subject: [PATCH 8/9] pipes test --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 7ab798b5..2a90b46f 100644 --- a/README.md +++ b/README.md @@ -157,3 +157,5 @@ To print all reporter logs of a specific pipe: ``` DEBUG=@testomatio/reporter:pipe:github ``` + + From 9dc557f5fb7cb51e8eb075d63968fdd8e7321453 Mon Sep 17 00:00:00 2001 From: Oleksandr Pelykh Date: Sun, 19 Jan 2025 15:33:08 +0200 Subject: [PATCH 9/9] test --- .github/workflows/linter-and-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/linter-and-tests.yml b/.github/workflows/linter-and-tests.yml index e210f1f5..8c7d1918 100644 --- a/.github/workflows/linter-and-tests.yml +++ b/.github/workflows/linter-and-tests.yml @@ -10,7 +10,7 @@ on: push: branches: [master] pull_request: - branches: [master] + branches: [master, 2.x-pipes, 2.x] jobs: linter-and-tests-on-latest-node: