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.
 
 
 
 

81 lines
4.4 KiB

const assert = require('node:assert/strict');
const { chromium, request } = require('playwright');
const webBase = process.env.YOUTHOME_WEB_URL || 'http://127.0.0.1:4173/pages';
const apiBase = process.env.YOUTHOME_BACKEND_URL || 'http://127.0.0.1:8009';
if (process.env.YOUTHOME_LIVE_BACKEND !== '1') {
console.error('Set YOUTHOME_LIVE_BACKEND=1 to run the write-and-cleanup test.');
process.exit(1);
}
(async () => {
const browser = await chromium.launch({ channel: 'msedge', headless: true });
const api = await request.newContext({ baseURL: apiBase });
const page = await browser.newPage({ viewport: { width: 1440, height: 900 } });
page.on('response', (response) => {
if (response.url().includes('/api/campus/moments') && response.request().method() === 'POST') {
console.log(`Create response: HTTP ${response.status()}`);
}
});
page.on('pageerror', (error) => console.log(`Page error: ${error.message}`));
const phone = `199${String(Date.now()).slice(-8)}`;
const password = `Webtest${String(Date.now()).slice(-6)}a`;
console.log(`Temporary test phone: ${phone}`);
let token;
let momentId;
let uploadUrl;
try {
const registration = await api.post('/api/auth/register', {
data: { phone, password, captcha: '111111', universityName: '复旦大学', nickname: '网页发布回归', platform: 'WEB' }
});
const registered = await registration.json();
assert.equal(registration.status(), 200, JSON.stringify(registered));
assert.equal(registered.code, 200, JSON.stringify(registered));
token = registered.data.token;
await page.goto(`${webBase}/login.html?next=publish-post.html&demo=0`);
await page.locator('#panel-password input[type="tel"]').fill(phone);
await page.locator('#panel-password input[type="password"]').fill(password);
await page.locator('#panel-password .btn-primary').click();
await page.waitForURL('**/publish-post.html');
await page.locator('.post-textarea').fill('网页端发布流程临时回归测试动态');
await page.locator('input[type="file"]').setInputFiles({
name: 'web-publishing-smoke.png',
mimeType: 'image/png',
buffer: Buffer.from('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVQIHWP4z8DwHwAFgAI/ScL/nwAAAABJRU5ErkJggg==', 'base64')
});
const uploadResponse = page.waitForResponse((response) => response.url().includes('/api/file/upload/image'));
await page.locator('.web-publish-actions .btn-primary').click();
const uploaded = await uploadResponse;
const uploadData = await uploaded.json();
assert.equal(uploaded.status(), 200, JSON.stringify(uploadData));
uploadUrl = uploadData.data?.url || uploadData.url;
await page.waitForURL('**/post-detail.html?moment=*', { timeout: 15000 });
momentId = new URL(page.url()).searchParams.get('moment');
assert.ok(momentId);
await page.locator('html:not(.notification-route-pending)').waitFor();
assert.ok((await page.locator('.post-detail-content').innerText()).includes('网页端发布流程临时回归测试动态'));
assert.equal(await page.locator('.post-detail-images img').count(), 1);
await page.locator('.post-detail-images img').evaluate((image) => image.decode());
assert.ok(await page.locator('.post-detail-images img').evaluate((image) => image.naturalWidth > 0));
await page.goto(`${webBase}/me.html`);
await page.locator('.web-live-card').waitFor();
assert.ok((await page.locator('.web-live-card').innerText()).includes('网页端发布流程'));
console.log('Real backend login, publish, detail, and profile passed');
} finally {
if (token && momentId) {
const deletion = await api.delete(`/api/campus/moments?id=${encodeURIComponent(momentId)}`, { headers: { access_token: token } });
console.log(`Temporary moment cleanup: HTTP ${deletion.status()}`);
}
if (uploadUrl) {
const deletion = await api.delete(`/api/file/delete?url=${encodeURIComponent(uploadUrl)}`, { headers: { access_token: token } });
console.log(`Temporary image cleanup: HTTP ${deletion.status()}`);
}
if (token) {
const deactivation = await api.post('/api/users/deactivate?confirm=true', { headers: { access_token: token } });
console.log(`Temporary account cleanup: HTTP ${deactivation.status()}`);
}
await api.dispose();
await browser.close();
}
})().catch((error) => { console.error(error); process.exitCode = 1; });