i was connfused when i watched the guide on the official website.
i dont know how to configure it.
i should add the sample to where?
and my case is that i need a sms code and picture code to login
I followed the guide and still don’t quite understand how it works. I added a ‘login’ function to the actor({}) object returned in the function in steps_file.js. I still just keep getting Object of type login is not defined in container
I think a more concrete example would be helpful here.
Scouring the net for answers as we speak
If you are using autoLogin plugin then, you will need a config placed in the plugins section specifically for your autoLogin.
Example:
autoLogin: {
enabled: true,
saveToFile: true,
inject: 'loginAs', // use `loginAs` instead of login
users: {
admin: {
login: (I) => {
I.amOnPage('/login-menu');
I.fillField('#login_email', cfg.personas.Admin.username);
I.fillField('#login_password', cfg.personas.Admin.pwd);
I.click('#login_login');
},
check: (I) => {
I.seeInCurrentUrl('/admin/');
},
},
servicePro: {
login: (I) => {
I.amOnPage('/login-menu');
I.fillField('#login_email', cfg.personas.servicePro.username);
I.fillField('#login_password', cfg.personas.servicePro.pwd);
I.click('#login_login');
},
check: (I) => {
I.seeInCurrentUrl('/service-pro/new-service-requests');
},
},
consumer: {
login: (I) => {
I.amOnPage('/login-menu');
I.fillField('#login_email', cfg.personas.consumer.username);
I.fillField('#login_password', cfg.personas.consumer.pwd);
I.click('#login_login');
},
check: (I) => {
I.seeInCurrentUrl('/consumer/my-projects');
},
},
},
},
Then in your test you call it as follows:
Given('I login as a Service Pro', async () => {
await loginAs('servicePro');
});
If you are using the Actor approach this is a bit different.
Actor Example:
module.exports = function () {
return actor({
// Define custom steps here, use 'this' to access default methods of I.
// It is recommended to place a general 'login' function here.
async login() {
this.amOnPage(`/?sba_transferToken=${conf.testAccount.ssoTransferToken}`);
const balance = await this.grabTextFrom(loginComponent.headerBar);
if (typeof balance !== 'string') {
output.error('Balance not found, login failed');
}
console.log(`Logged in as user: ${conf.testAccount.userName}`);
},
});
};
In your tests you use it like this:
Before(async () => {
await I.login();
});
Hello and thanks for the example.
Why do you use:
check: (I) => {
I.seeInCurrentUrl('/admin/');
},
Instead of:
check: (I) => {
I.waitForVisible(''selector');
},
I am trying to use the second approach by checking if a UI-element exists, and the test passes even thought I it shouldn’t login because of wrong credentials.
This is my autoLogin plugin configuration and I expect it not to pass as soon as I have put invalid credentials. So the check should not pass
autoLogin: {
enabled: true,
saveToFile: true,
inject: 'LoginAs',
users: {
admin: {
// loginAdmin function is defined in `steps_file.js`
login: async (I) => await I.loginAdmin(),
// if we see `Admin` on page, we assume we are logged in
check: (I) => {
I.waitForVisible('#navItem_1204785325 > a > div');
}
}
}
}
Oh that was mainly an example, I prefer using a lot more robust solutions for checks. After login in my case, the check has multiple validations to ensure everything worked as expected. I consider waiting for URL change not enough or not a good enough practice to rely solely on it.
As a recommendation I would suggest not using locators like this #navItem_1204785325 > a > div
because they increase flakiness of tests. if the a
element disappears from the chain your locator will fail and thus your test with it. However a more robust and reliable locator that would work even with UI elements being removed or added is either
- targeting the div directly with some specific attributes if it has them
- if the div does not have extra attributes you can add them yourself or ask the devs to do it for you
- use something like this instead
#navItem_1204785325 div
it works exactly the same without the reliance on the existence of thea
element.
I usually go for options 2 or 3