timeline-test-helpers.ts 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. import type { Page } from "@playwright/test"
  2. import { base64Encode } from "@kirincode-ai/core/util/encode"
  3. import { mockKirinCodeServer } from "../../utils/mock-server"
  4. import { fixture, pageMessages } from "./session-timeline-stress.fixture"
  5. export async function installTimelineSettings(page: Page) {
  6. await page.addInitScript(() => {
  7. localStorage.setItem(
  8. "settings.v3",
  9. JSON.stringify({
  10. general: {
  11. newLayoutDesigns: true,
  12. editToolPartsExpanded: true,
  13. shellToolPartsExpanded: true,
  14. showReasoningSummaries: true,
  15. },
  16. }),
  17. )
  18. })
  19. }
  20. export function mockStressTimeline(
  21. page: Page,
  22. input?: {
  23. onMessages?: (input: { sessionID: string; before?: string; phase: "start" | "end" }) => void
  24. vcsDiff?: unknown[]
  25. },
  26. ) {
  27. return mockKirinCodeServer(page, {
  28. sessions: fixture.sessions,
  29. provider: fixture.provider,
  30. directory: fixture.directory,
  31. project: fixture.project,
  32. pageMessages,
  33. onMessages: input?.onMessages,
  34. vcsDiff: input?.vcsDiff,
  35. })
  36. }
  37. export async function installStressSessionTabs(page: Page, input?: { draftID?: string; sessionIDs?: string[] }) {
  38. const server = stressServer()
  39. await page.addInitScript(
  40. ({ directory, sessionIDs, dirBase64, server, draftID }) => {
  41. localStorage.setItem(
  42. "opencode.global.dat:server",
  43. JSON.stringify({
  44. projects: { local: [{ worktree: directory, expanded: true }] },
  45. lastProject: { local: directory },
  46. }),
  47. )
  48. localStorage.setItem(
  49. "opencode.window.browser.dat:tabs",
  50. JSON.stringify([
  51. ...sessionIDs.map((sessionId) => ({
  52. type: "session",
  53. server,
  54. dirBase64,
  55. sessionId,
  56. })),
  57. ...(draftID ? [{ type: "draft", draftID, server, directory }] : []),
  58. ]),
  59. )
  60. },
  61. {
  62. directory: fixture.directory,
  63. sessionIDs: input?.sessionIDs ?? [fixture.sourceID, fixture.targetID],
  64. dirBase64: base64Encode(fixture.directory),
  65. server,
  66. draftID: input?.draftID,
  67. },
  68. )
  69. }
  70. export function stressSessionHref(sessionID: string) {
  71. return `/server/${base64Encode(stressServer())}/session/${sessionID}`
  72. }
  73. export function stressDraftHref(draftID: string) {
  74. return `/new-session?draftId=${encodeURIComponent(draftID)}`
  75. }
  76. function stressServer() {
  77. return `http://${process.env.PLAYWRIGHT_SERVER_HOST ?? "127.0.0.1"}:${process.env.PLAYWRIGHT_SERVER_PORT ?? "4096"}`
  78. }
  79. export function createReviewDiffs() {
  80. return Array.from({ length: Number(process.env.REVIEW_PANE_DIFF_COUNT ?? 72) }, (_, index) => {
  81. const lines = index % 3 === 0 ? 300 : index % 3 === 1 ? 120 : 38
  82. const file = `src/review/generated-${String(index).padStart(3, "0")}.ts`
  83. const before = reviewSource(index, lines)
  84. const after = before
  85. .replace(`value_${index}_4`, `updated_${index}_4`)
  86. .replace(
  87. `value_${index}_${Math.max(8, Math.floor(lines / 2))}`,
  88. `updated_${index}_${Math.max(8, Math.floor(lines / 2))}`,
  89. )
  90. .replace(`value_${index}_${lines - 4}`, `updated_${index}_${lines - 4}`)
  91. return {
  92. file,
  93. patch: reviewPatch(file, before, after),
  94. additions: 3,
  95. deletions: 3,
  96. status: "modified" as const,
  97. }
  98. })
  99. }
  100. function reviewSource(seed: number, lines: number) {
  101. return Array.from(
  102. { length: lines },
  103. (_, index) => `export const value_${seed}_${index} = "${reviewWords(seed + index, index % 5 === 0 ? 180 : 42)}"`,
  104. ).join("\n")
  105. }
  106. function reviewPatch(file: string, before: string, after: string) {
  107. const beforeLines = before.split("\n")
  108. const afterLines = after.split("\n")
  109. return [
  110. `diff --git a/${file} b/${file}`,
  111. `--- a/${file}`,
  112. `+++ b/${file}`,
  113. `@@ -1,${beforeLines.length} +1,${afterLines.length} @@`,
  114. ...beforeLines.flatMap((line, index) => {
  115. const next = afterLines[index]!
  116. if (line === next) return [` ${line}`]
  117. return [`-${line}`, `+${next}`]
  118. }),
  119. ].join("\n")
  120. }
  121. function reviewWords(seed: number, length: number) {
  122. const words = ["alpha", "bravo", "charlie", "delta", "echo", "foxtrot", "golf", "hotel", "india", "juliet"]
  123. return Array.from({ length: Math.ceil(length / 7) }, (_, index) => words[(seed + index * 3) % words.length]).join(" ")
  124. }