import { expect, Page, test } from '@playwright/test'; import path from 'node:path'; declare global { interface Window { __seedIpOperatorScenario?: (scenario: 'ready') => unknown; } } const scenarioSeedPath = path.resolve(__dirname, '../scripts/validation/ip-operator-scenario-seed.js'); const planKey = 'tiktok.ipOperator.plan.ip_plan_e2e_ready.local-guest'; async function seedReadyScenario(page: Page) { await page.addInitScript({ path: scenarioSeedPath }); await page.addInitScript(() => { window.__seedIpOperatorScenario?.('ready'); localStorage.setItem('tiktok.currentTab', 'ip-operator'); }); } test('direction topic can generate script, calendar item, publish package, and review task', async ({ page }) => { await seedReadyScenario(page); await page.goto('/'); await expect(page.locator('.account-workbench')).toBeVisible(); await expect(page.locator('.content-direction-grid .direction-topic-card').nth(1)).toBeVisible(); const topicCard = page.locator('.content-direction-grid .direction-topic-card').nth(1); const topicTitle = (await topicCard.locator('strong').textContent())?.trim() || ''; expect(topicTitle.length).toBeGreaterThan(0); const scriptAction = topicCard.getByRole('button', { name: /生成分镜脚本|分镜脚本已生成/ }); const scriptLabel = (await scriptAction.textContent()) || ''; await scriptAction.click(); if (!scriptLabel.includes('分镜脚本已生成')) { await expect(topicCard.getByRole('button', { name: '分镜脚本已生成' })).toBeVisible(); await topicCard.getByRole('button', { name: '分镜脚本已生成' }).click(); } await expect(page.locator('.shot-script-modal')).toContainText('秒'); await expect(page.locator('.shot-script-modal')).toContainText('开头钩子'); await page.locator('.shot-script-modal__close').click(); await topicCard.getByRole('button', { name: '加入内容日历' }).click(); await expect.poll(async () => page.evaluate(({ key, title }) => { const plan = JSON.parse(localStorage.getItem(key) || '{}'); return Boolean((plan.contentCalendar || []).some((item: { title?: string }) => item.title === title)); }, { key: planKey, title: topicTitle })).toBe(true); await topicCard.getByRole('button', { name: '生成发布包' }).click(); await expect(page.getByRole('heading', { name: '发布前人工审核资料包' })).toBeVisible(); await expect(page.getByText('不做自动发布、批量评论、Cookie 池或代理池')).toBeVisible(); await expect.poll(async () => page.evaluate(({ key, title }) => { const plan = JSON.parse(localStorage.getItem(key) || '{}'); const pkg = (plan.publishPackages || []).find((item: { titleOptions?: string[] }) => (item.titleOptions || []).includes(title)); const calendar = (plan.contentCalendar || []).find((item: { title?: string }) => item.title === title); return Boolean(pkg && calendar?.publishPackageId === pkg.id && (pkg.riskChecklist || []).some((item: { label?: string }) => item.label?.includes('不自动发布'))); }, { key: planKey, title: topicTitle })).toBe(true); const packageCard = page.locator('.ip-workbench-card--wide').filter({ hasText: topicTitle }).first(); await packageCard.locator('.publish-binding-panel--inline input').fill('https://www.douyin.com/video/7390000001'); await packageCard.getByRole('button', { name: '手动绑定作品' }).click(); await expect.poll(async () => page.evaluate(() => { const ids = JSON.parse(localStorage.getItem('tiktok.ipOperator.operationTasks.local-guest') || '[]'); return ids.some((id: string) => { const raw = localStorage.getItem(`tiktok.ipOperator.operationTask.${id}.local-guest`); const task = raw ? JSON.parse(raw) : null; return task?.type === 'review' && String(task?.title || '').includes('复盘'); }); })).toBe(true); });