favorites, favorites-filter, sold-filter, orders and pending-publish. Five more copies of "register a customer" and three more of the hardcoded base URL go with them. Two locators that were hiding real knowledge are now named. `gridCell` is the item's whole antd column rather than its card, needed because the SOLD ribbon renders outside the card — three specs reached for `.ant-col` directly to get at it. And `chooseAvailability` goes through the title attribute because antd's Segmented hides the real radio behind a styled label, so the input is found by role and cannot be clicked; that fact was written out twice in comments and is now written once in code. The favorite control is located page-wide rather than within a card. The storefront paginates as items accumulate and the control is named for its item anyway, so scoping to a card bought nothing and broke whenever the card was on another page. favorites-filter keeps its local `favorite()` helper. It is genuinely local — decline the opt-in, wait for the fading modal to stop intercepting pointer events, confirm the heart flipped — and belongs to that file's subject rather than to the storefront. It now takes page objects as parameters instead of reaching for locators itself, which is what a spec-level helper should look like. Two specs still drive the registration form rather than taking the `customer` fixture, and deliberately. Both are about a signed-out visitor being interrupted mid-action — favoriting an item, or switching on the favorites filter — and the claim is that the thing they asked for survives the interruption. Replacing the interruption with an API call would delete the test. Verified: favorites 6/6, favorites-filter 7/7, sold-filter 6/6, orders and pending-publish 8/8. Notably favorites-filter's "keeps showing a favorite after it sells" passes, which had been failing on a strict-mode violation from two items sharing a name across runs. Refs #137
119 lines
4.5 KiB
TypeScript
119 lines
4.5 KiB
TypeScript
import { test, expect, createAdminContext, createItem, uniqueSuffix, uniqueEmail, PASSWORD } from './fixtures';
|
|
|
|
const ITEM = `Favoritable ${uniqueSuffix()}`;
|
|
|
|
test.beforeAll(async ({ playwright }) => {
|
|
const api = await createAdminContext(playwright);
|
|
await createItem(api, { name: ITEM, price: '60' });
|
|
await api.dispose();
|
|
});
|
|
|
|
test.describe('Favoriting items', () => {
|
|
// Drives the registration form rather than taking the `customer` fixture:
|
|
// the claim here is that the favorite a signed-out visitor asked for survives
|
|
// being interrupted by signing up, so the interruption has to be real.
|
|
test('a signed-out visitor is prompted to sign in, and the favorite completes', async ({
|
|
storefront,
|
|
authModal
|
|
}) => {
|
|
await storefront.goto();
|
|
await storefront.favoriteToggle(ITEM).first().click();
|
|
|
|
// Same inline prompt Add to Cart already uses.
|
|
await expect(authModal.registerDialog).toBeVisible();
|
|
|
|
await authModal.fillRegistration({
|
|
email: uniqueEmail('fav'),
|
|
password: PASSWORD,
|
|
firstName: 'Test',
|
|
lastName: 'Customer'
|
|
});
|
|
await authModal.submitRegistration();
|
|
|
|
// The favorite the visitor originally asked for is applied on success.
|
|
await expect(storefront.removeFromFavoritesButton(ITEM)).toBeVisible({ timeout: 20000 });
|
|
});
|
|
|
|
test('offers the alert opt-in with a reason, and it is not the marketing consent', async ({
|
|
page,
|
|
customer,
|
|
storefront,
|
|
favoritePrompt
|
|
}) => {
|
|
await storefront.gotoSignedIn();
|
|
await storefront.favoriteToggle(ITEM).first().click();
|
|
|
|
await expect(favoritePrompt.dialog).toBeVisible();
|
|
await expect(favoritePrompt.dialog).toContainText('Want to know if this sells?');
|
|
// The reason for asking has to be given, not just the ask.
|
|
await expect(favoritePrompt.dialog).toContainText(/one of a kind/i);
|
|
await expect(favoritePrompt.dialog).toContainText(/separate from any marketing/i);
|
|
|
|
await favoritePrompt.acceptAlerts();
|
|
await expect(page.getByText('We will let you know')).toBeVisible();
|
|
|
|
const me = await (await page.request.get('/api/customers/me')).json();
|
|
expect(me.favorite_alerts).toBe(true);
|
|
// Accepting item alerts must not sign anyone up for marketing.
|
|
expect(me.marketing_consent).toBe(false);
|
|
});
|
|
|
|
test('declining the opt-in still keeps the favorite', async ({
|
|
page,
|
|
customer,
|
|
storefront,
|
|
favoritePrompt
|
|
}) => {
|
|
await storefront.gotoSignedIn();
|
|
await storefront.favoriteToggle(ITEM).first().click();
|
|
await favoritePrompt.declineAlerts();
|
|
|
|
await expect(storefront.removeFromFavoritesButton(ITEM)).toBeVisible();
|
|
|
|
const favorites = await (await page.request.get('/api/customers/me/favorites')).json();
|
|
expect(favorites).toHaveLength(1);
|
|
|
|
const me = await (await page.request.get('/api/customers/me')).json();
|
|
expect(me.favorite_alerts).toBe(false);
|
|
});
|
|
|
|
test('unfavoriting removes it', async ({ page, customer, storefront, favoritePrompt }) => {
|
|
await storefront.gotoSignedIn();
|
|
await storefront.favoriteToggle(ITEM).first().click();
|
|
await favoritePrompt.declineAlerts();
|
|
await expect(storefront.removeFromFavoritesButton(ITEM)).toBeVisible();
|
|
|
|
await storefront.removeFromFavoritesButton(ITEM).click();
|
|
await expect(storefront.addToFavoritesButton(ITEM)).toBeVisible();
|
|
|
|
const favorites = await (await page.request.get('/api/customers/me/favorites')).json();
|
|
expect(favorites).toEqual([]);
|
|
});
|
|
|
|
test('favorites survive a reload', async ({ page, customer, storefront, favoritePrompt }) => {
|
|
await storefront.gotoSignedIn();
|
|
await storefront.favoriteToggle(ITEM).first().click();
|
|
await favoritePrompt.declineAlerts();
|
|
await expect(storefront.removeFromFavoritesButton(ITEM)).toBeVisible();
|
|
|
|
// Proves it was stored server-side rather than held in component state.
|
|
await page.reload();
|
|
await expect(storefront.removeFromFavoritesButton(ITEM)).toBeVisible();
|
|
});
|
|
|
|
test('the account page can turn the alerts off again', async ({ page, customer, accountModal }) => {
|
|
await page.request.put('/api/customers/me/favorite-alerts', { data: { enabled: true } });
|
|
|
|
await accountModal.open();
|
|
await expect(
|
|
accountModal.dialog.getByText('Email me when an item I favorited is sold')
|
|
).toBeVisible();
|
|
|
|
await accountModal.favoriteAlertsSwitch.click();
|
|
await expect(page.getByText('Turned off')).toBeVisible();
|
|
|
|
const me = await (await page.request.get('/api/customers/me')).json();
|
|
expect(me.favorite_alerts).toBe(false);
|
|
});
|
|
});
|