employeePage.ts 7.24 KB
import { Page, Locator, expect } from '@playwright/test';
import { BasePage } from './basePage';

/**
 * 员工管理页面类
 * 处理员工管理相关操作
 */
export class EmployeePage extends BasePage {
  // 导航定位器
  readonly employeeMenu: Locator;
  
  // 操作按钮
  readonly newEmployeeButton: Locator;
  readonly manualAddButton: Locator;
  readonly confirmButton: Locator;
  
  // 表单字段
  readonly employeeNameInput: Locator;
  readonly phoneInput: Locator;
  readonly remarkInput: Locator;
  readonly positionInput: Locator;
  
  // 岗位列表
  readonly positionOption: Locator;

  constructor(page: Page) {
    super(page);
    
    this.employeeMenu = page.getByText('员工管理').first();
    this.newEmployeeButton = page.getByText('新建员工');
    this.manualAddButton = page.getByText('手动添加');
    this.confirmButton = page.getByText('确定');
    this.employeeNameInput = page.locator('uni-input').filter({ hasText: '请输入员工姓名' }).getByRole('textbox');
    this.phoneInput = page.getByRole('spinbutton');
    this.remarkInput = page.locator('uni-input').filter({ hasText: '请输入备注信息' }).getByRole('textbox');
    this.positionInput = page.locator('.nut-cell__link').first();
    this.positionOption = page.locator('uni-view').filter({ hasText: /^岗位名称$/ }).first();
  }

  /**
   * 进入员工管理页面
   */
  async openEmployeeManagement(): Promise<void> {
    await this.navigate('/');
    await this.employeeMenu.click();
    await this.page.waitForLoadState('networkidle', { timeout: 30000 });
  }

  /**
   * 点击新建员工按钮
   */
  async clickNewEmployee(): Promise<void> {
    await this.newEmployeeButton.click();
    await this.page.waitForTimeout(500);
  }

  /**
   * 点击手动添加
   */
  async clickManualAdd(): Promise<void> {
    await this.manualAddButton.click();
    await this.page.waitForTimeout(500);
  }

  /**
   * 填写员工姓名
   * @param name 员工姓名
   */
  async fillEmployeeName(name: string): Promise<void> {
    await this.employeeNameInput.click();
    await this.employeeNameInput.fill(name);
  }

  /**
   * 填写联系电话
   * @param phone 联系电话
   */
  async fillPhone(phone: string): Promise<void> {
    await this.phoneInput.click();
    await this.phoneInput.fill(phone);
  }

  /**
   * 填写备注
   * @param remark 备注信息
   */
  async fillRemark(remark: string): Promise<void> {
    await this.remarkInput.click();
    await this.remarkInput.fill(remark);
  }

  /**
   * 选择岗位
   * @param position 岗位名称(可选,不传则随机选择)
   */
  async selectPosition(position?: string): Promise<void> {
    // 点击岗位名称输入框打开下拉列表
    await this.page.locator('uni-view:nth-child(6) > .nut-cell__value > .nut-form-item__body__slots > .nut-input > .nut-input__value > .nut-input__mask').click();
    await this.page.waitForTimeout(500);
    
    if (position) {
      // 选择指定岗位
      await this.page.locator('uni-view').filter({ hasText: position }).first().click();
    } else {
      // 随机选择岗位 - 获取所有岗位选项并随机选择一个
      const options = this.page.locator('uni-view').filter({ hasText: /^销售员$|^仓库管理员$/ });
      const count = await options.count();
      if (count > 0) {
        const randomIndex = Math.floor(Math.random() * count);
        await options.nth(randomIndex).click();
      }
    }
    await this.page.waitForTimeout(300);
  }

  /**
   * 点击确定按钮
   */
  async clickConfirm(): Promise<void> {
    await this.confirmButton.click();
    await this.page.waitForTimeout(1000);
  }

  /**
   * 搜索员工
   * @param name 员工姓名
   */
  async searchEmployee(name: string): Promise<void> {
    await this.page.getByRole('textbox').click();
    await this.page.getByRole('textbox').fill(name);
    await this.page.waitForTimeout(1000);
  }

  /**
   * 验证员工是否存在
   * @param name 员工姓名
   * @returns 是否存在
   */
  async verifyEmployeeExists(name: string): Promise<boolean> {
    const isVisible = await this.page.getByText(name).first().isVisible().catch(() => false);
    return isVisible;
  }

  /**
   * 新增员工完整流程
   * @param name 员工姓名
   * @param phone 联系电话
   * @param remark 备注
   * @param position 岗位(可选)
   */
  async createEmployee(name: string, phone: string, remark: string, position?: string): Promise<void> {
    await this.openEmployeeManagement();
    await this.clickNewEmployee();
    await this.clickManualAdd();
    await this.fillEmployeeName(name);
    await this.fillPhone(phone);
    await this.fillRemark(remark);
    await this.selectPosition(position);
    await this.clickConfirm();
  }

  /**
   * 点击修改按钮
   */
  async clickEditButton(): Promise<void> {
    await this.page.locator('uni-button.execute-plain-btn').getByText('修改').click();
    await this.page.waitForTimeout(500);
  }

  /**
   * 填写备注(修改页面)
   * @param remark 备注信息
   */
  async fillRemarkForEdit(remark: string): Promise<void> {
    await this.page.locator('uni-input').filter({ hasText: '请输入备注信息' }).getByRole('textbox').click();
    await this.page.locator('uni-input').filter({ hasText: '请输入备注信息' }).getByRole('textbox').fill(remark);
  }

  /**
   * 点击状态开关
   */
  async clickStatusSwitch(): Promise<void> {
    await this.page.locator('uni-view:nth-child(5) > .nut-cell__value > .nut-form-item__body__slots > .nut-switch > .nut-switch-button').click();
    await this.page.waitForTimeout(300);
  }

  /**
   * 选择岗位(修改页面)
   * @param position 岗位名称
   */
  async selectPositionForEdit(position: string): Promise<void> {
    // 点击岗位名称输入框打开下拉列表(使用与新增相同的selector)
    await this.page.locator('uni-view:nth-child(6) > .nut-cell__value > .nut-form-item__body__slots > .nut-input > .nut-input__value > .nut-input__mask').click();
    await this.page.waitForTimeout(500);
    // 选择岗位
    await this.page.locator('uni-view').filter({ hasText: position }).first().click();
    await this.page.waitForTimeout(300);
  }

  /**
   * 验证员工备注是否包含指定内容
   * @param expectedRemark 期望的备注内容
   * @returns 是否包含
   */
  async verifyEmployeeRemarkContains(expectedRemark: string): Promise<boolean> {
    const remarkElement = this.page.getByText(expectedRemark).first();
    const isVisible = await remarkElement.isVisible({ timeout: 3000 }).catch(() => false);
    return isVisible;
  }

  /**
   * 点击解绑按钮
   */
  async clickUnbindButton(): Promise<void> {
    await this.page.locator('uni-button.warning-plain-btn').getByText('解绑').click();
    await this.page.waitForTimeout(500);
  }

  /**
   * 确认解绑
   */
  async confirmUnbind(): Promise<void> {
    await this.page.getByText('确定', { exact: true }).click();
    await this.page.waitForTimeout(1000);
  }

  /**
   * 验证员工不存在
   * @param name 员工姓名
   * @returns 是否不存在
   */
  async verifyEmployeeNotExists(name: string): Promise<boolean> {
    const employeeElement = this.page.getByText(name).first();
    const isHidden = await employeeElement.isHidden({ timeout: 3000 }).catch(() => true);
    return isHidden;
  }
}