Cypress: add function nameOfPromise as custom command - cypress

I'm quite new in Cypress and I'm trying to make the things works... Could you please help me a bit? There is a function:
function checkInput(selector, nameOfPromise) {
cy.get(selector).should("contain", nameOfPromise)
}
on execution it looks the following way:
cy.get("#nameOfPromise").then(nameOfPromise => (checkInput(selector, nameOfPromise)))
it works just fine when I add it at the beggining of test but I want to create a custom command from it, so I tried
Cypress.Commands.add("checkInput", (selector, nameOfPromise) => {
cy.get(selector).should("contain", nameOfPromise)
})
but it doesn't work. Is there any possible solution? Thanks a lot!

Calling the custom command instead of the function work very similar to the function
Cypress.Commands.add("checkInput", (selector, nameOfPromise) => {
cy.get(selector).should("contain", nameOfPromise)
})
it('my test', () => {
cy.get('something').as('nameOfPromise')
...
cy.get("#nameOfPromise")
.then(nameOfPromise => {
cy.checkInput(selector, nameOfPromise)
})
"it doesn't work" could mean 100 things, but if you have things as above it will work.

Related

Blank page after running Cypress tests

Whenever I run a new cypress test, the page that is supposed to show the UI is blank. Even when I click on each part of each test it remains blank. Please see image below.
image
Cypress package version: 10.4.0
Node v16.16.0
Code:
describe("home page", () => {
beforeEach(() => {
cy.visit("http://localhost:3000")
})
context("Hero section", () => {
it("the h1 contains the correct text", () => {
cy.getByData("hero-heading").contains(
"Testing Next.js Applications with Cypress"
)
})
it("the features on the homepage are correct", () => {
cy.get("dt").eq(0).contains("4 Courses")
cy.get("dt").eq(1).contains("25+ Lessons")
cy.get("dt").eq(2).contains("Free and Open Source")
})
})
context("Courses section", () => {
it("CourseL Testing Your First Next.js Application", () => {
cy.getByData('course-0')
.find('a')
.eq(3)
.contains('Get started')
})
})
})
/// <reference types="cypress" />
Cypress.Commands.add('getByData', (selector) => {
return cy.get(`[data-test=${selector}]`);
});
I faced the same issue in Cypress version 12.0.0 and I solved it by adding this configuration to cypress.config.js
testIsolation: false,
Try adding 's' to http; this might solve that else here is similar issue reported which might give you clue to your problem https://github.com/cypress-io/cypress/issues/4235
You might have put the it() describe() statements in the wrong place. Try creating the most simple test file possible or better still use an example test that cypress provides strip it down and continue to test it until it is barebones.
I have a "solution" in my tests - it seems that the it steps lose the URL.
Remove all the it steps:
describe('Register Native', () => {
// it("Verify1", () => {
: a
// })
// it("Verify2", () => {
: b
// })
})
Now I have a structure like this (only one it step):
describe('Registrer Native', () => {
it('Whole test- Without IT parts', () => {
: a
: b
: c
})
})
It is not an optimal solution as I now have a long test without intermediary it sections.

CDK AWS Lambda how to mock the asset provided

I am using jest for testing and I have a lambda function in my Stack I want to test.
Like this:
const lambda = new lambda.Function(this, "MyLambda", {
...
code: lambda.Code.fromAsset("../assets/lambda.zip"),
...
}
);
I want to test some of the properties but also if the lambda is in the stack. But when I run the test it complains that my lambda.zip doesn't exist. Which is fair enough, as it's built as part of the another build job.
Is there any way to inject or somehow mock the lambda's asset.
You can try using Code.fromInline() as it doesn't require any files on disk. Simply pass a dummy function code as a string.
lambda.Code.fromInline("exports.handler = async function(event, context) {}")
Based on kichik's idea to use Code.fromInline(), this worked for me:
import { InlineCode } from "#aws-cdk/aws-lambda"
jest.mock("#aws-cdk/aws-lambda", () => ({
...jest.requireActual("#aws-cdk/aws-lambda"),
Code: {
fromAsset: () => new InlineCode("foo"),
},
}))
Probably can be simplified with jest.spyOn, but I couldn't figure out how to make it work.
In a lot of simple scenarios, there's no need to bother with a complicated jest mocking.
beforeAll(() => {
Object.defineProperty(Code, 'fromAsset', {
value: () => Code.fromInline('test code'),
});
});

Cypress custom command wont return value

I have a function that I want to add as a command so i can reuse it.
Its on cypress/support/commands.js:
Cypress.Commands.add("generatePassword", () => {
return 'randomstring';
}
);
Then on my test I want to use it as:
it("Visits page", () => {
const password = generatePassword();
cy.log({password})
// Here it logs this:
//{password: {chainerid: chainer146, firstcall: false}}
});
Any idea on how to get the actual value? Now i get this:
{chainerid: chainer146, firstcall: false}
Thanks.
Basically cypress works in promise chain and you're returning the promise chainerid from your custom command. You have to chain it to use in next statement. Use something like below.
it("Visits page", () => {
return cy.generatePassword().then(pwd => {
cy.log(pwd);
});
});

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.

access the output of get in then block

how to access the element that is yielded from .get().contains() in .then() function
My code is not entering the Then block. where am i doing wrong ?
cy.get(".c-header-listItem").contains("My Account").should(($link) => {
expect(localStorage.read("CD-SessionId")).to.be.not.null;`enter code here`
}).then(($link) => {
$link.click();
});
I got the login from Cypress documentation https://docs.cypress.io/api/commands/should.html#Subjects
.should(elem => {}) behaves exactly as .then(elem => {}), except that the function passed to the should will retry until it doesn't throw any exceptions. With that in mind, the following code should work:
cy.get(".c-header-listItem").contains("My Account").should(($link) => {
expect(localStorage.read("CD-SessionId")).to.be.not.null;
// Notice I have to wrap this to perform a Cypress
// click on it. $link is a native DOM object.
cy.wrap($link).click();
});
This would also work, but the separation isn't necessary.
cy.get(".c-header-listItem").contains("My Account").should(($link) => {
expect(localStorage.read("CD-SessionId")).to.be.not.null;
});
cy.get(".c-header-listItem").contains("My Account").click();

Resources