如何在 Cypress 的 E2E 测试中登录 Auth0? [英] How to login in Auth0 in an E2E test with Cypress?

查看:30
本文介绍了如何在 Cypress 的 E2E 测试中登录 Auth0?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经开始测试 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.

Because Cypress changes its own host URL to match that of your applications, it requires that your application remain on the same superdomain for the entirety of a single 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆