/* eslint-disable */ /** * I18N / ARABIC TEST — RTL layout + Arabic text rendering. * Switches language to Arabic, verifies dir="rtl", Arabic text, layout. * * Run headed: * E2E_MAXIMATED=1 npx playwright test --headed --project chromium i18n-arabic-test --workers=1 */ import { test } from '@playwright/test'; import { attachObservers, observe, loginAndScope, OBS, BASE_URL } from '../../helpers/audit'; import { RoleName } from '../../helpers/helpers'; const M = 'I18N'; const ADMIN: RoleName = 'hospital_admin'; type Page = import('@playwright/test').Page; async function login(page: Page) { await page.context().clearCookies(); await loginAndScope(page, ADMIN, M); } test.describe('i18n / Arabic', () => { test.describe.configure({ mode: 'serial' }); test('Switch to Arabic + verify RTL + Arabic text on key pages', async ({ page }) => { attachObservers(page, M, ADMIN); await login(page); // 1. Switch language to Arabic via the set-language endpoint const csrf = await page.context().cookies().then((c) => c.find((x) => x.name === 'csrftoken')?.value || ''); await page.context().request.post(`${BASE_URL}/i18n/setlang/`, { headers: { 'X-CSRFToken': csrf }, form: { csrfmiddlewaretoken: csrf, language: 'ar' }, maxRedirects: 0, }).catch(() => {}); // 2. Visit key pages and check RTL + Arabic const pages = [ { url: '/', label: 'dashboard' }, { url: '/complaints/', label: 'complaint-list' }, { url: '/complaints/public/submit/', label: 'public-form' }, { url: '/observations/new/', label: 'obs-form' }, { url: '/core/public/submit/', label: 'public-landing' }, ]; for (const { url, label } of pages) { try { await page.goto(`${BASE_URL}${url}`); await page.waitForLoadState('domcontentloaded'); await page.waitForTimeout(1000); // Check dir attribute const htmlDir = await page.evaluate(() => document.documentElement.dir); const htmlLang = await page.evaluate(() => document.documentElement.lang); // Check for Arabic text (basic Unicode range check) const body = (await page.textContent('body')) || ''; const hasArabic = /[\u0600-\u06FF]/.test(body); // Check for layout issues (horizontal scrollbar) const scrollWidth = await page.evaluate(() => document.documentElement.scrollWidth); const clientWidth = await page.evaluate(() => document.documentElement.clientWidth); const hasOverflow = scrollWidth > clientWidth + 10; const rtlOk = htmlDir === 'rtl'; const langOk = htmlLang === 'ar' || htmlLang.includes('ar'); const arabicOk = hasArabic; const layoutOk = !hasOverflow; const allOk = rtlOk && arabicOk && layoutOk; observe(M, `${label}-arabic`, allOk ? 'PASS' : 'WARN', `dir=${htmlDir} lang=${htmlLang} arabic=${hasArabic} overflow=${hasOverflow} body=${body.length}`, { url: page.url() }); } catch (e) { observe(M, `${label}-arabic`, 'FAIL', `exception: ${(e as Error).message.slice(0, 100)}`, {}); } } // 3. Switch back to English await page.context().request.post(`${BASE_URL}/i18n/setlang/`, { headers: { 'X-CSRFToken': csrf }, form: { csrfmiddlewaretoken: csrf, language: 'en' }, maxRedirects: 0, }).catch(() => {}); // Verify English restored await page.goto(`${BASE_URL}/`); await page.waitForLoadState('domcontentloaded'); const htmlDirEn = await page.evaluate(() => document.documentElement.dir); observe(M, 'restore-english', htmlDirEn !== 'rtl' ? 'PASS' : 'WARN', `after switching back to EN: dir=${htmlDirEn}`, {}); }); }); test.afterAll(async () => { const counts = OBS.reduce>((a, o) => ((a[o.status] = (a[o.status] || 0) + 1), a), {}); console.log('\n=========== I18N / ARABIC SUMMARY ==========='); console.log('Total observations:', OBS.length, JSON.stringify(counts)); console.log('==============================================\n'); });