@serenity-js/webdriverio
Version:
Adapter that integrates @serenity-js/web with the latest stable version of WebdriverIO, enabling Serenity/JS reporting and using the Screenplay Pattern to write web and mobile test scenarios
128 lines • 6.01 kB
JavaScript
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.WebdriverIOFrameworkAdapter = void 0;
require("webdriverio");
const core_1 = require("@serenity-js/core");
const index_js_1 = require("@serenity-js/core/lib/io/index.js");
const rest_1 = require("@serenity-js/rest");
const deepmerge = __importStar(require("deepmerge"));
const isRecord_js_1 = require("tiny-types/lib/objects/isRecord.js");
const index_js_2 = require("../screenplay/index.js");
const index_js_3 = require("./reporter/index.js");
const OutputStreamBufferPrinter_js_1 = require("./reporter/OutputStreamBufferPrinter.js");
const TestRunnerLoader_js_1 = require("./TestRunnerLoader.js");
const WebdriverIONotifier_js_1 = require("./WebdriverIONotifier.js");
class WebdriverIOFrameworkAdapter {
serenity;
loader;
cwd;
cid;
specs;
capabilities;
reporter;
adapter;
notifier;
constructor(serenity, loader, cwd, cid, webdriverIOConfig, specs, capabilities, reporter) {
this.serenity = serenity;
this.loader = loader;
this.cwd = cwd;
this.cid = cid;
this.specs = specs;
this.capabilities = capabilities;
this.reporter = reporter;
const config = deepmerge.default(this.defaultConfig(), webdriverIOConfig, {
isMergeableObject: isRecord_js_1.isRecord,
});
// SauceLabs service serialises the config object for debugging.
// However, since Serenity/JS Stage is a pub/sub mechanism,
// it contains cyclic references which are not serialisable.
// We get rid of them from the config object to avoid confusing other services.
delete webdriverIOConfig.serenity;
this.adapter = new TestRunnerLoader_js_1.TestRunnerLoader(this.loader, this.cwd, this.cid)
.runnerAdapterFor(config);
this.notifier = new WebdriverIONotifier_js_1.WebdriverIONotifier(config, capabilities, reporter, this.adapter.successThreshold(), cid, this.specs);
const outputStreamBuffer = new index_js_3.OutputStreamBuffer(`[${this.cid}]`);
const outputStreamBufferPrinter = new OutputStreamBufferPrinter_js_1.OutputStreamBufferPrinter(outputStreamBuffer, reporter.getWriteStreamObject('@serenity-js/webdriverio-8'));
this.serenity.configure({
outputStream: outputStreamBuffer,
cueTimeout: config.serenity.cueTimeout,
interactionTimeout: config.serenity.interactionTimeout,
diffFormatter: config.serenity.diffFormatter ?? new core_1.AnsiDiffFormatter(),
actors: config.serenity.actors || core_1.Cast.where(actor => actor.whoCan(index_js_2.BrowseTheWebWithWebdriverIO.using(global.browser), core_1.TakeNotes.usingAnEmptyNotepad(), rest_1.CallAnApi.using({
baseURL: webdriverIOConfig.baseUrl,
}))),
crew: [
...config.serenity.crew,
this.notifier,
outputStreamBufferPrinter,
]
});
}
async init() {
// todo: review if there's a better way to do this
// This is the only (hacky) way to register a fake reporter programmatically (as of @wdio/reporter 7.4.2)
// - https://github.com/webdriverio/webdriverio/blob/365fb0ad79fcf4471f21f23e18afa6818986dbdb/packages/wdio-runner/src/index.ts#L147-L181
// - https://github.com/webdriverio/webdriverio/blob/365fb0ad79fcf4471f21f23e18afa6818986dbdb/packages/wdio-runner/src/reporter.ts#L24
const browserCapabilitiesReporter = await (this.reporter._loadReporter([
index_js_3.BrowserCapabilitiesReporter, {
serenity: this.serenity
},
]));
this.reporter._reporters.push(browserCapabilitiesReporter);
// WebdriverIO v8 represents paths to specs as file URIs, so they need to be converted to absolute paths to avoid confusing the test runners like Cucumber
const absolutePaths = this.specs.map(pathToSpec => index_js_1.Path.from(pathToSpec).value);
await this.adapter.load(absolutePaths);
return this;
}
hasTests() {
return this.adapter.scenarioCount() > 0;
}
async run() {
await this.adapter.run();
return this.notifier.failureCount();
}
defaultConfig() {
return {
serenity: {
crew: [
core_1.ArtifactArchiver.storingArtifactsAt(this.cwd.value, 'target/site/serenity'),
]
},
};
}
}
exports.WebdriverIOFrameworkAdapter = WebdriverIOFrameworkAdapter;
//# sourceMappingURL=WebdriverIOFrameworkAdapter.js.map