51 lines
6.7 KiB
JavaScript
51 lines
6.7 KiB
JavaScript
async (page) => {
|
|
const origin = page.url().startsWith('http') ? new URL(page.url()).origin : 'http://127.0.0.1:5179'; const browser = page.context().browser(); const contexts = []; const results = [];
|
|
const password = 'Channel-domains-test-password'; const suffix = Date.now(); const ownerName = `domains_owner_${suffix}`; const memberName = `domains_member_${suffix}`;
|
|
let owner, member; const failures = [];
|
|
async function account(username) {
|
|
const context = await browser.newContext({ viewport: { width: 1440, height: 900 } }); contexts.push(context); const target = await context.newPage();
|
|
await target.goto(origin); await target.getByLabel('用户名', { exact: true }).fill(username); await target.getByLabel('密码', { exact: true }).fill(password);
|
|
await target.getByRole('button', { name: '创建账号', exact: true }).click(); await target.getByRole('button', { name: '新建空间', exact: true }).waitFor(); return target;
|
|
}
|
|
async function send(target, text) { await target.getByRole('region', { name: '常规 聊天', exact: true }).locator('textarea').fill(text); await target.getByRole('button', { name: '发送消息', exact: true }).click(); await target.getByRole('article').getByText(text, { exact: true }).waitFor(); }
|
|
try {
|
|
owner = await account(ownerName); member = await account(memberName);
|
|
member.on('response', async response => { if (response.status() >= 400 && response.url().includes('/api/v1/')) failures.push({ status: response.status(), method: response.request().method(), path: new URL(response.url()).pathname, code: (await response.json().catch(() => ({}))).error }); });
|
|
await owner.getByRole('button', { name: '新建空间', exact: true }).click(); await owner.getByLabel('空间名称(加入者和服务端可见)').fill('独立数据域测试'); await owner.getByRole('button', { name: '创建', exact: true }).click();
|
|
await owner.getByRole('button', { name: '常规', exact: true }).waitFor(); const path = new URL(owner.url()).pathname;
|
|
await send(owner, '加入前的历史聊天');
|
|
const ownerExplorer = owner.getByRole('region', { name: '频道文件管理器' });
|
|
await ownerExplorer.locator('input[type=file]').setInputFiles({ name: 'old-domain-file.txt', mimeType: 'text/plain', buffer: Buffer.from('historical file must remain private') });
|
|
await owner.getByRole('button', { name: '继续上传', exact: true }).click(); await owner.getByRole('button', { name: 'old-domain-file.txt', exact: true }).waitFor();
|
|
await owner.getByRole('button', { name: '在未分组新建频道', exact: true }).click(); await owner.getByLabel('频道名称', { exact: true }).fill('单独授权频道'); await owner.getByRole('button', { name: '创建频道', exact: true }).click();
|
|
await owner.getByRole('button', { name: '单独授权频道', exact: true }).waitFor(); await owner.getByRole('button', { name: '常规', exact: true }).click();
|
|
await owner.getByRole('button', { name: '频道设置 常规', exact: true }).click(); await owner.getByLabel('新成员可读历史聊天').uncheck(); await owner.getByLabel('新成员可读历史文件').uncheck();
|
|
await owner.getByRole('button', { name: '保存', exact: true }).click(); await owner.getByRole('button', { name: '保存', exact: true }).waitFor({ state: 'hidden' });
|
|
await owner.getByRole('button', { name: '空间设置', exact: true }).click(); await owner.getByLabel('被邀请用户的用户名').fill(memberName); await owner.getByRole('button', { name: '发送邀请', exact: true }).click();
|
|
await owner.getByText(`${memberName} · 已邀请`, { exact: true }).waitFor(); await owner.getByRole('dialog').getByRole('button', { name: '关闭', exact: true }).click();
|
|
await member.goto(origin + path); await member.getByRole('button', { name: '接受并加入空间', exact: true }).click(); await member.getByRole('button', { name: '常规', exact: true }).waitFor();
|
|
if (await member.getByRole('button', { name: '单独授权频道', exact: true }).count()) throw new Error('Member received an unauthorized channel');
|
|
if (await member.getByRole('article').getByText('加入前的历史聊天', { exact: true }).count()) throw new Error('Member received historical chat keys');
|
|
if (await member.getByRole('button', { name: 'old-domain-file.txt', exact: true }).count()) throw new Error('Member received historical file keys');
|
|
await send(owner, '加入后的新聊天'); await member.getByRole('article').getByText('加入后的新聊天', { exact: true }).waitFor();
|
|
const ownerMessage = owner.locator('article').filter({ hasText: '加入后的新聊天' });
|
|
const memberCopy = member.locator('article').filter({ hasText: '加入后的新聊天' });
|
|
if (await ownerMessage.evaluate(element => getComputedStyle(element).flexDirection) !== 'row-reverse'
|
|
|| await memberCopy.evaluate(element => getComputedStyle(element).flexDirection) !== 'row') throw new Error('Messages are not aligned by sender');
|
|
await send(member, '成员发言验证'); await owner.getByRole('article').getByText('成员发言验证', { exact: true }).waitFor();
|
|
results.push('default-channel access is automatic; other channels and past epochs remain inaccessible');
|
|
const explorer = ownerExplorer;
|
|
await explorer.locator('input[type=file]').setInputFiles({ name: 'new-domain-file.txt', mimeType: 'text/plain', buffer: Buffer.from('independent random file key verification') });
|
|
await owner.getByRole('button', { name: '继续上传', exact: true }).click(); await member.getByRole('button', { name: 'new-domain-file.txt', exact: true }).waitFor();
|
|
await member.getByRole('button', { name: 'new-domain-file.txt', exact: true }).dblclick();
|
|
await member.getByRole('dialog').locator('pre').filter({ hasText: 'independent random file key verification' }).waitFor();
|
|
results.push('file-group key unwraps an independent file key and decrypts the file on another account');
|
|
await member.getByRole('dialog').getByRole('button', { name: '关闭', exact: true }).click(); await member.reload(); await member.getByRole('article').getByText('加入后的新聊天', { exact: true }).waitFor();
|
|
if (await member.getByRole('article').getByText('加入前的历史聊天', { exact: true }).count()) throw new Error('Reload restored disallowed history');
|
|
results.push('authorization and epoch boundaries survive reload');
|
|
return { passed: results };
|
|
} catch (error) {
|
|
throw new Error(`${error.message}; failures=${JSON.stringify(failures)}; owner alerts=${JSON.stringify(owner ? await owner.getByRole('alert').allTextContents() : [])}; member alerts=${JSON.stringify(member ? await member.getByRole('alert').allTextContents() : [])}`);
|
|
} finally { for (const context of contexts) await context.close(); }
|
|
}
|