I am using Mocha, Typescript and Cypress to write tests.
This is visualization of what I am trying to achieve (so far unsuccessfully :():
// this is in example-spec.ts file
context('Sharing variable test', function() {
let ctx: string;
beforeEach(function() {
ctx = 'Value given in beforeEach';
});
console.log(ctx); // prints undefined
consumeCtx(ctx);
});
// this is in separate example-template.ts file
export function consumeCtx(ctx: string) {
console.log(ctx); // this is undefined
// use ctx here
describe('Testing my stuff', function () {
it('should do something', function () {
// use ctx here
cy.log('This is a test');
});
});
}
I would like I could somehow fill the ctx data in beforeEach and then use it after that through calling a function which accepts ctx as parameter.
The idea is to have 2 different spec files (e.g. example1-spec.ts
and example2-spec.ts
) which can be run separately.
But they still share the same test logic defined in example-template.ts
file.
And the test data ctx
specific to each spec file is provided in the spec file and then just passed to the common test logic in template file.
Is there a way to achieve this in the set up that I have created?
Is my approach completely wrong? How would you do it better?
Thanks!
[EDIT] This is how I reorganized it based on the answers:
In each spec file there is mocha structure.
context('Voucher tests', function () {
let ctx: string;
beforeEach(function () {
ctx = 'Value given in beforeEach';
cy.wrap(ctx).as('ctx');
});
describe('Logged in user', function () {
it('valid voucher ', function () {
cy.get<string>('@ctx').then((ctx) => {
console.log(ctx); // should print the value of ctx now
validCtxTest(ctx);
});
});
it('invalid voucher ', function () {
cy.get<string>('@ctx').then((ctx) => {
console.log(ctx); // should print the value of ctx now
invalidCtxTest(ctx);
});
});
});
});
And in separate template file I have the shared logic.
export function validCtxTest(ctx: string) {
cy.log('Logic for valid test', ctx);
}
export function invalidCtxTest(ctx: string) {
cy.log('Logic for invalid test', ctx);
}
I learnt this the hard way. But you need to wrap ctx, provide an alias, and then call that alias to be passed to your function. I am not a type script person, but hope this helps. [Edit: adding a working script and result]
context("blah",()=> {
let ctx
beforeEach( function() {
const uuid = () => Cypress._.random(0, 1e3)
const id = uuid()
ctx=`some random number ${id}`
cy.wrap(ctx).as('ctx')
})
describe("Spec", () => {
it("Test1", function() {
cy.get('@ctx').then(ctx=> {
console.log(ctx)
})
})
it("Test2", function() {
cy.get('@ctx').then(ctx=> {
console.log(ctx)
})
})
})
})
Also, if you are not planning to have multiple test in a spec file, or pass different value of ctx for each test under 1 spec file, then just ignore the Before hook. You can declare a variable inside your test and then wrap it up and call it anywhere you want in that test. For the next test, do the same. Its the same approach i have used in my project. fixtures help a lot in defining and passing test data, rather than variables.