cypress - 如何在 Cypress 测试中等待成功响应

标签 cypress e2e-testing

背景

我使用 3 台后端服务器为我的一个在线 SaaS 应用程序提供容错功能。所有重要的 API 调用,例如获取用户数据,联系所有 3 个服务器并使用第一个成功解析的响应的值,如果有的话。

export function getSuccessValueOrThrow$<T>(
        observables$: Observable<T>[],
        tryUntilMillies = 30000,
    ): Observable<T> {
        return race(
            ...observables$.map(observable$ => {
                return observable$.pipe(
                    timeout(tryUntilMillies),
                    catchError(err => {
                        return of(err).pipe(delay(5000), mergeMap(_err => throwError(_err)));
                    }),
                );
            })
        );
    }

getSuccessValueOrThrow$ 调用如下:

const shuffledApiDomainList = ['server1-domain', 'server2-domain', 'server3-domain';
const sessionInfo = await RequestUtils.getSuccessValueOrThrow(
                        ...(shuffledApiDomainList.map(shuffledDomain => this.http.get<SessionDetails>(`${shuffledDomain}/file/converter/comm/session/info`))),
                    ).toPromise();

注意:如果一个请求解析得比其他请求快,通常情况下,race rxjs 函数将取消其他两个请求。在 Chrome 开发网络选项卡上,它会如下所示,其中发送的第一个请求由于速度太慢而被取消。

enter image description here

问题:

我使用 /file/converter/comm/session/info(我们称之为端点 1)来获取与用户相关的一些数据。此请求分派(dispatch)到所有 3 个后端服务器。如果一个 resolve,那么剩下的 2 个请求将被取消,即它们将返回 null。

在我的 Cypress E2E 测试中,我有

cy.route('GET', '/file/converter/comm/session/info').as('getSessionInfo');
cy.visit('https://www.ps2pdf.com/compress-mp4');
cy.wait('@getSessionInfo').its('status').should('eq', 200)

如果 getSessionInfo 别名连接到最终被 getSuccessValueOrThrow$ 取消的请求,这有时会失败,因为它不是成功的请求。下图显示了 3 个请求中的 1 个别名为 getSessionInfo 成功但测试失败,因为第一个请求失败。

enter image description here

在 Cypress 中,我如何等待成功,即 status = 200 请求?

最佳答案

方法一

如果状态不是 200,则使用 .should() 回调并重复 cy.wait 调用:

function waitFor200(routeAlias, retries = 2) {
  cy.wait(routeAlias).then(xhr => {
    if (xhr.status === 200) return // OK
    else if (retries > 0) waitFor200(routeAlias, retries - 1); // wait for the next response
    else throw "All requests returned non-200 response";
  })
}

// Usage example.
// Note that no assertions are chained here,
// the check has been performed inside this function already.
waitFor200('@getSessionInfo'); 

// Proceed with your test
cy.get('button').click(); // ...

方法二

首先修改您要测试的内容。 很有可能——页面上有一些东西告诉用户操作成功。例如。显示/隐藏微调器或进度条,或者只是更新页面内容以显示从后端获取的新数据。

因此,在这种方法中,您将完全删除 cy.wait(),并专注于用户在页面上看到的内容 - 对实际页面内容做一些断言。

关于cypress - 如何在 Cypress 测试中等待成功响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61720653/

相关文章:

jquery - 如何在 TestCafe 中单击 jQuery 对话框按钮

testing - 如何在 Cypress 中点击 x 次

javascript - 绕过 SSO 的 cypress 脚本示例

ubuntu - Cypress 无法在 Ubuntu/Linux 上启动

reactjs - 从 CRA+TS 应用程序的源代码导入时,Cypress 测试无法运行

pdf - TestCafe:测试在新选项卡中打开 PDF 的页面

cross-browser - 无需测试即可通过 testcafe 启动浏览器

javascript - 用 Protractor 获取伪元素的值

electron - 有没有办法在 Cypress Electron 浏览器中查看一些日志记录?

browser - 如何使用 Cypress.io 检查和查询出站网络请求?