如何在 Cypress 中为特定的 GraphQL 请求设置别名? [英] How can I alias specific GraphQL requests in Cypress?

查看:22
本文介绍了如何在 Cypress 中为特定的 GraphQL 请求设置别名?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 Cypress 中,您可以使用别名

仔细阅读文档后,似乎没有办法使用请求正文中的 operationName 为 graphQL 端点设置别名.我还将 operationName(黄色箭头)作为响应标头中的自定义属性返回;但是,我也没有找到一种方法来使用它来为特定的 graphQL 查询设置别名.

失败的方法 1:此方法尝试使用图像中显示的紫色箭头.

cy.server();cy.route({方法:'POST',网址:'/graphql',onResponse(reqObj) {如果(reqObj.request.body.operationName === 'editIpo'){cy.wrap('editIpo').as('graphqlEditIpo');}},});cy.wait('@graphqlEditIpo');

此方法不起作用,因为 graphqlEditIpo 别名是在运行时注册的,因此,我收到的错误如下.

<块引用>

CypressError:cy.wait() 找不到注册的别名:'@graphqlEditIpo'.可用的别名是:'ipoInitial, graphql'.

失败的方法 2:此方法尝试使用图像中显示的黄色箭头.

cy.server();cy.route({方法:'POST',网址:'/graphql',标题:{'操作名称':'editIpo',},}).as('graphql');cy.wait('graphql');

此方法不起作用,因为 cy.route 的选项对象中的 headers 属性实际上是为了根据 文档.在这里,我试图用它来识别我的特定 graphQL 查询,这显然不起作用.

这引出了我的问题:如何在 Cypress 中为特定的 graphQL 查询/突变设置别名?我错过了什么吗?

解决方案

6.0.0 中引入的 intercept API 通过请求处理函数支持这一点.我在我的代码中像这样使用它:

cy.intercept('POST', '/graphql', req => {if (req.body.operationName === 'queryName') {req.alias = 'queryName';} else if (req.body.operationName === 'mutationName') {req.alias = 'mutationName';}否则如果(...){...}});

其中 queryNamemutationName 是您的 GQL 操作的名称.您可以为要别名的每个请求添加附加条件.然后你可以像这样等待他们:

//等待单个请求cy.wait('@mutationName');//等待多个请求.//如果同时触发多个请求,例如在页面加载时,则很有用.cy.wait(['@queryName, @mutationName',...]);

文档在这里有一个类似的例子:https://docs.cypress.io/api/commands/intercept.html#Aliasing-individual-requests.

In Cypress, it is well-documented that you can alias specific network requests, which you can then "wait" on. This is especially helpful if you want to do something in Cypress after a specific network request has fired and finished.

Example below from Cypress documentation:

cy.server()
cy.route('POST', '**/users').as('postUser') // ALIASING OCCURS HERE
cy.visit('/users')
cy.get('#first-name').type('Julius{enter}')
cy.wait('@postUser')

However, since I'm using GraphQL in my app, aliasing no longer becomes a straightforward affair. This is because all GraphQL queries share one endpoint /graphql.

Despite it not being possible to differentiate between different graphQL queries using the url endpoint alone, it is possible to differentiate graphQL queries using operationName (refer to following image).

Having dug through the documentation, there doesn't appear to be a way to alias graphQL endpoints using operationName from the request body. I'm also returning the operationName (yellow arrow) as a custom property in my response header; however, I haven't managed to find a way to use it to alias specific graphQL queries either.

FAILED METHOD 1: This method attempts to use the purple arrow shown in image.

cy.server();
cy.route({
    method: 'POST',
    url: '/graphql',
    onResponse(reqObj) {
        if (reqObj.request.body.operationName === 'editIpo') {
            cy.wrap('editIpo').as('graphqlEditIpo');
        }
    },
});
cy.wait('@graphqlEditIpo');

This method doesn't work since the graphqlEditIpo alias is registered at runtime and as such, the error I receive is as follows.

CypressError: cy.wait() could not find a registered alias for: '@graphqlEditIpo'. Available aliases are: 'ipoInitial, graphql'.

FAILED METHOD 2: This method attempts to use the yellow arrow shown in image.

cy.server();
cy.route({
    method: 'POST',
    url: '/graphql',
    headers: {
        'operation-name': 'editIpo',
    },
}).as('graphql');
cy.wait('graphql');

This method doesn't work because the headers property in the options object for cy.route is actually meant to accept response headers for stubbed routes per the docs. Here, I'm trying to use it to identify my specific graphQL query, which obviously won't work.

Which leads me to my question: How can I alias specific graphQL queries/mutations in Cypress? Have I missed something?

解决方案

The intercept API introduced in 6.0.0 supports this via the request handler function. I used it in my code like so:

cy.intercept('POST', '/graphql', req => {
  if (req.body.operationName === 'queryName') {
    req.alias = 'queryName';
  } else if (req.body.operationName === 'mutationName') {
    req.alias = 'mutationName';
  } else if (...) {
    ...
  }
});

Where queryName and mutationName are the names of your GQL operations. You can add an additional condition for each request that you would like to alias. You can then wait for them like so:

// Wait on single request
cy.wait('@mutationName');

// Wait on multiple requests. 
// Useful if several requests are fired at once, for example on page load. 
cy.wait(['@queryName, @mutationName',...]);

The docs have a similar example here: https://docs.cypress.io/api/commands/intercept.html#Aliasing-individual-requests.

这篇关于如何在 Cypress 中为特定的 GraphQL 请求设置别名?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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