test(e2e): convert the favorites, availability and orders specs (#137)
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
This commit is contained in:
@@ -0,0 +1,29 @@
|
||||
import { Locator, Page } from '@playwright/test';
|
||||
|
||||
/**
|
||||
* Order history, which is a page rather than a modal.
|
||||
*
|
||||
* That distinction is the point of the specs using this: /orders is
|
||||
* deliberately not in MODAL_ROUTES, so there is no dialog and the storefront is
|
||||
* not rendered behind it. Putting it back would quietly undo that, which is why
|
||||
* the absence of a dialog is asserted rather than assumed.
|
||||
*/
|
||||
export class OrdersPage {
|
||||
readonly heading: Locator;
|
||||
readonly noOrdersNotice: Locator;
|
||||
readonly continueShoppingButton: Locator;
|
||||
readonly backToShopButton: Locator;
|
||||
readonly anyDialog: Locator;
|
||||
|
||||
constructor(private readonly page: Page) {
|
||||
this.heading = page.getByRole('heading', { name: 'Order History' });
|
||||
this.noOrdersNotice = page.getByText('No orders yet');
|
||||
this.continueShoppingButton = page.getByRole('button', { name: 'Continue Shopping' });
|
||||
this.backToShopButton = page.getByRole('button', { name: 'Back to Shop' });
|
||||
this.anyDialog = page.getByRole('dialog');
|
||||
}
|
||||
|
||||
async goto(): Promise<void> {
|
||||
await this.page.goto('/orders');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user