Search code examples
typescriptcucumbercypresscucumberjscypress-cucumber-preprocessor

Which is the best practice in identical Cucumberjs definitions for a state (Given) and an outcome (Then), in Cypress?



Having some doubt on best practices using Cucumber.js and Cypress for some step definitions.

Basically the test needs a state and an outcome that could be identically implemented:

This is the example of a state:

Given(
  'the {int} item of the {string} component is visible',
  (index, ComponentIndex, mapper: ComponentMapper) => {
    cy.get('[data-test^="cmp-"]').eq(cmpMap[mapper]).as(mapper)
    cy.get(`@${mapper}`)
      .find('.component__item')
      .eq(index)
      .should('be.visible')
  }
)

And this is the example of an outcome:

Then(
  'the {int} item of the {string} component is visible',
  (index, ComponentIndex, mapper: ComponentMapper) => {
    cy.get('[data-test^="cmp-"]').eq(cmpMap[mapper]).as(mapper)
    cy.get(`@${mapper}`)
      .find('.component__item')
      .eq(index)
      .should('be.visible')
  }
)

In this situation I see just code repetition, because the Given and the Then implements the same code, doing the same check. I would like to understand all possible solutions to implement this in the most efficient way.

DOUBLE IMPLEMENTATION

to leave the double steps defined as in the description
PRO: clearer
CONS: double code\

SINGLE IMPLEMENTATION

to leave one implementation, in the Given or in the Then, because cucumber actually does not check the match of the Step in the feature file and the function related to the step in the definition file
PRO: single implementation of code
CONS: less clear and more confusion in the step definitions

EXTERNAL FUNCTION

to create a function to put for example in some Commands of Cypress, or utils, and use it in both definitions
PRO: single implementation
CONS: over engineered? never saw this approach in Cucumber.js

Checking them all, which one would you suggest? Thanks


Solution

  • There is one more option, which is basically "Single implementation", but is a little more clear. I assume that you are using cypress-cucumber-preprocessor, besides Given/When/Then, you can also import defineStep which does exactly same thing, but from code perspective its more clear that step defined this way is universal.

    import { defineStep } from "cypress-cucumber-preprocessor/steps";
    
    defineStep('the {int} item of the {string} component is visible', 
        (index, ComponentIndex, mapper: ComponentMapper) => {
        ...
    });