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 page = await browser.newPage({ viewport: { width: 1440, height: 900 }, locale: 'zh-CN' }); 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}/post-detail.html?moment=demo-moment-1`); await page.locator('html:not(.notification-route-pending)').waitFor(); await page.waitForTimeout(600); const snippet = (await page.locator('.post-detail-content').innerText()).slice(0, 14); await page.locator('.post-detail-actions [aria-label="收藏"]').click(); await page.waitForFunction(() => document.querySelector('.post-detail-actions [aria-label="收藏"]')?.classList.contains('saved'), null, { timeout: 8000 }); await page.locator('.post-detail-actions [aria-label="点赞"]').click(); await page.waitForFunction(() => document.querySelector('.post-detail-actions [aria-label="点赞"] .count')?.textContent.trim() === '1', null, { timeout: 8000 }); await page.goto(`${base}/favorites.html`); await page.waitForTimeout(900); const favCard = page.locator('.favorites-grid .post-mini-card[data-kind="favorite"]'); assert.equal(await favCard.count(), 1, '收藏页应出现刚收藏的动态'); assert.ok((await favCard.first().innerText()).includes(snippet), '收藏卡片应显示动态内容'); await page.locator('.tab-bar .tab-item', { hasText: '喜欢' }).click(); await page.waitForTimeout(400); assert.equal(await page.locator('.favorites-grid .post-mini-card[data-kind="like"]:visible').count(), 1, '喜欢页应出现刚点赞的动态'); await page.locator('.tab-bar .tab-item', { hasText: '浏览历史' }).click(); await page.waitForTimeout(400); assert.equal(await page.locator('.favorites-grid .post-mini-card[data-kind="view"]:visible').count(), 1, '浏览历史应出现看过的动态'); await page.locator('.tab-bar .tab-item', { hasText: '收藏' }).click(); await page.waitForTimeout(400); await favCard.first().locator('.post-footer-collect').click(); await page.waitForTimeout(600); const stillFav = await page.evaluate(() => (JSON.parse(localStorage.getItem('youthome:web:db:v1')).favorites['demo-moment-1'] || []) .some((id) => id === JSON.parse(localStorage.getItem('youthome:web:authUser')).id)); assert.equal(stillFav, false, '取消收藏应写回数据层'); // ---------- 关注 ---------- await page.goto(`${base}/feed.html`); await page.waitForTimeout(1500); const followBtn = page.locator('.web-follow-btn, .follow-btn, [data-follow], .recommend-follow').first(); await followBtn.click(); await page.waitForTimeout(400); const followed = await page.evaluate(() => window.YouthomeLocal.following()); assert.equal(followed.length, 1, '关注后应记录到本地'); await page.goto(`${base}/follow.html`); await page.waitForTimeout(900); const followCard = page.locator(`.user-card[data-kind="real-follow"]`); assert.equal(await followCard.count(), 1, '关注页应出现刚关注的人'); assert.ok((await followCard.first().innerText()).includes(followed[0]), '关注卡片应显示对方昵称'); await followCard.first().locator('.follow-btn').click(); await page.waitForTimeout(600); assert.equal(await page.locator('.user-card[data-kind="real-follow"]').count(), 0, '取关后卡片应移除'); assert.equal((await page.evaluate(() => window.YouthomeLocal.following())).length, 0, '取关应写回本地'); // ---------- 活动报名 ---------- await page.goto(`${base}/activity-detail.html`); await page.waitForTimeout(900); const joinedTitle = await page.locator('.cover-title').innerText(); await page.locator('.join-btn:not(.secondary)').click(); await page.locator('.web-signup-submit').click(); await page.waitForTimeout(700); assert.equal((await page.locator('.join-btn:not(.secondary)').innerText()).trim(), '已报名'); await page.goto(`${base}/my-activity-apply.html`); await page.waitForTimeout(900); const joinedCard = page.locator('.activity-card[data-joined-id]'); assert.equal(await joinedCard.count(), 1, '我的报名应出现刚报名的活动'); assert.ok((await joinedCard.first().innerText()).includes(joinedTitle.trim().slice(0, 6)), '报名卡片应显示活动标题'); assert.ok((await joinedCard.first().innerText()).includes('待审核'), '新报名应为待审核'); // 另一个活动不应被标记成已报名 await page.goto(`${base}/activity-detail.html?id=other-activity`); await page.waitForTimeout(900); assert.equal((await page.locator('.join-btn:not(.secondary)').innerText()).trim(), '立即报名', '其他活动不应显示已报名'); // 取消报名 await page.goto(`${base}/my-activity-apply.html`); await page.waitForTimeout(900); await page.locator('.activity-card[data-joined-id] .btn, .activity-card[data-joined-id] .text-link').first().click(); await page.waitForTimeout(700); assert.equal(await page.locator('.activity-card[data-joined-id]').count(), 0, '取消报名后卡片应移除'); assert.equal((await page.evaluate(() => window.YouthomeLocal.joinedActivities())).length, 0, '取消报名应写回数据层'); assert.deepEqual(errors, []); await browser.close(); console.log(`collection flows passed in Edge (favorite/like/view, follow, activity ${joinedTitle.trim().slice(0, 8)})`); })().catch((error) => { console.error(error); process.exitCode = 1; });