import { expect } from "e2e";
import { test, WEB } from "./t3.ts";

test("Empty Enter resumes an interrupted thread and typed Enter still sends", WEB, async ({t3, app, screen, browser}) => {
  await t3.project("demo", {"src/math.ts": "export const sum = 1 + 1;\n"});
  await t3.open();
  const prompt = screen.getByRole("textbox");
  const stop = screen.getByRole("button", "Stop generation");
  const resume = screen.getByRole("button", "Resume thread");
  await prompt.fill("Give me a short tour");
  // Redact environment-local file paths from the recording; leave app behavior untouched.
  await browser.evaluate(() => {
    const redact = () => {
      const nodes = document.createTreeWalker(document.body, NodeFilter.SHOW_TEXT);
      for (let node = nodes.nextNode(); node; node = nodes.nextNode()) {
        const text = node.textContent ?? "";
        const clean = text.replace(/\/(?:home|Users)\/[^\s<>]+/g, (path) => "[workspace]/" + path.split("/").at(-1));
        if (clean !== text) node.textContent = clean;
      }
    };
    new MutationObserver(redact).observe(document.body, {subtree: true, childList: true, characterData: true});
    redact();
  });
  // Click Stop in the render that completes the reasoning, before later tool frames race it.
  await browser.evaluate(() => {
    const observer = new MutationObserver(() => {
      if (!document.body.textContent?.includes("then summarize with some markdown.")) return;
      const stop = document.querySelector<HTMLButtonElement>('button[aria-label="Stop generation"]');
      if (stop && !stop.disabled) { observer.disconnect(); stop.click(); }
    });
    observer.observe(document.body, {subtree: true, childList: true, characterData: true});
  });
  await prompt.press("Enter");
  await resume.waitFor();
  await screen.getByText("Stopped by user", {exact: false}).waitFor();
  await app.screenshot("interrupted-before-enter");
  await prompt.fill("");
  await prompt.press("Enter");
  // Retain the failure until after the control so both commits capture the same complete flow.
  let resumeFailure: unknown;
  try { await expect(stop).toBeVisible({timeout: 3000}); } catch (error) { resumeFailure = error; }
  await app.screenshot("after-empty-enter");
  if (await stop.isVisible()) {
    await stop.tap();
    await resume.waitFor();
  }
  await prompt.fill("Please explain the sum next.");
  await prompt.press("Enter");
  await screen.getByText("Please explain the sum next.", {exact: true}).waitFor();
  await stop.waitFor();
  await app.screenshot("typed-follow-up-sent");
  await stop.tap();
  await resume.waitFor();
  if (resumeFailure) throw resumeFailure;
});
