Send a REST message for each Cypress test result

Viewed 548

Is there a way to call a REST api based for each cypress test result?

We have a zephyr test definition system, and we must use it's API (https://support.smartbear.com/zephyr-scale-server/api-docs/v1/ ) to change the status of each testcase our testers defined, as part of the automation processes we have in our company.

In my research the only solution we found was to use a Reporter (https://docs.cypress.io/guides/tooling/reporters) and then parse the results with a small script which generates the said REST calls for each test result.

I was wondering: is there any more elegant solution to call the zephyr app directly, via Cypress maybe?

2 Answers

I don't know what info zephyr requires, but there's plenty of hooks/events you can use.

For example (at the top of the spec or in /support/index.js)

Cypress.on('test:after:run', (test, runnable) => {

  console.log('test,runnable', test, runnable)

  const details = {
    projectKey: Cypress.env('zephyr-project-key'),
    testName: test.invocationDetails.relativeFile,
    status: test.status,
    error: runnable.err.message,
    retries: runnable.retries.length,
    duration: test.wallClockDuration,
    startTime: test.wallClockStartedAt
  }
  
  cy.request('POST', 'api/end/point', { body: details })
  // or native fetch('POST',...) if a particular hook complains about using cy.request
})

There's also

on('after:run', (results) => {
  /* ... */
})

on('after:spec', (spec, results) => {
  /* ... */
})

on('after:screenshot', (details) => {
  /* ... */
})

Or (technically inside the test)

afterEach(() => {
  const test = cy.state('test')
  const runnable = cy.state('runnable')
  /* ... */
})

in the index.js:

module.exports = (on, config) => {
  on('after:spec', async (spec, results) => {
    /**
     * spec file data
     */
    const cycleName = getCycleName(spec);

    /**
     * CyPress test results parse
     */
    const zephyrResults = await parserSpecResults(results);
    const data = JSON.stringify(zephyrResults);

    /**
     * send data to our server
     */
    await sendTestResults(data, cycleName);
  });
};

And our sendTestResults:


async function sendTestResults(sendData, cycleName) {
  options.path = `/rest/atm/1.0/testrun/${cycleName}/testresults`; // our zephyr's dynamic endopints
  options.method = 'POST';
  options.headers['Content-Length'] = sendData.length;

  await new Promise((resolve, reject) => {
    const req = https.request(options, (res) => {
      res.on('data', function (chunk) {
        console.log('Response to sending test results to Zephyr : ', `${chunk}`);
        resolve(res);
      });
    });

    req.on('error', (error) => {
      console.error('Error the send test result to Zephyr: ', error);
      reject(error);
    });

    req.write(sendData);
    req.end();
  });
}
Related