ip-operator-account-workbench.spec.ts 3.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. import { expect, Page, test } from '@playwright/test';
  2. import path from 'node:path';
  3. declare global {
  4. interface Window {
  5. __seedIpOperatorScenario?: (scenario: 'empty' | 'ready' | 'needs_input' | 'failed') => unknown;
  6. }
  7. }
  8. const scenarioSeedPath = path.resolve(__dirname, '../scripts/validation/ip-operator-scenario-seed.js');
  9. async function seedScenario(page: Page, scenario: 'ready' | 'needs_input' = 'ready') {
  10. await page.addInitScript({ path: scenarioSeedPath });
  11. await page.addInitScript((nextScenario) => {
  12. window.__seedIpOperatorScenario?.(nextScenario);
  13. localStorage.setItem('tiktok.currentTab', 'ip-operator');
  14. }, scenario);
  15. }
  16. test('account-driven workbench connects account evidence, tasks, scripts, and publish binding', async ({ page }) => {
  17. await seedScenario(page, 'ready');
  18. await page.goto('/');
  19. await expect(page.locator('.account-workbench')).toBeVisible();
  20. await expect(page.locator('.operator-cockpit')).toContainText('账号运营驾驶舱');
  21. await expect(page.locator('.operator-cockpit__status')).toContainText('林川老板增长笔记');
  22. await expect(page.locator('.operator-cockpit__status')).toContainText('数据诊断');
  23. await expect(page.locator('.priority-task-board')).toContainText('今天必须做');
  24. await expect(page.locator('.priority-task-board')).toContainText('本周要做');
  25. await expect(page.locator('.account-monitor-panel')).toContainText('账号内容与数据');
  26. await expect(page.locator('.account-monitor-panel')).toContainText('重点证据作品');
  27. const firstWork = page.locator('.account-monitor-work-list article').first();
  28. await expect(firstWork).toBeVisible();
  29. await expect(page.getByText('装了很多,收藏了很多,但真正开工的时候还是不知道该先用哪个。')).toHaveCount(0);
  30. await expect(page.locator('.publish-binding-panel').first()).toContainText('发布包绑定');
  31. await page.getByRole('button', { name: /方向选题/ }).click();
  32. const cardsNeedingScript = page.locator('.direction-topic-card').filter({
  33. has: page.getByRole('button', { name: '生成分镜脚本' }),
  34. });
  35. const firstTopicCard = (await cardsNeedingScript.count()) ? cardsNeedingScript.first() : page.locator('.direction-topic-card').first();
  36. const scriptAction = firstTopicCard.getByRole('button', { name: /生成分镜脚本|分镜脚本已生成/ });
  37. const hadGeneratedScript = (await scriptAction.textContent())?.includes('分镜脚本已生成') || false;
  38. await scriptAction.click();
  39. if (hadGeneratedScript) {
  40. await expect(page.locator('.shot-script-modal')).toBeVisible();
  41. } else {
  42. await expect(firstTopicCard.getByRole('button', { name: '分镜脚本已生成' })).toBeVisible();
  43. await firstTopicCard.getByRole('button', { name: '分镜脚本已生成' }).click();
  44. }
  45. await expect(page.locator('.shot-script-modal')).toContainText('秒');
  46. await expect(page.locator('.shot-script-modal')).toContainText('开头钩子');
  47. await page.locator('.shot-script-modal__close').click();
  48. await firstTopicCard.getByRole('button', { name: '生成发布包' }).click();
  49. await expect(page.locator('.workspace-tabs button.is-active')).toContainText('发布复盘');
  50. await expect(page.locator('.publish-binding-panel').first()).toContainText('发布包绑定');
  51. await expect.poll(async () => page.evaluate(() => {
  52. const raw = localStorage.getItem('tiktok.ipOperator.plan.ip_plan_e2e_ready.local-guest');
  53. const plan = raw ? JSON.parse(raw) : null;
  54. return (plan?.publishPackages || []).length;
  55. })).toBeGreaterThan(0);
  56. });