You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
91 lines
5.5 KiB
91 lines
5.5 KiB
const assert = require('node:assert/strict');
|
|
const { chromium } = require('playwright');
|
|
|
|
const base = process.env.YOUTHOME_WEB_URL || 'http://127.0.0.1:4173/pages';
|
|
const png = Buffer.from('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVQIHWP4z8DwHwAFgAI/ScL/nwAAAABJRU5ErkJggg==', 'base64');
|
|
|
|
(async () => {
|
|
const browser = await chromium.launch({ channel: 'msedge', headless: true });
|
|
const page = await browser.newPage({ viewport: { width: 1280, height: 900 } });
|
|
const errors = [];
|
|
const calls = [];
|
|
const comments = [];
|
|
page.on('pageerror', (error) => errors.push(error.message));
|
|
await page.addInitScript(() => {
|
|
localStorage.setItem('youthome:web:dataSource', 'api');
|
|
sessionStorage.setItem('youthome:web:accessToken', 'mock-token');
|
|
sessionStorage.setItem('youthome:web:authUser', JSON.stringify({ id: 'u1', nickname: '演示用户' }));
|
|
});
|
|
await page.route('**/api/**', async (route) => {
|
|
const request = route.request();
|
|
const path = new URL(request.url()).pathname;
|
|
const body = request.headers()['content-type']?.includes('application/json') ? request.postDataJSON() : null;
|
|
calls.push({ path, method: request.method(), body });
|
|
let data = null;
|
|
if (path === '/api/campus/moments/detail') data = {
|
|
id: 'video-1', content: '后端视频标题\n后端视频简介', userId: 'u1', userName: '演示用户',
|
|
allowComment: true, playUrl: '', commentCount: comments.length
|
|
};
|
|
if (path === '/api/campus/moments/comments' && request.method() === 'GET') data = { items: comments, total: comments.length };
|
|
if (path === '/api/campus/moments/comments' && request.method() === 'POST') {
|
|
const comment = { id: `c${comments.length + 1}`, userId: 'u1', userName: '演示用户', content: body.content, createdAt: '2026-10-22 12:00:00', replies: [] };
|
|
comments.push(comment);
|
|
data = comment;
|
|
}
|
|
if (path === '/api/file/upload/image') data = { url: 'https://example.com/cover.png' };
|
|
if (path === '/api/campus/activities' && request.method() === 'POST') data = { id: 'activity-1' };
|
|
if (path === '/api/campus/activities/detail') data = {
|
|
id: 'activity-1', title: '后端演示活动', description: '接口活动介绍', coverImage: 'https://example.com/cover.png',
|
|
location: '演示体育馆', startTime: '2026-10-25 18:00:00', endTime: '2026-10-25 19:00:00',
|
|
registrationDeadline: '2026-10-24 18:00:00'
|
|
};
|
|
await route.fulfill({ status: 200, contentType: 'application/json', body: JSON.stringify({ code: 200, data }) });
|
|
});
|
|
await page.route('https://nominatim.openstreetmap.org/search?**', (route) => route.fulfill({
|
|
status: 200, contentType: 'application/json', body: JSON.stringify([{
|
|
lat: '31.299', lon: '121.504', name: '演示体育馆', display_name: '演示体育馆, 上海市杨浦区'
|
|
}])
|
|
}));
|
|
try {
|
|
await page.goto(`${base}/video-detail.html?id=video-1`);
|
|
await page.waitForFunction(() => document.querySelector('.video-title')?.textContent === '后端视频标题');
|
|
assert.ok((await page.locator('.video-desc').innerText()).includes('后端视频简介'));
|
|
await page.locator('.comment-textarea').fill('接口视频评论');
|
|
await page.locator('.comment-submit-btn').click();
|
|
await page.locator('.comment-list .comment-item').filter({ hasText: '接口视频评论' }).waitFor();
|
|
assert.deepEqual(calls.find((call) => call.path === '/api/campus/moments/comments' && call.method === 'POST').body,
|
|
{ momentId: 'video-1', content: '接口视频评论', parentId: null });
|
|
|
|
await page.goto(`${base}/activity-create.html`);
|
|
await page.locator('.location-locate-btn').click();
|
|
await page.locator('.web-map-dialog input[type="search"]').fill('演示体育馆');
|
|
await page.locator('.web-map-dialog').getByRole('button', { name: '搜索' }).click();
|
|
await page.locator('.web-map-dialog .primary:enabled').waitFor();
|
|
await page.locator('.web-map-dialog .primary').click();
|
|
assert.equal(await page.locator('#location-name').inputValue(), '演示体育馆');
|
|
await page.locator('#activity-title').fill('后端演示活动');
|
|
await page.locator('#activity-desc').fill('接口活动介绍');
|
|
await page.locator('#activity-type').selectOption('sports');
|
|
await page.locator('.web-activity-cover-input').setInputFiles({ name: 'cover.png', mimeType: 'image/png', buffer: png });
|
|
await page.evaluate(() => {
|
|
const date = new Date(Date.now() + 3 * 86400000);
|
|
const pad = (value) => String(value).padStart(2, '0');
|
|
const day = `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}`;
|
|
document.getElementById('start-time').value = `${day}T18:00`;
|
|
document.getElementById('end-time').value = `${day}T19:00`;
|
|
document.getElementById('registration-deadline').value = `${day}T17:00`;
|
|
});
|
|
await page.locator('.btn-next').click();
|
|
await page.waitForURL('**/activity-detail.html?id=activity-1');
|
|
const activity = calls.find((call) => call.path === '/api/campus/activities' && call.method === 'POST');
|
|
assert.equal(activity.body.location, '演示体育馆 上海市杨浦区');
|
|
assert.equal(activity.body.coverImage, 'https://example.com/cover.png');
|
|
assert.equal(activity.body.latitude, 31.299);
|
|
assert.equal(activity.body.longitude, 121.504);
|
|
assert.ok(activity.body.startTime.endsWith(':00'));
|
|
assert.deepEqual(errors, []);
|
|
console.log('mock API video comments, description, map selection, activity publish passed');
|
|
} finally {
|
|
await browser.close();
|
|
}
|
|
})().catch((error) => { console.error(error); process.exitCode = 1; });
|
|
|