Cypress(TypeScript)如何拦截首个加载的图片或文档资源?
问题解决:Cypress中等待首个图片或文档资源加载完成
场景说明
- 页面包含图片(源路径
/img/image/**)或文档(源路径/content/docs/**),可能仅含其一或混合排列 - 需求:确保至少有一个资源加载完成,只需等待首个加载的资源
之前尝试的问题
- 正则URL拦截无请求触发
cy.intercept({ method: 'GET', url: /\/content\/docs\/.*|\/img\/image\/.*/, }).as('Thumbnail'); cy.visit(URL); cy.wait('@Thumbnail');
问题:正则表达式匹配逻辑存在缺陷,导致未拦截到目标请求
- 单一资源拦截仅部分场景生效
cy.intercept('GET', '/img/image/**').as('Thumbnail'); cy.visit(URL); cy.wait('@Thumbnail');
问题:仅在页面存在图片时生效,无图片场景下测试直接失败
- 双拦截等待导致无对应资源时失败
export const waitForFirstAsset = (): void => { let assetIntercepted = false; const waitForRequest = (): void => { cy.wait(['@imageRequest', '@documentRequest'], { timeout: 10000 }).then( (interceptions): void => { if (!assetIntercepted) { assetIntercepted = true; const interceptedRequest = interceptions[0]; } }, ); }; waitForRequest(); }; cy.intercept('GET', '/img/image/**').as('imageRequest'); cy.intercept('GET', '/content/docs/**').as('documentRequest'); cy.visit(URL); waitForFirstAsset();
问题:会持续等待所有匹配请求,且页面无文档时,因等待不存在的
documentRequest导致测试失败
可行解决方案
方案一:利用Promise捕获首个触发的拦截
// 定义Promise,捕获首个加载的资源 const firstAssetLoaded = new Promise((resolve) => { // 拦截图片请求,首个请求触发时resolve cy.intercept('GET', '/img/image/**', (req) => { req.continue(); resolve('image'); }).as('imageRequest'); // 拦截文档请求,首个请求触发时resolve cy.intercept('GET', '/content/docs/**', (req) => { req.continue(); resolve('document'); }).as('documentRequest'); }); // 访问目标页面 cy.visit(URL); // 等待首个资源加载完成,设置超时避免无限等待 cy.wrap(firstAssetLoaded, { timeout: 10000 }).then((assetType) => { cy.log(`首个加载的资源类型:${assetType}`); });
方案说明
- 借助Promise特性,只要任意一个拦截触发就立即resolve,无需等待不存在的资源
req.continue()确保请求正常完成,不会阻塞页面加载流程
方案二:使用Promise.race等待首个完成的请求
// 分别定义图片和文档的拦截 cy.intercept('GET', '/img/image/**').as('imageRequest'); cy.intercept('GET', '/content/docs/**').as('documentRequest'); // 访问目标页面 cy.visit(URL); // 用Promise.race等待第一个完成的请求 cy.wrap(Promise.race([ cy.wait('@imageRequest').then(() => 'image'), cy.wait('@documentRequest').then(() => 'document') ]), { timeout: 10000 }).then((assetType) => { cy.log(`首个加载的资源类型:${assetType}`); });
方案说明
Promise.race会在第一个Promise完成时立即返回结果,因此只要有一个资源加载就会通过测试- 若页面只有一种资源,未触发的
cy.wait不会影响测试,因为Promise.race已提前resolve
内容的提问来源于stack exchange,提问作者Darksymphony
相关产品推荐
相关产品推荐

