feat(edit): 编辑上报细节优化
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
import assert from 'node:assert/strict';
|
||||
import { readFile } from 'node:fs/promises';
|
||||
import { createRequire } from 'node:module';
|
||||
import test from 'node:test';
|
||||
import { collectedProductPayloadSchema } from '@atlas/contracts';
|
||||
import { collectPlatformDomAssets, normaliseImageUrl } from '../lib/product-media.ts';
|
||||
import { collectCurrentProduct } from '../lib/source-parsers.ts';
|
||||
|
||||
// 使用 WXT 已有的 HTML 解析依赖构建离线 DOM,不加载样本里的远程媒体。
|
||||
const require = createRequire(import.meta.url);
|
||||
const wxtRequire = createRequire(require.resolve('wxt'));
|
||||
const { parseHTML } = wxtRequire('linkedom');
|
||||
const pageUrl = 'https://detail.1688.com/offer/1012823100668.html';
|
||||
const videoUrl = 'https://cloud.video.taobao.com/qa-product.mp4';
|
||||
const poster = 'https://cbu01.alicdn.com/img/ibank/O1CN01lCwIgP1UjKGylKwAN_!!2563422553-0-cib.jpg';
|
||||
|
||||
async function fixture(extra = ''): Promise<Document> {
|
||||
const html = await readFile(new URL('./fixtures/1688-gallery-background.html', import.meta.url), 'utf8');
|
||||
const { document, window } = parseHTML(`<html><body>${html}${extra}</body></html>`);
|
||||
window.getComputedStyle = (element: HTMLElement) => ({ backgroundImage: element.style.backgroundImage });
|
||||
Object.defineProperty(document, 'scripts', { get: () => document.querySelectorAll('script') });
|
||||
for (const element of document.querySelectorAll('.v-image-cover')) {
|
||||
Object.defineProperty(element, 'offsetWidth', { value: 60 });
|
||||
Object.defineProperty(element, 'offsetHeight', { value: 60 });
|
||||
}
|
||||
return document;
|
||||
}
|
||||
|
||||
test('用户画廊样本的 15 张背景缩略图完整采集、还原原图,排除参数与视频控件', async () => {
|
||||
const assets = collectPlatformDomAssets('1688', await fixture(), pageUrl);
|
||||
assert.equal(assets.length, 15);
|
||||
assert.ok(assets.every((asset) => asset.mediaType === 'image' && asset.role === 'source_main'));
|
||||
assert.equal(assets[0].url, poster);
|
||||
assert.ok(assets.every((asset) => asset.url.endsWith('.jpg') && !asset.url.includes('_b.jpg')));
|
||||
assert.ok(assets.every((asset) => !/undefined|\.svg/.test(asset.url)));
|
||||
assert.equal(normaliseImageUrl('undefined', pageUrl, '1688'), undefined);
|
||||
});
|
||||
|
||||
test('画廊播放器可采集真实视频及封面,忽略推荐视频、blob 和 HLS', async () => {
|
||||
const root = await fixture(`<div class="od-picture-gallery"><video src="${videoUrl}"></video><video src="blob:https://detail.1688.com/opaque"></video><video src="https://cloud.video.taobao.com/stream.m3u8"></video></div><aside><video src="https://cloud.video.taobao.com/recommend.mp4"></video></aside>`);
|
||||
const assets = collectPlatformDomAssets('1688', root, pageUrl);
|
||||
const videos = assets.filter((asset) => asset.mediaType === 'video');
|
||||
assert.equal(videos.length, 1);
|
||||
assert.equal(videos[0].url, videoUrl);
|
||||
assert.equal(videos[0].posterUrl, poster);
|
||||
assert.equal(assets.filter((asset) => asset.mediaType === 'image').length, 15);
|
||||
});
|
||||
|
||||
test('脚本画廊数据与 DOM 视频去重,完整采集载荷符合 API 契约', async () => {
|
||||
const gallery = { fields: { video: { url: videoUrl, videoThumbnailURL: poster } } };
|
||||
const root = await fixture(`<div class="od-picture-gallery"><video><source src="${videoUrl}"></video></div><script>window.context=${JSON.stringify({ gallery })};</script>`);
|
||||
const payload = await collectCurrentProduct(root, pageUrl);
|
||||
assert.equal(payload.assets.filter((asset) => asset.mediaType === 'video').length, 1);
|
||||
assert.equal(payload.assets.filter((asset) => asset.mediaType === 'image').length, 15);
|
||||
assert.equal(collectedProductPayloadSchema.safeParse(payload).success, true);
|
||||
});
|
||||
|
||||
test('尚未挂载播放器时仍可从明确的 gallery 字面值读取视频直链', async () => {
|
||||
const gallery = { fields: { video: { url: '', videoAddress: videoUrl, videoThumbnailURL: poster } } };
|
||||
const payload = await collectCurrentProduct(await fixture(`<script>window.context=${JSON.stringify({ gallery })};</script>`), pageUrl);
|
||||
const videos = payload.assets.filter((asset) => asset.mediaType === 'video');
|
||||
assert.equal(videos.length, 1);
|
||||
assert.equal(videos[0].url, videoUrl);
|
||||
assert.equal(videos[0].posterUrl, poster);
|
||||
});
|
||||
Reference in New Issue
Block a user