Npm cypress: Using fixtures in foreach? - cypress

I like to use cypress for frontend testing, but after writing a lot of very simple tests I try to overwork it.
I defined fixtures in cypress/fixtures/login.json and initialize it with cy.fixture("login").as("login) in beforeEach() section to use it as 'this.login.KEY' in it() section. Is runs perfect.
But it is possible to use these fixtures directly in beforeEach() section?
Example:
context('description one', function() {
beforeEach(function(){
cy.fixture("login").as("login");
-> here I would like to use fixture like
-> cy.visit("/");
-> cy.get('#password').type(this.login.password);
});
it('sub-description', function() {
cy.get(#firstName).type(this.login.userFirstName);
...
})
});

I've also had trouble with this.myFixture not working. Try using it like this:
context('description one', function() {
beforeEach(function(){
cy.fixture("login").then(login => {
cy.visit("/");
cy.get('#password').type(login.password);
});
it('sub-description', function() {
cy.fixture("login").then(login => {
cy.get(#firstName).type(login.userFirstName);
...
})
});

Related

How to skip a cypress test in beforeeach hook?

I want to skip and allow tests in the before each hook as follows
beforeEach(() =>{
if(Cypress.mocha.getRunner().suite.ctx.currentTest.title === `Skip this`){
// skip the first test case only but run the second one [How?]
}
});
it(`Skip this`, () => {
});
it(`Don't skip this`, () => {
});
In the place of [How?] I tried using the following:
cy.skipOn(true) from the cypress skip-test plugin but apparently it skips the beforeEach hook not the test itself.
this.skip() but apparently this is not a valid function. Also, if I changed the beforeEach from an arrow function expression, the skip function works but it skips the whole suite and not just the desired test case.
Any ideas?
Change the function type from arrow function to regular function, then you can use the built-in Mocha skip() method.
beforeEach(function() {
if (condition) {
this.skip()
}
})
Your code sample will look like this:
beforeEach(function() { // NOTE regular function
if (Cypress.mocha.getRunner().suite.ctx.currentTest.title === 'Skip this') {
this.skip()
}
});
it(`Skip this`, () => {
});
it(`Don't skip this`, () => {
});
Or use the Mocha context you already use for test title
beforeEach(() => { // NOTE arrow function is allowed
const ctx = Cypress.mocha.getRunner().suite.ctx
if (ctx.currentTest.title === 'Skip this') {
ctx.skip()
}
});
afterEach()
If you have an afterEach() hook, the this.skip() call does not stop it running for the skipped test.
You should check the condition inside that hook also,
afterEach(function() {
if (condition) return;
... // code that should not run for skipped tests.
})

Looking for a way tu use Cypress fixtures for all my custom commands outside an it block

I'm building some custom commands and trying to use my fixtures data for all my commands. Right now I'm forced to define it inside an it block.
Looks similar to this:
it("Commands", () => {
cy.fixture("fixtureFile").as("data");
cy.get("#data").then((data) => {
Cypress.Commands.add('login', () => {
cy.visit("/login");
cy.get('#login-email').type(data.userEmail);
cy.get('#login-pass').type(data.userPass, {log: false});
cy.get('.btn').debug().click();
})
Cypress.Commands.add('createTagMedia', () => {
cy.get(".close").click();
cy.get("#form-field-name").type(data.releaseVersion);
cy.get(".form-group-adTag > .CodeMirror > .CodeMirror-scroll").type(data.mediaTag);
cy.get("#media-save-btn").click();
})
})
})
This it block is being count as a test case, Is there a better way to pass this for more than one command at the same time?
The workaround I found was to put everything inside a before block, for example:
before(() => {
cy.fixture("fixtureFile").as("data");
cy.get("#data").then((data) => {
Cypress.Commands.add('login', () => {
cy.visit("/login");
cy.get('#login-email').type(data.userEmail);
cy.get('#login-pass').type(data.userPass, {log: false});
cy.get('.btn').debug().click();
})
Cypress.Commands.add('createTagMedia', () => {
cy.get(".close").click();
cy.get("#form-field-name").type(data.releaseVersion);
cy.get(".form-group-adTag > .CodeMirror > .CodeMirror-scroll").type(data.mediaTag);
cy.get("#media-save-btn").click();
})
})
})
Is there a reason why you won't use the following:
import {data} from '../fixtures/FixtureFile'
Considering you have the following JSON file:
{
"data": {
"userEmail": "blah",
"userPass": "blah",
"releaseVersion": "1"
}
}
You can include this on your tests, commands (Cypress.custom.commands), etc.
before(() => {
const data = cy.fixture("fixtureFile");
cy.login(data);
cy.createTagMedia(data);
})
You could literally do something like the above. With your Cypress.Commands in your command.ts or js whichever you're using.
And make the commands take in a parameter. Then the above before hook would just be in your tests.

How to send the success of a test to testingBot from a Protractor project?

Following the testingBot example for protractor-based projects I got this code
var TestingBot = require('testingbot-api');
describe('Protractor Demo App', function () {
var tb;
beforeEach(function () {
tb = new TestingBot({
api_key: "master_key",
api_secret: "secret_007"
});
});
afterEach(function () {
browser.getSession().then(function (session) {
tb.updateTest({
'test[success]': true/*where do I get this 'test[success]' attribute? */
}, session.getId(), function () {
console.log("Hi! :D");
});
})
});
it('should have a title', function () {
browser.get('http://juliemr.github.io/protractor-demo/');
expect(browser.getTitle()).toEqual('Super Calculator');
});
});
I need to send the success of the test back through the tb.updateTest() but I don't know where I get the value of a passed or failed test. For now the value is a static true. I'd appreciate a jasmine approach too.
You can use a custom reporter with Jasmine.
There you can hook into specDone or suiteDone which has a result parameter, containing the test's success state.
You can then use this state to write a custom report or send it to somewhere else.

Conditionally run tests at runtime using Nightwatchjs

I'm using nightwatch to run my end to end tests but I would like to conditionally run certain tests based on some global settings at runtime.
// globals.js
module.exports = {
FLAG: true
};
// test.js
describe('Something', () => {
it('should do something', client => {
if (client.globals.FLAG) {
expect(1).to.equal(1);
}
});
});
The above works fine, but I want to silent the whole test and conditionally include the it e.g:
// test.js
describe('Something', () => {
// client does not exist out here so it does not work.
if (client.globals.FLAG) {
it('should do something', client => {
expect(1).to.equal(1);
});
}
});
I am aware I can skip tests by defining them in the nightwatch.js and excluding files etc etc but thats not the approach I can use in this implementation. Another solution might be to use tags but I'm not sure this is possible using Mocha.
You could access the flag in the second example by importing your module globals.js:
// test.js
const globals = require('../globals.js');
describe('Something', () => {
if (globals.FLAG) {
it('should do something', client => {
expect(1).to.equal(1);
});
}
});
you could also create a function to ignore the test when the condition is met:
// test.js
const FLAG = require('../globals.js').FLAG;
const not = function(v){ return {it: v ? function(){}: it} };
describe('Something', () => {
not(FLAG).it('should do something', client => {
expect(1).to.equal(1);
});
});

Jasmine avoid beforeEach for certain tests

Is there a way to NOT execute beforeEach function only for certain tests ('it' blocks). Lets say I have 10 it blocks, I do not want beforeEach to be executed for two of the blocks. Is it possible?
You can group specs which you want to run with beforeEach into a separate describe:
it('should 1...', function () {});
it('should 2...', function () {});
describe('group', function () {
beforeEach(function () {
// ...
});
it('should 3...', function () {});
it('should 4...', function () {});
// ...
});
I currently managed this with a work around as follows:
var executeBeforeEach = true;
function beforeEach() {
if(!executeBeforeEach) return;
//your before each code here.
}
describe('some test case 1', function(){
it('Start', function(){
//this is a dummy block to disable beforeeach for next test
})
it('The test that does not need beforeEach', function(){
//this test does not need before each.
})
it('Start', function(){
//this is a dummy block to enable beforeeach for next test
})
})
But, I am wondering if there is a more elegant way!?!

Resources