Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

optional text in cucumber expression does not match #784

Closed
3 tasks done
iomedico-beyer opened this issue Aug 1, 2022 · 15 comments
Closed
3 tasks done

optional text in cucumber expression does not match #784

iomedico-beyer opened this issue Aug 1, 2022 · 15 comments

Comments

@iomedico-beyer
Copy link

iomedico-beyer commented Aug 1, 2022

Current behavior

Omitted optional text in cucumber expressions do not match.

Expected behavior

Omitted optional text in cucumber expressions should match.

Test code to reproduce

I assume 'this is a cucumber epression' as indicated in the preprocessor docs and defined in the cucumber docs.

Then('I am on the start page (again)', () => {});
does not match
Then I am on the start page

Step implementation missing for "I am on the start page".

(However, it does match Then I am on the start page again.)

Versions

  • Cypress: 10.3.1
  • Preprocessor: 12.0.0
  • Node: 14.17.0

Checklist

  • I've read the FAQ.
  • I've read Instructions for logging issues.
  • I'm not using cypress-cucumber-preprocessor@4.3.1 (package name has changed and it is no longer the most recent version, see #689).
@badeball
Copy link
Owner

badeball commented Aug 1, 2022

I assume /this is a cucumber epression/

The docs are inaccurate, cucumber expressions are strings.

@badeball badeball closed this as completed Aug 1, 2022
@badeball
Copy link
Owner

badeball commented Aug 1, 2022

Additionally, if you were to write a step Then("I am on the start page (again)", () => {});, then I think the last space would be required.

@iomedico-beyer
Copy link
Author

iomedico-beyer commented Aug 1, 2022

So for Then('foo (again) bar', () => {}); I have to write literally foo bar with two spaces instead of one? Yes, indeed. So in reality this feature is only usable for a plural s? Then why do they call it “optional text”? Or do the test spec writers have to cripple the specs like Then('foo (again )bar', () => {});. Doesn’t makes any sense either. Oh man, I’m so disappointed.

But thanks for fixing the docs. Is Given(/^a table step$/, wrong too? Same page, a few lines further down.

@badeball
Copy link
Owner

badeball commented Aug 1, 2022

Save your opinion of it for the authors.

https://github.com/cucumber/cucumber-expressions

And the rest of the docs look fine.

@iomedico-beyer
Copy link
Author

iomedico-beyer commented Aug 1, 2022

Save your opinion of it for the authors.

https://github.com/cucumber/cucumber-expressions

Thank you. But their specification does not imply if my use case should work or not. Common sense tells me that it should. Sorry, but may I ask if it is their or your code we are talking about? Just to clarify.

And the rest of the docs look fine.

  1. You say “cucumber expressions are strings”
  2. The docs says “A step definition’s expression can either be a regular expression or a cucumber expression. The examples in this section use cucumber expressions.”
  3. Visual Studio says /^a table step$/ (from that page) is not a string but a regular expression.
  4. You say “the resut of the docs looks fine”

Although I’m new to Typescript, I think one of those four statements must be wrong.

@badeball
Copy link
Owner

badeball commented Aug 1, 2022

Given, When and Then accepts both strings and regular expressions. Strings automatically are turned into regular expressions, this is what's referred to as "cucumber expressions". This is handled by https://github.com/cucumber/cucumber-expressions, IE. it is not my invention.

@iomedico-beyer
Copy link
Author

iomedico-beyer commented Aug 1, 2022

So /^a table step$/ is a regular expression but not a cucumber expression, right?

Ah, I guess “The examples in this section” just does not include the rest of the page (and in fact is only one example).

@badeball
Copy link
Owner

badeball commented Aug 1, 2022

So /^a table step$/ is a regular expression but not a cucumber expression, right?

That's right.

@iomedico-beyer
Copy link
Author

The thing I do not understand is: Do you use some original cucumber code to parse those expressions? Something you cannot touch? Or do you just reject my let’s call it request for improvement?

@badeball
Copy link
Owner

badeball commented Aug 1, 2022

You can find multiple cucumber libs listed as dependencies in package.json, including @cucumber/cucumber-expressions.

@iomedico-beyer
Copy link
Author

iomedico-beyer commented Aug 25, 2022

Thanks for your information! One last question, if I may: I am thinking about workarounds. Is it possible for me to transform the string before it goes to cucumber-expressions? I mean without needing to fork this project?

To be more specific, I want to replace all " (" with "( " so that

  • I am on the start page (again) becomes I am on the start page( again)
  • but I have {int} cucumber(s) in my belly remains the same

@badeball
Copy link
Owner

Sure, like this

Given(transform("I am on the start page (again)"), function () {
  ...
});

@iomedico-beyer
Copy link
Author

Thank you! My workaround now looks like this: (“Dann” is German for “Then”.)

interface IStepDefinitionBody<T extends unknown[]> {
    (this: Mocha.Context, ...args: T): void;
}
function toCucumberExpOrRegExp(description: string | RegExp) {
    return typeof description === 'string' ? description.replace(' (', '( ') : description;
}
export const Dann = function (description: string | RegExp, implementation: IStepDefinitionBody<any>) {
    return Then(toCucumberExpOrRegExp(description), implementation);
};

Usage:

Dann('erscheint (wieder) die Startseite', function () {
    // ...
});

I wonder if I am losing anything by having implementation: IStepDefinitionBody<any> as parameter instead of implementation: IStepDefinitionBody<T>. Everything seems to be just fine, though.

@badeball
Copy link
Owner

No, I don't think so. It's not possible to infer the types of the args of a step-def-body statically. I might have replaced any with unknown and require each dev to explicitly state each expected type, although it's not going to give you any runtime guarantees.

@iomedico-beyer
Copy link
Author

Good point! I replaced implementation: IStepDefinitionBody<any> with implementation: IStepDefinitionBody<unknown[]>.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants