veza/tests/e2e/08-marketplace.spec.ts

205 lines
7.8 KiB
TypeScript
Raw Normal View History

import { test, expect } from '@playwright/test';
import { loginViaAPI, CONFIG, navigateTo } from './helpers';
test.describe('MARKETPLACE — Navigation', () => {
test.beforeEach(async ({ page }) => {
await loginViaAPI(page, CONFIG.users.listener.email, CONFIG.users.listener.password);
});
test('01. Page marketplace se charge @critical', async ({ page }) => {
await navigateTo(page, '/marketplace');
const body = await page.textContent('body') || '';
expect(body).not.toMatch(/500|Internal Server Error/);
expect(body.length).toBeGreaterThan(50);
// MarketplacePage renders heading "Marketplace"
const heading = page.locator('h1').filter({ hasText: /marketplace/i });
const hasHeading = await heading.isVisible().catch(() => false);
console.log(` Heading Marketplace: ${hasHeading ? '✓' : '✗'}`);
});
test('02. Les produits (beats/samples) s\'affichent', async ({ page }) => {
await navigateTo(page, '/marketplace');
// ProductCard wraps in <article aria-label="Product: ...">
const products = page.locator('article[aria-label^="Product:"]');
const count = await products.count();
console.log(` Produits affichés: ${count}`);
});
test('03. Filtres marketplace fonctionnent', async ({ page }) => {
await navigateTo(page, '/marketplace');
// Search input in the filters bar
const searchInput = page.getByPlaceholder(/search tracks|search/i).first();
const hasSearch = await searchInput.isVisible().catch(() => false);
console.log(` Champ recherche: ${hasSearch ? '✓' : '✗'}`);
// Filters button
const filtersBtn = page.getByRole('button', { name: /filters/i }).first();
const hasFilters = await filtersBtn.isVisible().catch(() => false);
console.log(` Bouton Filters: ${hasFilters ? '✓' : '✗'}`);
// Cart button
const cartBtn = page.getByRole('button', { name: /cart/i }).first();
const hasCart = await cartBtn.isVisible().catch(() => false);
console.log(` Bouton Cart: ${hasCart ? '✓' : '✗'}`);
});
test('04. Page détail d\'un produit se charge', async ({ page }) => {
await navigateTo(page, '/marketplace');
// ProductCard has "Buy Now" button — check if products exist first
const products = page.locator('article[aria-label^="Product:"]');
const count = await products.count();
if (count === 0) {
console.log(' ⚠ Aucun produit disponible');
return;
}
// Look for a link to product detail page
const productLink = page.locator('a[href*="/marketplace/products/"]').first();
if (await productLink.isVisible().catch(() => false)) {
await productLink.click();
await page.waitForLoadState('networkidle');
const body = await page.textContent('body') || '';
expect(body).not.toMatch(/500|Internal Server Error/);
console.log(' Page détail produit chargée');
} else {
// Products exist but no detail links — the cards may use buy directly
console.log(' ⚠ Pas de liens vers page détail (achat direct sur carte)');
}
});
test('05. Bouton Buy Now et Add to Cart présents', async ({ page }) => {
await navigateTo(page, '/marketplace');
// ProductCard has "Buy Now" and "Add to Cart" buttons
const buyBtn = page.getByRole('button', { name: /buy now/i }).first();
const addToCartBtn = page.getByRole('button', { name: /add to cart/i }).first();
// Hover the first product card to reveal the Add to Cart button (it has opacity-0 by default)
const firstProduct = page.locator('article[aria-label^="Product:"]').first();
if (await firstProduct.isVisible().catch(() => false)) {
await firstProduct.hover();
await page.waitForTimeout(500);
}
const hasBuy = await buyBtn.isVisible().catch(() => false);
const hasAddToCart = await addToCartBtn.isVisible().catch(() => false);
console.log(` Bouton Buy Now: ${hasBuy ? '✓' : '✗'}`);
console.log(` Bouton Add to Cart: ${hasAddToCart ? '✓' : '✗'}`);
});
});
test.describe('MARKETPLACE — Dashboard vendeur', () => {
test.beforeEach(async ({ page }) => {
await loginViaAPI(page, CONFIG.users.creator.email, CONFIG.users.creator.password);
});
test('06. Dashboard vendeur accessible @critical', async ({ page }) => {
// Seller dashboard is at /sell
await navigateTo(page, '/sell');
const body = await page.textContent('body') || '';
expect(body).not.toMatch(/500|Internal Server Error/);
expect(body.length).toBeGreaterThan(100);
console.log(' Dashboard vendeur chargé à /sell');
});
});
test.describe('MARKETPLACE — Wishlist', () => {
test.beforeEach(async ({ page }) => {
await loginViaAPI(page, CONFIG.users.listener.email, CONFIG.users.listener.password);
});
test('07. Page wishlist accessible @critical', async ({ page }) => {
// Wishlist is at /wishlist
await navigateTo(page, '/wishlist');
const body = await page.textContent('body') || '';
expect(body).not.toMatch(/500|Internal Server Error/);
expect(body.length).toBeGreaterThan(50);
console.log(' Page /wishlist chargée');
});
});
test.describe('MARKETPLACE — Purchases', () => {
test.beforeEach(async ({ page }) => {
await loginViaAPI(page, CONFIG.users.listener.email, CONFIG.users.listener.password);
});
test('08. Page purchases accessible', async ({ page }) => {
// Purchases page is at /purchases
await navigateTo(page, '/purchases');
const body = await page.textContent('body') || '';
expect(body).not.toMatch(/500|Internal Server Error/);
expect(body.length).toBeGreaterThan(50);
console.log(' Page /purchases chargée');
});
});
test.describe('MARKETPLACE — Cart (in-page)', () => {
test.beforeEach(async ({ page }) => {
await loginViaAPI(page, CONFIG.users.listener.email, CONFIG.users.listener.password);
});
test('09. Cart s\'ouvre via le bouton Cart sur marketplace', async ({ page }) => {
await navigateTo(page, '/marketplace');
// MarketplacePage has a Cart button that opens a slide-over Cart component
const cartBtn = page.getByRole('button', { name: /cart/i }).first();
if (await cartBtn.isVisible().catch(() => false)) {
await cartBtn.click();
await page.waitForTimeout(500);
// Cart component should be visible (it's a slide-over panel, not a separate page)
const body = await page.textContent('body') || '';
// Cart panel should show something (empty cart message or items)
console.log(' Cart panel ouvert');
} else {
console.log(' ⚠ Bouton Cart non visible');
}
});
test('10. Ajouter un produit au cart affiche un feedback', async ({ page }) => {
await navigateTo(page, '/marketplace');
const firstProduct = page.locator('article[aria-label^="Product:"]').first();
if (!(await firstProduct.isVisible().catch(() => false))) {
console.log(' ⚠ Aucun produit disponible');
return;
}
// Hover to reveal "Add to Cart" button (hidden by default with opacity-0)
await firstProduct.hover();
await page.waitForTimeout(500);
const addToCartBtn = firstProduct.getByRole('button', { name: /add to cart/i });
if (await addToCartBtn.isVisible().catch(() => false)) {
await addToCartBtn.click();
await page.waitForTimeout(1_000);
// Toast feedback: "{title} added to cart"
const toast = page.getByTestId('toast-alert').first();
const hasToast = await toast.isVisible().catch(() => false);
console.log(` Toast feedback: ${hasToast ? '✓' : '✗'}`);
// Cart badge should update
const cartBadge = page.locator('button').filter({ hasText: /cart/i }).locator('[class*="badge"], [class*="Badge"]').first();
const hasBadge = await cartBadge.isVisible().catch(() => false);
console.log(` Cart badge mis à jour: ${hasBadge ? '✓' : '✗'}`);
} else {
console.log(' ⚠ Bouton Add to Cart non visible après hover');
}
});
});