如何为Playwright不同项目配置专属POM Fixture?
问题描述
我需要配置Playwright,让不同项目使用不同的POM Fixture。目前找到的示例都是扩展基础测试时配置POM,这种方式会导致所有项目共用同一个POM Fixture,不符合需求。
现有实现代码:
import { test as base } from '@playwright/test'; type TestOptions = { productDetailPom: ProductDetailPom }; export const test = base.extend<TestOptions>({ productDetailPom: async ({ browser }, use) => { await use(await ProductDetailPom.create(browser, 'url')); }, });
我希望能在配置文件中结合browser或page Fixture为每个项目创建对应的POM实例,期望的配置形式如下:
// playwright.config.ts const config: PlaywrightTestConfig<TestOptions> = { ... projects: [ { name: 'proj1', use: { productDetailPom: new ProductDetailPom1(browser, 'url1') // POM实例1 } }, { name: 'proj2', use: { productDetailPom: new ProductDetailPom2(browser, 'url2') // POM实例2 } } ], };
解决方案
核心说明
不能直接在playwright.config.ts的use字段中实例化POM——因为配置文件执行时browser/page这类fixture还未初始化。需要通过扩展基础测试fixture + 项目配置传递参数的方式,让每个项目根据自身配置生成对应的POM实例。
实现方式一:通过项目标识动态生成POM
1. 扩展测试选项与fixture
在自定义测试文件中,新增用于区分项目的配置字段,然后根据该字段动态初始化对应POM:
// test.ts import { test as base } from '@playwright/test'; import { ProductDetailPom1 } from './pom/proj1/ProductDetailPom1'; import { ProductDetailPom2 } from './pom/proj2/ProductDetailPom2'; // 定义包含项目POM配置的测试选项 type TestOptions = { pomConfig: { type: 'proj1' | 'proj2'; url: string; }; productDetailPom: ProductDetailPom1 | ProductDetailPom2; }; export const test = base.extend<TestOptions>({ // 设置默认配置,后续项目会覆盖该值 pomConfig: { type: 'proj1', url: 'default-url' }, // 根据项目配置生成对应POM实例 productDetailPom: async ({ browser, pomConfig }, use) => { let pomInstance; switch (pomConfig.type) { case 'proj1': pomInstance = await ProductDetailPom1.create(browser, pomConfig.url); break; case 'proj2': pomInstance = await ProductDetailPom2.create(browser, pomConfig.url); break; default: throw new Error(`不支持的项目类型: ${pomConfig.type}`); } await use(pomInstance); }, }); export { expect } from '@playwright/test';
2. 在配置文件中为项目指定POM配置
在playwright.config.ts中,给每个项目配置专属的pomConfig:
// playwright.config.ts import { PlaywrightTestConfig } from '@playwright/test'; import { TestOptions } from './test'; const config: PlaywrightTestConfig<TestOptions> = { projects: [ { name: 'proj1', use: { pomConfig: { type: 'proj1', url: 'url1' }, }, }, { name: 'proj2', use: { pomConfig: { type: 'proj2', url: 'url2' }, }, }, ], }; export default config;
3. 测试用例中使用POM
测试代码直接通过fixture获取对应项目的POM实例即可:
// tests/proj1.spec.ts import { test, expect } from '../test'; test('proj1商品详情测试', async ({ productDetailPom }) => { await productDetailPom.navigate(); await expect(productDetailPom.productName).toBeVisible(); });
实现方式二:直接传递POM构造函数
如果不想用switch判断,可直接在项目配置中传递POM的构造函数,再在fixture中初始化:
1. 修改测试选项与fixture
// test.ts import { test as base } from '@playwright/test'; import type { ProductDetailPom } from './pom/ProductDetailPom'; // 定义包含构造函数和URL的测试选项 type TestOptions = { PomConstructor: typeof ProductDetailPom; pomUrl: string; productDetailPom: ProductDetailPom; }; export const test = base.extend<TestOptions>({ // 抛出默认错误,强制项目配置指定构造函数 PomConstructor: async () => { throw new Error('必须在项目配置中指定PomConstructor'); }, pomUrl: '', // 通过构造函数初始化POM productDetailPom: async ({ browser, PomConstructor, pomUrl }, use) => { const pomInstance = await PomConstructor.create(browser, pomUrl); await use(pomInstance); }, });
2. 配置文件中指定构造函数与URL
// playwright.config.ts import { PlaywrightTestConfig } from '@playwright/test'; import { TestOptions } from './test'; import { ProductDetailPom1 } from './pom/proj1/ProductDetailPom1'; import { ProductDetailPom2 } from './pom/proj2/ProductDetailPom2'; const config: PlaywrightTestConfig<TestOptions> = { projects: [ { name: 'proj1', use: { PomConstructor: ProductDetailPom1, pomUrl: 'url1', }, }, { name: 'proj2', use: { PomConstructor: ProductDetailPom2, pomUrl: 'url2', }, }, ], }; export default config;
内容的提问来源于stack exchange,提问作者Reynicke
相关产品推荐
相关产品推荐

