网络拦截是 Cypress 的核心系统,它允许用户在测试中拦截、监视、模拟和修改 HTTP 请求和响应。与旧技术不同,cy.intercept() 命令可以拦截所有类型的 HTTP 请求,包括 XHR、fetch、页面加载和资源加载。
有关浏览器自动化和通信协议的信息,请参阅浏览器自动化和通信。
网络拦截系统位于浏览器和服务器之间,充当代理,可以观察和操纵网络流量。它提供了以下功能:
cy.wait() 等待特定请求完成来源:packages/net-stubbing/lib/server/middleware/request.ts60-200 packages/net-stubbing/lib/server/route-matching.ts5-139 packages/driver/src/cy/net-stubbing/add-command.ts176-317
网络拦截系统同时实现在 Cypress driver(客户端)和 server 组件中
来源:packages/net-stubbing/lib/external-types.ts74-168 packages/driver/src/cy/net-stubbing/add-command.ts175-319 packages/net-stubbing/lib/server/middleware/request.ts24-200 packages/net-stubbing/lib/server/intercepted-request.ts10-225
路由匹配器决定拦截哪些 HTTP 请求。匹配器可以是
/api/users/*)/\/api\/users\/\d+/)| 属性 | 类型 | 描述 |
|---|---|---|
url | String/RegExp | 要匹配的 URL |
method | String/RegExp | HTTP 方法(GET、POST 等) |
hostname | String/RegExp | 要匹配的主机名 |
path | String/RegExp | 要匹配的路径(包括查询字符串) |
pathname | String/RegExp | 不带查询字符串的路径 |
query | 对象 | 要匹配的查询参数 |
headers | 对象 | 要匹配的请求头 |
认证 | 对象 | Basic auth credentials |
port | Number/Number[] | 要匹配的端口号 |
https | 布尔值 | 仅匹配 HTTPS 或 HTTP 请求 |
times | 数字 | 匹配的最大次数 |
middleware | 布尔值 | 在非中间件处理程序之前运行 |
来源:packages/net-stubbing/lib/external-types.ts210-395 packages/driver/src/cy/net-stubbing/add-command.ts110-173
路由处理程序定义了拦截请求时发生的操作。处理程序可以是
函数处理程序接收一个具有以下关键方法的请求对象
| 方法 | 描述 |
|---|---|
req.reply() | 发送响应,而不让请求出站 |
req.continue() | 允许请求继续,可选地修改响应 |
req.redirect() | 将请求重定向到另一个 URL |
req.destroy() | 模拟网络错误 |
req.on() | 订阅响应事件 |
来源:packages/driver/src/cy/net-stubbing/events/before-request.ts150-261 packages/net-stubbing/lib/external-types.ts397-399
静态响应允许为拦截的请求定义固定的响应
来源:packages/net-stubbing/lib/external-types.ts412-449 packages/driver/src/cy/net-stubbing/static-response-utils.ts24-62
下图显示了拦截请求的完整生命周期
来源:packages/net-stubbing/lib/server/middleware/request.ts60-200 packages/net-stubbing/lib/server/middleware/response.ts21-84 packages/net-stubbing/lib/server/intercepted-request.ts132-224
当一个请求被拦截时,Cypress 会按照特定的顺序将其与已注册的路由进行匹配
来源:packages/net-stubbing/lib/server/route-matching.ts13-93 packages/net-stubbing/lib/server/route-matching.ts128-139
cy.intercept() 命令cy.intercept() 命令是网络拦截的主要 API。它支持多种重载
来源:packages/driver/src/cy/net-stubbing/add-command.ts175-318 packages/net-stubbing/lib/external-types.ts490-517
要稍后引用拦截,您可以使用别名
来源:packages/net-stubbing/lib/external-types.ts532-566 packages/driver/src/cy/net-stubbing/wait-for-route.ts10-51
InterceptedRequest 类网络拦截系统的核心是 InterceptedRequest 类,它代表一个正在被拦截的请求,并提供处理它的方法
InterceptedRequest 类管理请求的整个生命周期,包括
来源:packages/net-stubbing/lib/server/intercepted-request.ts17-225
网络拦截系统使用基于事件的架构来处理请求的不同阶段
| 事件 | 描述 | 可用数据 |
|---|---|---|
before:request | 在请求发送之前 | 请求详情 |
before:response | 在响应发送到浏览器之前 | 响应 + 请求 |
response | 在响应发送之前(在 before:response 之后) | 响应 + 请求 |
after:response | 响应发送之后 | 响应 + 请求 |
处理程序可以使用 req.on() 订阅这些事件
来源: packages/driver/src/cy/net-stubbing/events/before-request.ts25-362 packages/driver/src/cy/net-stubbing/events/response.ts19-167 packages/driver/src/cy/net-stubbing/events/index.ts21-28
使用网络拦截时
选择性拦截:仅拦截您需要存根或断言的请求,因为拦截所有请求可能会影响性能。
最小化修改:修改响应时,尽量做最小的改动,以避免性能影响。
响应流式传输:对于大型响应,Cypress 使用流式传输来高效处理数据,并提供限制响应的选项来模拟网络条件。
来源: packages/net-stubbing/lib/server/util.ts183-236
网络拦截系统处理各种类型的请求/响应正文
该系统还可以正确处理
来源: packages/net-stubbing/lib/server/util.ts27-53 packages/net-stubbing/lib/server/util.ts266-286 packages/net-stubbing/test/unit/util-spec.ts8-101
该系统自动处理 CORS(跨源资源共享)要求
这确保了即使跨不同源,拦截的请求也能正常工作。
来源: packages/net-stubbing/lib/server/util.ts110-141 packages/net-stubbing/lib/server/middleware/request.ts41-52
网络拦截系统与其他 Cypress 系统集成
cy.wait() 进行别名每个拦截的请求都可以设置别名、等待并能在测试代码中访问,从而可以对应用程序的网络行为进行强大的断言。
来源: packages/driver/src/cy/net-stubbing/add-command.ts229-237 packages/driver/src/cy/net-stubbing/wait-for-route.ts10-51