import { test, expect } from '@playwright/test' import { mkdirSync } from 'node:fs' test('a default installation creates and saves encrypted passwords through the settings UI', async ({ page }) => { const evidence='test-results/credential-vault-default';mkdirSync(evidence,{recursive:true}) const master='DUMMY-browser-vault-master',secret='DUMMY-browser-entry-secret' await page.goto('/conversations') await page.getByRole('textbox',{name:'账号',exact:true}).fill('fixture') await page.getByRole('textbox',{name:'密码',exact:true}).fill('fixture-pass') await page.getByRole('button',{name:'登录',exact:true}).click() await page.locator('.desktop-sidebar .sidebar-account-switcher__main').click() await page.getByRole('menuitem',{name:'我的设置',exact:true}).click() await page.getByRole('button',{name:'密码管理',exact:true}).click() const panel=page.locator('.credential-vault') await expect(panel.getByText(/需要你授权具体任务/)).toBeVisible() await panel.getByLabel('主密码',{exact:true}).fill(master) await panel.getByLabel('确认主密码',{exact:true}).fill(master) await panel.getByRole('button',{name:'创建密码库',exact:true}).click() await expect(panel.getByRole('button',{name:'手动解锁 5 分钟',exact:true})).toBeVisible() await panel.getByLabel('主密码',{exact:true}).fill(master) await panel.getByRole('button',{name:'手动解锁 5 分钟',exact:true}).click() await panel.getByRole('button',{name:'添加凭据',exact:true}).click() await panel.getByLabel('名称',{exact:true}).fill('浏览器测试网站') await panel.getByLabel('用户名',{exact:true}).fill('dummy-user') await panel.getByLabel('准确网站 origin',{exact:true}).fill('https://example.test') await panel.getByLabel('密码',{exact:true}).fill(secret) await panel.getByRole('button',{name:'加密保存',exact:true}).click() await expect(panel.locator('li strong').filter({hasText:'浏览器测试网站'})).toBeVisible() await expect(panel.getByRole('status').filter({hasText:'凭据已加密保存'})).toBeVisible() await expect(panel.getByRole('button',{name:'授予本任务 60 秒引用权限'})).toBeDisabled() expect(await panel.textContent()).not.toContain(secret) await panel.getByRole('button',{name:'添加凭据',exact:true}).click() await panel.getByRole('combobox',{name:/^用途/}).selectOption('ssh') await expect(panel.getByRole('combobox',{name:/^SSH 认证方式/})).toHaveValue('password') await panel.getByLabel('名称',{exact:true}).fill('浏览器测试 SSH 密码') await panel.getByLabel('用户名',{exact:true}).fill('dummy-ssh-user') await panel.getByLabel('SSH 主机',{exact:true}).fill('ssh.example.test') await expect(panel.getByLabel(/^服务器指纹/)).toBeHidden() await expect(panel.getByLabel(/^服务器指纹/)).not.toHaveAttribute('required') const sshPassword=panel.getByLabel(/^SSH 登录密码/) await expect(sshPassword).toHaveAttribute('type','password') await sshPassword.fill('DUMMY-browser-ssh-password') await panel.getByLabel('配置允许 Bot 执行的固定操作',{exact:true}).check() await expect(panel.getByRole('combobox',{name:/^允许操作/})).toHaveValue('ssh.exec') await expect(panel.getByLabel('批准的绝对可执行路径(无参数、无 shell 拼接)',{exact:true})).toHaveValue('/usr/bin/uptime') await expect(panel.getByLabel('私钥口令(可选)',{exact:true})).toHaveCount(0) await page.screenshot({path:evidence+'/ssh-password-editor.png'}) await panel.getByRole('button',{name:'加密保存',exact:true}).click() const sshEntry=panel.locator('li').filter({hasText:'浏览器测试 SSH 密码'}) await expect(sshEntry).toContainText('密码登录') await expect(panel.getByRole('heading',{name:'本次任务授权',exact:true})).toBeVisible() expect(await panel.textContent()).not.toContain('DUMMY-browser-ssh-password') await sshEntry.getByRole('button',{name:'编辑',exact:true}).click() await expect(sshPassword).toHaveValue('') await expect(panel.getByRole('combobox',{name:/^SSH 认证方式/})).toHaveValue('password') await panel.getByText('高级连接设置(可选)',{exact:true}).click() await expect(panel.getByLabel(/^服务器指纹/)).toHaveValue('') await expect(panel.getByLabel('端口',{exact:true})).toHaveValue('22') await panel.getByRole('button',{name:'加密保存',exact:true}).click() await expect(sshEntry).toContainText('密码登录') await page.screenshot({path:evidence+'/desktop-saved.png'}) await page.setViewportSize({width:375,height:812}) await expect(panel.getByRole('button',{name:'添加凭据',exact:true})).toBeVisible() expect(await panel.evaluate(el=>el.scrollWidth<=el.clientWidth)).toBe(true) await page.screenshot({path:evidence+'/mobile-saved.png'}) await page.setViewportSize({width:1440,height:1000}) await panel.getByRole('button',{name:'立即锁定并撤销授权',exact:true}).click() await expect(panel.getByText('浏览器测试网站',{exact:true})).toHaveCount(0) await panel.getByLabel('主密码',{exact:true}).fill('DUMMY-wrong-master-password') await panel.getByRole('button',{name:'手动解锁 5 分钟',exact:true}).click() await expect(panel.getByRole('alert')).toContainText('主密码错误') await expect(page.getByRole('textbox',{name:'账号',exact:true})).toHaveCount(0) await expect(panel.getByLabel('主密码',{exact:true})).toHaveValue('') await page.screenshot({path:evidence+'/wrong-master-stays-signed-in.png'}) })