Files
Profa 2253d05618 feat: flatten project structure — archive v2, promote v3 to root
Remove the nested v3/ subdirectory by moving all active source code,
tests, configs, and assets directly to the project root. Archive v2/
(dead code, 847MB) to v2-archive.tar.gz.

Key changes:
- Move v3/src/ → src/, v3/tests/ → tests/, v3/packages/ → packages/
- Move v3/tsconfig.json, v3/vitest.config.ts to root
- Merge v3/package.json into root package.json (ESM, scripts, deps, exports)
- Merge v3/scripts/ into scripts/, v3/implementation/ into docs/implementation/
- Update all CI workflows to remove "cd v3 &&" and v3/ path prefixes
- Fix all init installer path resolution (3-level-up → 2-level-up)
- Fix hooks to use "node ./dist/cli/bundle.js" instead of bare "aqe"
- Update settings.json ADR/DDD directories to docs/implementation/
- Fix helper scripts (statusline, adr-compliance, ddd-tracker, guidance-hooks)
- Update 58 agent definitions: aqe/v3/ → aqe/ memory namespaces
- Update 15 guidance shards: v3/src/ → src/ path references
- Fix sync interfaces: remove v3/ and v2/ path references
- Fix test path calculations (process.cwd() + '..' no longer needed)
- Fix flaky perf test threshold (500ms → 1000ms for CI environments)
- Fix complexity-analyzer test to match ADR-051 keyword-based eligibility

Build passes, 17,901 tests pass, CLI and MCP bundles verified.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 11:35:41 +00:00

272 lines
8.9 KiB
TypeScript

import { test, expect } from '@playwright/test';
import { HomePage, CatalogPage, ProductPage, CartPage, CheckoutPage } from '../pages';
import { testData } from '../fixtures/test-data';
/**
* Purchase Flow E2E Tests
* Tests the complete guest purchase journey
*
* Generated by: qe-queen-coordinator
* Priority: P0 (Critical User Journey)
*/
test.describe('Purchase Flow @purchase @critical', () => {
test.describe('Guest Purchase Journey', () => {
test('should complete full purchase flow from homepage to checkout', async ({ page }) => {
// Arrange
const homePage = new HomePage(page);
const productPage = new ProductPage(page);
const cartPage = new CartPage(page);
const checkoutPage = new CheckoutPage(page);
// Act - Navigate to homepage
await homePage.navigate();
await homePage.verifyHomepageLoaded();
// Act - Click on a product
await homePage.clickProduct(testData.products.greyJacket.name);
// Verify - Product page loaded
await productPage.verifyProductPageLoaded();
const productTitle = await productPage.getProductTitle();
expect(productTitle).toContain('jacket');
// Act - Add to cart
await productPage.addToCart();
// Act - Go to cart
await productPage.goToCart();
// Verify - Cart has item
await cartPage.verifyCartPageLoaded();
const isEmpty = await cartPage.isCartEmpty();
expect(isEmpty).toBe(false);
const itemNames = await cartPage.getItemNames();
expect(itemNames.length).toBeGreaterThan(0);
// Act - Proceed to checkout
await cartPage.proceedToCheckout();
// Verify - Checkout page loaded
await checkoutPage.verifyCheckoutLoaded();
});
test('should browse catalog and add multiple products to cart', async ({ page }) => {
const catalogPage = new CatalogPage(page);
const productPage = new ProductPage(page);
const cartPage = new CartPage(page);
// Navigate to catalog
await catalogPage.navigate();
await catalogPage.verifyCatalogLoaded();
// Verify products are displayed
const productCount = await catalogPage.getProductCount();
expect(productCount).toBeGreaterThan(0);
// Click first available product
await catalogPage.clickProductByIndex(0);
await productPage.verifyProductPageLoaded();
// Add to cart
if (await productPage.isInStock()) {
await productPage.addToCart();
}
// Verify cart updated
const cartCount = await productPage.getCartItemCount();
expect(cartCount).toBeGreaterThanOrEqual(0);
});
test('should display correct product information on product page', async ({ page }) => {
const productPage = new ProductPage(page);
// Navigate directly to a product
await productPage.navigate(testData.products.greyJacket.slug);
await productPage.verifyProductPageLoaded();
// Verify product details
const title = await productPage.getProductTitle();
const price = await productPage.getProductPrice();
expect(title.toLowerCase()).toContain('grey');
expect(price).toContain('55');
});
test('should show related products on product page', async ({ page }) => {
const productPage = new ProductPage(page);
await productPage.navigate(testData.products.greyJacket.slug);
await productPage.verifyProductPageLoaded();
// Check for related products section
const relatedProducts = await productPage.getRelatedProductNames();
// Related products may or may not be present
if (relatedProducts.length > 0) {
expect(relatedProducts.length).toBeGreaterThan(0);
}
});
});
test.describe('Cart Management', () => {
test('should handle empty cart state correctly', async ({ page }) => {
const cartPage = new CartPage(page);
await cartPage.navigate();
await cartPage.verifyCartPageLoaded();
const isEmpty = await cartPage.isCartEmpty();
expect(isEmpty).toBe(true);
});
test('should add product and verify cart contents', async ({ page }) => {
const productPage = new ProductPage(page);
const cartPage = new CartPage(page);
// Add a product
await productPage.navigate(testData.products.greyJacket.slug);
if (await productPage.isInStock()) {
await productPage.addToCart();
await productPage.goToCart();
const isEmpty = await cartPage.isCartEmpty();
expect(isEmpty).toBe(false);
const itemCount = await cartPage.getItemCount();
expect(itemCount).toBeGreaterThan(0);
}
});
test('should continue shopping from cart', async ({ page }) => {
const cartPage = new CartPage(page);
await cartPage.navigate();
// Try to continue shopping
await cartPage.continueShopping();
// Should be on collections page
const url = page.url();
expect(url).toContain('/collections');
});
});
test.describe('Checkout Process', () => {
test.beforeEach(async ({ page }) => {
// Add a product to cart before checkout tests
const productPage = new ProductPage(page);
const cartPage = new CartPage(page);
await productPage.navigate(testData.products.greyJacket.slug);
if (await productPage.isInStock()) {
await productPage.addToCart();
await productPage.goToCart();
// Verify cart is not empty
const isEmpty = await cartPage.isCartEmpty();
if (isEmpty) {
test.skip();
}
} else {
test.skip();
}
});
test('should load checkout page with contact information form', async ({ page }) => {
const cartPage = new CartPage(page);
const checkoutPage = new CheckoutPage(page);
await cartPage.navigate();
if (!(await cartPage.isCartEmpty())) {
await cartPage.proceedToCheckout();
await checkoutPage.verifyCheckoutLoaded();
// Email input should be visible
await expect(checkoutPage.emailInput).toBeVisible();
}
});
test('should validate required fields in checkout', async ({ page }) => {
const cartPage = new CartPage(page);
const checkoutPage = new CheckoutPage(page);
await cartPage.navigate();
if (!(await cartPage.isCartEmpty())) {
await cartPage.proceedToCheckout();
await checkoutPage.verifyCheckoutLoaded();
// Try to continue without filling required fields
await checkoutPage.continueToNextStep();
// Should show validation errors or remain on same step
const hasErrors = await checkoutPage.hasValidationErrors();
// Either errors shown or form not submitted
expect(page.url()).toContain('checkout');
}
});
test('should allow returning to cart from checkout', async ({ page }) => {
const cartPage = new CartPage(page);
const checkoutPage = new CheckoutPage(page);
await cartPage.navigate();
if (!(await cartPage.isCartEmpty())) {
await cartPage.proceedToCheckout();
await checkoutPage.verifyCheckoutLoaded();
await checkoutPage.returnToCart();
// Should be back on cart page
await cartPage.verifyCartPageLoaded();
}
});
});
test.describe('Product Discovery Flow', () => {
test('should navigate from homepage to catalog', async ({ page }) => {
const homePage = new HomePage(page);
const catalogPage = new CatalogPage(page);
await homePage.navigate();
await homePage.goToCatalog();
await catalogPage.verifyCatalogLoaded();
const productCount = await catalogPage.getProductCount();
expect(productCount).toBeGreaterThan(0);
});
test('should display all products in catalog', async ({ page }) => {
const catalogPage = new CatalogPage(page);
await catalogPage.navigate();
await catalogPage.verifyCatalogLoaded();
const productNames = await catalogPage.getAllProductNames();
const productPrices = await catalogPage.getAllProductPrices();
expect(productNames.length).toBeGreaterThan(0);
expect(productPrices.length).toBe(productNames.length);
// Verify prices are in expected format (GBP)
for (const price of productPrices) {
expect(price).toMatch(/[\d,.]+/);
}
});
test('should show sold out status for unavailable products', async ({ page }) => {
const catalogPage = new CatalogPage(page);
await catalogPage.navigate();
const soldOutProducts = await catalogPage.getSoldOutProducts();
// Just verify the method works - sold out products may or may not exist
expect(Array.isArray(soldOutProducts)).toBe(true);
});
});
});