how to make proper async request inside cypress.on(test:after:run,...) - cypress

I am facing an issue with cleanup action after test run, What I need to do is after each test run, I need to call a certain API to store the result , here's my simplified code,
Cypress.on('test:after:run', (test) => {
Cypress.log({
name: 'Reporting..',
message: 'Sending Test result..',
})
...
add_result(test..) //async request
...
Cypress.log({
name: 'Reporting..',
message: 'Test Result Send Succesfully',
})
})
And this works for most of the test, but it doesnt work for the last test run of spec file, i am assuming it is because the browser is closed after the last test run but i am not sure, What can i do here?

Related

Cypress - Unable to run multiple tests

I am very new to cypress automation and have been following though some examples and have ran into an issue that does not appear to be addressed in any video I have seen, where multiple tests in the same 'describe' do not run as expected.
If I create the following code & run it, it all works perfectly:-
describe('My First Test', () => {
it('Open Google', () => {
cy.visit('https://google.co.uk')
cy.get('#L2AGLb > .QS5gu').click()
cy.get('.gLFyf').type('Automation Step by Step{Enter}')
})
})
I have then attempted to split up the test into individual tests, as follows:-
describe('My First Test', () => {
it('Open Google', () => {
cy.visit('https://google.co.uk')
})
it('Confirm warning', () => {
cy.get('#L2AGLb > .QS5gu').click()
cy.get('.gLFyf').type('Automation Step by Step{Enter}')
})
it('Confirm warning', () => {
cy.get('.gLFyf').type('Automation Step by Step{Enter}')
})
})
The problem now is that after opening Chrome and then going into the next test, which should allow me to type the text, a 'default blank page' is displayed and the tests then fail.
What am I missing here to be able to run these three tests fully?
Code in VS Code
Error after opening Chrome & attempting to type in box
As above really, I was hoping to be able to run all three simple tests together.
EDIT - I rolled back my version of Cypress to 10.10.0 and it works perfectly, so no idea what has changed on the latest version released yesterday.
Try it with Test Isolation turned to false.
Best Practice: Tests should always be able to be run independently from one another and still pass
This was added in Cypress 12.0.0.
But if you want to play without it,
Test Isolation Disabled
testIsolation
beforeEach test
true
- clears page by visiting about:blank
- clears cookies in all domains
- local storage in all domains
- session storage in all domains
false
does not alter the current browser context
cypress.config.js
const { defineConfig } = require('cypress')
module.exports = defineConfig({
e2e: {
testIsolation: false,
},
})
You should visit your page for every test. You can put the cy.visit in a beforeEach function.

In my Cypress.io tests why do I need to treat a cy.task like it is asyncronous when its not

I have Cypress.io tests that use a simple Cypress task to log some table information to the terminal. For example I have a test like so:
it("Writes some console logs and checks a val", () => {
cy.task("rowLog", { id: 1, name: "foo", type: "bar" });
let one = 1;
expect(one).to.equal(2);
});
And the task, "rowLog" like so:
module.exports = (on, config) => {
on("task", {
rowLog(data) {
// use node.js console.table to pretty print table data:
console.table(data);
return null;
},
}
But the result of rowLog will not display in my terminal if I run Cypress headlessly via Cypress run. This is because the test will fail. If we switch the test so that it passes, then it will show.
However I just realized that if I treat rowLog like it's async like below. It will print the results to the terminal:
it("Writes some console logs and checks a val", () => {
// add a .then to task:
cy.task("rowLog", { id: 1, name: "foo", type: "bar" }).then(() => {
let one = 1;
expect(one).to.equal(2);
});
});
This is not what I would expect from the docs. They say that:
cy.task() yields the value returned or resolved by the task event in the pluginsFile.
(source)
And that a task can yield either a promise or a value.
I'm new to Cypress here-- is there something I'm missing or doing wrong? I'd like to be able to not have to chain my tasks with .then statements if it is just synchronous stuff like writing output to ensure everything is emitted to my terminal.
If you look into the type definition of cy.task command, you will see that it returns a Chainable (that is a promise-like entity). So it behaves like any other cy command (ansynchrounously).
As for the yield either a promise or a **value** - this statement refers to the handler of the task, not the task itself. As for the other command, Cypress will wrap a returned value into a promise if it was not done by the handler.

Failed screenshot in Mochawesome Report in case of Test Retry

I am using addContext() that mocha provides to append failure screenshots in the Mochawesome html report. I have written this under support/index.js
Cypress.on('test:after:run', (test, runnable) => {
if (test.state === 'failed') {
const screenshot = `FailureScreenshots/${Cypress.spec.name
}/${runnable.parent.title} -- ${test.title} (failed).png`;
addContext({ test }, screenshot);
}
});
This works perfectly when there is a failure(and there are no Test Retries) it just appends the failure screenshot in the html report bases on test.state. However, in case of Test Retries, where on the first run the test failed but on the second run the test passed, it still attaches the failure screenshot. How can I prevent that? It should only append the screenshot when the test finally fails after the number of retries have been exhausted.

webdriverio mocha How write function in wdio.conf.js if a test fails

I am trying to write a function in wdio.conf.js that executes when a test passes.
At the end of the test, it shows all of the tests passing, however it never hits the console.log("testpassed") code shown here:
afterTest: function (test) {
if (test.passed === true) {
console.log("testpassed")
}
},
If I console.log - 'test' - it prints [object Object].
However, if I console log test.passed it prints undefined.
At the end of the test it shows all tests as passed.
What am I doing wrong?
Further investigation: These are the only keys returned in the 'test' array:
type,title,fn,body,async,sync,_timeout,_slow,_retries,timedOut,_currentRetry,pending,file,parent,ctx,_events,_eventsCount,callback,timer
So there doesn't seem to be a key for test.passed
afterTest: function (test, context, { passed }) {
if(passed){
console.log("THE TEST PASSED");
}
},

Is there a way to add cypress test steps execution information into allure report?

I'm trying to add test step information into an allure report, i use cypress and generate report with allure, report are correctly generate but no details appears in testcases.
I try to use the on('task') without success...
my plugins/index.js contain:
...
on('task', {
allureTestStep () {
const testStep = allure.createStep("Initial", () => {
console.log("First Test")
});
testStep()
return null
}
})
...
and i call it with:
cy.task('allureTestStep')
in my test.
No log in console only two error:
allure-js-commons: Unexpected startStep() of initial. There is no parent step
First Test
allure-js-commons: Unexpected endStep(). There are no any steps running
and in the report nothing is displayed(no error, no step detail).
Any help is welcome :)
I'm using the cypress-allure plugin and you can set it to show cypress commands in the test results. If you call cy.log those also get placed there. It's pretty nice.
it(`Should have title of ${treeListTitle}`, () => {
cy.log('title should be set');
...
}
Notice in the allure results where that is printed out.

Resources