当文件缓存在磁盘上时,赛普拉斯拦截不起作用

Posted

技术标签:

【中文标题】当文件缓存在磁盘上时,赛普拉斯拦截不起作用【英文标题】:Cypress intercept doesn't work when file is cached on a disk 【发布时间】:2021-08-19 14:26:58 【问题描述】:

我想在打开页面时处理一些对某些文件的请求。在屏幕截图中,您可以看到来自 cypress 面板的日志:

为了处理这些请求,我添加了如下代码:

    it('Check intercept', () => 
        cy.intercept('/settings.json').as('settings');
        cy.intercept('/static/model/*').as('plates');

        cy.visit('/editor/ckpdx02f7098c08632il2aetr');

        cy.wait('@settings')
        cy.wait('@plates')
    );

它适用于settings.json,但不适用于.stl 文件

这样写也行不通:

    it('Check intercept', () => 
        cy.intercept('/settings.json').as('settings');
        cy.intercept('/static/model/ckpdwtgpg096g08636kd57n39/plate_4.stl').as('plate4');
        cy.intercept('/static/model/ckpdwtgpg096g08636kd57n39/plate_3.stl').as('plate3');
        cy.intercept('/static/model/ckpdwtgpg096g08636kd57n39/plate_2.stl').as('plate2');
        cy.intercept('/static/model/ckpdwtgpg096g08636kd57n39/plate_1.stl').as('plate1');
        cy.intercept('/static/model/ckpdwtgpg096g08636kd57n39/plate_0.stl').as('plate0');

        cy.visit('/editor/ckpdx02f7098c08632il2aetr');

        cy.wait('@settings')
        cy.wait('@plate4')
        cy.wait('@plate3')
        cy.wait('@plate2')
        cy.wait('@plate1')
    );

我在文档中没有发现任何限制,欢迎提出您的想法:)

赛普拉斯:v7.4.0

UPDATE 1:

我发现了更多细节:如果打开 chrome 开发者工具并在“网络”选项卡中禁用缓存 - 它总是可以正常工作

UPDATE 2:

我在演示库中创建了一个问题:https://github.com/cypress-io/cypress/issues/16766

【问题讨论】:

【参考方案1】:

使用fetch() 协议,磁盘缓存读取不会被cy.intercept() 捕获。

您可以在应用中更改fetch() 以关闭缓存,

fetch("http://127.0.0.1:2000/plate.stl", cache: "no-store");

但如果您更喜欢在测试中这样做,请将其添加到规范的顶部

beforeEach(() => 
  const disableCache = (win) => 
    const original = win.fetch;
    win.fetch = (...args) => original(...args, cache: "no-store");
  
  cy.on('window:before:load', win => disableCache(win))
)

注意,通常你可以像这样修改拦截中的标题

cy.intercept("/plate.stl", req => 
  req.headers['cache'] = 'no-store'
)

但似乎拦截与缓存读取不匹配,因此它永远不会到达那个点。


附带说明,您使用 Cypress v4.12.0 的工作分支使用 xhr 而不是 fetch。如果您将 xhr 方法替换到 Cypress v7.4.0 构建中(仍然使用拦截),问题就会消失。

这意味着你也可以通过使用旧的 fetch polyfill 来解决这个问题,它可以即时将 fetch 转换为 xhr(但我没有尝试过)。


还有第三种方式

本次讨论Using Chrome Debugger Protocol from Cypress

示例配方offline-spec.js

参考Network.clearBrowserCache

beforeEach(() => 
  Cypress.automation('remote:debugger:protocol', 
    command: 'Network.clearBrowserCache'
  )
)

【讨论】:

【参考方案2】:

如有疑问,请添加额外的*

cy.intercept('**/static/model/**/*').as('plates')

前导** 用于前面任意数量的部分,例如https://my-domain/static...

/** 用于子目录,/* 用于文件名。

【讨论】:

这很奇怪,但是重启cypress后,它可以正常工作,但是如果我点击重新启动按钮是不 - “没有请求发生过。”。总结:启动cypress后立即生效 更多详细信息:如果在测试完成后再次启动相同的测试(热键“R”),拦截不适用于我的“.stl”文件,但如果我将返回仪表板进行测试列表并单击“停止”按钮,然后再次启动此测试 - 它再次像第一次一样正常工作 还有一件事:如果我在同一个文件中有两个带有此拦截的测试 - 它仅适用于第一个测试,但在第二个测试中我再次收到错误“从未发生过请求。”跨度> 我发现了更多细节:如果打开 chrome 开发者工具并在“网络”选项卡中禁用缓存 - 它总是可以正常工作

以上是关于当文件缓存在磁盘上时,赛普拉斯拦截不起作用的主要内容,如果未能解决你的问题,请参考以下文章

赛普拉斯:组合键

赛普拉斯获取 href 属性

赛普拉斯与SystemJS

赛普拉斯:我们如何在赛普拉斯中使用不记名令牌编写 GET 请求?

赛普拉斯:如何使用键盘事件

赛普拉斯:如何计算按钮数量