Closed RichardCariven closed 5 months ago
You can continue using regex with playwright-bdd. Why do you want to convert it to Cucumber expression?
I have non technical people in my team writing tests (product owners, designers etc), cucumber expressions are easier to teach them as a first pass then regex. So wondered if there was a way of doing this kind of step as a cucumber expression so we don't have a mix of regex and cucumber, but if there is not no problem.
Fair enough! So, that's possible.
For the nth element you can use {int}
instead of {string}
.
For elementKey you correctly used {string}
.
The most tricky part is should( not)
. Currently Cucumber expressions can't capture optional text. The solution is to define custom parameter to capture not
:
import { defineParameterType } from '@cucumber/cucumber'
defineParameterType({
name: 'not',
regexp: /( not)?/,
transformer: s => Boolean(s)
});
Then('the {int}th/st/nd/rd {string} should{not} be displayed',
async ({}, elementPosition: number, elementKey: string, negate: boolean) => {
console.log(`the ${elementPosition} ${elementKey} should ${negate?'not ':''}be displayed`);
});
Note:
Another idea I came while thinking on your question - it would be useful to provide access to step text inside step body.
I didn't find such built-in feature in cucumber-js, although it can be achieved with beforeStep
hook:
BeforeStep({tags: "@foo"}, function ({ pickleStep }) {
this.currentStep = pickleStep;
});
In playwright-bdd we can introduce $step
fixture, that will hold info about current step. Having such fixture, we can avoid creating custom parameter type and just check step text for negate
:
// proposed syntax
Then('the {int}th/st/nd/rd {string} should( not) be displayed',
async ({ $step }, elementPosition: number, elementKey: string) => {
const negate = /should not/.text($step.text);
console.log(`the ${elementPosition} ${elementKey} should ${negate?'not ':''}be displayed`);
});
thankyou, just to clarify is the step fixture a future improvement your thinking of making, or something that would be possible now? I think that would be a really useful addition.
Step fixture is a future improvement, for now I suggest to use defineParameterType
.
Lets keep this issue open for it.
I can confirm defineParameterType worked great, thanks.
am continuing to refactor a project from Cucumber Runner to Playwright-BDD, thanks to your help I have all of the Fixture and setup side and element mapping working so am now going through step by step refactoring.
I have a number of steps that look for the nth element or index and also handle both should and should not in the same step. An example of this is given below.
And the "1st" "contact" should be displayed And the "3rd" "contact" should not be displayed The Regex and code for these 2 steps is all in the same step under regex as.
Then( /^the "([0-9]+th|[0-9]+st|[0-9]+nd|[0-9]+rd)" "([^"]*)" should( not)? be displayed$/, async function(this: ScenarioWorld, elementPosition: string, elementKey: ElementKey, negate: boolean) { const { screen: { page }, globalConfig, } = this
How would I write the above as a Cucumber expression, and make the step work? is it even possible in this format? I did wonder for the nth element would work as per the below but no idea about the should( not)? part.
Then( 'the {string}th/st/nd/rd {string } should( not)? be displayed',
} )