Execute 'step 1' inside 'step 2' - cypress+cucumber - cucumber

I faced with many similar pieces of code in my steps, re-using steps inside 'bigger' steps can solve the problem. Is it possible to run step 1 inside step 2?
And('My Step 1', () => {
some code;
});
And('My Step 2', () => {
can I execute 'My Step 1' here?
code;
});

You can add the steps in the command file and then call them in your tests.
Your commands will look something like this:
Cypress.Commands.add("Step1", function () {
Do stuff here
});
And then in your tests you can reuse those commands like this:
it('My Step 2', () => {
cy.Step1();
code;
});
Remember to import the command file in your index.js

Related

How to run tests related to changed files in cypress

I'm using cypress to set E2E tests.
But i'm facing some troubles, because every time I implement a new feature or refactor some code, i need to run all my tests to see if my modifications doesn't broke something in my application.
In Jest we have the flag --findRelatedTests that run only related tests files modified.
I wonder if there's a way to do the same in cypress.
Are you looking for the plugin cypress-watch-and-reload?
// cypress.json
{
"cypress-watch-and-reload": {
"watch": ["page/*", "src/*.js"] // watch source and page-object (helper) files
}
}
YouTube - Re-run Cypress Tests When Application Files Change
if you try in locally, then
1, If you want to skip a specific test group or test case, one approach is to add .skip at the end of context or it blocks. For example, context.skip() or it.skip().
context.skip('Test group', () => {
// This whole test group will be skipped
it('Test case 1', () => {
// This test case will not run because test group is skipped
});
});
context('Test group', () => {
it.skip('test case1', () => {
// Test case one will be skipped
});
it('test case2', () => {
// Detail for test case two
// This will execute
});
});
Run Specific/modified Tests Only
you can add .only at the end of context or it block, such as context.only() or it.only().
// Only 1st test group will run
context.only('test group1', () => {
it('test case', () => {
// Test case one will run
});
it('test case2', () => {
// Test case two will run
});
});
// The 2nd test group will not run
context('test group2', () => {
it('test case3', () => {
// Test case three will be skipped
});
it('test cas4', () => {
// Test case three will be skipped
});
});
context('test group', () => {
it.only('test case1', () => {
// Test case one will run
});
it('test case2', () => {
// Test case two will be skipped
});
});
Run Tests Conditionally by Using cypress.json
run tests conditionally is to use cypress.json file, if you want to run a specific test file.
If you only want to run tests in test.spec.js file, you can just add file path to test files in the cypress.json.
{
"testFiles": "**/test.spec.js"
}
run multiple test files
{
"testFiles": ["**/test-1.spec.js", "**/test-2.spec.js"]
}
ignore specific tests from your test runs
{
"ignoreTestFiles": "**/*.ignore.js"
}
Run Tests Conditionally by Using command line
npx cypress run --spec "cypress/integration/test.spec.js"
To run all the tests in a specific folder with file name end with .spec.js
npx cypress run --spec "cypress/integration/testgroup-directory-name/*.spec.js"
If you are using CI/CD then this will help you and you can get an idea.
Faster test execution with cypress-grep

Basic jest test on a 1 function file gets 0% coverage

I have 2 files with 1 function in it. My test is just as simple, see below:
doc.js
export function createSynthId(doc) {
const synthId = `${doc.attachmentId}-${doc.materialId}-${doc.fileName}-${doc.title}-${doc.materialURL}`;
return synthId;
}
doc.test.js
import { createSynthId } from './doc';
describe('doc', () => {
it('create synthetic id', () => {
expect(createSynthId(global.doc)).toEqual('987654-123456-File Name.pptx-undefined-');
});
it('create synthetic id', () => {
expect(createSynthId({})).toEqual('undefined-undefined-undefined-undefined-undefined');
});
});
My second file is virtually the same, just a larger function. Both tests pass, but coverage is being reported at 0% for Statements, Functions, and Lines, but 100% for Branches. The coverage report is showing all the lines red as well.
We have many similar files and they all work. What am I missing here?
UPDATE
I added a temp function to doc.js
export const makeTestsHappy = () => {
console.log(CONFIG);
};
adding to doc.test.js
it('does more', () => {
makeTestsHappy();
});
and when I try to test that, I get the error TypeError: (0 , _doc.makeTestsHappy) is not a function
Dummy over here was mocking the file I was testing. I forgot to jest.unmock('/doc') It immediately started working when I unlocked. Thanks all for your patience :D
Try to rename your test file from doc.test.js to doc.spec.js. You are using the BDD syntax and the correct name should include spec.

How to stop jest describe without throw all the test

I want to stop a whole describe of JEST without throwing an error or stoping the other describes.
Im writing e2e test for my app with JEST and PUPPETEER, I write the test in a way every DESCRIBE its a flow of the path and every IT its a step, inside a IT I want to stop the flow if the pages dont match some conditions.
describe('Book a Room', ()=> {
it ('enter on main page' async() => await mainPage.navigateToMainPage())
it('go to book room page', async() => await bookRoomPage.navigateToBookRoomPage())
// The function its inside the "bookRoomPage"
it('check if the user can book room', () => {
if (!page.userCanOpenARoom()) {
// DONT EXECUTE THE NEXT IT BUT CONTINUE WITH THE OTHER DESCRIBE
}
})
it('go to book preview...', async() => bookRoomPreviewPage.navigateToBookRoomPreviewPage());
// REMAINING FLOW
})
I already try with process.exit(0) but exit the whole process
You can try out what this blog says here its for sharing specs in your test suites which is pretty handy. But for your case specifically you could extract your page cases in separate suites and then dynamically include the test case on runtime if a condition is met.
Something like:
Include Spec function shared_specs/index.js
const includeSpec = (sharedExampleName, args) => {
require(`./${sharedExampleName}`)(args);
};
exports.includeSpec = includeSpec;
Test A shared_specs/test_a.js
describe('some_page', () => {
it...
})
Test B shared_specs/test_b.js
describe('some_other_page', () => {
it...
})
and then in your test case
// Something like this would be your path I guess
import {includeSpec} from '../shared_specs/includeSpec.js'
describe('Book a Room', async ()=> {
if (page.userCanOpenARoom()) {
includeSpec('test_a', page);
} else {
includeSpec('test_b', page); // Or dont do anything
}
});
Just make sure that you check the paths since
require(`./${sharedExampleName}`)(args);
will load it dynamically at runtime, and use includeSpec in your describe blocks not it blocks. You should be able to split up your test suites pretty nicely with this.

how to set a particular test file as the first when running mocha?

Is there a way to set a particular test file as the first in mocha and then the rest of the test files can execute in any order.
One technique that can be used is to involve number in test filename such as
01-first-test.js
02-second-test.js
03-third-test.js
So by defining this, the test will be executed from first test until third test.
No. There is no guarantee your tests will run in any particular order. If you need to do some setup for tests inside of a given describe block, try using the before hook like so.
There is no direct way, but there is certainly a solution to this. Wrap your describe block in function and call function accordingly.
firstFile.js
function first(){
describe("first test ", function () {
it("should run first ", function () {
//your code
});
});
}
module.exports = {
first
}
secondFile.js
function second(){
describe("second test ", function () {
it("should run after first ", function () {
//your code
})
})
}
module.exports = {
second
}
Then create one main file and import modules.
main.spec.js
const firstThis = require('./first.js)
const secondSecond = require(./second.js)
firstThis.first();
secondSecond.second();
In this way you can use core javaScript features and play around with mocha as well.
This is the solution I have been using since long. would highly appreciate if anyone would come with better approach.

Getting the test name in the afterEach function in mocha

Let me start by saying I am quite new to node.js and mocha.It just breaks my head. I started using the tdd approach and I am trying to get the test that will start or has just finished from within the beforeEach and afterEach functions, but I've had no luck.(I am mostly interested in afterEach). At least I couldn't figure a neat way of doing it. The only thing I could think of was keeping the tests and the suite in a variable and then on afterEach() just do some matching to see which test has finished.
Ideally where it says 'test name' I want to have something like suite.test.name
suite('my test suite', function() {
beforeEach(function () {
console.log('test name');
});
test('first test', function (done) {
var testarray = ['1', '3', '5', '7'];
testarray.forEach(function(num, index) {
console.log('num: ' + num + ' index: ' + index);
},
done());
});
afterEach(){
console.log('test name');
}
}
You get the name of the current test with this.currentTest.title
afterEach(function(){
console.log(this.currentTest.title)
})
I find that i use this.currentTest.fullTitle() more than this.currentTest.title-- i prefer to have the describe names as well.
If you have nested describe blocks and for some reason you want to separate the title portions you can do something like the following in either the beforeEach or afterEach methods:
function titles(test) {
console.log(test.title)
if (test.parent) {
titles(test.parent)
}
}
titles(this.currentTest)

Resources