Как протестировать одностраничное приложение с Cypress и Auth0 - PullRequest
0 голосов
/ 09 января 2020

У меня одностраничное приложение, спрятанное за блокировкой Auth0, использующее @ auth0 / auth0-spa- js. Я хотел бы протестировать его с помощью Cypress, поэтому я решил следовать официальному сообщению Auth0 , а также сообщению Джонни Рейли .

Я могу чтобы успешно получить действительный токен JWT из auth0, используя предложенный запрос. Я понятия не имею, что с этим делать: (

Проблема, с которой я сталкиваюсь, заключается в том, что оба вышеупомянутых подхода полагаются на приложение для локального хранения токена JWT (либо в cook ie, либо в localalstorage) Однако @ auth0 / auth0-spa- js использует другой подход, и я предполагаю, что все соответствующие файлы cookie / localalstorage хранятся в доменах auth0.

Делаете ли вы есть какие-то идеи, если есть способ обойти это?

Есть аналогичная проблема, о которой сообщалось здесь , поднятая в июле 2018 года, на самом деле не предоставляющая никакого решения

Ответы [ 2 ]

1 голос
/ 13 января 2020

Я нашел решенную проблему на @auth0/auth0-spa-js github. Подход , предложенный cwmrowe , кажется работает

Подход, кажется, работает для нас

Я копирую образец кода cwmrowe предоставил

Cypress.Commands.add(
  'login',
  (username, password, appState = { target: '/' }) => {
    cy.log(`Logging in as ${username}`);
    const options = {
      method: 'POST',
      url: Cypress.env('Auth0TokenUrl'),
      body: {
        grant_type: 'password',
        username,
        password,
        audience: Cypress.env('Auth0Audience'),
        scope: 'openid profile email',
        client_id: Cypress.env('Auth0ClientId'),
        client_secret: Cypress.env('Auth0ClientSecret')
      }
    };
    cy.request(options).then(({ body }) => {
      const { access_token, expires_in, id_token } = body;

      cy.server();

      // intercept Auth0 request for token and return what we have
      cy.route({
        url: 'oauth/token',
        method: 'POST',
        response: {
          access_token,
          expires_in,
          id_token,
          token_type: 'Bearer'
        }
      });

      // Auth0 SPA SDK will check for value in cookie to get appState
      // and validate nonce (which has been removed for simplicity)
      const stateId = 'test';
      const encodedAppState = encodeURI(JSON.stringify(appState));
      cy.setCookie(
        `a0.spajs.txs.${stateId}`,
        `{%22appState%22:${encodedAppState}%2C%22scope%22:%22openid%20profile%20email%22%2C%22audience%22:%22default%22}`
      );

      const callbackUrl = `/auth/callback?code=test-code&state=${stateId}`;
      return cy.visit(callbackUrl);
    });
  }
);

declare namespace Cypress {
  interface Chainable<Subject> {
    login(
      username: string,
      password: string,
      appState?: any
    ): Chainable<Subject>;
  }
}
0 голосов
/ 13 января 2020

Хотя не рекомендуется использовать пользовательский интерфейс для входа в систему, я сам делаю это один раз перед всеми тестами, а затем использую автоматическую аутентификацию для тестов: - cy.visit("/") тихая авторизация и позволяет получить доступ к приложению.

интеграция / приложение. js

describe("App", () => {
  before(() => {
    Cypress.config("baseUrl", "http://localhost:3000");
    cy.login();
  });

  /** Uses silent auth for successive tests */
  beforeEach(() => {
    cy.restoreLocalStorage();
  });

  afterEach(() => {
    cy.saveLocalStorage();
  });

  /** tests */

поддержка / команды. js

/**
 * Auth0 login
 * https://github.com/cypress-io/cypress/issues/461#issuecomment-392070888
 *
 * Allows silent auth login between tests
 */
let LOCAL_STORAGE_MEMORY = {};

Cypress.Commands.add("saveLocalStorage", () => {
  Object.keys(localStorage).forEach(key => {
    LOCAL_STORAGE_MEMORY[key] = localStorage[key];
  });
});

Cypress.Commands.add("restoreLocalStorage", () => {
  Object.keys(LOCAL_STORAGE_MEMORY).forEach(key => {
    localStorage.setItem(key, LOCAL_STORAGE_MEMORY[key]);
  });
});

Cypress.Commands.add("clearLocalStorage", () => {
  LOCAL_STORAGE_MEMORY = {};
});
...