-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
Arrow function support with world option #2004
Comments
This is consistent with the Typescript idiom, where you use |
I think the current API was right for its time but yeah if we were designing it now we'd probably do what you describe. We've previously balked at the breaking change but introducing as an option and giving a couple of major releases to switch over seems fair. I could see an option like |
As first parameter
But Typescript is not Javascript; I wasn't even aware of this until I saw this in cucumber (#1948). Further, if this change is to be accepted, this will be typescript valid: Then(/^the response status is (.*)$/, function (this, world, status) {
assert.equal(this.responseStatus, status)
}); which is super-confusing. In addition, not everyone is using So if it is an additional parameter, I'd vote for it to be last. How others solve it?World and this.context Whereas with Functional Components the API is:
So I believe this is doable: import { Then, getWorld } from '@cucumber/cucumber';
Then(/^the response status is (.*)$/, (status) => {
const world = getWorld();
assert.equal(world.responseStatus, status)
}); This leaves OOP vs functional (again)Understandably, the current API involves a So the question we could ask is "had we designed it ground-up today what would be the solution?". In a typescript project I was reluctant to adopt the export const context = createContext<Context>({
uid: string,
}) Now I haven't thought this through and through, and I'm not really pitching this as a possible solution. But the takeaway is that instead of trying to bridge two conflicting paradigms, maybe the way is just to accept these are two different paradigms, and support both in the right way (so PS |
@Izhaki thanks for those thoughts, and sorry for the late reply.
Very fair! Parameter placementI agree the analogy to TypeScript's Hooks-style solutionI think this could be good. The React comparison makes sense. I'd even be tempted to name it
The world is one instance per scenario, so not quite "global". However we are only executing one scenario at a time per process (for the parallel runtime we spawn child processes) so it should be fine to implement hooks-style without too much complexity. I'll try and do a POC for this soon. |
In https://github.com/cucumber/cucumber-js/releases/tag/v10.8.0 we released a new feature to solve this issue, where import { Then, world } from '@cucumber/cucumber';
Then(/^the response status is (.*)$/, (status) => {
assert.equal(world.responseStatus, status)
}); This feature is considered experimental for now - please do give it a try and raise an issue if you see anything unexpected. |
Apologies for bumping this, but I haven't found an answer anywhere - what's the recommended way of applying this new |
🤔 What's the problem you're trying to solve?
It is such a common problem that users use arrow functions in step definitions, that this is a FAQ item https://github.com/cucumber/cucumber-js/blob/main/docs/faq.md#the-world-instance-isnt-available-in-my-hooks-or-step-definitions
This is likely due to the fact that popular testing libraries such as Jest use of arrow functions https://jestjs.io/docs/api#testname-fn-timeout
The problem is cucumber-js is violating Principle of least astonishment
✨ What's your proposed solution?
I propose an API breaking changes where
world
is passed in as the first parameter of arrow function.BEFORE
BREAKING AFTER
This could be introduced as an option with the default as the existing behaviour to allow users try the new behaviour without a breaking semver. Then once stable, release breaking semver and change the default behaviour. This also allows users who wish to upgrade to use option to restore previous default.
⛏ Have you considered any alternatives or workarounds?
No other obvious way to achieve this. The
world
could be added as the last parameter of the arrow function, but I think in the long run that is more confusing.📚 Any additional context?
Related Github issues: https://github.com/cucumber/cucumber-js/issues?q=is%3Aissue+arrow+is%3Aclosed
This text was originally generated from a template, then edited by hand. You can modify the template here.
The text was updated successfully, but these errors were encountered: