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

/**
 * 商品分类页面选择器
 */
const selectors = {
  // 导航
  moreMenu: 'text=更多 >',
  categoryMenu: 'text=商品分类',
  
  // 功能按钮
  addCategoryButton: 'text=新增分类',
  editCategoryButton: 'text=修改分类',
  confirmButton: 'text=确定',
  clearSearchButton: '.nut-searchbar__search-icon',
  
  // 表单
  categoryNameInput: 'textbox',
  categoryDescriptionInput: 'textbox',
  categoryStatusSwitch: '.nut-switch > .nut-switch-button',
  
  // 搜索
  searchInput: 'textbox',
  
  // 列表
  categoryItem: (categoryName: string) => `span:has-text("${categoryName}")`,
};

/**
 * 商品分类页面类
 * 处理商品分类相关操作
 */
export class ProductCategoryPage extends BasePage {
  // 导航定位器
  readonly moreMenu: Locator;
  readonly categoryMenu: Locator;
  
  // 功能按钮
  readonly addCategoryButton: Locator;
  readonly editCategoryButton: Locator;
  readonly deleteCategoryButton: Locator;
  readonly confirmButton: Locator;
  readonly clearSearchButton: Locator;
  
  // 表单定位器
  readonly categoryNameInput: Locator;
  readonly categoryDescriptionInput: Locator;
  readonly categoryStatusSwitch: Locator;
  
  // 搜索
  readonly searchInput: Locator;

  constructor(page: Page) {
    super(page);
    
    this.moreMenu = page.getByText('更多 >');
    this.categoryMenu = page.getByText('商品分类').first();
    this.addCategoryButton = page.getByText('新增分类');
    this.editCategoryButton = page.getByText('修改分类');
    this.deleteCategoryButton = page.getByText('删除分类');
    this.confirmButton = page.getByText('确定', { exact: true });
    this.clearSearchButton = page.locator('uni-view:nth-child(7) > .default-container > uni-view > .z-paging-content > .nut-searchbar > .nut-searchbar__search-input > .nut-searchbar__input-inner-icon > .nut-searchbar__search-icon > .nut-icon');
    this.categoryNameInput = page.getByRole('textbox').nth(1);
    this.categoryDescriptionInput = page.getByRole('textbox').nth(2);
    this.categoryStatusSwitch = page.locator('.uni-scroll-view-content > uni-view:nth-child(3) > .nut-cell__value > .nut-form-item__body__slots > .nut-switch > .nut-switch-button');
    this.searchInput = page.getByRole('textbox').first();
  }

  /**
   * 打开商品分类管理页面
   * 完整流程:首页 -> 更多 -> 商品分类
   */
  async openProductCategoryManagement(): Promise<void> {
    await this.navigate('/');
    await this.moreMenu.click();
    await this.page.waitForTimeout(500);
    await this.categoryMenu.click();
    await this.page.waitForLoadState('networkidle', { timeout: 30000 });
  }

  /**
   * 点击新增分类按钮
   */
  async clickAddCategory(): Promise<void> {
    await this.addCategoryButton.click();
  }

  /**
   * 输入分类名称
   * @param categoryName 分类名称
   */
  async enterCategoryName(categoryName: string): Promise<void> {
    await this.categoryNameInput.click();
    await this.categoryNameInput.fill(categoryName);
  }

  /**
   * 输入分类描述
   * @param description 分类描述
   */
  async enterCategoryDescription(description: string): Promise<void> {
    await this.categoryDescriptionInput.click();
    await this.categoryDescriptionInput.fill(description);
  }

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

  /**
   * 搜索分类
   * @param categoryName 分类名称
   */
  async searchCategory(categoryName: string): Promise<void> {
    await this.searchInput.click();
    await this.searchInput.fill(categoryName);
  }

  /**
   * 验证分类是否存在
   * @param categoryName 分类名称
   */
  async expectCategoryVisible(categoryName: string): Promise<void> {
    await expect(this.page.locator('span').filter({ hasText: categoryName })).toBeVisible();
  }

  /**
   * 创建新商品分类(完整流程)
   * @param categoryName 分类名称
   * @param description 分类描述
   */
  async createCategory(categoryName: string, description: string): Promise<void> {
    await this.openProductCategoryManagement();
    await this.clickAddCategory();
    await this.enterCategoryName(categoryName);
    await this.enterCategoryDescription(description);
    await this.clickConfirm();
    await this.searchCategory(categoryName);
    await this.expectCategoryVisible(categoryName);
  }

  /**
   * 点击修改分类按钮
   */
  async clickEditCategory(): Promise<void> {
    await this.editCategoryButton.click();
  }

  /**
   * 清除搜索框内容
   */
  async clearSearch(): Promise<void> {
    await this.searchInput.click();
    await this.searchInput.selectText();
    await this.searchInput.fill('');
    await this.page.waitForTimeout(300);
  }

  /**
   * 切换分类状态
   */
  async toggleCategoryStatus(): Promise<void> {
    await this.categoryStatusSwitch.click();
  }

  /**
   * 修改商品分类(完整流程)
   * @param oldCategoryName 原分类名称
   * @param newCategoryName 新分类名称
   * @param newDescription 新描述
   * @param toggleStatus 是否切换状态
   */
  async updateCategory(oldCategoryName: string, newCategoryName: string, newDescription: string, toggleStatus: boolean = false): Promise<void> {
    // 搜索原分类
    await this.searchCategory(oldCategoryName);
    await this.expectCategoryVisible(oldCategoryName);
    
    // 点击修改分类
    await this.clickEditCategory();
    
    // 编辑分类信息
    await this.enterCategoryName(newCategoryName);
    await this.enterCategoryDescription(newDescription);
    
    // 切换状态(可选)
    if (toggleStatus) {
      await this.toggleCategoryStatus();
    }
    
    // 点击保存
    await this.clickConfirm();
    
    // 清除搜索框并搜索新分类名
    await this.clearSearch();
    await this.searchCategory(newCategoryName);
    await this.expectCategoryVisible(newCategoryName);
  }

  /**
   * 点击删除分类按钮
   */
  async clickDeleteCategory(): Promise<void> {
    await this.deleteCategoryButton.click();
  }

  /**
   * 验证分类已删除(不存在)
   * @param categoryName 分类名称
   */
  async expectCategoryNotVisible(categoryName: string): Promise<void> {
    await expect(this.page.locator('span').filter({ hasText: categoryName })).not.toBeVisible();
  }

  /**
   * 删除商品分类(完整流程)
   * @param categoryName 分类名称
   */
  async deleteCategory(categoryName: string): Promise<void> {
    // 搜索要删除的分类
    await this.searchCategory(categoryName);
    await this.expectCategoryVisible(categoryName);
    
    // 点击删除分类
    await this.clickDeleteCategory();
    
    // 确认删除
    await this.clickConfirm();
    
    // 等待删除完成
    await this.page.waitForTimeout(1000);
    
    // 验证分类已删除
    await this.expectCategoryNotVisible(categoryName);
  }
}