Closed rohShinde closed 1 year ago
First I want to thank you for describing things to help setup the project.
I am facing one issue in automating my application using your way of cypress + BDD. The issue is in step definitions where my application login process deals with two different urls.
Given('I am on the landing page', () => { cy.visit('first_url') cy.origin('second_url', () => cy.contains('Log in to Page')) })
using cy.origin() helps me change the active url application currently have, however while trying POM I am getting error as
Variables must either be defined within the cy.origin() command or passed in using the args option.
Hi @rohShinde, you're welcome! My pleasure.
I think this is not related to step definitions. In cy.origin(), you should serialize the variables and data you want to use in call back function. This should be done with args
option which is an object sent from the primary origin to the secondary origin, where it will be deserialized and passed into the callback function as its first and only argument. This is the only available way without violating the browser's same-origin policy. Because cypress runs directly inside browser.
Look at this example, assume you want to signup in application and you should click on Complete registration button or GET request its href attribute (containing token) from your email which is in another origin (Ethereal.email). I'm serializing identity
variable and etheralMailLocators
object with args.
Maybe this is your problem's root cause.
import { signupLocators, etheralMailLocators, sharedLocators } from "./locators"
import { generateRandomIdentity } from "../support/utils"
it('Should signup succesfully', () => {
cy.visit('/sign-up')
let identity = generateRandomIdentity()
cy.get('button').contains('Agree').click()
cy.get(signupLocators.EMAIL_INPUT).type(identity.email)
cy.get(signupLocators.PASSWORD_INPUT).type(identity.password)
cy.get(signupLocators.PASSWORD_CONFIRM_INPUT).type(identity.password)
cy.get(signupLocators.ACCEPT_TERMS_CHECKBOX).check()
cy.get(signupLocators.CREATE_ACCOUNT_BUTTON).should('be.enabled').click()
cy.origin('https://ethereal.email', { args: { etheralMailLocators, identity } }, ({ etheralMailLocators, identity }) => {
cy.get(etheralMailLocators.EMAIL_ADDRESSES).eq(1).should('have.attr', 'title', identity.email)
cy.get("iframe").then(($iframe) => {
const iFrameContents = $iframe.contents().find('body')
cy.wrap(iFrameContents).contains('Welcome to AutomationCamp')
cy.wrap(iFrameContents).find(etheralMailLocators.COMPLETE_REGISTRATION_BUTTON).click()
})
})
cy.get(sharedLocators.GENERIC_NOTIFICATION).should('be.visible').contains("Your email has been successfully associated with your account")
cy.location('pathname').should('eq', '/dashboard')
cy.get(sharedLocators.PROFILE_BUTTON).should('be.visible')
@mmonfared Thanks for your help on this I am now able to use cy.origin() with steps. I am now writing my BDD steps as
Given('I am on the landing page', () => {
cy.visit('/')
cy.origin(loginPageUrl, () => cy.contains('Log in to Application'))
})
When('I click on the login with email button', () => {
cy.origin(loginPageUrl, () => {
cy.get('div:nth-child(1) > a > button').click()
})
})
When('I type in my email address {string}', (value) => {
cy.origin(loginPageUrl, {args: {value}}, ({ value }) => {
cy.get('#login').type(value)
cy.wait(500)
})
})
However still not able figure out a way to use POM style syntax with this, if I wrote something like
const loginPage = new LoginPage()
When('I click on the login with email button', () => {
cy.origin(loginPageUrl, {args: {loginPage}}, ({ loginPage }) => {
loginPage.clickLoginWithEmail.click()
})
})
Its giving me error as loginPage is not defined.
@rohShinde I think it is not possible to pass the class instance as an object to cy.origin.
Can you try this:
const loginPage = new LoginPage()
When('I click on the login with email button', () => {
cy.origin(loginPageUrl, () => {
loginPage.clickLoginWithEmail.click()
})
})
Or this:
When('I click on the login with email button', () => {
cy.origin(loginPageUrl, () => {
const loginPage = new LoginPage()
loginPage.clickLoginWithEmail.click()
})
})
Nevermind, we can close this issue, I m following the classic way than POM for login scenario and for all other places using POM. Though you suggested second option seems to work but it will increase the duplicacy in code.
First I want to thank you for describing things to help setup the project.
I am facing one issue in automating my application using your way of cypress + BDD. The issue is in step definitions where my application login process deals with two different urls.
using cy.origin() helps me change the active url application currently have, however while trying POM I am getting error as
Variables must either be defined within the cy.origin() command or passed in using the args option.