Cypress hooks in grouped describe

Viewed 314

I want to execute a hook for every describe call. My structure should look like this:

describe('Main', ()=> {
  beforeEach(() => {
    // should call for every describe
  })
  
  describe('Sub', () => {
    it('some tests', ()=> {
      
    })
    
    it('some tests2', ()=> {
      
    })
  })
  
  describe('Sub 2', () => {
    it('some tests', ()=> {
      
    })
  })
})

I tried executing this but beforeEach fires for every test not every describe.

3 Answers

You can patch the standard describe() function, which will add the hook transparently.

const originalDescribe = global.describe
const describe = (title, callback) => {
  originalDescribe(title, () => {
    before(() => {
      console.log('describe', title)
    });
    callback();
  });
}

describe('Main', ()=> {
  
  describe('Sub', () => {
    it('some tests', ()=> {
      console.log('it', 1)
    })
    
    it('some tests2', ()=> {
      console.log('it', 2)
    })
  })
  
  describe('Sub 2', () => {
    it('some tests', ()=> {
      console.log('it', 3)
    })
  })
})

Or another (simpler) approach is just to call you beforeDescribe() hook at the start of each describe() block.

const beforeDescribeHook = () => {
  const title = Cypress.mocha.getRunner().suite.title;
  console.log('describe', title)
}

describe('Main', ()=> {

  before(beforeDescribeHook)
  
  describe('Sub', () => {

    before(beforeDescribeHook)

    it('some tests', ()=> {
      console.log('it', 1)
    })
    
    it('some tests2', ()=> {
      console.log('it', 2)
    })
  })
  
  describe('Sub 2', () => {

    before(beforeDescribeHook)

    it('some tests', ()=> {
      console.log('it', 3)
    })
  })
})

Since beforeEach() won't execute before each describe block, you have to create a custom function to achieve this. You can do something like this. Create a custom function and instead of describe block you can call this function to run the before block every time.

function customSuite(name, tests) {
  describe(name, function() {
    before(function() {
      //Do Something
    });
    tests();
  });
}

describe('Main', () => {

  customSuite('Sub1', function() {
    it('some tests', function() {

    })

    it('some tests2', function() {

    })
  })

  customSuite('Sub2', function() {
    it('some tests', function() {

    })
  })
  
})

I had the same problem and found the workaround of just putting one testcase inside of the highest describe like this:

describe( () => {
    beforeEach(//do smth)
    it('workaround', () => {})
    describe( () => {
        //executes beforeEach here
    })
    describe( () => {
        //executes beforeEach here also
    })
})

As you can see the test can be comletely empty. But maybe you will even find some use for it. Let me know if it also worked for you!

Related