Home > Mobile >  Cypress-Cucumber-Preprocessor: Using BeforeAll for specific tags/feature files
Cypress-Cucumber-Preprocessor: Using BeforeAll for specific tags/feature files

Time:08-24

According to the Cypress Cucumber Preprocessor docs regarding Before and After hooks:

The cypress-cucumber-preprocessor supports both Mocha's before/beforeEach/after/afterEach hooks and Cucumber's Before and After hooks.

However for some reason it doesn't seem to support the Cucumber's BeforeAll and AfterAll hooks. This is somewhat problematic for me. I'm currently trying to write some API tests that need to use an auth token that can only be obtained by manually logging in to the site first.

Ideally I would like my tests to log in through the UI only once, grab the auth token, and then run all of my API tests using that auth token.

I have all of these API scenarios tagged with @api and would love to be able to use a BeforeAll({ tags: '@api' }, () => { function (or equivalent) to have my Cypress tests log in and grab the auth token for use in those scenarios. However it seems like my only options are:

  1. Use Before instead of BeforeAll (which would force me to login through the UI for every single scenario with the @api tag even though should I only need to do it once)
  2. Use a Background on the feature file (which has the same problem)
  3. Use Mocha's before hook instead of Cucumber's (which unfortunately doesn't support tagging and therefore would run before every feature file, instead of just the ones I have tagged)

Is there no way to replicate the Cucumber BeforeAll functionality with Cypress-Cucumber-Preprocessor?

CodePudding user response:

The way I would approach the problem is to flag the first login in the run, and prevent the login code from running once the flag is set.

let loggedIn = false;
Before(() => {
  const tags  = window.testState.pickle.tags.map(tag => tag.name)
  if (tags.includes('@api') && !loggedIn) {
    loggedIn = true
    console.log('logging in')    // check this is called once
    // do the login
  }
})

You should also be able to get the same effect by wrapping the login code in a cy.session(), which is a cache that only runs it's callback once per run.

Before(() => {
  const tags  = window.testState.pickle.tags.map(tag => tag.name)
  if (tags.includes('@api')) {
    cy.session('login', () => {
      console.log('logging in')    // check this is called once
      // do the login
    })
  }
})

Update from @rmoreltandem

This syntax is simpler

let loggedIn = false;
Before({ tags: '@api' }, () => {
  if (!loggedIn) {
    loggedIn = true
    console.log('logging in')    // check this is called once
    // do the login
  }
})

with session

Before({ tags: '@api' }, () => {
  cy.session('login', () => {
    console.log('logging in')    // check this is called once
    // do the login
  })
})
  • Related