Tests / test (push) Canceled after 0s
Native crypto / native-crypto (push) Canceled after 0s
Release (main) / android (oneme) (push) Canceled after 0s
Release (main) / android (qlyra) (push) Canceled after 0s
Release (main) / windows (push) Canceled after 0s
Release (main) / linux (push) Canceled after 0s
Release (main) / macos (push) Canceled after 0s
Release (main) / ios (push) Canceled after 0s
Release (main) / release (push) Canceled after 0s
75 lines
6.1 KiB
JavaScript
75 lines
6.1 KiB
JavaScript
// Run against the isolated fixture from start_admin_test_server.ps1, never production.
|
|
const fs = require('node:fs');
|
|
const path = require('node:path');
|
|
const assert = require('node:assert/strict');
|
|
const { chromium } = require(process.env.PLAYWRIGHT_MODULE || 'playwright');
|
|
const repo = path.resolve(__dirname, '..');
|
|
const run = JSON.parse(fs.readFileSync(path.join(repo, 'artifacts/admin-local-server.json'), 'utf8').replace(/^\uFEFF/, ''));
|
|
const fixture = JSON.parse(fs.readFileSync(path.join(repo, 'artifacts/admin-ui-fixture.json'), 'utf8'));
|
|
if (run.url !== 'http://127.0.0.1:15199') throw new Error('Only the loopback fixture is allowed');
|
|
(async () => {
|
|
const browser = await chromium.launch({headless: true, executablePath: process.env.ADMIN_BROWSER || 'C:/Program Files (x86)/Microsoft/Edge/Application/msedge.exe'});
|
|
try {
|
|
const page = await browser.newPage({viewport: {width: 1440, height: 1000}});
|
|
page.setDefaultTimeout(15000);
|
|
const errors = []; page.on('pageerror', e => errors.push(e.message));
|
|
page.on('dialog', d => d.accept());
|
|
await page.goto(run.url + '/admin/');
|
|
await page.locator('#loginUsername').fill('admin-test');
|
|
await page.locator('#loginPassword').fill('test-only-password');
|
|
await page.locator('#loginForm button').click();
|
|
await page.waitForFunction(() => document.querySelector('#usersCount').textContent.includes('пользователей'));
|
|
assert.equal(await page.locator('#adminIdentity').textContent(), 'admin-test');
|
|
await page.screenshot({path: path.join(repo, 'artifacts/admin-overview.png'), fullPage: true});
|
|
await page.locator('.nav-item[data-section=users]').click();
|
|
await page.locator('#usersPager [data-page="2"]').click();
|
|
await page.waitForFunction(() => document.querySelector('#usersPager').textContent.includes('Страница 2'));
|
|
await page.locator('#globalSearch').fill('UI пользователь <script>');
|
|
await page.waitForFunction(() => document.querySelectorAll('#usersTable tr').length === 1);
|
|
assert.equal(await page.locator('#usersTable script').count(), 0);
|
|
await page.locator(`[data-action=console-user][data-id="${fixture.userId}"]`).click();
|
|
await page.locator('#consoleDialog input[name=displayName]').fill('Имя после редактирования');
|
|
await page.locator('form[data-console-form=user] button').click();
|
|
await page.waitForFunction(() => document.querySelector('#dialogTitle').textContent.startsWith('Имя после редактирования'));
|
|
await page.locator('[data-action=console-revoke-all]').click();
|
|
await page.waitForFunction(() => !document.querySelector('[data-action=console-revoke-session]'));
|
|
await page.locator('[data-action=console-close]').click();
|
|
await page.locator('#globalSearch').fill('');
|
|
await page.locator('.nav-item[data-section=reports]').click();
|
|
await page.locator('[data-action=console-report]').click();
|
|
await page.locator('form[data-console-form=report] textarea').fill('Спам подтверждён, сообщение скрыто');
|
|
await page.locator('form[data-console-form=report] select[name=action]').selectOption('delete-message');
|
|
await page.locator('form[data-console-form=report] button').click();
|
|
await page.waitForFunction(() => !document.querySelector('#consoleDialog').open);
|
|
await page.locator('#reportStatus').selectOption('resolved');
|
|
await page.locator('[data-action=console-report]').waitFor();
|
|
await page.locator('.nav-item[data-section=bots]').click();
|
|
await page.locator(`[data-action=console-bot][data-id="${fixture.botId}"]`).click();
|
|
await page.locator('form[data-console-form=bot] input[name=enabled]').uncheck();
|
|
await page.locator('form[data-console-form=bot] button').click();
|
|
await page.waitForFunction(() => document.querySelector('#botsContent').textContent.includes('Отключён'));
|
|
await page.locator('.nav-item[data-section=chats]').click();
|
|
await page.locator(`[data-action=open-chat][data-chat-id="${fixture.chatId}"]`).click();
|
|
await page.locator('[data-action=console-messages]').click();
|
|
await page.locator(`[data-action=console-message][data-id="${fixture.messageId}"][data-mode=restore]`).click();
|
|
await page.locator(`[data-action=console-message][data-id="${fixture.messageId}"][data-mode=hide]`).waitFor();
|
|
await page.locator('[data-action=console-close]').click();
|
|
for (const section of ['media', 'moderation', 'audit', 'security', 'updates', 'operations']) {
|
|
await page.locator(`.nav-item[data-section=${section}]`).click();
|
|
if (section === 'audit') await page.waitForFunction(() => document.querySelector('#auditContent').textContent.includes('admin-test'));
|
|
if (section === 'security') await page.waitForFunction(() => document.querySelector('#securityContent').textContent.includes('Эта сессия'));
|
|
if (section === 'operations') await page.waitForFunction(() => document.querySelector('#operationsDetails').textContent.includes('Свободно на диске'));
|
|
}
|
|
await page.locator('.nav-item[data-section=overview]').click();
|
|
await page.setViewportSize({width: 390, height: 844});
|
|
await page.screenshot({path: path.join(repo, 'artifacts/admin-mobile.png'), fullPage: true});
|
|
const width = await page.evaluate(() => ({viewport: innerWidth, content: document.documentElement.scrollWidth}));
|
|
assert.ok(width.content <= width.viewport + 1, `Mobile overflow: ${JSON.stringify(width)}`);
|
|
await page.locator('#logoutButton').click(); await page.locator('#loginForm').waitFor({state: 'visible'});
|
|
assert.deepEqual(errors, []);
|
|
const result = {passed: true, login: true, pagination: true, escapedHtml: true, profileEdit: true, sessionRevocation: true, reportResolution: true, botSettings: true, messageRestore: true, allSections: true, responsive: width, browserErrors: errors, logout: true};
|
|
fs.writeFileSync(path.join(repo, 'artifacts/admin-ui-verification.json'), JSON.stringify(result, null, 2));
|
|
console.log(JSON.stringify(result));
|
|
} finally { await browser.close(); }
|
|
})().catch(e => { console.error(e); process.exitCode = 1; });
|