I want to create a one login function that accepts user name and password of Auth Dialog using .httpAuth in helper.js in TestCafe. How I can create the function so that I can use it wherever the login is required.
Please note that the .httpAuth method can be used as a method of fixture or test.
If I understand you correctly, you want to use some imported {username, password} object with HTTP Autentication.
It can be reached by using import from a helper file:
authHelper.js
const authCredentials = {
username: 'username',
password: 'password'
}
export default authCredentials;
test-1.js
import auth from './authHelper'
fixture `My fixture 1`
.page `http://example.com`
.httpAuth(auth);
test('Test1', async t => {}); // Logs in as username
test-2.js
import auth from './authHelper'
fixture `My fixture 2`
.page `http://example.com`;
test
.httpAuth(auth)
('Test1', async t => {}); // Logs in as username
Related
According to the Cypress Cucumber Preprocessor docs regarding Before and After hooks:
The cypress-cucumber-preprocessor supports both Mocha's before/beforeEach/after/afterEach hooks and Cucumber's Before and After hooks.
However for some reason it doesn't seem to support the Cucumber's BeforeAll and AfterAll hooks. This is somewhat problematic for me. I'm currently trying to write some API tests that need to use an auth token that can only be obtained by manually logging in to the site first.
Ideally I would like my tests to log in through the UI only once, grab the auth token, and then run all of my API tests using that auth token.
I have all of these API scenarios tagged with #api and would love to be able to use a BeforeAll({ tags: '#api' }, () => { function (or equivalent) to have my Cypress tests log in and grab the auth token for use in those scenarios. However it seems like my only options are:
Use Before instead of BeforeAll (which would force me to login through the UI for every single scenario with the #api tag even though should I only need to do it once)
Use a Background on the feature file (which has the same problem)
Use Mocha's before hook instead of Cucumber's (which unfortunately doesn't support tagging and therefore would run before every feature file, instead of just the ones I have tagged)
Is there no way to replicate the Cucumber BeforeAll functionality with Cypress-Cucumber-Preprocessor?
The way I would approach the problem is to flag the first login in the run, and prevent the login code from running once the flag is set.
let loggedIn = false;
Before(() => {
const tags = window.testState.pickle.tags.map(tag => tag.name)
if (tags.includes('#api') && !loggedIn) {
loggedIn = true
console.log('logging in') // check this is called once
// do the login
}
})
You should also be able to get the same effect by wrapping the login code in a cy.session(), which is a cache that only runs it's callback once per run.
Before(() => {
const tags = window.testState.pickle.tags.map(tag => tag.name)
if (tags.includes('#api')) {
cy.session('login', () => {
console.log('logging in') // check this is called once
// do the login
})
}
})
Update from #rmoreltandem
This syntax is simpler
let loggedIn = false;
Before({ tags: '#api' }, () => {
if (!loggedIn) {
loggedIn = true
console.log('logging in') // check this is called once
// do the login
}
})
with session
Before({ tags: '#api' }, () => {
cy.session('login', () => {
console.log('logging in') // check this is called once
// do the login
})
})
I've been working with Testcafe and have had some issues working with multiple "Fixtures" or "Tests" from within the same "file".
IE TESTFILE.js:
import { Selector, Role } from 'testcafe';
import Games from '../Pages/Games.js'
import {partnerAdmin} from '../Data/Roles.js'
const config = require('../Data/config.json')
fixture `Test Fixture #1`
.page `${config.envs.dev.baseUrl}`
test('Testing Test #1', async t => {
await t
.useRole(partnerAdmin)
await t
.expect(Selector(Games.gamesList).exists).ok()
.expect(Selector(Games.topRowGame).exists).ok()
.click(Games.gameActionsBtn)
});
fixture `Test Fixture #2`
.page `${config.envs.dev.baseUrl}`
test('Testing Test #2', async t => {
await t
.useRole(partnerAdmin)
await t
// DO OTHER STUFF
});
When I try this the 1st fixture will run perfectly... HOWEVER, the 2nd Fixture will stop at the login page. It's as if the 'useRole' function is failing the second time it's getting called.
I'm using the Roles as followed in the documentation.
IE Roles.js:
import { Selector, Role, t } from 'testcafe';
import Login from '../Pages/Login.js'
const config = require('../Data/config.json')
const partnerAdmin = Role(`${config.envs.dev.baseUrl}`, async t => {
await
Login.login(config.users.partnerAutoAdmin.name, config.users.partnerAutoAdmin.pass)
});
export { partnerAdmin }
It doesn't matter the order I place the "Fixtures" or "Tests" in. I can literally swap the 2nd fixture to before the 1st and it still does the same thing. The first runs, but the second just straight up fails as if it can't remember what it just did when it hits the login page the second time.
Anyone have any idea what I might be missing here? I'm using Roles and page models that seem to be working normally. Unfortunately the first test runs, but fails to continue on through the second for some reason even if I did just duplicate the same login/roles setup.
New to TestCafe. Got some simple example tests working easily. However, I wasn't able to find any examples of features that would seem to allow me to log in to my application via a CAS authentication page.
This code works to find the login button on the login page and click it.
fixture`VRT`
.page `http://myapp.com/login/`;
test('Find Login button', async t => {
const input = Selector('input.btn');
await t.click(input);
});
And this would work to type in the username and password on the login page:
test('Login using CAS', async t => {
await t
.expect("#username").exists
.typeText('#username', 'myuser')
.typeText('#password', '***')
.click('#submit');
});
But the problem is that there seems to be no way to continue from one test to another. So I can't go from the first test that opens the login page, to the next test that enters the credentials. It seems like, for TestCafe, every test has to specify its own page.
If I try to go to the CAS login page directly, by specifying it as the fixture "page", TestCafe fails to open the page, I think because the URL is extremely long.
Thanks for any suggestions.
Update:
So, using roles got me a bit further (thanks) but had to get through one more CAS page with an input button to click before getting to the page I wanted to test. Was able to add in another click to the role login:
import { Role } from 'testcafe';
import { Selector } from 'testcafe';
const finalLoginBtn = Selector('input.btn');
const myUserRole = Role('http://example.com/login', async t => {
await t
.click('input.btn')
.typeText('#username', 'my-username')
.typeText('#password', '*****')
.click('#submit')
.click(finalLoginBtn);
}, { preserveUrl: true });
fixture`VRT`
test("My User Page", async t => {
await t.navigateTo(`http://example.com`)
await t.useRole(myUserRole);
});
The TestCafe 'User Roles' functionality should suit your requirements. Please, refer to the following topic in the TestCafe documentation for details: https://devexpress.github.io/testcafe/documentation/test-api/authentication/user-roles.html
I use the Testcafe roles in my script to avoid new logins each test inside a fixture. It works really good, but I run into a problem where I cannot find any solution.
If I use the role to log in into the page and I use the common page functions to logout of the page, it means to click the selector Logout, then the upcoming script still thinks that the role is still logged in and the test fails.
As sample:
test('Login und Logout', async t => {
const loginheader = Selector('.login-header')
await t
.useRole(bc3Tester)
.navigateTo(inputStore.metaUrl)
.click(Selector('.cl-sidemenu-button'))
.click(Selector('.side-menu-logout.cl-asset-button-animation'))
await t
.wait(2000)
.expect(loginheader.exists).ok()
});
If I run this test a second time it will fail at
.click(Selector('.cl-sidemenu-button'))
because the role script not work (No auto login again)
const bc3Tester = Role(inputStore.metaUrl, async t => {
await t
.typeText(Selector('#email'), inputStore.clLogin, {
caretPos: 0
})
.typeText(Selector('#password'), inputStore.clPassword, {
caretPos: 0
})
.click(Selector('span').withText('Login'))
});
Because it will not log in. Any idea?
I wonder how can I use one of my test case (test file also) (assume that tests are separated as one test for one file. I mean all js files includes only one test case).
It will be very good if I can use one of my test case(test file) inside fixture so that before a test starts it can prepare my environment with another test.
Suppose that my fixture is like below
import LoginPage from '../../../pages/login-page';
fixture `Regression - UI`
.page(DOMAIN)
.beforeEach(async t => {
await t.maximizeWindow()
await loginPage.login(t, EMAIL, PASSWORD);
});
so what I want to do is execute another test after login is executed then run test Adding a new item test
test(`Adding a new creative`, async t => {
await leftNavigation.clickCampaignSection(t)
await leftNavigation.clickAllCampaigns(t)
}
so the fixture will gonna like below and EXECUTE.ANOTHER.TEST will gonna executed
import LoginPage from '../../../pages/login-page';
import EXECUTE.ANOTHER.TEST from ../another_test_file.js
fixture `Regression - UI`
.page(DOMAIN)
.beforeEach(async t => {
await t.maximizeWindow()
await loginPage.login(t, EMAIL, PASSWORD);
await EXECUTE.ANOTHER.TEST
});
You can not execute a test in other test or in one of a fixture hooks (beforeEach, afterEach). You need to create a separate method (leftNavigation.addNewCreative) with appropriate logic and call it when it's necessary.