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

Deprecate And and But functions for step definitions #821

Closed
3 tasks done
aslakhellesoy opened this issue Sep 5, 2022 · 19 comments
Closed
3 tasks done

Deprecate And and But functions for step definitions #821

aslakhellesoy opened this issue Sep 5, 2022 · 19 comments

Comments

@aslakhellesoy
Copy link

Current behavior

Step definitions can be defined with Given, When, Then, And and But - see

export {
defineStep as Given,
defineStep as When,
defineStep as Then,
defineStep as And,
defineStep as But,
};

Desired behavior

Step definitions can be defined with Given, When and Then. This is what Cucumber.js does: https://github.com/cucumber/cucumber-js/blob/01368ca6e3c9b097a7a88bb72de5beeddb4a0326/src/index.ts#L45-L51

Here is an example illustrating why:

Feature: banking
  Scenario: Overdraft
    Given I have an overdraft limit of 50
    And I have a balance of 300
    When I withdraw 330
    Then my balance should be -30

With the currentl API, people might implement step definitions this way:

Given('I have an overdraft limit of {int}')
And('I have a balance of {int}')

But what if I add a new scenario:

  Scenario: No overdraft
    Given I have a balance of 300
    When I withdraw 330
    Then my balance should be 300
    And I should be told my overdraft limit is 0

It no longer makes sense that the step defnition is defined with And.

The And and But keywords only belong in Gherkin. Step definitions are reusable in any order, and should therefore not use And and But.

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 added a commit that referenced this issue Sep 16, 2022
These aren't available in cucumber-js and therefore won't be here
either. This fixes #821.
badeball added a commit that referenced this issue Sep 16, 2022
These aren't available in cucumber-js and therefore won't be here
either. This fixes #821.
badeball added a commit that referenced this issue Sep 16, 2022
These aren't available in cucumber-js and therefore won't be here
either. This fixes #821.
@badeball
Copy link
Owner

Fixed with v13.0.0.

@iomedico-beyer
Copy link

iomedico-beyer commented Oct 4, 2022

Wow. This is a huge breaking change, isn't it?

Could you please explain, why And/But steps are not reusable? And/But after Then come with a should that And/But after Given or When do not. As in your examples. Thus they cannot be mixed up. The syntax is clear. Without should it is an action (clicks etc), with should it is a check (cy.contains() etc).

I also have those reusable steps in different files like And-after-Then.ts and And-after-When.ts.

@badeball
Copy link
Owner

badeball commented Oct 4, 2022

Wow. This is a huge breaking change, isn't it?

You thinking this make me suspect that you're misunderstanding the implications of this change. This only affects the method you use for defining steps, aka Given(..), When(..) and Then(..). With this change, you would still use the keywords And and But in the gherkin / feature files.

However, with a file a

Feature:
  Scenario:
    Given something
    And another thing

.. then another thing is implicitly considered to be a given-step and it should be declared using Given(..).

Thus, the only thing I expect anyone to change is swapping out calls to And(..) and But(..) with the more appropriate methods.

@iomedico-beyer
Copy link

iomedico-beyer commented Oct 4, 2022

Ah, now I understand. But in German this does not work. The sentence structure after Dann (German for Then) is different than after Und (German for And).

But I already found a workaround. I just use defineStep instead.

import { Before, defineStep, Given, Step, Then, When } from '@badeball/cypress-cucumber-preprocessor';
export const Und = function (description: string | RegExp, implementation: IStepDefinitionBody<unknown[]>) {
    return defineStep(toCucumberExpOrRegExp(description), implementation);
};
export const Aber = function (description: string | RegExp, implementation: IStepDefinitionBody<unknown[]>) {
    return defineStep(toCucumberExpOrRegExp(description), implementation);
};

@badeball
Copy link
Owner

badeball commented Oct 4, 2022

FYI, defineStep() is going away from cucumber-js (cucumber/cucumber-js#2043) and this will eventually be reflected in this lib as well.

@iomedico-beyer
Copy link

iomedico-beyer commented Oct 4, 2022

FYI, defineStep() is going away from cucumber-js (cucumber/cucumber-js#2043) and this will eventually be reflected in this lib as well.

I guess this means that my workaround will get quite ugly then, e. g. mapping everything to When or so. But thanks anyway!

@aslakhellesoy
Copy link
Author

Ah, now I understand. But in German this does not work. The sentence structure after Dann (German for Then) is different than after Und (German for And).

@iomedico-beyer can you give me a concrete example of a sentence/step that would be different with Dann and Und? I'm one of the maintainers of Cucumber and understanding this would be helpful.

@iomedico-beyer
Copy link

iomedico-beyer commented Oct 5, 2022

@iomedico-beyer can you give me a concrete example of a sentence/step that would be different with Dann and Und? I'm one of the maintainers of Cucumber and understanding this would be helpful.

Sure :)

Then there should be an "OK" button
And there should be a "Cancel" button

is in German

Dann sollte es einen "OK"-Button geben
Und es sollte einen "Cancel"-Button geben

Subject and predicate swap places.

A linguistic alternative would be to add a "dann " to the Und:

Dann sollte es einen "OK"-Button geben
Und dann sollte es einen "Cancel"-Button geben

However, that sounds more than a little odd.
(And I would have to do a little transformation to the strings, removing the "dann " prefix.)

@sszemer
Copy link

sszemer commented Oct 6, 2022

woulnd't it be better to support defining steps as both 'When' and 'And' like other bdd frameworks?

@iomedico-beyer
Copy link

iomedico-beyer commented Oct 6, 2022

woulnd't it be better to support defining steps as both 'When' and 'And' like other bdd frameworks?

I guess the idea is that When is more descriptive/clear than And, because And can also be used after Given and Then.

Also the framework can narrow its matching to look e. g. only in When declarations for a specific And test step (that comes after a When test step) – although I'm not sure if this is particularly helpful (Given and When seem semantically similar enough for me for And to match both).

@aslakhellesoy
Copy link
Author

Given and When seem semantically similar enough for me for And to match both

Recommended reading: A little tense

@iomedico-beyer
Copy link

Recommended reading: A little tense

Interesting! Here is a typical test of mine translated into English and trying to follow that guide:

Given I went to the "Select analysis" page
And I clicked on "Create new analysis"
When I click on "Go back"
And I click on "Discard config"
Then I should be on the "Select analysis" page again

So for the clicking steps I would have to implement the "clicked" variant with the Given command and the "click" variant with the When command. I'm not quite sure if that's a good idea. What do you think?

Sorry if that's awfully off topic!

@jordan-bite
Copy link

I agree this was hastily implemented. This feels a bit too opinionated from the author.

@atilla8huno
Copy link

what a shame, AND/OR is widely used in Gherkin sintax and should reflect in the tests.

@badeball
Copy link
Owner

badeball commented Nov 4, 2022

And(..) and Or(..) has afaik never been exported members in cucumber-js (ref. cucumber/cucumber-js#1118 and cucumber/cucumber-js#1615) and this has not changed recently. The only thing that has changed recently, is the feature alignment between this preprocessor and cucumber-js, where this preprocessor aims for feature identicality. Exporting And and But was simply a mistake and did not correctly reflect the experience found in cucumber-js.

Furthermore, cucumber-js is not developed here. Changes there can trickle down and be reflected here, but not the other way around, because this preprocessor simply isn't associated with Cucumber in any way. If you think it's a mistake that cucumber-js doesn't export And(..) and But(..), then I suggest you take it up somewhere more appropriate.

@badeball
Copy link
Owner

badeball commented Nov 4, 2022

I want to highlight the following comment from Mar 16, 2021: cucumber/cucumber-js#1615 (comment)

We're never going to add And and But as step definition methods.

@marijnwebers
Copy link

@badeball ,
Thanks for the update, so we can have in our feature file still the And or But.
However in our code we should state Given, When or Then

E.g.
Feature file:

Given I open website
Then my website is shown
And the data is shown

Code:

Given('I open website', () => {
  do stuff;
});

Then('my website is shown', () => {
  do stuff;
});

Then('the data is shown', () => {
  do stuff;
});

Making it also easier to understand if the command is a given, when or then command.

@thekucays
Copy link

Ah, now I understand. But in German this does not work. The sentence structure after Dann (German for Then) is different than after Und (German for And).

But I already found a workaround. I just use defineStep instead.

import { Before, defineStep, Given, Step, Then, When } from '@badeball/cypress-cucumber-preprocessor';
export const Und = function (description: string | RegExp, implementation: IStepDefinitionBody<unknown[]>) {
    return defineStep(toCucumberExpOrRegExp(description), implementation);
};
export const Aber = function (description: string | RegExp, implementation: IStepDefinitionBody<unknown[]>) {
    return defineStep(toCucumberExpOrRegExp(description), implementation);
};

are you still using this method? where did u place this, in your step definition fille?

@iomedico-beyer
Copy link

are you still using this method?

No, in the end we switched to English.

where did u place this, in your step definition fille?

No, somewhere in cypress/support/.

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

8 participants