Customer-to-order traversal
GET customers → extract data[0].id → GET customer detail → follow links.orders → extract an order ID → GET order detail.
NATHANOAK / QA / PLAYGROUND
Prefer accessible roles and labels in tests. Use data-testid when the control has no stable user-facing identity.
12 products found
| ID | Product | Category | Price | Status | Rating | Action |
|---|---|---|---|---|---|---|
| P-1001 | Aurora Keyboard | Accessories | £89 | In stock | 4.7 | |
| P-1002 | Beacon Webcam | Cameras | £129 | In stock | 4.4 | |
| P-1003 | Cedar Laptop Stand | Accessories | £54 | Back order | 4.2 | |
| P-1004 | Drift Noise-Cancelling Headset | Audio | £199 | In stock | 4.8 | |
| P-1005 | Ember USB Microphone | Audio | £149 | In stock | 4.5 |
Start with role and accessible name, then label or text. Use test IDs for implementation-neutral hooks. Avoid CSS classes and DOM position.
FRAMEWORK-NEUTRAL API LAB
The API is the system under test; Playwright and REST Assured are independent test clients. Use either framework—or separate repositories for both—against the same endpoints and expected contracts.
/api/qa/auth/login.nathanoak_qa_session cookie from Set-Cookie.401.Keep credentials in environment variables or a CI secret store. Never commit passwords, cookies or authentication-state files.
| Method | Endpoint | What to practise |
|---|---|---|
| GET | /api/qa/health | Availability, response headers and a simple 200 response. |
| GET | /api/qa/products | Query parameters, filtering, sorting, pagination and validation errors. |
| GET | /api/qa/products/{productId} | Path parameter, nested detail JSON and a 404 problem response. |
| GET | /api/qa/customers | Pagination links, nested objects, arrays, booleans and nullable fields. |
| GET | /api/qa/customers/{customerId} | Resource links, ETag caching and a conditional 304 response. |
| GET | /api/qa/customers/{customerId}/orders | Extract a customer ID, then discover related order IDs. |
| GET | /api/qa/orders/{orderId} | Nested line items, totals, timestamps, enums and null tracking data. |
| POST | /api/qa/auth/login | Credentials in the request body and an HttpOnly signed session cookie. |
| GET | /api/qa/auth/session | A protected read that proves the session cookie is being reused. |
| POST | /api/qa/profile | Authenticated request-body validation and a synthetic 201 response. |
| PUT | /api/qa/customers/{customerId}/preferences | Full replacement, 401 authentication and 422 validation. |
| POST | /api/qa/quotes | Pass customer and product IDs from earlier calls and assert calculated totals. |
| POST | /api/qa/orders | Pass the quote ID, add an Idempotency-Key and follow the Location header. |
| PATCH | /api/qa/orders/{orderId} | Partial update plus valid, invalid and conflicting state transitions. |
| DELETE | /api/qa/orders/{orderId} | Assert an empty 204 response or a 409 business-rule conflict. |
| POST | /api/qa/reports | Start asynchronous work and extract a polling URL from a 202 response. |
| GET | /api/qa/reports/{jobId} | Poll a job and assert nested aggregate/map response values. |
| GET | /api/qa/reports/orders/export | Content negotiation: JSON, CSV download or 406 Not Acceptable. |
| POST | /api/qa/auth/logout | Session termination and verification that later requests return 401. |
Do not hard-code IDs returned by discovery endpoints. Extract them, store them in a typed model or scenario context, and pass them to the next client call.
GET customers → extract data[0].id → GET customer detail → follow links.orders → extract an order ID → GET order detail.
Login → GET a customer → GET products → POST quote with extracted IDs → extract quoteId → POST order with Idempotency-Key → assert Location.
Login → POST report → assert 202 and Retry-After → follow Location → assert completed aggregates → follow export link.
GET customer → capture ETag → repeat with If-None-Match → assert 304 and an empty response body.
Login → GET a shipped order → PATCH or DELETE it → assert the 409 application/problem+json contract.
Request the export as application/json and text/csv, then request an unsupported media type and assert 406.
Best for one TypeScript portfolio containing browser and API tests. Its request context maintains cookies automatically.
const login = await request.post('/api/qa/auth/login', {
data: { username: process.env.QA_USERNAME, password: process.env.QA_PASSWORD }
});
expect(login.status()).toBe(200);
expect(login.headers()['set-cookie']).toContain('HttpOnly');
// The same request context automatically reuses the cookie.
const session = await request.get('/api/qa/auth/session');
expect(session.status()).toBe(200);Use a separate Maven or Gradle test project. Extract the cookie at login and explicitly attach it to later requests.
String sessionCookie = given()
.contentType(ContentType.JSON)
.body(Map.of("username", username, "password", password))
.when()
.post("/api/qa/auth/login")
.then()
.statusCode(200)
.header("Set-Cookie", containsString("HttpOnly"))
.extract().cookie("nathanoak_qa_session");
given().cookie("nathanoak_qa_session", sessionCookie)
.when().get("/api/qa/auth/session")
.then().statusCode(200)
.body("authenticated", equalTo(true));Assert status, body values, headers, content type, pagination, sorting and response time.
Try missing fields, invalid parameters, bad credentials, no cookie, rejected origins and rate limits. Use only synthetic data.
Validate responses against the OpenAPI 3.1 specification. Add Zod in TypeScript, JSON Schema in Java, and Pact when practising consumer-driven contracts.
Keep assertions in tests and HTTP mechanics in reusable clients. Apply patterns only where they reduce duplication or make change safer.
BaseApiClient owns base URL, headers, logging and request execution.
CustomerClient, OrderClient and ReportClient extend shared behaviour sparingly.
Expose methods such as createQuote() instead of request-library details.
Implement AuthStrategy for cookie, bearer-token or anonymous requests.
Use TypeScript interfaces or Java records/POJOs for requests and responses.
Build valid quote/profile payloads and override one field for boundary tests.
Create clients, test data and authentication contexts for each environment.
A workflow service composes customer, product, quote and order clients for chained journeys.
Suggested layers: config → HTTP client → auth strategy → domain clients → models/builders → workflows → schema validators → tests.
Objects, arrays, empty arrays, nested objects, string-keyed maps, integers, decimals, booleans, nulls, enums, ISO timestamps, pagination metadata, hypermedia links, standard JSON, problem JSON, CSV text and empty bodies.
Formats such as SOAP/XML, GraphQL, WebSocket and server-sent events are different API paradigms and should be separate focused modules rather than pretending they are ordinary REST endpoints.