Playwright测试中动态导入parseEndpoint模块的问题求助
我在做Playwright E2E测试时,需要调用特定API接口优化测试流程,得先拿到API的URI。这些API端点是通过index.html里引用的loadEndpoint.js脚本加载的——这个脚本会给浏览器的window对象添加config属性,在浏览器里运行完全正常,但Playwright的Node测试环境没法直接访问window对象。
我知道可以用page.evaluate访问浏览器全局变量,但我有个parseEndpoint.ts脚本,它依赖window上的基础URL生成查询字符串,而且这个脚本得在测试文件顶部导入(不在Playwright的测试上下文里),这时候window还没定义,直接导入就会报错。
试过动态导入这个脚本,但测试里的动态导入路径全是localhost:port/pathToModule开头的,要是能延迟模块导入的时机,应该就能解决问题。
相关代码
parseEndpoint.ts
export type WindowConfig = Window & typeof globalThis & { config: EndpointConfig }; const config = (window as WindowConfig).config; export default { config };
index.html片段
<script type="application/javascript" src="%BASE_URL%loadEndpoint.js"></script>
解决方法
方法1:改造parseEndpoint.ts,延迟获取config
把原来直接读取window.config的逻辑改成函数,等Playwright测试上下文准备好后再调用:
export type WindowConfig = Window & typeof globalThis & { config: EndpointConfig }; // 改成函数,需要时再读取window.config export const getConfig = () => { return (window as WindowConfig).config; }; export default { getConfig };
然后在测试文件里,等页面加载完成后通过page.evaluate调用这个函数:
import { test, expect } from '@playwright/test'; import parseEndpoint from './parseEndpoint'; test('获取API端点', async ({ page }) => { await page.goto('/'); // 等待loadEndpoint.js加载完成,确保window.config已存在 await page.waitForFunction(() => typeof window.config !== 'undefined'); // 在浏览器上下文里调用getConfig const config = await page.evaluate(() => parseEndpoint.getConfig()); // 现在就能用config里的API URI调用接口了 console.log('API基础地址:', config.apiBaseUrl); });
方法2:直接在测试中提取config,跳过模块导入
如果parseEndpoint的逻辑只是单纯获取config,那完全可以直接在测试里提取,不用导入模块:
import { test, expect } from '@playwright/test'; test('直接获取window.config', async ({ page }) => { await page.goto('/'); await page.waitForFunction(() => typeof window.config !== 'undefined'); const config = await page.evaluate(() => window.config); // 用拿到的config调用API const apiResp = await page.request.get(`${config.apiBaseUrl}/your-endpoint`); expect(apiResp.ok()).toBeTruthy(); });
方法3:动态注入模块到浏览器上下文
如果必须保留parseEndpoint的原有结构,可以通过Playwright的addScriptTag把模块注入到浏览器中,再获取结果:
import { test, expect } from '@playwright/test'; test('注入parseEndpoint获取config', async ({ page }) => { await page.goto('/'); await page.waitForFunction(() => typeof window.config !== 'undefined'); // 把parseEndpoint脚本注入到浏览器(注意用编译后的JS文件) await page.addScriptTag({ path: './parseEndpoint.js' }); // 获取注入后的config const config = await page.evaluate(() => window.parseEndpoint.config); // 使用config console.log('API端点:', config.apiBaseUrl); });
注:如果用的是TypeScript,需要先把parseEndpoint.ts编译成JavaScript,或者配置Playwright支持直接加载TS(比如搭配ts-node)。
内容的提问来源于stack exchange,提问作者CenterADiv

