【问题标题】:Cypress 7.0+ / Override responses in intercept赛普拉斯 7.0+ / 在拦截中覆盖响应
【发布时间】:2021-06-07 10:52:01
【问题描述】:

希望你一切顺利。 我目前正在将 cypress 升级到 7.0。 (更准确地说是 v7.4.0) 我对拦截调用的覆盖有疑问。

赛普拉斯团队似乎致力于解决最重要的问题https://github.com/cypress-io/cypress/pull/14543(问题:https://github.com/cypress-io/cypress/issues/9302),但它对我不起作用。

BREAKING CHANGE: Request handlers supplied to cy.intercept are now matched starting with the most-recently-defined request interceptor. This allows users to override request handlers by calling cy.intercept again. This matches the previous behavior that was standard in cy.route.

我的第一个电话处理 2xx 响应(我自己模拟)

cy.intercept('GET', 'sameUrl', {
statusCode: 2xx
}

但是我需要另一个具有相同 url 但状态不同的拦截:

cy.intercept('GET', 'sameUrl', {
statusCode: 4xx
}

我尝试使用 middlewareA new option, middleware, has been added to the RouteMatcher type. If true, the supplied request handler will be called before any non-middleware request handlers.

cy.intercept({ method: 'GET', url: 'sameUrl', middleware: true}, req => {
    req.continue(res => {
         res.statusCode = 4xx
    });
}

但它不起作用,第一个拦截总是被调用的那个。如果您知道我做错了什么/另一种解决方案,我会全力以赴!

【问题讨论】:

    标签: javascript testing cypress e2e-testing


    【解决方案1】:

    如果我制作一个最小的示例应用程序 + 测试,它会遵循您上面引用的规则。

    测试

    it('overrides the intercept stub', () => {
    
      cy.visit('../app/intercept-override.html')
      
      cy.intercept('GET', 'someUrl', { statusCode: 200 })
    
      cy.get('button').click()
    
      cy.get('div')
        .invoke('text')
        .should('eq', '200')                               // passes
    
      cy.intercept('GET', 'someUrl', { statusCode: 404 })
    
      cy.get('button').click()
    
      cy.get('div')
        .invoke('text')
        .should('eq', '404')                               // passes
    })
    

    应用程序

    <button onclick="clicked()">Click</button>
    <div>Result</div>
    <script>
      function clicked() {
        fetch('someUrl').then(response => {
          const div = document.querySelector('div')
          div.innerText = response.status
        })
      }
    </script>
    

    那么,您的应用有什么不同?


    测试根据 cmets 修改

    测试失败的要点

    • 需要唯一的别名
    • 基于字符串的 url(第二次测试)需要 minimatch 通配符前缀 ** 才能工作
    beforeEach(() => {
      cy.intercept('GET', /api\/test-id\/\d+/, { statusCode: 200 })
        .as('myalias1')
      cy.visit('../app/intercept-overide.html')
    })
    
    it('sees the intercept stub status 200', () => {
      cy.get('button').click()
      cy.wait('@myalias1')
      cy.get('div')
        .invoke('text')
        .should('eq', '200')
    })
    
    it('sees the intercept stub status 404', () => {
      cy.intercept('GET', '**/api/test-id/1', { statusCode: 404 })
        .as('myalias2')
    
      cy.get('button').click()
      cy.wait('@myalias2')
      cy.get('div')
        .invoke('text')
        .should('eq', '404')
    })
    

    应用程序

    <button onclick="clicked()">Click</button>
    <div>Result</div>
    <script>
      function clicked() {
        fetch('/api/test-id/1').then(response => { 
          // logs as "http://localhost:53845/api/test-id/1" in the Cypress test runner
          const div = document.querySelector('div')
          div.innerText = response.status
        })
      }
    </script>
    

    迷你匹配

    第二次截取使用将使用 minimatch 进行匹配的字符串。使用此代码检查拦截是否适用于您应用的 URL

    Cypress.minimatch(<full-url-from-app>, <url-in-intercept>)  // true if matching 
    

    【讨论】:

    • 您好,感谢您的回复。以下是有关我的应用程序中实现的内容的更多详细信息。所以这两个调用都是在其他地方创建的(一个模拟服务文件)并且它们具有相同的别名。在我的测试文件中,2xx 在beforeEach() 中被调用,第二个在实际it 测试中被调用。另外,我想补充一点,如果我在第二次调用中保留 cy.route()(状态代码为 4xx),它工作得很好!这就是为什么我认为这可能是一个 cy.intercept() 压倒一切的问题......
    • 别名也只用于wait的调用,所以我认为它与这个问题没有任何关系。
    • 再次感谢您的回复,我尝试给他们唯一的别名,但现在它在 wait 指令上失败,并说 Timed out retrying after 5000ms: cy.wait() timed out waiting 5000ms for the 1st request to the route: (alias of that request). No request ever occurred。这很奇怪,因为我有你描述的相同代码......
    • 我也应该提到这一点; 2xx 请求有一个正则表达式 url,例如 /api\/test-id\/\d+/,而 4xx 请求是一个填充了 id 的字符串(我们将其作为方法中的参数)/api/test-id/${id},也许赛普拉斯在这个版本中对正则表达式的处理方式不同跨度>
    • 我再次修改了测试,下一个更改是在第二个截距(使用字符串的截距)中添加通配符前缀。我不确定这是否完全反映了您的情况,应用程序中的 fetch 可能会有所不同,因此匹配它的模式也可能会有所不同。请参阅有关 minimatch 的说明。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-09
    • 1970-01-01
    • 2021-09-04
    • 2021-08-08
    • 1970-01-01
    相关资源
    最近更新 更多