Replace 105+ fake assertions across 8 E2E test files that used
console.log('✓'/'✗') instead of expect(), causing tests to always
pass even when features were broken. Now 87 tests correctly fail,
exposing real application bugs.
Files converted:
- 09-chat-notifications-settings.spec.ts (33 fakes → real)
- 18-empty-states.spec.ts (14 fakes → real)
- 17-modals-dialogs.spec.ts (15 fakes → real)
- 07-social.spec.ts (12 fakes → real)
- 06-search-discover.spec.ts (12 fakes → real)
- 05-playlists.spec.ts (6 fakes → real)
- 08-marketplace.spec.ts (8 fakes → real)
- 10-features.spec.ts (5 fakes → real)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
242 lines
9.1 KiB
TypeScript
242 lines
9.1 KiB
TypeScript
import { test, expect } from '@chromatic-com/playwright';
|
|
import { loginViaAPI, CONFIG, navigateTo } from './helpers';
|
|
|
|
// ============================================================================
|
|
// CHAT — Messagerie temps réel (/chat)
|
|
// ============================================================================
|
|
|
|
test.describe('CHAT — Messagerie', () => {
|
|
test.beforeEach(async ({ page }) => {
|
|
await loginViaAPI(page, CONFIG.users.listener.email, CONFIG.users.listener.password);
|
|
});
|
|
|
|
test('01. Page /chat se charge @critical', async ({ page }) => {
|
|
await navigateTo(page, '/chat');
|
|
|
|
const body = await page.textContent('body') || '';
|
|
expect(body).not.toMatch(/500|error|crash/i);
|
|
expect(body.length).toBeGreaterThan(100);
|
|
});
|
|
|
|
test('02. Sidebar avec liste des conversations (Channels)', async ({ page }) => {
|
|
await navigateTo(page, '/chat');
|
|
|
|
const channelsHeading = page.getByText('Channels', { exact: true });
|
|
await expect(channelsHeading).toBeVisible();
|
|
|
|
const sidebar = page.locator('[class*="w-80"]');
|
|
await expect(sidebar.first()).toBeVisible();
|
|
});
|
|
|
|
test('03. Champ de saisie de message visible', async ({ page }) => {
|
|
await navigateTo(page, '/chat');
|
|
|
|
const msgInput = page.getByLabel('Type a message')
|
|
.or(page.getByPlaceholder(/broadcast message|écrire dans/i))
|
|
.or(page.locator('input[type="text"][aria-label="Type a message"]'));
|
|
|
|
await expect(msgInput.first()).toBeVisible();
|
|
});
|
|
|
|
test('04. Boutons attach/emoji/send présents', async ({ page }) => {
|
|
await navigateTo(page, '/chat');
|
|
|
|
await expect(page.getByLabel('Attach file')).toBeVisible();
|
|
await expect(page.getByLabel(/add emoji|close emoji/i)).toBeVisible();
|
|
await expect(page.getByLabel('Send message')).toBeVisible();
|
|
});
|
|
|
|
test('05. WebSocket status indicator visible', async ({ page }) => {
|
|
await navigateTo(page, '/chat');
|
|
|
|
const statusDot = page.locator('[class*="rounded-full"][class*="bg-success"], [class*="rounded-full"][class*="bg-destructive"]');
|
|
await expect(statusDot.first()).toBeVisible();
|
|
});
|
|
});
|
|
|
|
// ============================================================================
|
|
// NOTIFICATIONS — Centre de notifications
|
|
// ============================================================================
|
|
|
|
test.describe('NOTIFICATIONS — Centre de notifications', () => {
|
|
test.beforeEach(async ({ page }) => {
|
|
await loginViaAPI(page, CONFIG.users.listener.email, CONFIG.users.listener.password);
|
|
});
|
|
|
|
test('06. Bouton notifications (bell) visible dans le header @critical', async ({ page }) => {
|
|
await navigateTo(page, '/dashboard');
|
|
|
|
const notifBtn = page.getByRole('button', { name: 'Notifications' });
|
|
await expect(notifBtn).toBeVisible();
|
|
});
|
|
|
|
test('07. Page /notifications se charge', async ({ page }) => {
|
|
await navigateTo(page, '/notifications');
|
|
|
|
const body = await page.textContent('body') || '';
|
|
expect(body).not.toMatch(/500|error|crash/i);
|
|
|
|
const heading = page.getByRole('heading', { name: /notifications/i });
|
|
await expect(heading.first()).toBeVisible();
|
|
});
|
|
|
|
test('08. Bouton "Mark All as Read" présent si notifications non lues', async ({ page }) => {
|
|
await navigateTo(page, '/notifications');
|
|
|
|
// This button only appears when there are unread notifications — skip if none
|
|
const markAllBtn = page.getByRole('button', { name: /mark all as read|marking/i });
|
|
const visible = await markAllBtn.isVisible().catch(() => false);
|
|
test.skip(!visible, 'No unread notifications — Mark All button not expected');
|
|
|
|
await expect(markAllBtn).toBeVisible();
|
|
});
|
|
|
|
test('09. Préférences de notifications accessibles via settings', async ({ page }) => {
|
|
await navigateTo(page, '/settings');
|
|
|
|
const notifTab = page.getByRole('tab', { name: /notification/i });
|
|
await expect(notifTab.first()).toBeVisible();
|
|
|
|
await notifTab.first().click();
|
|
await page.waitForTimeout(500);
|
|
|
|
const emailNotifCheckbox = page.locator('#email_notifications');
|
|
await expect(emailNotifCheckbox).toBeVisible();
|
|
|
|
const pushNotifCheckbox = page.locator('#push_notifications');
|
|
await expect(pushNotifCheckbox).toBeVisible();
|
|
});
|
|
});
|
|
|
|
// ============================================================================
|
|
// SETTINGS — Paramètres utilisateur (/settings)
|
|
// ============================================================================
|
|
|
|
test.describe('SETTINGS — Paramètres', () => {
|
|
test.beforeEach(async ({ page }) => {
|
|
await loginViaAPI(page, CONFIG.users.listener.email, CONFIG.users.listener.password);
|
|
});
|
|
|
|
test('10. Page /settings se charge avec les tabs @critical', async ({ page }) => {
|
|
await navigateTo(page, '/settings');
|
|
|
|
const body = await page.textContent('body') || '';
|
|
expect(body).not.toMatch(/500|Internal Server Error|crash|TypeError/i);
|
|
|
|
const heading = page.getByRole('heading', { name: /system config/i });
|
|
await expect(heading).toBeVisible();
|
|
|
|
const tabPatterns: [string, RegExp][] = [
|
|
['Account', /account|compte/i],
|
|
['Preferences', /pr[ée]f[ée]rences|preferences/i],
|
|
['Notifications', /notification/i],
|
|
['Privacy', /confidentialit[ée]|privacy/i],
|
|
['Playback', /playback|lecture/i],
|
|
];
|
|
for (const [, pattern] of tabPatterns) {
|
|
const tab = page.getByRole('tab', { name: pattern }).first();
|
|
await expect(tab).toBeVisible();
|
|
}
|
|
});
|
|
|
|
test('11. Tab Account — password change form present', async ({ page }) => {
|
|
await navigateTo(page, '/settings');
|
|
|
|
const changePasswordTitle = page.getByText('Change Password', { exact: true });
|
|
await expect(changePasswordTitle.first()).toBeVisible();
|
|
|
|
await expect(page.locator('#current-password')).toBeVisible();
|
|
await expect(page.locator('#new-password')).toBeVisible();
|
|
await expect(page.locator('#confirm-password')).toBeVisible();
|
|
});
|
|
|
|
test('12. Tab Account — 2FA section present', async ({ page }) => {
|
|
await navigateTo(page, '/settings');
|
|
|
|
const twoFactorTitle = page.getByText('Two-Factor Authentication (2FA)');
|
|
await expect(twoFactorTitle).toBeVisible();
|
|
|
|
const statusText = page.getByText(/2FA is (enabled|not enabled)/);
|
|
await expect(statusText.first()).toBeVisible();
|
|
});
|
|
|
|
test('13. Tab Account — data export button (GDPR)', async ({ page }) => {
|
|
await navigateTo(page, '/settings');
|
|
|
|
const exportTitle = page.getByText('Data Export', { exact: true });
|
|
await expect(exportTitle.first()).toBeVisible();
|
|
|
|
const exportBtn = page.getByRole('button', { name: /export my data/i });
|
|
await expect(exportBtn).toBeVisible();
|
|
});
|
|
|
|
test('14. Tab Account — delete account button with warning', async ({ page }) => {
|
|
await navigateTo(page, '/settings');
|
|
|
|
const deleteTitle = page.getByText('Delete Account').first();
|
|
await expect(deleteTitle).toBeVisible();
|
|
|
|
const warningText = page.getByText(/this action cannot be undone/i);
|
|
await expect(warningText.first()).toBeVisible();
|
|
|
|
const deleteBtn = page.getByRole('button', { name: /delete account/i });
|
|
await expect(deleteBtn).toBeVisible();
|
|
});
|
|
|
|
test('15. Tab Preferences — theme radio group', async ({ page }) => {
|
|
await navigateTo(page, '/settings');
|
|
|
|
const prefsTab = page.getByRole('tab', { name: /pr[ée]f[ée]rences|preferences/i }).first();
|
|
await expect(prefsTab).toBeVisible();
|
|
await prefsTab.click();
|
|
await page.waitForTimeout(500);
|
|
|
|
await expect(page.locator('#theme-light')).toBeVisible();
|
|
await expect(page.locator('#theme-dark')).toBeVisible();
|
|
await expect(page.locator('#theme-auto')).toBeVisible();
|
|
});
|
|
|
|
test('16. Tab Preferences — language selector', async ({ page }) => {
|
|
await navigateTo(page, '/settings');
|
|
|
|
const prefsTab = page.getByRole('tab', { name: /pr[ée]f[ée]rences|preferences/i }).first();
|
|
await expect(prefsTab).toBeVisible();
|
|
await prefsTab.click();
|
|
await page.waitForTimeout(500);
|
|
|
|
const langSelect = page.locator('[name="language"]')
|
|
.or(page.locator('select[name="language"]'));
|
|
await expect(langSelect.first()).toBeVisible();
|
|
});
|
|
|
|
test('17. Tab Privacy — confidentiality settings', async ({ page }) => {
|
|
await navigateTo(page, '/settings');
|
|
|
|
const privacyTab = page.getByRole('tab', { name: /confidentialit[ée]|privacy/i }).first();
|
|
await expect(privacyTab).toBeVisible();
|
|
await privacyTab.click();
|
|
await page.waitForTimeout(500);
|
|
|
|
const body = await page.textContent('body') || '';
|
|
expect(body).toMatch(/profil|privacy|visibility|visibilit/i);
|
|
});
|
|
|
|
test('18. Tab Playback — audio quality and crossfade', async ({ page }) => {
|
|
await navigateTo(page, '/settings');
|
|
|
|
const playbackTab = page.getByRole('tab', { name: /playback|lecture/i }).first();
|
|
await expect(playbackTab).toBeVisible();
|
|
await playbackTab.click();
|
|
await page.waitForTimeout(500);
|
|
|
|
const body = await page.textContent('body') || '';
|
|
expect(body).toMatch(/quality|crossfade|autoplay|volume/i);
|
|
});
|
|
|
|
test('19. Save Config button visible', async ({ page }) => {
|
|
await navigateTo(page, '/settings');
|
|
|
|
const saveBtn = page.getByRole('button', { name: /save config/i });
|
|
await expect(saveBtn).toBeVisible();
|
|
});
|
|
});
|