Files
pokemon-inventory/apps/web/tests/e2e/admin-catalog-workflow.spec.js
T
fragginwagon 455971431f
Quality / test (push) Canceled after 0s
feat: add admin dashboard summary
Add seller-scoped dashboard aggregation and API, private financial summary DTOs, responsive admin metrics, and authenticated E2E coverage.
2026-09-09 01:00:28 -04:00

80 lines
4.9 KiB
JavaScript

import { expect, test } from '@playwright/test';
const tinyPng = Buffer.from('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNk+A8AAQUBAScY42YAAAAASUVORK5CYII=', 'base64');
test('signs in and publishes a listing after adding an inventory image', async ({ page }) => {
const email = process.env.INITIAL_ADMIN_EMAIL;
const password = process.env.INITIAL_ADMIN_PASSWORD;
test.skip(!email || !password, 'Set INITIAL_ADMIN_EMAIL and INITIAL_ADMIN_PASSWORD for the local authenticated workflow.');
await page.goto('/login');
await page.getByLabel('Email').fill(email);
await page.getByLabel('Password').fill(password);
await page.getByRole('button', { name: 'Sign in' }).click();
await expect(page).toHaveURL(/\/admin$/);
await expect(page.getByRole('heading', { name: 'Collector workspace' })).toBeVisible();
await expect(page.getByRole('status', { name: 'Loading inventory...' })).toHaveCount(0);
await expect(page.getByRole('heading', { name: 'At a glance' })).toBeVisible();
await expect(page.getByText('Active inventory')).toBeVisible();
const category = page.locator('#product-category option').nth(1);
await expect(category).toBeAttached();
const productName = `Browser test collectible ${Date.now()}`;
await page.getByLabel('Name').fill(productName);
await page.getByLabel('Category').selectOption({ index: 1 });
await page.getByRole('button', { name: 'Create product' }).click();
await expect(page.locator('#inventory-product option').nth(1)).toBeAttached();
const createdProductId = await page.getByLabel('Product', { exact: true }).locator('option', { hasText: productName }).getAttribute('value');
await page.getByLabel('Product', { exact: true }).selectOption(createdProductId);
await page.getByLabel('Condition', { exact: true }).selectOption({ index: 1 });
await page.getByRole('button', { name: 'Create copy' }).click();
const createdInventoryRow = page.locator(`section[aria-labelledby="inventory-title"] li[data-product-id="${createdProductId}"]`).last();
const createdInventoryId = await createdInventoryRow.locator('a').getAttribute('href').then((href) => href.split('/').at(-2));
const inventoryLink = page.locator(`a[href="/admin/inventory/${createdInventoryId}/images"]`);
await expect(inventoryLink).toBeVisible();
await page.locator('#acquisition-inventory').selectOption(createdInventoryId);
await page.getByLabel('Method').fill('PURCHASE');
await page.getByLabel('Acquisition date').fill('2026-09-09');
await page.getByLabel('Cost (cents)').fill('1000');
await page.getByLabel('Shipping (cents)').fill('100');
await page.getByLabel('Tax (cents)').fill('50');
await page.getByRole('button', { name: 'Record acquisition' }).click();
await expect(page.locator('section[aria-labelledby="acquisitions-title"] li').first()).toContainText('Basis $11.50');
await inventoryLink.click();
await expect(page).toHaveURL(/\/admin\/inventory\/[^/]+\/images$/);
await expect(page.getByRole('heading', { name: 'Manage images' })).toBeVisible();
await page.getByLabel('Add image').setInputFiles({
name: 'front.png',
mimeType: 'image/png',
buffer: tinyPng,
});
await expect(page.getByLabel('Alt text')).toHaveValue('front.png');
await page.goto('/admin');
await expect(page.getByRole('heading', { name: 'Create listing draft' })).toBeVisible();
await page.getByLabel('Inventory copy', { exact: true }).first().selectOption(createdInventoryId);
await page.getByLabel('Asking price (cents)').fill('2499');
await page.getByRole('button', { name: 'Create listing' }).click();
const createdListing = page.locator('section[aria-labelledby="listings-title"] article').filter({ hasText: productName }).last();
await expect(createdListing.getByText('Add at least one image before publishing.')).toHaveCount(0);
await createdListing.getByRole('button', { name: 'Publish' }).click();
await expect(createdListing).toContainText('AVAILABLE');
await page.locator('#sale-inventory').selectOption(createdInventoryId);
await page.getByLabel('Sale date').fill('2026-09-09');
await page.getByLabel('Sold price (cents)').fill('2499');
await page.getByLabel('Cost basis (cents)').fill('1200');
await page.getByRole('button', { name: 'Record sale' }).click();
await expect(page.locator('section[aria-labelledby="inventory-title"]').getByText(`${createdInventoryId} · SOLD`)).toBeVisible();
await expect(page.getByRole('heading', { name: 'Sale history' })).toBeVisible();
const latestSale = page.locator('section[aria-labelledby="sales-title"] li').first();
await expect(latestSale).toContainText('Profit $12.99');
await latestSale.getByLabel('Void reason').fill('Browser test correction');
await latestSale.getByRole('button', { name: 'Void sale' }).click();
await expect(latestSale).toContainText('VOIDED');
await expect(page.locator('section[aria-labelledby="inventory-title"]').getByText(`${createdInventoryId} · ACTIVE`)).toBeVisible();
});