My login functionality testing does this:
- Type username
- Type password
- click login button
- check for agreement page
My POM for login page:
class loginPage {
fillUsername(value) {
cy.get('[id=username]').clear().invoke('val', value);
return this;
}
fillPassword(value) {
cy.get('[id=password]').clear().invoke('val', value);
return this;
}
clickLogin() {
//cy.intercept('/portal/api/login').as('login')
cy.contains("Login / S'identifier").click();
}
checkForAgreementPage(){
const path ='/license-agreement'
cy.wait(500) // <- All the problem is here in this line
// If I comment this line cy.url() yields current page's url
cy.url().then(($url) => {
cy.log($url)
if ($url.includes(path)) {
//cy.log('Clicked')
cy.get('[type=button]').contains('Accept').click();
}
});
}
}
export default loginPage;
My custom function command.js:
Cypress.Commands.add('login', (username, password) => {
lp.fillUsername(username);
lp.fillPassword(password);
lp.clickLogin();
lp.checkForAgreementPage();
});
My spec file:
it('TC01 - Login with valid data as wholesaler', () => {
cy.login(id.username, id.password); // for valid data
cy.visit('/users');
cy.logout();
});
it('TC05 - Login with username but no password ', () => {
cy.login(id.username, id.password); // For invalid data
cy.expected('span', 'Invalid username or password');
});
How can i remove wait function from POM login page? and wait till url is changed?
Also, I've tried to intercept 'api/login' and waited for it to load, but then this will fail the other tests where I am testing failed login scenarios
CodePudding user response:
By the looks of it, it seems you are only validating the pathname of the url in your checkForAgreementPage() function. Although the following does not take into account of other scenarios you may have in your suite as there is a if statement which can entail different scenarios, you can remove the cy.url() portion and do the following instead:
checkForAgreementPage(){
const path ='/license-agreement'
// The should will trigger retrying the previous command so cypress will
// continuously check for the pathname to include the path until the
// command timeout, so you don't have to have an explicit wait
cy.location('pathname')
.should('include', path)
.then(cy.log) // can comment out if you don't want to log the pathname
// now you can click on the accept button
cy.get('[type=button]').contains('Accept').click();
});
CodePudding user response:
I've tried to intercept 'api/login' and waited for it to load, but then this will fail the other tests where I am testing failed login scenarios
Intercept is the best option IMO, but I can see with your POM structure you sometimes need to wait for the alias and sometimes not.
Easiest way forward is making wait on intercept optional,
Cypress.Commands.add('login', (username, password, waitForUrl = false) => {
lp.fillUsername(username);
lp.fillPassword(password);
cy.intercept('/portal/api/login').as('login') // ignored if not waited on
lp.clickLogin();
if (waitForUrl) {
cy.wait('@login')
}
lp.checkForAgreementPage();
});
it('TC01 - Login with valid data as wholesaler', () => {
cy.login(id.username, id.password, true); // for valid data
cy.visit('/users');
cy.logout();
});
it('TC05 - Login with username but no password ', () => {
cy.login(id.username, id.password); // For invalid data
cy.expected('span', 'Invalid username or password');
});
Shows one of the problems when you try to encapsulate things too much, the logic gets a bit fixed in the "happy path".
