Playwright编写含Fetch调用的E2E测试问题求助
Playwright 测试 React 项目 E2E 问题解决方案
问题场景
我需要用 Playwright 给 React 项目写 E2E 测试,网站核心功能:
- 首次渲染时,从 API 获取随机事实,再以事实前三个词为查询条件调用另一 API 获取随机图片,加载完成后展示两者;
- 页面有一个按钮,点击后重新发起请求获取新事实和对应图片,效果等同于刷新。
需要验证:点击按钮后请求成功,且新展示的事实、图片与之前内容不同(已完成初始内容存在性测试)。
我尝试的代码:
const button = await page.getByRole('button') const prevText = await page.getByRole('paragraph') const prevImage = await page.getByRole('img') await button.click() page.waitForResponse(res => res.status() === 200) const newText = await page.getByRole('paragraph') const newImage = await page.getByRole('img') await expect(newText).not.toEqual(prevText) await expect(newImage).not.toEqual(prevImage)
也试过把点击和 waitForResponse 放进 Promise.all,但依然失败。
问题根源
- 错误比较元素句柄而非内容:你保存的
prevText和prevImage是 Playwright 的元素句柄,不是文本或图片链接这类实际内容。直接比较句柄要么永远是不同对象,要么元素重新渲染后句柄失效,断言逻辑完全错误。 - 未正确等待请求完成:
page.waitForResponse没加await,代码会跳过等待直接执行后续逻辑,导致新内容还没加载就获取到旧内容;即使放进Promise.all,仅判断状态码的条件太宽泛,可能匹配到无关请求,没等到目标请求完成。 - 图片判断逻辑缺失:需要比较图片的
src属性,而非元素句柄本身。
修正后的测试代码
test('点击按钮加载新的事实与图片', async ({ page }) => { await page.goto('/'); // 替换为你的项目访问地址 // 获取初始内容的实际值 const initialFact = await page.getByRole('paragraph').textContent(); const initialImageSrc = await page.getByRole('img').getAttribute('src'); // 同时执行点击和等待目标请求完成 const [factResp, imageResp] = await Promise.all([ // 替换为你项目中事实API的URL关键词,确保监听目标请求 page.waitForResponse(res => res.url().includes('fact-api-key') && res.status() === 200), // 替换为你项目中图片API的URL关键词 page.waitForResponse(res => res.url().includes('image-api-key') && res.status() === 200), page.getByRole('button').click() ]); // 等待DOM更新完成 await page.waitForSelector('p'); await page.waitForSelector('img'); // 获取新内容的实际值 const newFact = await page.getByRole('paragraph').textContent(); const newImageSrc = await page.getByRole('img').getAttribute('src'); // 断言内容不同 await expect(newFact).not.toBe(initialFact); await expect(newImageSrc).not.toBe(initialImageSrc); });
关键优化点
- 获取实际内容:用
textContent()提取段落文本,getAttribute('src')获取图片链接,比较真实内容而非元素句柄。 - 精准监听请求:结合 API URL 的关键词做判断,避免匹配到页面其他无关请求,确保等待的是目标事实和图片请求。
- 正确处理异步流程:用
Promise.all同步执行点击和等待响应,保证请求完成后再获取新内容;额外用waitForSelector确保 DOM 渲染完成。 - 可选:增加空值校验:如果 API 可能返回空内容,可以先断言初始内容非空,比如
await expect(initialFact).not.toBeNull();
内容的提问来源于stack exchange,提问作者krst221
相关产品推荐
相关产品推荐

