veza/tests/e2e/audit/pixel-perfect/14-disabled-states.spec.ts
senke 4d4bfc5452 fix(e2e): prepend CONFIG.baseURL in all audit test page.goto calls
Fix 11 page.goto() calls in 6 test files that used relative URLs
without baseURL (incompatible with @chromatic-com/playwright).

Functional audit: 44/50 pass (6 test-level issues, not app bugs)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 14:26:09 +01:00

84 lines
3.7 KiB
TypeScript

import { test, expect } from '@chromatic-com/playwright';
import { loginViaAPI, navigateTo, CONFIG } from '../helpers';
import { TEST_USERS, ROUTES } from '../design-tokens';
test.describe('DISABLED — Les éléments désactivés sont visuellement distincts', () => {
test.beforeEach(async ({ page }) => {
await loginViaAPI(page, TEST_USERS.listener.email, TEST_USERS.listener.password);
});
const pagesToCheck = [
{ path: '/settings', name: 'Settings' },
{ path: '/profile', name: 'Profile' },
{ path: '/playlists', name: 'Playlists' },
{ path: '/marketplace', name: 'Marketplace' },
{ path: '/sell', name: 'Seller Dashboard', user: 'creator' },
];
for (const p of pagesToCheck) {
test(`${p.name} — boutons disabled ont opacité réduite et cursor not-allowed`, async ({ page }) => {
if (p.user === 'creator') {
await loginViaAPI(page, TEST_USERS.creator.email, TEST_USERS.creator.password);
}
await navigateTo(page, p.path);
const issues = await page.evaluate(() => {
const problems: string[] = [];
document.querySelectorAll('button[disabled], button[aria-disabled="true"], input[disabled], select[disabled], [aria-disabled="true"]').forEach(el => {
const style = getComputedStyle(el);
const opacity = parseFloat(style.opacity);
const cursor = style.cursor;
const text = el.textContent?.trim().slice(0, 20) || el.getAttribute('aria-label') || '';
const testid = el.getAttribute('data-testid');
const className = (typeof el.className === 'string' ? el.className : '').split(' ')[0] || '';
const selector = testid ? `[data-testid="${testid}"]` : `${el.tagName.toLowerCase()}.${className}`;
if (opacity > 0.7) {
problems.push(
`ÉLÉMENT: ${selector} "${text}" | PAGE: ${location.pathname} | MESURÉ: opacity ${opacity} | ATTENDU: <=0.5 | FIX TAILWIND: Ajouter disabled:opacity-50 sur ${selector}`
);
}
if (cursor !== 'not-allowed' && cursor !== 'default') {
problems.push(
`ÉLÉMENT: ${selector} "${text}" | PAGE: ${location.pathname} | MESURÉ: cursor "${cursor}" | ATTENDU: not-allowed | FIX TAILWIND: Ajouter disabled:cursor-not-allowed sur ${selector}`
);
}
});
return problems;
});
for (const issue of issues) {
console.log(`[DISABLED] ${issue}`);
}
expect(issues.length,
`Boutons disabled mal stylés sur ${p.path}:\n${issues.join('\n')}`
).toBe(0);
});
}
test('Login — soumettre avec champs vides produit un bouton loading ou disabled', async ({ page }) => {
await page.goto(CONFIG.baseURL + '/login', { waitUntil: 'domcontentloaded' });
await page.waitForLoadState('networkidle').catch(() => {});
await page.locator('main, [role="main"]').first().waitFor({ state: 'visible', timeout: 15_000 }).catch(() => {});
const email = page.locator('input[type="email"]');
await email.waitFor({ state: 'visible', timeout: 10_000 });
await email.fill(TEST_USERS.listener.email);
await page.locator('input[type="password"]').fill(TEST_USERS.listener.password);
const submit = page.getByTestId('login-submit');
await submit.click();
// Juste après le clic, le bouton devrait montrer un état loading
await page.waitForTimeout(300);
const state = await submit.evaluate(el => ({
disabled: (el as HTMLButtonElement).disabled,
ariaBusy: el.getAttribute('aria-busy'),
opacity: getComputedStyle(el).opacity,
text: el.textContent?.trim() || '',
}));
console.log(`[DISABLED] Submit after click: disabled=${state.disabled}, aria-busy=${state.ariaBusy}, opacity=${state.opacity}, text="${state.text}"`);
});
});