mirror of
https://github.com/proffesor-for-testing/agentic-qe.git
synced 2026-09-19 08:45:47 +08:00
2253d05618
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>
272 lines
8.9 KiB
TypeScript
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);
|
|
});
|
|
});
|
|
});
|