You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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:

  1. 修改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);
  },
});
  1. 简化测试用例,直接使用对应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();
  });
});

方案二:动态切换用户的通用方案

如果需要更灵活的用户切换,可以通过参数化用户类型实现:

  1. 修改用户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();
  },
});
  1. 扩展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);
  },
});
  1. 在测试中切换用户类型:
// 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 18:53:18