0

实际上,我可以通过浏览所有表单、输入用户名、密码并单击登录按钮来测试我在 Cypress 中的应用程序的登录。

这在我的浏览器中的(应用程序)IndexedDB - ngStorage - localStorage 部分中设置了令牌。因为我用的是@ngx-pwa/local-storage插件。

然后赛普拉斯就可以进入我的应用程序的主页。

但是如何在浏览器中设置令牌,而不使用 UI?

我尝试使用localForage插件,但它在我的浏览器的 localForage 部分设置了令牌。而且我的应用程序无法读取我的令牌。

我尝试使用window.localStorage.setItem('token', myToken);,但它在我的浏览器的 localStorage 中设置了令牌。

如何将我的令牌设置在合适的位置:(应用程序)IndexedDB - ngStorage - localStorage

4

1 回答 1

0

我还没有找到解决方案,尽管@ngx-pwa/local-storage许多使用 Angular 编程的人都使用该插件。

我不知道是否有比这个更好、更清洁的解决方案。

我用过window

赛普拉斯/支持/window-helper.ts


export class WindowHelper {
  static addLocalStorage(
    window: Cypress.AUTWindow,
    key: string, 
    value: any
  ): Promise<IDBRequest<IDBValidKey>> {
    return WindowHelper.openNgStorage(window)
    .then(
      (store: IDBObjectStore) => store.add(value, key)
    );
  }
  
  static async getLocalStorage(
    window: Cypress.AUTWindow
  ): Promise<Map<string, JSONValue>> {

    const openCursor: IDBRequest<IDBCursorWithValue> = await WindowHelper
    .openNgStorage(window)
    .then(
      (store: IDBObjectStore) => store.openCursor()
    );

    let objects: Map<string, JSONValue> = new Map<string, JSONValue>();

    return new Promise((resolve, reject) => {
      openCursor.onsuccess = (event) => {
        const cursor: IDBCursorWithValue = event.target['result'];

        if (cursor) {
          objects.set(cursor.key.toString(), cursor.value);
          cursor.continue();
        }
        else {
          resolve(objects)
        }
      };
      openCursor.onerror = () => {
        const errorMessage = {
          title: 'Failed to open cursor',
          this: openCursor,
          function: 'getLocalStorage',
          result: openCursor.result
        }
        console.error(errorMessage);
        reject(errorMessage);
      }
    })
  }

  private static openNgStorage(window: Cypress.AUTWindow): Promise<IDBObjectStore> {
    const open: IDBOpenDBRequest = window.indexedDB.open("ngStorage");

    return new Promise(
      (resolve, reject) => {
        open.onsuccess = () => {
          resolve(
            open.result
            .transaction("localStorage", "readwrite")
            .objectStore("localStorage")
          );
        }
        open.onerror = () => {
          const errorMessage = {
            title: 'Failed to open localStorage',
            this: open,
            function: 'addLocalStorage',
            result: open.result
          }
          console.error(errorMessage);
          reject(errorMessage);
        }
      }
    );
  }
}

赛普拉斯/支持/commands.ts

import { WindowHelper } from './window-helper'

Cypress.Commands.add('getAndSetToken', () => {
  Cypress.log({
    message: 'Requests token and sets in local storage (IndexedDB.ngStorage.localStorage)',
    displayName: 'GetToken'
  });

  let result: Token;

  return cy.signin().then((response: Cypress.Response<JSONObject>) => {
    const {
      token
    } = response.body;
    result = token as string;

    return cy.addLocalStorage('token', token)
  })
  .then(() => result);
});

Cypress.Commands.add('addLocalStorage', (key: string, value: JSONValue) => {
  return cy.window()
  .then(
    (window: Cypress.AUTWindow) => 
      WindowHelper.addLocalStorage(window, key, value)
  )
});

Cypress.Commands.add('getLocalStorage', () => {
  return cy.window()
  .then(
    (window: Cypress.AUTWindow) =>
      WindowHelper.getLocalStorage(window)
      .then((map) => Object.fromEntries(map))
  )
});

赛普拉斯/支持/index.ts

declare global {
  namespace Cypress {
    interface Chainable {

      /**
     * Custom command to get and set token to browser localStorage
     * requested from back.
     * @return string token 
     * @example cy.getAndSetToken()
     */
      getAndSetToken(): Chainable<Token>

      /**
     * Custom command to get and set token to browser localStorage (IndexedDB.ngStorage.localStorage)
     * requested from back.
     * @example cy.addLocalStorage('token', 'my-token-value')
     */
      addLocalStorage(key: string, value: any): Chainable<IDBRequest<IDBValidKey>>

      /**
     * Custom command to get and set token to browser localStorage (IndexedDB.ngStorage.localStorage)
     * requested from back.
     * @example cy.getLocalStorage()
     */
       getLocalStorage(): Chainable<JSONObject>
    }
  } 
}

在规范文件中使用

  describe('signin without UI', () => {
    beforeEach(() => {
      cy.getAndSetToken()
    })
  
    it('logs in programmatically without using the UI', () => {
      cy.visit('/')
    })
  })

这个主题对我有帮助:链接

感谢rajd90

于 2022-01-03T11:31:44.970 回答