import { test, expect } from '@playwright/test' import { fetchMe, loginViaUi, logoutViaProfile, registerViaUi, uniqueUsername } from './helpers/auth' test.describe('session and errors', () => { test('wrong password shows login failure', async ({ page }) => { await page.goto('/login') await page.getByLabel('نام کاربری').fill('no_such_user_e2e') await page.getByLabel('رمز عبور').fill('wrongpass') await page.getByRole('button', { name: 'ورود', exact: true }).click() await expect(page.locator('.toast--error')).toBeVisible({ timeout: 10_000 }) await expect(page).toHaveURL(/login/) }) test('second account does not show first account data', async ({ page }) => { const u1 = uniqueUsername('acct1') const u2 = uniqueUsername('acct2') await registerViaUi(page, u1, 'pass1234', 'کاربر یک') const me1 = await fetchMe(page) await page.goto('/profile') await expect(page.locator('.user-section__name')).toContainText(me1.user.name ?? 'کاربر یک') await logoutViaProfile(page) await page.getByRole('button', { name: 'ثبت‌نام کن' }).click() await page.getByLabel('نام نمایشی').fill('کاربر دو') await page.getByLabel('نام کاربری').fill(u2) await page.getByLabel('رمز عبور').fill('pass1234') await page.getByRole('button', { name: 'ثبت‌نام' }).click() await page.waitForURL('/') const me2 = await fetchMe(page) await page.goto('/profile') await expect(page.locator('.user-section__name')).toContainText(me2.user.name) await expect(page.locator('.user-section__name')).not.toContainText('کاربر یک') }) test('401 clears session to login', async ({ page }) => { const user = uniqueUsername('401') await registerViaUi(page, user, 'pass1234') await page.goto('/wallet') await page.evaluate(() => localStorage.setItem('gold-land-auth-token', 'invalid-token')) await page.goto('/market') await page.waitForURL('/login', { timeout: 15_000 }) }) test('catalog load retry after network failure', async ({ page }) => { const user = uniqueUsername('net') await registerViaUi(page, user, 'pass1234') let storeCalls = 0 await page.route('**/api/store/products', async (route) => { storeCalls += 1 if (storeCalls === 1) { await route.abort('failed') return } await route.continue() }) await page.goto('/store') await expect(page.locator('.store-status--error')).toBeVisible({ timeout: 15_000 }) await expect(page.getByText(/اتصال به سرور|خطا در دریافت/)).toBeVisible() await page.getByRole('button', { name: 'تلاش مجدد' }).click() await page.getByRole('button', { name: 'تقویت XP' }).waitFor({ timeout: 20_000 }) expect(storeCalls).toBeGreaterThan(1) }) test('bootstrap network error keeps token and retry loads server data', async ({ page }) => { const user = uniqueUsername('boot') await registerViaUi(page, user, 'pass1234') const meOk = await fetchMe(page) let meCalls = 0 await page.route('**/api/me', async (route) => { meCalls += 1 if (meCalls === 1) { await route.abort('failed') return } await route.continue() }) await page.reload() await expect(page.getByRole('alert')).toContainText('اتصال به سرور', { timeout: 15_000 }) expect(await page.evaluate(() => localStorage.getItem('gold-land-auth-token'))).toBeTruthy() await page.getByRole('button', { name: 'تلاش مجدد' }).click() await expect(page.getByRole('alert')).toBeHidden({ timeout: 20_000 }) const meAfter = await fetchMe(page) expect(meAfter.user.xp).toBe(meOk.user.xp) expect(meAfter.user.coins).toBe(meOk.user.coins) expect(meCalls).toBeGreaterThan(1) }) })