you will see the below message or similar for npx shake --help
npx shake -b TestResults TestReports
assumes you have saved your TestResults in the folder named "TestResults", then we export the TestResults to a folder called "TestReports".
Requires Venv Activation before using it
Replaces Existing TestReports if found
Generates static output
you can serve the static reports located at TestReports like with, serve: npx serve TestReports
Requires Venv Activation before using it
What it does:
Gives the Version of the Custom Reporter
Check whether you want to update your handshakes Python package
In case you want to fix the mismatch in the version, execute: npx shake -fix-version. but note it will not update your requirements.txt or any of your lock files for Python packages.
Sample Message
Shake CLI: A tool to use handshake CLI with a custom reporter context.
Note: To use most commands in Shake CLI, you need to first activate the virtual environment.
--version or -v: Checks if the version matches with the required version against the python-build. If not, it installs the required version.
--build or -b: Requires two arguments - TestResults followed by TestReports. TestResults is where your results are stored, and TestReports is where the generated reports will be saved.
--download or -d: Downloads the raw build for the dashboard. This command is typically called automatically post-installation.
--help or -h: Prints this help message.
Examples:
npx shake --build Results Reports
npx shake -b Results Reports
npx shake -d
npx shake --download
We would expect the attachReporter function to handle the required configuration for your file. attachReporter will add the required service: HandshakeService and HandshakeReporter to the services and reporters in the webdriver.Config
attachReporter(YOUR_CONFIG, HANDSHAKE_SPECIFIC_CONFIG) -> Returns the modified webdriver.Config
Know More
Refer to the below files on how it is implemented:
import type { Options } from '@wdio/types';
import { Assertion, checkVersion } from '@hand-shakes/common-handshakes';
import { AttachReporterOptions } from './types';
import HandshakeService from './service';
import HandshakeReporter from './reporter';
import { currentReporter } from './contacts';
import skipIfRequired from './internals';
/**
* adds handshake custom reporter and service. provide the WebdriverIO Configuration
* and required options to get started.
* @param config WebdriverIO configuration object
* @param options options to configure custom reporter and custom service
* @returns modified WebdriverIO Configuration
*/
export function attachReporter(
config: Options.Testrunner,
options: AttachReporterOptions,
): Options.Testrunner {
if (options.disabled) return config;
checkVersion();
const port = options.port ?? 6969;
const toModify = config;
toModify.reporters = toModify.reporters || [];
toModify.services = toModify.services || [];
toModify.reporters.push([
HandshakeReporter,
{
port,
addScreenshots: options.addScreenshots || false,
requestsTimeout: Math.max(
options.requestsTimeout ?? config.reporterSyncTimeout ?? 60e3,
60e3,
),
logLevel: options.logLevel ?? config.logLevel ?? 'info',
},
]);
toModify.services.push([
HandshakeService,
{
port,
requestsTimeout: Math.max(
options.requestsTimeout
?? config.connectionRetryTimeout
?? 120e3,
120e3,
),
reportGenerationTimeout: Math.max(
options.reportGenerationTimeout ?? 180e3,
180e3,
),
root: options.root,
workers: options.workers,
resultsFolderName: options.resultsFolderName,
logLevel: options.logLevel ?? config.logLevel ?? 'info',
testConfig: {
...options.testConfig,
avoidParentSuitesInCount:
options.testConfig?.avoidParentSuitesInCount
?? config.framework === 'cucumber',
},
exportOutDir: options.exportOutDir,
},
]);
return toModify;
}
/**
* attaches custom screenshot to a current test case.
* @param title title of the screenshot
* @param content PNG content
* @param description description for the screenshot
* @param is_suite is it for suite ? so we take parent of the current test entity
* @returns
*/
export async function attachScreenshot(
title: string,
content: string,
description?: string,
is_suite?: boolean,
) {
if (skipIfRequired()) {
return;
}
await currentReporter?.supporter?.attachScreenshot(
title,
content,
currentReporter?.currentEntity(is_suite),
description,
);
}
/**
* adds a description or the paragraph about the test or suite
* @param content content to include in the description
* @param is_suite is it for suite ? so we take parent of the current test entity
* @returns
*/
export async function addDescription(content: string, is_suite?: boolean) {
if (skipIfRequired()) {
return;
}
await currentReporter?.supporter?.addDescription(
content,
currentReporter?.currentEntity(is_suite),
);
}
/**
* adds a link for reference for test or suite
* @param url as it says
* @param title title of the link
* @param is_suite is it for suite ? so we take parent of the current test entity
* @returns
*/
export async function addLink(url: string, title: string, is_suite?: boolean) {
if (skipIfRequired()) {
return;
}
await currentReporter?.supporter?.addLink(
url,
title,
currentReporter?.currentEntity(is_suite),
);
}
/**
* adds the assertion for the current running test case
* @param title title of the assertion
* @param assertion assertion details
* @returns
*/
export async function addAssertion(title: string, assertion: Assertion) {
if (skipIfRequired()) {
return;
}
await currentReporter?.supporter?.addAssertion(
title,
assertion,
currentReporter?.currentTestID ?? '',
);
}
import { Level } from 'pino';
export interface ReporterOptions {
port: number; // port at which we would run the handshake server
addScreenshots?:boolean; // do we need to add screenshots to the report ?
requestsTimeout?:number; // dependent on reportSyncTimeout in webdriverIOConfig.
logLevel?:Level; // log level for pino logger that we use
disabled?: boolean; // make it true to not add reporter and service
// if disabled it is as if we haven't added handshake-reporter
}
export interface HandshakeServiceOptions {
port: number;
root: string; // Results are stored relative to this root
// and handshake.json is assumed to be in this root.
resultsFolderName: string; // Results are stored in ${{ROOT}}/${{resultsFolderName}}
requestsTimeout?: number; // we send bulk requests to the server so if it takes more than this,
// it will stop
reportGenerationTimeout?:number; // stop generating reports if it takes more than this timeout
workers?:number; // workers to support handshake-server
logLevel?:Level; // log level for pino logger that we use (for custom service)
exportOutDir?: string; // directory path to store the Dashboard (HTML) Reports
testConfig: {
projectName: string; // Name of the project
avoidParentSuitesInCount?: boolean;
// In Gherkin:
// Feature -> Scenario -> Step.. in this case we get 2 suites but its 1.
// so we ignore the parent suites in the totalNumberOfSuites.
// do not use this unless required. it is true only when you cucumber as framework
// else it is false.
}
}
// for attachReporter function we need both (union) the above options
export type AttachReporterOptions = ReporterOptions & HandshakeServiceOptions & { root?: string };