@qanalyzer/forge-wdio 1.1.1

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,35 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FailureScreenshotBuffer = void 0;
4
+ const pending = [];
5
+ exports.FailureScreenshotBuffer = {
6
+ clear() {
7
+ pending.length = 0;
8
+ },
9
+ add(title, attachment) {
10
+ pending.push({ title, attachment });
11
+ },
12
+ /**
13
+ * Take all shots matching a test title (exact or substring), removing them from the buffer.
14
+ */
15
+ takeForTitle(title) {
16
+ const out = [];
17
+ for (let i = pending.length - 1; i >= 0; i -= 1) {
18
+ const entry = pending[i];
19
+ if (entry.title === title ||
20
+ title.includes(entry.title) ||
21
+ entry.title.includes(title)) {
22
+ out.unshift(entry.attachment);
23
+ pending.splice(i, 1);
24
+ }
25
+ }
26
+ return out;
27
+ },
28
+ /** Drain remaining shots (ordered) for publish-time fallback. */
29
+ takeAll() {
30
+ return pending.splice(0, pending.length);
31
+ },
32
+ size() {
33
+ return pending.length;
34
+ },
35
+ };
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Programmatic helpers for WebdriverIO Mocha specs (FR125–FR126).
3
+ * Prefer Jira issue keys in `it('AUTH-101 ...')` titles (FR43).
4
+ *
5
+ * Steps: `await qa.step('name', async (step) => { await step.step('nested', ...) })`.
6
+ *
7
+ * `qa.attach({ type })` — use **type** (not contentType). With content/paths,
8
+ * attempts Forge upload (FR133).
9
+ */
10
+ import { MetadataManager } from './metadata-manager';
11
+ export type QaStepFn = (step: QaStepApi) => void | Promise<void>;
12
+ export type QaStepApi = {
13
+ step(name: string, body: QaStepFn): Promise<void>;
14
+ };
15
+ export type QaHelpers = {
16
+ title(value: string): void;
17
+ comment(value: string): void;
18
+ suite(value: string): void;
19
+ fields(values: Record<string, string>): void;
20
+ parameters(values: Record<string, string>): void;
21
+ ignore(): void;
22
+ /** Async step with nested `step.step()` (FR125). */
23
+ step(name: string, body: QaStepFn): Promise<void>;
24
+ /** Use `type` (FR126); with content/paths uploads via Forge (FR133). */
25
+ attach(attach: {
26
+ name?: string;
27
+ type?: string;
28
+ content?: string | Buffer;
29
+ paths?: string[];
30
+ path?: string;
31
+ issueKey?: string;
32
+ }): void | Promise<void>;
33
+ };
34
+ export declare const qa: QaHelpers;
35
+ export { MetadataManager };
36
+ export type { QaMetaEntry } from './metadata-manager';
@@ -0,0 +1,101 @@
1
+ "use strict";
2
+ /**
3
+ * Programmatic helpers for WebdriverIO Mocha specs (FR125–FR126).
4
+ * Prefer Jira issue keys in `it('AUTH-101 ...')` titles (FR43).
5
+ *
6
+ * Steps: `await qa.step('name', async (step) => { await step.step('nested', ...) })`.
7
+ *
8
+ * `qa.attach({ type })` — use **type** (not contentType). With content/paths,
9
+ * attempts Forge upload (FR133).
10
+ */
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.MetadataManager = exports.qa = void 0;
13
+ const forge_commons_1 = require("@qanalyzer/forge-commons");
14
+ const metadata_manager_1 = require("./metadata-manager");
15
+ Object.defineProperty(exports, "MetadataManager", { enumerable: true, get: function () { return metadata_manager_1.MetadataManager; } });
16
+ function push(type, body) {
17
+ metadata_manager_1.MetadataManager.push(type, body);
18
+ }
19
+ function currentTitle() {
20
+ try {
21
+ // Mocha context title when available
22
+ const g = globalThis;
23
+ return g.currentTest?.title;
24
+ }
25
+ catch {
26
+ return undefined;
27
+ }
28
+ }
29
+ async function runStep(name, body) {
30
+ push('qa-step-start', name);
31
+ const api = {
32
+ step(nestedName, nestedBody) {
33
+ return runStep(nestedName, nestedBody);
34
+ },
35
+ };
36
+ try {
37
+ await body(api);
38
+ push('qa-step-end', { name, status: 'passed' });
39
+ }
40
+ catch (err) {
41
+ push('qa-step-end', { name, status: 'failed' });
42
+ throw err;
43
+ }
44
+ }
45
+ exports.qa = {
46
+ title(value) {
47
+ push('qa-title', value);
48
+ },
49
+ comment(value) {
50
+ push('qa-comment', value);
51
+ },
52
+ suite(value) {
53
+ push('qa-suite', value);
54
+ },
55
+ fields(values) {
56
+ push('qa-fields', values);
57
+ },
58
+ parameters(values) {
59
+ push('qa-parameters', values);
60
+ },
61
+ ignore() {
62
+ push('qa-ignore', true);
63
+ },
64
+ step(name, body) {
65
+ return runStep(name, body);
66
+ },
67
+ attach(attach) {
68
+ const mime = attach.type;
69
+ const path = attach.path ?? attach.paths?.[0];
70
+ const hasBinary = attach.content !== undefined || Boolean(path);
71
+ if (!hasBinary) {
72
+ push('qa-attach', {
73
+ name: attach.name,
74
+ type: mime,
75
+ });
76
+ return;
77
+ }
78
+ return (0, forge_commons_1.uploadAttachmentForQa)({
79
+ fileName: attach.name,
80
+ mimeType: mime,
81
+ content: attach.content,
82
+ path,
83
+ issueKey: attach.issueKey,
84
+ issueKeySources: [attach.issueKey, currentTitle()],
85
+ })
86
+ .then((outcome) => {
87
+ push('qa-attach', {
88
+ name: outcome.attachment.file_name ?? attach.name,
89
+ type: outcome.attachment.mime_type ?? mime,
90
+ size: outcome.attachment.size,
91
+ content_ref: outcome.attachment.content_ref,
92
+ });
93
+ })
94
+ .catch(() => {
95
+ push('qa-attach', {
96
+ name: attach.name,
97
+ type: mime,
98
+ });
99
+ });
100
+ },
101
+ };
@@ -0,0 +1,23 @@
1
+ import { type OptionsType } from '@qanalyzer/forge-commons';
2
+ /**
3
+ * Tracks onPrepare/onComplete hook pairing (FR123 / NFR33).
4
+ */
5
+ export declare const hooksLifecycle: {
6
+ beforeCalled: boolean;
7
+ afterCalled: boolean;
8
+ reset(): void;
9
+ };
10
+ /**
11
+ * Call from `wdio.conf.js` `onPrepare`.
12
+ * Initializes commons reporter config (default mode=off).
13
+ */
14
+ export declare function beforeRunHook(options?: OptionsType): Promise<void>;
15
+ /**
16
+ * Call from `wdio.conf.js` `onComplete`.
17
+ * Publishes buffered FR41 results when mode is ingest|file (with onRunnerEnd).
18
+ */
19
+ export declare function afterRunHook(): Promise<void>;
20
+ /**
21
+ * Fail fast when ingest/file mode runs without hooks (NFR33).
22
+ */
23
+ export declare function assertHooksForMode(mode: unknown, debug?: boolean): void;
package/dist/hooks.js ADDED
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.hooksLifecycle = void 0;
4
+ exports.beforeRunHook = beforeRunHook;
5
+ exports.afterRunHook = afterRunHook;
6
+ exports.assertHooksForMode = assertHooksForMode;
7
+ const forge_commons_1 = require("@qanalyzer/forge-commons");
8
+ const publish_1 = require("./publish");
9
+ /**
10
+ * Tracks onPrepare/onComplete hook pairing (FR123 / NFR33).
11
+ */
12
+ exports.hooksLifecycle = {
13
+ beforeCalled: false,
14
+ afterCalled: false,
15
+ reset() {
16
+ this.beforeCalled = false;
17
+ this.afterCalled = false;
18
+ },
19
+ };
20
+ function isOff(mode) {
21
+ return mode === forge_commons_1.ModeEnum.off || mode === 'off' || mode == null;
22
+ }
23
+ /**
24
+ * Call from `wdio.conf.js` `onPrepare`.
25
+ * Initializes commons reporter config (default mode=off).
26
+ */
27
+ async function beforeRunHook(options = {}) {
28
+ exports.hooksLifecycle.beforeCalled = true;
29
+ forge_commons_1.QAnalyzerReporter.getInstance(options);
30
+ }
31
+ /**
32
+ * Call from `wdio.conf.js` `onComplete`.
33
+ * Publishes buffered FR41 results when mode is ingest|file (with onRunnerEnd).
34
+ */
35
+ async function afterRunHook() {
36
+ exports.hooksLifecycle.afterCalled = true;
37
+ try {
38
+ await (0, publish_1.publishBufferedResults)();
39
+ }
40
+ catch {
41
+ // Never fail the WDIO run
42
+ }
43
+ }
44
+ /**
45
+ * Fail fast when ingest/file mode runs without hooks (NFR33).
46
+ */
47
+ function assertHooksForMode(mode, debug = false) {
48
+ if (isOff(mode))
49
+ return;
50
+ if (exports.hooksLifecycle.beforeCalled && exports.hooksLifecycle.afterCalled)
51
+ return;
52
+ // Allow publish from onRunnerEnd before onComplete — only error if before never ran.
53
+ if (exports.hooksLifecycle.beforeCalled)
54
+ return;
55
+ const message = '@qanalyzer/forge-wdio requires onPrepare → beforeRunHook() and onComplete → afterRunHook() when QANALYZER_MODE is ingest or file (NFR33)';
56
+ if (debug) {
57
+ throw new Error(message);
58
+ }
59
+ // eslint-disable-next-line no-console
60
+ console.error(`[@qanalyzer/forge-wdio] ${message}`);
61
+ }
@@ -0,0 +1,10 @@
1
+ export { QaWdioReporter, type QaWdioReporterOptions, } from './reporter';
2
+ export { QaWdioService } from './service';
3
+ export { beforeRunHook, afterRunHook, assertHooksForMode, hooksLifecycle, } from './hooks';
4
+ export { publishBufferedResults } from './publish';
5
+ export { qa, MetadataManager, type QaHelpers, type QaMetaEntry, type QaStepApi, type QaStepFn, } from './helpers';
6
+ export { toJestJsonReport, mapWdioStatus, type WdioAssertionInput, type WdioSpecInput, } from './report-builder';
7
+ export { ResultsBuffer } from './results-buffer';
8
+ export { applyCucumberTags, type TagLike } from './cucumber-tags';
9
+ import { QaWdioReporter } from './reporter';
10
+ export default QaWdioReporter;
package/dist/index.js ADDED
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.applyCucumberTags = exports.ResultsBuffer = exports.mapWdioStatus = exports.toJestJsonReport = exports.MetadataManager = exports.qa = exports.publishBufferedResults = exports.hooksLifecycle = exports.assertHooksForMode = exports.afterRunHook = exports.beforeRunHook = exports.QaWdioService = exports.QaWdioReporter = void 0;
4
+ var reporter_1 = require("./reporter");
5
+ Object.defineProperty(exports, "QaWdioReporter", { enumerable: true, get: function () { return reporter_1.QaWdioReporter; } });
6
+ var service_1 = require("./service");
7
+ Object.defineProperty(exports, "QaWdioService", { enumerable: true, get: function () { return service_1.QaWdioService; } });
8
+ var hooks_1 = require("./hooks");
9
+ Object.defineProperty(exports, "beforeRunHook", { enumerable: true, get: function () { return hooks_1.beforeRunHook; } });
10
+ Object.defineProperty(exports, "afterRunHook", { enumerable: true, get: function () { return hooks_1.afterRunHook; } });
11
+ Object.defineProperty(exports, "assertHooksForMode", { enumerable: true, get: function () { return hooks_1.assertHooksForMode; } });
12
+ Object.defineProperty(exports, "hooksLifecycle", { enumerable: true, get: function () { return hooks_1.hooksLifecycle; } });
13
+ var publish_1 = require("./publish");
14
+ Object.defineProperty(exports, "publishBufferedResults", { enumerable: true, get: function () { return publish_1.publishBufferedResults; } });
15
+ var helpers_1 = require("./helpers");
16
+ Object.defineProperty(exports, "qa", { enumerable: true, get: function () { return helpers_1.qa; } });
17
+ Object.defineProperty(exports, "MetadataManager", { enumerable: true, get: function () { return helpers_1.MetadataManager; } });
18
+ var report_builder_1 = require("./report-builder");
19
+ Object.defineProperty(exports, "toJestJsonReport", { enumerable: true, get: function () { return report_builder_1.toJestJsonReport; } });
20
+ Object.defineProperty(exports, "mapWdioStatus", { enumerable: true, get: function () { return report_builder_1.mapWdioStatus; } });
21
+ var results_buffer_1 = require("./results-buffer");
22
+ Object.defineProperty(exports, "ResultsBuffer", { enumerable: true, get: function () { return results_buffer_1.ResultsBuffer; } });
23
+ var cucumber_tags_1 = require("./cucumber-tags");
24
+ Object.defineProperty(exports, "applyCucumberTags", { enumerable: true, get: function () { return cucumber_tags_1.applyCucumberTags; } });
25
+ const reporter_2 = require("./reporter");
26
+ exports.default = reporter_2.QaWdioReporter;
@@ -0,0 +1,13 @@
1
+ /**
2
+ * In-process metadata buffer for unit tests and when WDIO IPC is unavailable.
3
+ * Live runs may also emit process events (see helpers) for the reporter (2.8.2).
4
+ */
5
+ export type QaMetaEntry = {
6
+ type: string;
7
+ body: unknown;
8
+ };
9
+ export declare const MetadataManager: {
10
+ clear(): void;
11
+ push(type: string, body: unknown): void;
12
+ getEntries(): QaMetaEntry[];
13
+ };
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ /**
3
+ * In-process metadata buffer for unit tests and when WDIO IPC is unavailable.
4
+ * Live runs may also emit process events (see helpers) for the reporter (2.8.2).
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.MetadataManager = void 0;
8
+ const entries = [];
9
+ exports.MetadataManager = {
10
+ clear() {
11
+ entries.length = 0;
12
+ },
13
+ push(type, body) {
14
+ entries.push({ type, body });
15
+ },
16
+ getEntries() {
17
+ return [...entries];
18
+ },
19
+ };
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Publish buffered specs via commons (idempotent).
3
+ * Called from `onRunnerEnd` and `afterRunHook` (FR123).
4
+ * Merges FR133 failure screenshots before publish.
5
+ */
6
+ export declare function publishBufferedResults(): Promise<void>;
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.publishBufferedResults = publishBufferedResults;
4
+ const forge_commons_1 = require("@qanalyzer/forge-commons");
5
+ const enrich_screenshots_1 = require("./enrich-screenshots");
6
+ const failure_screenshot_buffer_1 = require("./failure-screenshot-buffer");
7
+ const hooks_1 = require("./hooks");
8
+ const report_builder_1 = require("./report-builder");
9
+ const results_buffer_1 = require("./results-buffer");
10
+ /**
11
+ * Publish buffered specs via commons (idempotent).
12
+ * Called from `onRunnerEnd` and `afterRunHook` (FR123).
13
+ * Merges FR133 failure screenshots before publish.
14
+ */
15
+ async function publishBufferedResults() {
16
+ if (results_buffer_1.ResultsBuffer.published)
17
+ return;
18
+ const options = results_buffer_1.ResultsBuffer.options;
19
+ const mode = String(options.mode ?? forge_commons_1.ModeEnum.off);
20
+ (0, hooks_1.assertHooksForMode)(mode, Boolean(options.debug));
21
+ if (mode === 'off') {
22
+ results_buffer_1.ResultsBuffer.published = true;
23
+ results_buffer_1.ResultsBuffer.takeSpecs();
24
+ failure_screenshot_buffer_1.FailureScreenshotBuffer.clear();
25
+ return;
26
+ }
27
+ const specs = results_buffer_1.ResultsBuffer.takeSpecs();
28
+ results_buffer_1.ResultsBuffer.published = true;
29
+ if (specs.length === 0) {
30
+ failure_screenshot_buffer_1.FailureScreenshotBuffer.clear();
31
+ return;
32
+ }
33
+ try {
34
+ (0, enrich_screenshots_1.enrichSpecsWithFailureScreenshots)(specs);
35
+ }
36
+ catch {
37
+ // Never fail the WDIO run because of attach errors
38
+ }
39
+ forge_commons_1.QAnalyzerReporter.resetInstance();
40
+ const reporter = forge_commons_1.QAnalyzerReporter.getInstance({
41
+ ...options,
42
+ mode: options.mode ?? forge_commons_1.ModeEnum.off,
43
+ frameworkPackage: options.frameworkPackage ?? '@wdio/cli',
44
+ frameworkName: options.frameworkName ?? 'wdio',
45
+ reporterName: options.reporterName ?? '@qanalyzer/forge-wdio',
46
+ });
47
+ const report = (0, report_builder_1.toJestJsonReport)(specs, results_buffer_1.ResultsBuffer.runStart);
48
+ await reporter.publishReport(report, {
49
+ format: 'jest-json',
50
+ launchName: options.launchName,
51
+ projectKey: options.projectKey,
52
+ });
53
+ failure_screenshot_buffer_1.FailureScreenshotBuffer.clear();
54
+ }
@@ -0,0 +1,25 @@
1
+ import type { JestVitestJsonReport, QaMetaWire } from '@qanalyzer/forge-commons';
2
+ export type WdioAssertionInput = {
3
+ ancestorTitles: string[];
4
+ title: string;
5
+ fullName?: string;
6
+ status: 'passed' | 'failed' | 'pending' | 'todo';
7
+ duration?: number;
8
+ failureMessages?: string[];
9
+ meta?: {
10
+ qa?: QaMetaWire;
11
+ };
12
+ };
13
+ export type WdioSpecInput = {
14
+ /** Spec file path */
15
+ name: string;
16
+ startTime?: number;
17
+ endTime?: number;
18
+ assertions: WdioAssertionInput[];
19
+ };
20
+ /**
21
+ * Normalize collected WDIO/Mocha specs into FR41 jest-json shape A.
22
+ */
23
+ export declare function toJestJsonReport(specs: readonly WdioSpecInput[], startTime?: number): JestVitestJsonReport;
24
+ /** Map WDIO / Mocha test state → FR41 assertion status. */
25
+ export declare function mapWdioStatus(status: string | undefined): WdioAssertionInput['status'];
@@ -0,0 +1,83 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.toJestJsonReport = toJestJsonReport;
4
+ exports.mapWdioStatus = mapWdioStatus;
5
+ function mapAssertion(a) {
6
+ const fullName = a.fullName ??
7
+ (a.ancestorTitles.length > 0
8
+ ? `${a.ancestorTitles.join(' ')} ${a.title}`
9
+ : a.title);
10
+ const assertion = {
11
+ ancestorTitles: a.ancestorTitles,
12
+ fullName,
13
+ title: a.title,
14
+ status: a.status,
15
+ duration: a.duration,
16
+ failureMessages: a.failureMessages ?? [],
17
+ };
18
+ if (a.meta?.qa) {
19
+ assertion.meta = { qa: a.meta.qa };
20
+ }
21
+ return assertion;
22
+ }
23
+ function fileStatus(assertions) {
24
+ return assertions.some((a) => a.status === 'failed') ? 'failed' : 'passed';
25
+ }
26
+ /**
27
+ * Normalize collected WDIO/Mocha specs into FR41 jest-json shape A.
28
+ */
29
+ function toJestJsonReport(specs, startTime) {
30
+ const testResults = specs.map((spec) => {
31
+ const assertionResults = spec.assertions.map(mapAssertion);
32
+ return {
33
+ name: spec.name,
34
+ status: fileStatus(assertionResults),
35
+ startTime: spec.startTime,
36
+ endTime: spec.endTime,
37
+ assertionResults,
38
+ };
39
+ });
40
+ let numPassedTests = 0;
41
+ let numFailedTests = 0;
42
+ let numPendingTests = 0;
43
+ let numTodoTests = 0;
44
+ for (const file of testResults) {
45
+ for (const a of file.assertionResults ?? []) {
46
+ if (a.status === 'passed')
47
+ numPassedTests += 1;
48
+ else if (a.status === 'failed')
49
+ numFailedTests += 1;
50
+ else if (a.status === 'todo')
51
+ numTodoTests += 1;
52
+ else
53
+ numPendingTests += 1;
54
+ }
55
+ }
56
+ const numTotalTests = numPassedTests + numFailedTests + numPendingTests + numTodoTests;
57
+ const numFailedTestSuites = testResults.filter((t) => t.status === 'failed').length;
58
+ const numPassedTestSuites = testResults.length - numFailedTestSuites;
59
+ return {
60
+ numTotalTestSuites: testResults.length,
61
+ numPassedTestSuites,
62
+ numFailedTestSuites,
63
+ numPendingTestSuites: 0,
64
+ numTotalTests,
65
+ numPassedTests,
66
+ numFailedTests,
67
+ numPendingTests,
68
+ numTodoTests,
69
+ startTime,
70
+ success: numFailedTests === 0,
71
+ testResults,
72
+ };
73
+ }
74
+ /** Map WDIO / Mocha test state → FR41 assertion status. */
75
+ function mapWdioStatus(status) {
76
+ if (status === 'passed')
77
+ return 'passed';
78
+ if (status === 'failed')
79
+ return 'failed';
80
+ if (status === 'skipped' || status === 'pending')
81
+ return 'pending';
82
+ return 'pending';
83
+ }
@@ -0,0 +1,44 @@
1
+ import WDIOReporter from '@wdio/reporter';
2
+ import type { SuiteStats, TestStats } from '@wdio/reporter';
3
+ import { type OptionsType } from '@qanalyzer/forge-commons';
4
+ export type QaWdioReporterOptions = OptionsType & {
5
+ /** Prefer programmatic `qa.step` over auto WebDriver commands (FR127). Default true. */
6
+ disableWebdriverStepsReporting?: boolean;
7
+ disableWebdriverScreenshotsReporting?: boolean;
8
+ /** When true, treat suites as Cucumber scenarios and tests as Gherkin steps (FR135). */
9
+ useCucumber?: boolean;
10
+ outputDir?: string;
11
+ };
12
+ /**
13
+ * WebdriverIO reporter for QAnalyzer.
14
+ *
15
+ * Configure:
16
+ * reporters: [[QaWdioReporter, { disableWebdriverStepsReporting: true }]]
17
+ * // Cucumber:
18
+ * reporters: [[QaWdioReporter, { useCucumber: true }]]
19
+ *
20
+ * Mocha: each `it()` → FR41 assertion; `qa.step` → `meta.qa.steps`.
21
+ * Cucumber: each scenario suite → FR41 assertion; Gherkin steps → `meta.qa.steps` (FR135).
22
+ */
23
+ export declare class QaWdioReporter extends WDIOReporter {
24
+ private readonly qaOptions;
25
+ readonly disableWebdriverStepsReporting: boolean;
26
+ readonly disableWebdriverScreenshotsReporting: boolean;
27
+ readonly useCucumber: boolean;
28
+ private readonly suiteStack;
29
+ private currentFile;
30
+ private scenario;
31
+ constructor(options?: QaWdioReporterOptions);
32
+ onSuiteStart(suite: SuiteStats): void;
33
+ onSuiteEnd(suite: SuiteStats): void;
34
+ onTestStart(test: TestStats): void;
35
+ onTestPass(test: TestStats): void;
36
+ onTestFail(test: TestStats): void;
37
+ onTestSkip(test: TestStats): void;
38
+ onTestRetry(test: TestStats): void;
39
+ onRunnerEnd(): Promise<void>;
40
+ private endCucumberStep;
41
+ private finalizeCucumberScenario;
42
+ private record;
43
+ }
44
+ export default QaWdioReporter;