如何在 Cypress 的 E2E 测试中登录 Auth0? [英] How to login in Auth0 in an E2E test with Cypress?
问题描述
我已经开始测试 React Web 应用程序,但我没有走多远,因为我在登录时遇到了问题.我正在使用
尝试 3. 从网络应用程序以编程方式登录
尝试过:我开始认为 cypress 只是从应用程序发出的间谍请求,而不是从测试本身发出的请求(正如我在上面所尝试的那样).
我在欢迎页面中添加了一个 fake-login 按钮,它将使用硬编码凭据调用 auth0-js
(因此没有域更改)并从测试中单击它
cy.get('#fake-login').click()
问题:该策略有效,但我当然不想在欢迎页面中添加带有凭据的按钮.所以我在测试过程中尝试将button元素添加到webapp中:
it('登录添加元素', () => {cy.visit('http://localhost:3000')const = document.createElement('div')fakeLogin.innerHTML = '假登录'fakeLogin.onclick = function() {const auth = new auth0.WebAuth(authOptions)auth.login(登录选项)}fakeLogin.style.position = '绝对'fakeLogin.style.zIndex = 1000fakeLogin.id = '假登录'cy.get('#root').invoke('prepend', fakeLogin)cy.get('#fake-login').click()cy.get('[class*="hamburger"]').click()//登录后可见})
由于某种原因,这不起作用,添加了元素,但不会等到发出请求.
所以我不知道还能尝试什么.也许一切都是对 E2E 中应该如何登录的误解,我是否应该使用模拟数据以便不需要登录?
你可以关注这个 文章 但对我来说它不起作用.我在这篇文章的帮助下管理了它:
纱线添加 auth0-js --dev
让我们创建一个名为 loginAsAdmin
的自定义命令:
import { WebAuth } from 'auth0.js';Cypress.Commands.add('loginAsAdmin', (overrides = {}) => {赛普拉斯.log({名称:'loginAsAdminBySingleSignOn'});const webAuth = new WebAuth.WebAuth({domain: 'my-super-duper-domain.eu.auth0.com',//从 https://manage.auth0.com/#/applications 和您的应用程序获取clientID: 'myclientid',//从 https://manage.auth0.com/#/applications 和您的应用程序获取responseType: 'token id_token'});webAuth.client.login({领域:'用户名-密码-身份验证',用户名:'mytestemail@something.co.uk',密码:'SoVeryVeryVery$ecure',Audience: 'myaudience',//从 https://manage.auth0.com/#/apis 和你的 api 获取这个,使用标识符属性范围:'openid 电子邮件配置文件'},功能(错误,authResult){//在结果中验证令牌或错误如果(authResult && authResult.accessToken && authResult.idToken){常量令牌 = {accessToken: authResult.accessToken,idToken: authResult.idToken,//设置访问令牌到期的时间expiresAt: authResult.expiresIn * 1000 + new Date().getTime()};window.sessionStorage.setItem('my-super-duper-app:storage_token', JSON.stringify(token));} 别的 {console.error('登录 Auth0 有问题', err);抛出错误;}});});
使用:
describe('访问秘密管理功能', () => {it('应该能够导航到', () => {cy.visitHome().loginAsAdmin().get('[href="/secret-adminny-stuff"]')//这个链接应该只对管理员可见.点击().url().should('contain', 'secret-adminny-stuff/');//非管理员应该被重定向远离这个 url});});
所有功劳归于 Johnny Reilly
I have started testing a react webapp but I didn't go far because I had issues with the login. I am using cypress e2e testing tool.
A welcome page is shown with a button to login, which will redirect you to auth0
service. User is login with email and password , then is redirected back to the webapp with a token.
I tried many different approach each of them resulting in a different problem.
Note: I don't want to test Auth0, I just want to enter in my webapp.
Attempt 1. Clicking on login button
Tried: Cypress should do the same as what the user does, therefore the test will click login button and go to Auth0 and fill in credentials. Problem: Cypress doesn't allow you to navigate to another domain during the test.
You are supposed to be able to disable that setting setting "chromeWebSecurity": false
in cypress.json
but it will not work yet because you can only visit a single domain with cy.visit()
Attempt 2. Login programmatically from the test
Tried: login from the cypress test with auth0-js
library so it is not needed to click in login button and thus no domain change occurs.
describe('Waiting to fetch', () => {
beforeEach(() => {
this.fetchAuthDeferred = getDeferred()
cy.visit('http://localhost:3000', {
onBeforeLoad(win) {
cy.stub(win, 'fetch')
.withArgs($url)
.as('fetchAuth')
.returns(this.fetchAuthDeferred.promise)
}
})
})
it('login', () => {
cy.visit('http://localhost:3000')
const auth = new auth0.WebAuth(authOptions)
auth.login(loginOptions)
cy.get('@fetchAuth', { timeout: 10000 }).should('haveOwnProperty', 'token')
cy.visit('http://localhost:3000')
cy.get('[class*="hamburger"]').click()
})
})
Problems: cy.route()
doesn't wait for fetch request, a workaround is to use cy.stub(win, 'fetch')
. It won't wait:
Attempt 3. Login programmatically from the webapp
Tried: I started to think that cypress only spy request made from the app and not from the test itself (as I tried in the point above).
I added a fake-login button in the welcome page which will call auth0-js
(so no domain change) with hardcoded credentials and click it from the test
cy.get('#fake-login').click()
Problems: that strategy worked, but of course I don't want to add a button with credential in the welcome page. So I tried adding the button element to the webapp during the test:
it('Login adding element', () => {
cy.visit('http://localhost:3000')
const = document.createElement('div')
fakeLogin.innerHTML = 'Fake login'
fakeLogin.onclick = function() {
const auth = new auth0.WebAuth(authOptions)
auth.login(loginOptions)
}
fakeLogin.style.position = 'absolute'
fakeLogin.style.zIndex = 1000
fakeLogin.id = 'fake-login'
cy.get('#root').invoke('prepend', fakeLogin)
cy.get('#fake-login').click()
cy.get('[class*="hamburger"]').click() // Visible when logged in
})
And for some reason this doesn't work, the element is added but yt will not wait until the request are made.
So I don't know what else to try. Maybe everything is a misunderstanding of how login should be done in E2E, should I work with mock data so login is not needed?
You can follow this article though for me it didn't work. I managed it work with the help of this article:
yarn add auth0-js --dev
Let's create a custom command called loginAsAdmin
:
import { WebAuth } from 'auth0.js';
Cypress.Commands.add('loginAsAdmin', (overrides = {}) => {
Cypress.log({
name: 'loginAsAdminBySingleSignOn'
});
const webAuth = new WebAuth.WebAuth({
domain: 'my-super-duper-domain.eu.auth0.com', // Get this from https://manage.auth0.com/#/applications and your application
clientID: 'myclientid', // Get this from https://manage.auth0.com/#/applications and your application
responseType: 'token id_token'
});
webAuth.client.login(
{
realm: 'Username-Password-Authentication',
username: 'mytestemail@something.co.uk',
password: 'SoVeryVeryVery$ecure',
audience: 'myaudience', // Get this from https://manage.auth0.com/#/apis and your api, use the identifier property
scope: 'openid email profile'
},
function(err, authResult) {
// Auth tokens in the result or an error
if (authResult && authResult.accessToken && authResult.idToken) {
const token = {
accessToken: authResult.accessToken,
idToken: authResult.idToken,
// Set the time that the access token will expire at
expiresAt: authResult.expiresIn * 1000 + new Date().getTime()
};
window.sessionStorage.setItem('my-super-duper-app:storage_token', JSON.stringify(token));
} else {
console.error('Problem logging into Auth0', err);
throw err;
}
}
);
});
To use it:
describe('access secret admin functionality', () => {
it('should be able to navigate to', () => {
cy.visitHome()
.loginAsAdmin()
.get('[href="/secret-adminny-stuff"]') // This link should only be visible to admins
.click()
.url()
.should('contain', 'secret-adminny-stuff/'); // non-admins should be redirected away from this url
});
});
All credit goes to Johnny Reilly
这篇关于如何在 Cypress 的 E2E 测试中登录 Auth0?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!