import { expect, Page, test } from '@playwright/test'; import path from 'node:path'; declare global { interface Window { __seedIpOperatorScenario?: (scenario: 'empty' | 'ready' | 'needs_input' | 'failed') => unknown; } } const scenarioSeedPath = path.resolve(__dirname, '../scripts/validation/ip-operator-scenario-seed.js'); async function seedScenario(page: Page, scenario: 'ready' | 'needs_input' = 'ready') { await page.addInitScript({ path: scenarioSeedPath }); await page.addInitScript((nextScenario) => { window.__seedIpOperatorScenario?.(nextScenario); localStorage.setItem('tiktok.currentTab', 'ip-operator'); }, scenario); } test('account-driven workbench connects account evidence, tasks, scripts, and publish binding', async ({ page }) => { await seedScenario(page, 'ready'); await page.goto('/'); await expect(page.locator('.account-workbench')).toBeVisible(); await expect(page.locator('.operator-cockpit')).toContainText('账号运营驾驶舱'); await expect(page.locator('.operator-cockpit__status')).toContainText('林川老板增长笔记'); await expect(page.locator('.operator-cockpit__status')).toContainText('数据诊断'); await expect(page.locator('.priority-task-board')).toContainText('今天必须做'); await expect(page.locator('.priority-task-board')).toContainText('本周要做'); await expect(page.locator('.account-monitor-panel')).toContainText('账号内容与数据'); await expect(page.locator('.account-monitor-panel')).toContainText('重点证据作品'); const firstWork = page.locator('.account-monitor-work-list article').first(); await expect(firstWork).toBeVisible(); await expect(page.getByText('装了很多,收藏了很多,但真正开工的时候还是不知道该先用哪个。')).toHaveCount(0); await expect(page.locator('.publish-binding-panel').first()).toContainText('发布包绑定'); await page.getByRole('button', { name: /方向选题/ }).click(); const cardsNeedingScript = page.locator('.direction-topic-card').filter({ has: page.getByRole('button', { name: '生成分镜脚本' }), }); const firstTopicCard = (await cardsNeedingScript.count()) ? cardsNeedingScript.first() : page.locator('.direction-topic-card').first(); const scriptAction = firstTopicCard.getByRole('button', { name: /生成分镜脚本|分镜脚本已生成/ }); const hadGeneratedScript = (await scriptAction.textContent())?.includes('分镜脚本已生成') || false; await scriptAction.click(); if (hadGeneratedScript) { await expect(page.locator('.shot-script-modal')).toBeVisible(); } else { await expect(firstTopicCard.getByRole('button', { name: '分镜脚本已生成' })).toBeVisible(); await firstTopicCard.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 firstTopicCard.getByRole('button', { name: '生成发布包' }).click(); await expect(page.locator('.workspace-tabs button.is-active')).toContainText('发布复盘'); await expect(page.locator('.publish-binding-panel').first()).toContainText('发布包绑定'); await expect.poll(async () => page.evaluate(() => { const raw = localStorage.getItem('tiktok.ipOperator.plan.ip_plan_e2e_ready.local-guest'); const plan = raw ? JSON.parse(raw) : null; return (plan?.publishPackages || []).length; })).toBeGreaterThan(0); });