Playwright中如何结合Fixture实现多用户登录态下的POM测试
问题描述
需求说明
我希望通过Fixture实现带登录用户的测试,并将该用户用于页面对象模型(POM)操作,具体场景如下:
- 管理员用户场景:创建
Page并配置管理员用户的storageState,再将该Page用于其他Fixture的POM操作 - 操作员用户场景:创建
Page并配置操作员用户的storageState,再将该Page用于其他Fixture的POM操作
已实现内容
我已创建初始化不同用户登录态Page的Fixture:
// setStorageState.fixture.ts type MyFixtures = { customer_admin_Page: Page customer_operator_Page: Page } const filePath = `${process.env.PROJECT_PATH}/temp/users/${process.env.ENV}/generated/` import { test as base, type Page } from "@playwright/test" export * from "@playwright/test" export const test = base.extend<MyFixtures>({ customer_admin_Page: async ({ browser }, use) => { const fileName = "rmaintainer.json" const context = await browser.newContext({ storageState: filePath + fileName }) const newPage = await context.newPage() await use(newPage) await context.close() }, customer_operator_Page: async ({ browser }, use) => { const fileName = "roperator.json" const context = await browser.newContext({ storageState: filePath + fileName }) const newPage = await context.newPage() await use(newPage) await context.close() }, })
随后创建了基于POM的Fixture:
// machinegroups.fixture.ts import { test as base } from "@playwright/test" import { MachineGroups } from "/src/pom/pages/machinegroups/machinegroups.page" export const test = base.extend<{ machineGroup: MachineGroups }>({ //定义Fixture machineGroup: async ({ page }, use) => { const machineGroup = new MachineGroups(page) await use(machineGroup) }, })
最后尝试在测试中结合两者,但代码无法正常工作:
// addgroup.spec.ts import { test } from "../fixtures/machinegroups/machinegroups.fixtures" import { test as pippo } from "../fixtures/users/local/setStorageState.fixtures" test.describe("Admin user", () => { test("Admin user should add a new group", async ({ customer_admin_Page, machineGroup }) => { await machineGroup.clickBtnAddGroup() }) }) test.describe("Operator user", () => { test( "Operator user could not add a new group", async ({ customer_operator_Page, machineGroup }) => { await machineGroup.clickBtnAddGroup() }, ) })
我的思路是将customer_operator_Page或customer_admin_Page传入machineGroup Fixture中使用的page,例如当使用管理员用户登录时,让machineGroup Fixture中的page自动替换为测试中的customer_admin_Page:
machineGroup: async ({ customer_admin_Page }, use) => { }
解决方案
方案一:为不同用户单独创建POM Fixture
核心是基于用户Fixture扩展出对应POM实例,让POM直接绑定登录后的Page:
- 修改
machinegroups.fixture.ts,导入用户Fixture并扩展:
// machinegroups.fixture.ts import { test as base } from "../fixtures/users/local/setStorageState.fixtures"; import { MachineGroups } from "/src/pom/pages/machinegroups/machinegroups.page"; export const test = base.extend<{ adminMachineGroup: MachineGroups; operatorMachineGroup: MachineGroups; }>({ adminMachineGroup: async ({ customer_admin_Page }, use) => { const machineGroup = new MachineGroups(customer_admin_Page); await use(machineGroup); }, operatorMachineGroup: async ({ customer_operator_Page }, use) => { const machineGroup = new MachineGroups(customer_operator_Page); await use(machineGroup); }, });
- 简化测试用例,直接使用对应POM:
// addgroup.spec.ts import { test } from "../fixtures/machinegroups/machinegroups.fixtures"; test.describe("Admin user", () => { test("Admin user should add a new group", async ({ adminMachineGroup }) => { await adminMachineGroup.clickBtnAddGroup(); // 此处添加断言,例如验证分组是否创建成功 }); }); test.describe("Operator user", () => { test("Operator user could not add a new group", async ({ operatorMachineGroup }) => { await expect(operatorMachineGroup.addGroupBtn).toBeDisabled(); }); });
方案二:动态切换用户的通用方案
如果需要更灵活的用户切换,可以通过参数化用户类型实现:
- 修改用户Fixture,定义通用登录逻辑:
// setStorageState.fixture.ts type MyFixtures = { loggedInPage: Page; userType: "admin" | "operator"; }; const filePath = `${process.env.PROJECT_PATH}/temp/users/${process.env.ENV}/generated/`; import { test as base, type Page } from "@playwright/test"; export * from "@playwright/test"; export const test = base.extend<MyFixtures>({ userType: "admin", // 默认用户类型 loggedInPage: async ({ browser, userType }, use) => { const fileName = userType === "admin" ? "rmaintainer.json" : "roperator.json"; const context = await browser.newContext({ storageState: filePath + fileName }); const newPage = await context.newPage(); await use(newPage); await context.close(); }, });
- 扩展POM Fixture绑定通用登录Page:
// machinegroups.fixture.ts import { test as base } from "../fixtures/users/local/setStorageState.fixtures"; import { MachineGroups } from "/src/pom/pages/machinegroups/machinegroups.page"; export const test = base.extend<{ machineGroup: MachineGroups }>({ machineGroup: async ({ loggedInPage }, use) => { const machineGroup = new MachineGroups(loggedInPage); await use(machineGroup); }, });
- 在测试中切换用户类型:
// addgroup.spec.ts import { test } from "../fixtures/machinegroups/machinegroups.fixtures"; test.describe("Admin user tests", () => { test("Admin user should add a new group", async ({ machineGroup }) => { await machineGroup.clickBtnAddGroup(); }); }); test.describe("Operator user tests", () => { test.use({ userType: "operator" }); // 批量设置当前describe下的用户类型 test("Operator user could not add a new group", async ({ machineGroup }) => { await expect(machineGroup.addGroupBtn).toBeDisabled(); }); });
内容的提问来源于stack exchange,提问作者Rachid G
相关产品推荐
相关产品推荐

