I have a class with method performing login
LoginPage.js
class loginPage {
fillCredentials(username, password) {
cy.get('[id=username]').type(username);
cy.get('[id=password]').type(password);
return this;
}
clickLogin() {
cy.contains("Login").click();
}
}
export default loginPage;
I have another spec file for testing:
login.spec.js
import {fillCredentials,clickLogin} from '../../support/PageObjects/loginPage'
describe('User Onboarding Emails', () => {
it('Verification email', () => {
cy.visit('/')
fillCredentials('username','password')
clickLogin()
});
});
However, it is giving an error of
(0 , _loginPage.fillCredentials) is not a function
I know its a wrong way of calling a method. Is there any way I can use the methods without creating an instance of class to access methods
CodePudding user response:
So, what's going on is that you are mixing up the module structure with is defined by Closures with the class-instance pattern.
For this scenario (which is class-instance) the functions are NOT part of the object itself, but of it's PROTOTYPE.
So in order to get that function you should access it's prototype.
//create a class (class syntax and this one is pretty much the same)
function xx (){}
//this is what class syntax makes to create a method for the class
xx.prototype.theFunctionIwant = function (){}
//create an instance
var example = new xx()
//this is how you can spy that function in the test
xx.prototype.theFunctionIwant
//ƒ (){}
Try it out : )
CodePudding user response:
You can do so if you make the methods static
class loginPage {
static fillCredentials(username, password) {
cy.get('[id=username]').type(username);
cy.get('[id=password]').type(password);
//return this; // you can't return "this" because there is no this for static methods
}
static clickLogin() {
cy.contains("Login").click();
}
}
export default loginPage;
import {fillCredentials,clickLogin} from '../../support/PageObjects/loginPage'
describe('User Onboarding Emails', () => {
it('Verification email', () => {
cy.visit('/')
fillCredentials('username','password')
clickLogin()
});
});
With static methods you lose this which refers to the class instance, and therefore lose the ability to chain methods,
import {fillCredentials,clickLogin} from '../../support/PageObjects/loginPage'
describe('User Onboarding Emails', () => {
it('Verification email', () => {
cy.visit('/')
fillCredentials('username','password').clickLogin() // can't do this with static
});
});
CodePudding user response:
The other answers given will work, but if you are trying to implement something like the Page-Object model, they are missing the mark. Instead of marking the functions as static, you'll want to instantiate the class before calling the functions.
//LoginPage.js
export class LoginPage { ... }
//login.spec.js
import { LoginPage } from '../../support/PageObjects/loginPage';
describe('User Onboarding Emails', () => {
it('Verification email', () => {
const loginPage = new LoginPage()
cy.visit('/')
loginPage.fillCredentials('username','password')
loginPage.clickLogin()
});
});
You could also use a beforeEach() block to instantiate the variable before each test.
describe('User Onboarding Emails', () => {
let loginPage: LoginPage;
beforeEach(() => {
loginPage = new LoginPage();
});
it('Verification email', () => {
...
});
})
As an aside, it is usually preferred to name classes beginning with an uppercase (LoginPage vs. loginPage). When naming a class this way, you can easily differentiate the class vs. the instantiated variable.
