Cypress で Fetch リクエストを wait する
E2E テストスイートの Cypress で、Fetch API を利用したリクエストのレスポンスを cy.wait()
するための設定を記載しています。
何が問題?
Cypress でウェブページ上で行われる HTTP リクエストの完了まで、次のテスト処理の実行を待機する場合 cy.wait()
を利用しますが、デフォルトでは XMLHttpRequest で行われるリクエストしか待機することができません (Cypress 5.x 系まで)。
しかしながら、最近は XMLHttpRequest ではなく、Fetch API を利用したリクエスト処理を実装しているウェブアプリケーションも多いかと思います。
GraphQL サーバーへのリクエストによく用いられる apollo-client も、query や mutation に Fetch を利用しており、そのままでは Cypress のテストケース内で GraphQL サーバーからのレスポンスを待って判定処理を行う、といったことができません。
以下では、Cypress の v4.9.0 - 5.x 系と、v6.0.0 以降それぞれの対応方法を説明します。
Cypress v4.9.0 - v5.x 系
設定
{
"experimentalFetchPolyfill": true
}
experimentalFetchPolyfill
を cypress.json
で有効にすることで、Fetch を利用したリクエストをキャッチすることができるようになります。
利用方法 (v4.9.0 - v5.x)
context('Fetch Test', () => {
cy.server();
// GraphQL
cy.route('POST', '/graphql').as('graphql');
// …
it('wait fetch', () => {
cy.visit('/');
// …
cy.get('[data-cy=new-button]').click();
// Wait Fetch Response
cy.wait('@graphql');
// …
});
// …
});
Cypress v6.x 系
Cypress 6.0.0 では上記の experimentalFetchPolyfill
が廃止され、
cy.server()
および cy.route()
の代わりとなる cy.intercept()
というメソッドが導入されました。
利用方法 (v6.x)
context('Fetch Test', () => {
// GraphQL
cy.intercept('POST', '/graphql').as('graphql');
// …
it('wait fetch', () => {
cy.visit('/');
// …
cy.get('[data-cy=new-button]').click();
// Wait Fetch Response
cy.wait('@graphql');
// …
});
// …
});
cy.intercept()
はブラウザのリクエスト処理に割り込める、高機能なメソッドとして用意されていますが、基本的には cy.route()
の置き換えで動作できます。また、 cy.server()
は不要となりました。
おわり
上記のような設定・コードで無事、GraphQL の query や mutation のレスポンスが返ってきてから、以降のテストを進める、ということができるようになりました。