4

I'm trying to convert my RegExp based Cucumber v1 step definitions into Cucumber Expression based Cucumber v2.0.0-rc.9 step definitions. I have a few step definitions that use regular expressions like the following:

/^I (?:am on|go to) the "([^"]*)" page$/

That way, I can write either of the following in my feature file:

I am on the "Login" page
I go to the "Home" page

I'd like to switch to Cucumber Expressions so that I can start making use of Custom Parameters, but I can't find a great way to duplicate the (?:am on|go to). The best I've come up with is to use multiple alternative texts:

I am/go on/to the "{captureString}" page

What I don't like about that approach though is that it allows for writing nonsensical steps like the following:

I am to the "Login" page

I also tried using a single optional text that contained a | character like so:

I (am on|go to) the "{captureString}" page

but cucumber-expressions-javascript intentionally escapes the | character, so the resulting RegExp looked like this:

/^I (?:am on\|go to)? the "([^"]*)" page$/

Is there any way to have a single, multi-word alternative text group using Cucumber Expressions?

Nathan Thompson
  • 2,354
  • 1
  • 23
  • 28

4 Answers4

5

I ended up going with multiple optional texts:

I (am on)(go to) the "{captureString}" page This solution is still not as strict as I would like, as it will match strings like the following:

I the "Login" page

I am ongo to the "Home" page

But I find the Cucumber Expression itself more readable that doing multiple alternative texts. I'm still open to other suggestions for the "right" way to do this.

Adding a slash '/' between variants will eliminate I am ongo to the "Home" page from being triggered:

I (am on)/(go to) the "{captureString}" page

Misha Gariachiy
  • 103
  • 2
  • 7
1

An alternative is write your steps so they describe what you've done rather than how you have done things so

Given I am logged in

Give I am a visitor

and in general avoid using regex's or expressions. Personally I'd rather have

Given 'I am logged in' do 
  login user: @i
end

Given 'I have logged in' do
  login user: @i
end

than have a single expression to do both. My reasons are:

  1. its much easier to search your step defs and features for calls and duplicates
  2. it combines well with having step bodies that call and delegate, instead of step bodies that do stuff.
  3. its simpler. I always prefer simple and a bit verbose over complex and succinct.

I never have any steps that say which page I am on, because that is all about how I am doing something where scenarios should only be about what and why.

Anyhow hope thats of some use.

diabolist
  • 3,990
  • 1
  • 11
  • 15
1

The best option is to use a combination between Optional text and Alternative text.

I (am on)/(go to) the "{captureString}" page

It covers the following cases:

  • I am on the "Login" page
  • I go to the "Home" page
D-One
  • 11
  • 2
0

I ended up going with multiple optional texts:

I (am on)(go to) the "{captureString}" page

This solution is still not as strict as I would like, as it will match strings like the following:

I  the "Login" page
I am ongo to the "Home" page

But I find the Cucumber Expression itself more readable that doing multiple alternative texts. I'm still open to other suggestions for the "right" way to do this.

Nathan Thompson
  • 2,354
  • 1
  • 23
  • 28