Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

2.x pipes #479

Open
wants to merge 9 commits into
base: 2.x
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/linter-and-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -157,3 +157,5 @@ To print all reporter logs of a specific pipe:
```
DEBUG=@testomatio/reporter:pipe:github
```


68 changes: 35 additions & 33 deletions build/scripts/edit-package-json.js
Original file line number Diff line number Diff line change
@@ -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}`);
// });
// });
// 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}`);
});
});
2 changes: 1 addition & 1 deletion docs/functions.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,5 +128,5 @@ Supported frameworks:
- 🟢 Cucumber
- 🟢 Jest
- 🟢 Mocha
- 🟢 Playwright
- 🔴 Playwright (use native functionality instead)
- 🟢 WDIO (everything, except artifacts)
15 changes: 0 additions & 15 deletions src/adapter/playwright.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 };
133 changes: 63 additions & 70 deletions src/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -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=<your_api_key> 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=<your_api_key> 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));
Expand Down
26 changes: 17 additions & 9 deletions src/reporter-functions.js
Original file line number Diff line number Diff line change
@@ -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');

Check failure on line 9 in src/reporter-functions.js

View workflow job for this annotation

GitHub Actions / Linter&tests (latest node)

This line has a length of 124. Maximum allowed is 120
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);
}

Expand Down
24 changes: 16 additions & 8 deletions src/reporter.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,22 @@
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';


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`
Expand All @@ -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;
2 changes: 1 addition & 1 deletion src/services/key-values.js
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
2 changes: 1 addition & 1 deletion src/xmlReader.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
};
Expand Down
Loading