import { expect, test, type Page } from './fixtures'; // The Wallet section against the mock transport (no backend). The mock seeds a web/native (direct) // account holding a direct + vk chip segment and a small catalog (two chip-priced values and one // rouble-priced chip pack — see lib/mock/client.ts), so the storefront, the store-compliance // warning and the Google Play stub are all exercisable without a backend. async function loginLobby(page: Page): Promise { await page.goto('/'); await page.getByRole('button', { name: /guest/i }).click(); await expect(page.getByText('Your turn')).toBeVisible(); } async function openSettings(page: Page): Promise { await page.getByRole('button', { name: /Settings/ }).click(); // lobby ⚙️ tab await expect(page.locator('.pane')).toHaveCount(1); // let the slide settle } async function openWallet(page: Page): Promise { await openSettings(page); await page.getByRole('button', { name: 'Wallet', exact: true }).click(); await expect(page.getByTestId('wallet')).toBeVisible(); } test('wallet: balances, benefits and the storefront render for a durable account', async ({ page }) => { await loginLobby(page); await openWallet(page); // Balances: the seeded direct ("Web") and vk segments. await expect(page.getByRole('heading', { name: 'Balance' })).toBeVisible(); await expect(page.getByText('Web', { exact: true })).toBeVisible(); await expect(page.getByText('VK', { exact: true })).toBeVisible(); // Benefits + the storefront: two values priced in chips, one pack priced in roubles. await expect(page.getByRole('heading', { name: 'Benefits' })).toBeVisible(); await expect(page.getByRole('heading', { name: 'Store' })).toBeVisible(); await expect(page.getByTestId('product')).toHaveCount(3); const pack = page.locator('[data-kind="pack"]'); await expect(pack).toContainText('₽'); // The pack purchase is wired to money intake: an enabled Buy action, with the public-offer link. await expect(pack.getByTestId('buy-pack')).toBeEnabled(); await expect(page.getByTestId('offer')).toContainText('Public offer'); }); test('wallet: buying a chip pack opens the provider payment page', async ({ page }) => { await loginLobby(page); await openWallet(page); // The purchase opens the provider's hosted-payment page in a new tab (window.open); capture it. await page.evaluate(() => { (window as { __opened?: string }).__opened = ''; window.open = ((u: string) => { (window as { __opened?: string }).__opened = u; return null; }) as typeof window.open; }); await page.locator('[data-kind="pack"]').getByTestId('buy-pack').click(); await expect .poll(() => page.evaluate(() => (window as { __opened?: string }).__opened)) .toContain('robokassa'); }); test('wallet: the tab sits between Friends and About', async ({ page }) => { await loginLobby(page); await openSettings(page); const labels = await page.locator('.tab .lbl').allInnerTexts(); const iFriends = labels.indexOf('Friends'); const iWallet = labels.indexOf('Wallet'); const iAbout = labels.indexOf('Info'); expect(iFriends).toBeGreaterThanOrEqual(0); expect(iWallet).toBe(iFriends + 1); expect(iAbout).toBe(iWallet + 1); }); test('wallet: a guest has no wallet (nor friends) tab', async ({ page }) => { await page.goto('/?guest'); await page.getByRole('button', { name: /guest/i }).click(); await expect(page.getByText('Your turn')).toBeVisible(); await openSettings(page); await expect(page.getByRole('button', { name: 'Wallet', exact: true })).toBeHidden(); await expect(page.getByRole('button', { name: 'Friends', exact: true })).toBeHidden(); }); test('wallet: the Google Play build hides the money purchases behind the RuStore stub', async ({ page }) => { await page.goto('/?gp'); await page.getByRole('button', { name: /guest/i }).click(); await expect(page.getByText('Your turn')).toBeVisible(); await openWallet(page); // The chip pack is gone; the stub points at the RuStore build. Spending earned chips still works. await expect(page.getByTestId('gp-stub')).toBeVisible(); await expect(page.locator('[data-kind="pack"]')).toHaveCount(0); await expect(page.locator('[data-kind="value"]').first().getByTestId('buy')).toBeVisible(); }); test('wallet: a web spend that would draw store chips warns first, then completes', async ({ page }) => { await loginLobby(page); await openWallet(page); // The 300-chip value drains direct (120) then reaches into vk (180) → a store segment → warn. await page.locator('[data-pid="val-noads-30"]').getByTestId('buy').click(); await expect(page.getByTestId('warn')).toBeVisible(); await page.getByTestId('warn-confirm').click(); await expect(page.getByTestId('warn')).toBeHidden(); // The spend applied: the no-ads benefit now shows an end date. await expect(page.getByTestId('wallet')).toContainText('No ads until'); }); test('wallet: a spend the direct segment covers alone does not warn', async ({ page }) => { await loginLobby(page); await openWallet(page); // The 100-chip value is covered by the direct segment (120) alone → no store draw, no warning. await page.locator('[data-pid="val-hints-50"]').getByTestId('buy').click(); await expect(page.getByTestId('warn')).toBeHidden(); // The hints benefit rose from 5 to 55. await expect(page.getByTestId('wallet')).toContainText('Hints 55'); });