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

/**
 * 客户分组页面选择器
 */
const selectors = {
  // 导航
  moreMenu: 'text=更多 >',
  customerGroupMenu: 'text=客户分组',
  
  // 操作按钮
  newButton: 'text=新建',
  confirmButton: 'text=确定',
  saveButton: 'text=保存',
  deleteButton: 'text=删除',
  editButton: 'text=编辑',
  
  // 表单字段
  groupNameInput: 'text=分组名称*',
  sortInput: 'textbox',
  
  // 搜索
  searchInput: 'textbox',
  clearSearchButton: '.nut-searchbar__search-icon',
};

/**
 * 客户分组页面类
 * 处理客户分组相关操作
 */
export class CustomerGroupPage extends BasePage {
  // 导航定位器
  readonly moreMenu: Locator;
  readonly customerGroupMenu: Locator;
  
  // 操作按钮
  readonly newButton: Locator;
  readonly confirmButton: Locator;
  readonly saveButton: Locator;
  readonly deleteButton: Locator;
  readonly editButton: Locator;
  
  // 表单字段
  readonly groupNameInput: Locator;
  readonly sortInput: Locator;
  
  // 搜索
  readonly searchInput: Locator;
  readonly clearSearchButton: Locator;

  constructor(page: Page) {
    super(page);
    
    this.moreMenu = page.getByText('更多 >');
    this.customerGroupMenu = page.getByText('客户分组').first();
    this.newButton = page.getByText('新建');
    this.confirmButton = page.getByText('确定');
    this.saveButton = page.getByText('保存');
    this.deleteButton = page.getByText('删除');
    this.editButton = page.getByText('编辑');
    this.groupNameInput = page.locator('uni-view').filter({ hasText: /^分组名称\*$/ }).first();
    this.sortInput = page.getByRole('textbox').nth(2);
    this.searchInput = page.getByRole('textbox');
    this.clearSearchButton = page.locator('.nut-searchbar__search-icon');
  }

  /**
   * 进入客户分组页面
   */
  async openCustomerGroupManagement(): Promise<void> {
    await this.navigate('/');
    await this.moreMenu.click();
    await this.page.waitForTimeout(500);
    await this.customerGroupMenu.click();
    await this.page.waitForLoadState('networkidle', { timeout: 30000 });
  }

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

  /**
   * 填写分组名称
   * @param name 分组名称
   */
  async fillGroupName(name: string): Promise<void> {
    await this.page.getByRole('textbox').nth(1).click();
    await this.page.getByRole('textbox').nth(1).fill(name);
  }

  /**
   * 填写排序号
   * @param sort 排序号
   */
  async fillSortNumber(sort: string): Promise<void> {
    await this.page.getByRole('textbox').nth(2).click();
    await this.page.getByRole('textbox').nth(2).fill(sort);
  }

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

  /**
   * 搜索分组
   * @param name 分组名称
   */
  async searchGroup(name: string): Promise<void> {
    await this.searchInput.click();
    await this.searchInput.fill(name);
    await this.page.waitForTimeout(500);
  }

  /**
   * 点击清除搜索按钮
   */
  async clearSearch(): Promise<void> {
    await this.clearSearchButton.click();
    await this.page.waitForTimeout(2000);
  }

  /**
   * 点击编辑按钮
   */
  async clickEdit(): Promise<void> {
    await this.editButton.click();
    await this.page.waitForTimeout(500);
  }

  /**
   * 点击删除按钮
   */
  async clickDelete(): Promise<void> {
    await this.deleteButton.click();
    await this.page.waitForTimeout(500);
  }

  /**
   * 验证分组是否存在(验证前先搜索)
   * @param name 分组名称
   * @returns 是否存在
   */
  async verifyGroupExists(name: string): Promise<boolean> {
    await this.searchGroup(name);
    await this.page.waitForTimeout(500);
    const count = await this.page.locator('uni-view').filter({ hasText: new RegExp(`^${name}$`) }).count();
    return count > 0;
  }

  /**
   * 验证分组是否不存在
   * @param name 分组名称
   * @returns 是否不存在
   */
  async verifyGroupNotExists(name: string): Promise<boolean> {
    const count = await this.page.locator('uni-view').filter({ hasText: new RegExp(`^${name}$`) }).count();
    return count === 0;
  }

  /**
   * 新增客户分组完整流程
   * @param groupName 分组名称
   * @param sortNumber 排序号(可选)
   */
  async createGroup(groupName: string, sortNumber?: string): Promise<void> {
    await this.openCustomerGroupManagement();
    await this.clickNewButton();
    await this.fillGroupName(groupName);
    if (sortNumber) {
      await this.fillSortNumber(sortNumber);
    }
    await this.clickConfirm();
  }

  /**
   * 修改客户分组完整流程
   * @param originalName 原分组名称
   * @param newName 新分组名称
   * @param newSortNumber 新排序号(可选)
   */
  async updateGroup(originalName: string, newName: string, newSortNumber?: string): Promise<void> {
    await this.searchGroup(originalName);
    await this.page.locator('uni-view').filter({ hasText: new RegExp(`^${originalName}$`) }).first().click();
    await this.page.waitForTimeout(500);
    await this.clickEdit();
    // 清空分组名称并填写新名称
    await this.page.getByRole('textbox').nth(1).click();
    await this.page.locator('.nut-input__clear-icon').first().click();
    await this.page.getByRole('textbox').nth(1).click();
    await this.page.getByRole('textbox').nth(1).fill(newName);
    if (newSortNumber) {
      await this.page.getByRole('textbox').nth(2).click();
      await this.page.getByRole('textbox').nth(2).fill(newSortNumber);
    }
    await this.clickConfirm();
  }

  /**
   * 删除客户分组完整流程
   * @param groupName 分组名称
   */
  async deleteGroup(groupName: string): Promise<void> {
    await this.searchGroup(groupName);
    await this.page.locator('uni-view').filter({ hasText: new RegExp(`^${groupName}$`) }).first().click();
    await this.page.waitForTimeout(500);
    await this.clickDelete();
    await this.page.getByText('确定', { exact: true }).click();
    await this.page.waitForTimeout(1000);
    await this.clearSearch();
  }
}