session-child-navigation.spec.ts 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. import { seedSessionTask, withSession } from "../actions"
  2. import { test, expect } from "../fixtures"
  3. import { inputMatch } from "../prompt/mock"
  4. test("task tool child-session link does not trigger stale show errors", async ({ page, llm, project }) => {
  5. test.setTimeout(120_000)
  6. const errs: string[] = []
  7. const onError = (err: Error) => {
  8. errs.push(err.message)
  9. }
  10. page.on("pageerror", onError)
  11. try {
  12. await project.open()
  13. await withSession(project.sdk, `e2e child nav ${Date.now()}`, async (session) => {
  14. const taskInput = {
  15. description: "Open child session",
  16. prompt: "Search the repository for AssistantParts and then reply with exactly CHILD_OK.",
  17. subagent_type: "general",
  18. }
  19. await llm.toolMatch(inputMatch(taskInput), "task", taskInput)
  20. const child = await seedSessionTask(project.sdk, {
  21. sessionID: session.id,
  22. description: taskInput.description,
  23. prompt: taskInput.prompt,
  24. })
  25. project.trackSession(child.sessionID)
  26. await project.gotoSession(session.id)
  27. const header = page.locator("[data-session-title]")
  28. await expect(header.getByRole("button", { name: "More options" })).toBeVisible({ timeout: 30_000 })
  29. const card = page
  30. .locator('[data-component="task-tool-card"]')
  31. .filter({ hasText: /open child session/i })
  32. .first()
  33. await expect(card).toBeVisible({ timeout: 30_000 })
  34. await card.click()
  35. await expect(page).toHaveURL(new RegExp(`/session/${child.sessionID}(?:[/?#]|$)`), { timeout: 30_000 })
  36. await expect(header.locator('[data-slot="session-title-parent"]')).toHaveText(session.title)
  37. await expect(header.locator('[data-slot="session-title-child"]')).toHaveText(taskInput.description)
  38. await expect(header.locator('[data-slot="session-title-separator"]')).toHaveText("/")
  39. await expect
  40. .poll(
  41. () =>
  42. header.locator('[data-slot="session-title-separator"]').evaluate((el) => ({
  43. left: getComputedStyle(el).paddingLeft,
  44. right: getComputedStyle(el).paddingRight,
  45. })),
  46. { timeout: 30_000 },
  47. )
  48. .toEqual({ left: "8px", right: "8px" })
  49. await expect(header.getByRole("button", { name: "More options" })).toHaveCount(0)
  50. await expect(page.getByText("Subagent sessions cannot be prompted.")).toBeVisible({ timeout: 30_000 })
  51. await expect(page.getByRole("button", { name: "Back to main session." })).toBeVisible({ timeout: 30_000 })
  52. await expect.poll(() => errs, { timeout: 5_000 }).toEqual([])
  53. })
  54. } finally {
  55. page.off("pageerror", onError)
  56. }
  57. })