const assert = require('node:assert/strict'); const { chromium } = require('playwright'); const base = 'http://127.0.0.1:4173/pages'; (async () => { const browser = await chromium.launch({ channel: 'msedge', headless: true }); const ctx = await browser.newContext({ viewport: { width: 1440, height: 900 }, locale: 'zh-CN', permissions: ['clipboard-read', 'clipboard-write'] }); const page = await ctx.newPage(); const errors = []; page.on('pageerror', (error) => errors.push(error.message)); page.on('dialog', (dialog) => dialog.accept()); await page.goto(`${base}/login.html`); await page.evaluate(() => window.YouthomeLocal.reset()); await page.goto(`${base}/login.html`); await page.locator('#panel-password input[type="tel"]').fill('13800000000'); await page.locator('#panel-password input[type="password"]').fill('qinghe123'); await page.locator('#panel-password .btn-primary').click(); await page.waitForURL('**/feed.html'); // ---------- 钱包:标签切换 / 签到 / 兑换 / 已完成 ---------- await page.goto(`${base}/wallet.html`); await page.waitForTimeout(800); const taskPanel = page.locator('[data-wallet-panel="task"]').first(); const mallPanel = page.locator('[data-wallet-panel="mall"]'); const levelPanel = page.locator('[data-wallet-panel="level"]'); assert.ok(await taskPanel.isVisible(), '默认应显示任务中心'); assert.ok(!(await mallPanel.isVisible()), '默认不应显示积分商城'); await page.locator('.tab-nav .tab-item', { hasText: '积分商城' }).click(); await page.waitForTimeout(300); assert.ok(await mallPanel.isVisible(), '点击后应显示积分商城'); assert.ok(!(await taskPanel.isVisible()), '切换到商城后任务区应隐藏'); await page.locator('.tab-nav .tab-item', { hasText: '等级特权' }).click(); await page.waitForTimeout(300); assert.ok(await levelPanel.isVisible(), '点击后应显示等级特权'); assert.equal(await levelPanel.locator('.level-item').count(), 5, '等级特权应列出 5 个等级'); assert.equal(await levelPanel.locator('.level-item.is-current').count(), 1, '应标注当前等级'); const pointsBefore = Number((await page.locator('.points-number').innerText()).replace(/[^0-9]/g, '')); assert.ok(pointsBefore > 0, '登录后应显示账号积分'); await page.locator('.btn-signin').click(); await page.waitForTimeout(600); const pointsAfterSign = Number((await page.locator('.points-number').innerText()).replace(/[^0-9]/g, '')); assert.equal(pointsAfterSign, pointsBefore + 5, '签到应加 5 积分'); await page.locator('.tab-nav .tab-item', { hasText: '积分商城' }).click(); await page.waitForTimeout(300); const card = page.locator('.mall-card').first(); const cost = Number((await card.locator('.mall-points').innerText()).replace(/[^0-9]/g, '')); await card.locator('.mall-btn').click(); await page.waitForTimeout(600); const pointsAfterRedeem = Number((await page.locator('.points-number').innerText()).replace(/[^0-9]/g, '')); assert.equal(pointsAfterRedeem, pointsAfterSign - cost, '兑换应扣除对应积分'); await page.locator('.tab-nav .tab-item', { hasText: '任务中心' }).click(); await page.waitForTimeout(300); await page.locator('.btn-task-done').first().click(); await page.waitForTimeout(300); assert.ok((await page.locator('.web-toast').allInnerTexts()).length > 0, '已完成的每日任务应给出反馈'); // ---------- 搜索页:换一换 / 更多 ---------- await page.goto(`${base}/search.html`); await page.waitForTimeout(800); const refresh = page.locator('.widget-more', { hasText: '换一换' }).first(); const firstHotBefore = await page.locator('.hot-list .hot-item').first().innerText(); await refresh.click(); await page.waitForTimeout(400); const firstHotAfter = await page.locator('.hot-list .hot-item').first().innerText(); assert.notEqual(firstHotAfter, firstHotBefore, '换一换应改变热门搜索的顺序'); await page.locator('.widget-more', { hasText: '更多' }).first().click(); await page.waitForURL('**/feed.html', { timeout: 8000 }); // ---------- 话题详情:换一批 / 更多 ---------- await page.goto(`${base}/topic-detail.html`); await page.waitForTimeout(800); const firstRelatedBefore = await page.locator('.related-topic-list .related-topic-item').first().innerText(); await page.locator('.widget-more', { hasText: '换一批' }).first().click(); await page.waitForTimeout(400); const firstRelatedAfter = await page.locator('.related-topic-list .related-topic-item').first().innerText(); assert.notEqual(firstRelatedAfter, firstRelatedBefore, '换一批应改变相关话题的顺序'); await page.locator('.widget-more', { hasText: '更多' }).first().click(); await page.waitForURL('**/follow.html', { timeout: 8000 }); // ---------- 示例详情页:评论 / 分享 / 更多 ---------- await page.goto(`${base}/post-detail.html`); await page.waitForTimeout(900); await page.locator('[aria-label="查看评论"]').click(); await page.waitForTimeout(500); assert.ok(await page.locator('.comment-input, .comment-textarea').first().evaluate((node) => node === document.activeElement), '点评论数应聚焦评论输入框'); await page.locator('[aria-label="分享"]').click(); await page.waitForTimeout(400); assert.ok((await page.locator('.web-toast').allInnerTexts()).length > 0, '分享应给出反馈'); await page.locator('[aria-label="更多操作"]').click(); await page.waitForTimeout(300); assert.equal(await page.locator('.web-detail-more-menu button').count(), 2, '更多菜单应有两个操作'); await page.locator('.web-detail-more-menu button').first().click(); await page.waitForTimeout(400); assert.equal(await page.locator('.web-detail-more-menu').count(), 0, '选择后菜单应关闭'); assert.deepEqual(errors, []); await browser.close(); console.log(`wallet and dead-control wiring passed in Edge (points ${pointsBefore} -> ${pointsAfterRedeem})`); })().catch((error) => { console.error(error); process.exitCode = 1; });