UNPKG

playwright-bdd

Version:
108 lines 5.55 kB
"use strict"; /** * Class to invoke step in playwright runner. */ Object.defineProperty(exports, "__esModule", { value: true }); exports.BddStepInvoker = void 0; const getLocationInFile_1 = require("../playwright/getLocationInFile"); const DataTable_1 = require("../cucumber/DataTable"); const bddTestFixturesAuto_1 = require("./bddTestFixturesAuto"); const runStepWithLocation_1 = require("../playwright/runStepWithLocation"); const finder_1 = require("../steps/finder"); const step_1 = require("../hooks/step"); class BddStepInvoker { constructor(bddContext, world) { this.bddContext = bddContext; this.world = world; this.stepFinder = new finder_1.StepFinder(bddContext.config); } /** * Invokes particular step. * See: https://github.com/cucumber/cucumber-js/blob/main/src/runtime/test_case_runner.ts#L299 */ async invoke(stepText, // step text without keyword argument, providedFixtures) { this.bddContext.stepIndex++; this.bddContext.step.title = stepText; const stepTextWithKeyword = this.getBddStepData().textWithKeyword; const matchedDefinition = this.findStepDefinition(stepText, stepTextWithKeyword); // Get location of step call in generated test file. // This call must be exactly here to have correct call stack (before async calls) const location = (0, getLocationInFile_1.getLocationInFile)(this.bddContext.testInfo.file); const stepParameters = await this.getStepParameters(matchedDefinition, stepText, argument || undefined); const stepHookFixtures = this.getStepHookFixtures(providedFixtures || {}); const stepFixtures = this.getStepFixtures(providedFixtures || {}); await (0, runStepWithLocation_1.runStepWithLocation)(this.bddContext.test, stepTextWithKeyword, location, async () => { // Although pw-style does not expect usage of world / this in steps, // some projects request it for better migration process from cucumber. // Here, for pw-style we pass empty object as world. // See: https://github.com/vitalets/playwright-bdd/issues/208 await this.runBeforeStepHooks(stepHookFixtures); const result = await matchedDefinition.definition.fn.call(this.world, stepFixtures, ...stepParameters); await this.runAfterStepHooks(stepHookFixtures); return result; }); } async runBeforeStepHooks(stepHookFixtures) { const beforeHooksToRun = (0, step_1.getStepHooksToRun)('beforeStep', this.bddContext.tags); await (0, step_1.runStepHooks)(beforeHooksToRun, this.world, stepHookFixtures); } async runAfterStepHooks(stepHookFixtures) { const afterHooksToRun = (0, step_1.getStepHooksToRun)('afterStep', this.bddContext.tags); afterHooksToRun.reverse(); await (0, step_1.runStepHooks)(afterHooksToRun, this.world, stepHookFixtures); } findStepDefinition(stepText, stepTextWithKeyword) { const { keywordType, gherkinStepLine } = this.getBddStepData(); const stepDefinitions = this.stepFinder.findDefinitions(keywordType, stepText, this.bddContext.tags); const firstFoundDefinition = stepDefinitions[0]; if (firstFoundDefinition && stepDefinitions.length === 1) return firstFoundDefinition; const fullStepLocation = `${this.bddContext.featureUri}:${gherkinStepLine}`; if (stepDefinitions.length === 0) { // todo: better error? throw new Error(`Missing step: ${stepTextWithKeyword}`); } const message = (0, finder_1.formatDuplicateStepsMessage)(stepDefinitions, stepTextWithKeyword, fullStepLocation); throw new Error(message); } async getStepParameters(matchedDefinition, world, argument) { const parameters = await matchedDefinition.getMatchedParameters(world); if (argument?.dataTable) { parameters.push(new DataTable_1.DataTable(argument.dataTable)); } else if (argument?.docString) { parameters.push(argument.docString.content); } // todo: handle invalid code length // see: https://github.com/cucumber/cucumber-js/blob/main/src/models/step_definition.ts#L25 return parameters; } getStepFixtures(providedFixtures) { const { pomFixtureName } = this.getBddStepData(); if (pomFixtureName) { // for decorator steps keep only one fixture - POM instance. const pomFixture = providedFixtures[pomFixtureName]; if (!pomFixture) throw new Error(`POM fixture not provided: ${pomFixtureName}`); providedFixtures = { [pomFixtureName]: pomFixture }; } return Object.assign({}, providedFixtures, (0, bddTestFixturesAuto_1.getBddAutoInjectFixtures)(this.bddContext)); } getStepHookFixtures(providedFixtures) { return Object.assign({}, providedFixtures, (0, bddTestFixturesAuto_1.getBddAutoInjectFixtures)(this.bddContext)); } getBddStepData() { const { stepIndex, bddTestData } = this.bddContext; const bddStepData = bddTestData.steps[stepIndex]; if (!bddStepData) { throw new Error([ `bddStepData not found for step index: ${stepIndex}.`, `Steps: ${JSON.stringify(bddTestData.steps)}`, ].join(' ')); } return bddStepData; } } exports.BddStepInvoker = BddStepInvoker; //# sourceMappingURL=bddStepInvoker.js.map