import { test, expect } from './fixtures'; const suffix = () => `s${Date.now().toString(36)}${Math.random().toString(36).slice(2, 7)}`; // Creates an item and leaves it as it arrives — pending. Deliberately does not // publish, unlike the other specs' fixtures, because the staged state is what // is being tested here. async function createStagedItem(page: import('@playwright/test').Page, name: string) { const created = await page.request.post('/api/admin/items', { multipart: { name, description: '', price: '55', category_id: '', tags: '[]' } }); expect(created.ok()).toBeTruthy(); const body = await created.json(); // The whole premise: creating something does not publish it. expect(body.status).toBe('pending'); return body.id as number; } const rowFor = (page: import('@playwright/test').Page, name: string) => page.getByRole('row').filter({ hasText: name }); test.describe('Staging an item until it is published', () => { test('a new item is held back from the storefront until published', async ({ page }) => { const name = `Staged ${suffix()}`; await createStagedItem(page, name); // Not in the catalogue while pending. await page.goto('/'); await expect(page.getByText(name)).toHaveCount(0); // It is in the admin, marked as pending. await page.goto('/admin'); const row = rowFor(page, name); await expect(row).toBeVisible(); await expect(row.getByText('PENDING')).toBeVisible(); await row.getByRole('button', { name: 'Publish' }).click(); await expect(row.getByText('AVAILABLE')).toBeVisible(); // And now a customer can see it. await page.goto('/'); await expect(page.getByText(name)).toBeVisible(); }); test('publishing can be undone while nobody is holding the item', async ({ page }) => { const name = `Staged ${suffix()}`; const id = await createStagedItem(page, name); expect((await page.request.post(`/api/admin/items/${id}/mark-available`)).ok()).toBeTruthy(); await page.goto('/'); await expect(page.getByText(name)).toBeVisible(); await page.goto('/admin'); const row = rowFor(page, name); await row.getByRole('button', { name: 'Unpublish' }).click(); await expect(row.getByText('PENDING')).toBeVisible(); await page.goto('/'); await expect(page.getByText(name)).toHaveCount(0); }); // The two features together, which is the reason for wanting both: a staged // item is previewed as it will look once live, because a customer never sees // the pending state and "how will this look" is the question being asked. test('a pending item previews as it will look once published', async ({ page }) => { const name = `Staged ${suffix()}`; await createStagedItem(page, name); await page.goto('/admin'); await page.getByRole('button', { name }).click(); const drawer = page.getByRole('dialog', { name: `Preview: ${name}` }); await expect(drawer).toBeVisible(); await expect(drawer.getByText('$55.00')).toBeVisible(); // The live card's action, not a pending placeholder. await expect(drawer.getByRole('button', { name: 'Add to Cart' })).toBeVisible(); }); });