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>
84 lines
3.7 KiB
TypeScript
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}"`);
|
|
});
|
|
});
|