import { Locator, Page } from '@playwright/test'; /** * The admin inventory tab: the item table and the form that adds to it. * * Rows are located by the item's name rather than by index. The table is shared * with every other run's items and is paginated and sortable, so an index means * a different row depending on what else exists. */ export class AdminInventory { readonly addItemButton: Locator; readonly name: Locator; readonly price: Locator; readonly category: Locator; readonly saveButton: Locator; constructor(private readonly page: Page) { this.addItemButton = page.getByRole('button', { name: 'Add Item' }); this.name = page.getByLabel('Name'); this.price = page.getByLabel('Price (USD)'); this.category = page.getByLabel('Category', { exact: true }); this.saveButton = page.getByRole('button', { name: 'Save', exact: true }); } row(itemName: string): Locator { return this.page.getByRole('row').filter({ hasText: itemName }); } /** The status chip in an item's row — PENDING, AVAILABLE, RESERVED, SOLD. */ status(itemName: string, status: string): Locator { return this.row(itemName).getByText(status); } publishButton(itemName: string): Locator { return this.row(itemName).getByRole('button', { name: 'Publish' }); } unpublishButton(itemName: string): Locator { return this.row(itemName).getByRole('button', { name: 'Unpublish' }); } /** * The preview drawer, opened by clicking an item's name. * * It renders the item as the storefront card will, which is the question an * admin is asking of a pending item — a customer never sees the pending state. */ previewDrawer(itemName: string): Locator { return this.page.getByRole('dialog', { name: `Preview: ${itemName}` }); } async openPreview(itemName: string): Promise { await this.page.getByRole('button', { name: itemName }).click(); } async openItemForm(): Promise { await this.addItemButton.click(); } }