Example App UI Components
Relevant source files
The following files were used as context for generating this wiki page:
The Example App UI Components constitute a minimal React-based checkout application designed to demonstrate the integration of the playwright-page-object library. The application provides a functional interface for managing a shopping cart, applying promotional codes, and viewing order summaries. Sources: example/README.md, example/src/App.tsx:21-42
These components are structured to expose specific data-testid attributes, facilitating a decorator-driven locator strategy in end-to-end tests. The architecture follows a standard React unidirectional data flow, where state is managed at the root and passed down to specialized UI components. Sources: example/src/components/CheckoutPage.tsx:18-54, example/e2e/page-objects/CheckoutPage.ts:13-25
Core Application Structure
The application is bootstrapped from a standard HTML entry point and managed by a root React component that maintains the global state for the cart and promotions. Sources: example/index.html:10, example/src/App.tsx:21-23
App Component Logic
The App component serves as the central state controller. it initializes a list of items and handles the removal logic and promo application. Sources: example/src/App.tsx:11-30
The diagram above illustrates the data flow from the central App state to the UI sub-components.
Sources: example/src/App.tsx:32-41, example/src/components/CheckoutPage.tsx:47-51
UI Component Breakdown
CheckoutPage Component
The CheckoutPage is the primary layout component, divided into a promotional section and a cart display section. It utilizes semantic HTML and test-specific attributes for automation. Sources: example/src/components/CheckoutPage.tsx:18-54
| Element | Attribute | Purpose |
|---|---|---|
| Main Container | data-testid="CheckoutPage" | Root locator for the page object. |
| Promo Input | data-testid="PromoCodeInput" | Text field for entering discount codes. |
| Apply Button | data-testid="ApplyPromoButton" | Trigger for promo application logic. |
| Cart List | data-testid="CartItemsList" | Container for individual cart items. |
| Empty State | data-testid="EmptyCart" | Displayed when the cart length is zero. |
Sources: example/src/components/CheckoutPage.tsx:19-45, example/e2e/page-objects/CheckoutPage.ts:13-17
Promotional Logic Flow
When a user interacts with the promo section, the application updates the local state which reflects back in the UI via a conditional success message. Sources: example/src/App.tsx:29-31, example/src/components/CheckoutPage.tsx:39
Sequence diagram showing the interaction between user input and state update for promotional codes.
Sources: example/src/components/CheckoutPage.tsx:22-39, example/src/App.tsx:26-31
E2E Testing Integration
The UI components are specifically modeled in Playwright using the playwright-page-object pattern. The CheckoutPage class maps the React components to typed accessors. Sources: example/e2e/page-objects/CheckoutPage.ts:13-33
Selector Composition
The page object uses different decorator styles to interact with the UI:
- @Selector: Used for standard test IDs like the promo input. Sources: example/e2e/page-objects/CheckoutPage.ts:15-19
- @SelectorByRole: Used for semantic elements like buttons. Sources: example/e2e/page-objects/CheckoutPage.ts:22-23
- @ListStrictSelector: Used to manage the collection of cart items rendered in the list. Sources: example/e2e/page-objects/CheckoutPage.ts:25-26
Testing Workflow Example
The following snippet demonstrates how a test interacts with the UI components via the Page Object:
test("should apply promo code", async ({ checkoutPage }) => {
// Interacts with data-testid="PromoCodeInput" and "ApplyPromoButton"
await checkoutPage.applyPromoCode("SAVE20");
// Interacts with data-testid="CartItem" collection
await checkoutPage.expectCartHasItemCount(2);
});
Sources: example/e2e/checkout.spec.ts:11-17, example/e2e/page-objects/CheckoutPage.ts:33-43
Summary
The Example App UI Components provide a clear demonstration of how React component structures (containers, inputs, and lists) map directly to a typed, decorator-driven testing framework. By decoupling selector logic into Page Objects, the application ensures that UI changes in components like CheckoutPage.tsx only require single-point updates in the corresponding TypeScript models. Sources: example/README.md, example/src/App.tsx:32-42