/* WITNESS · pos-non-regression + bar-tender (the parts a person can see)
   pos-non-regression promises: the public menu returns dishes, the same number of them
   every time you look, and never fewer than the recorded baseline.
   bar-tender promises: a diner on the mosaic menu sees a drinks band.

   WHERE: Anant. The canary uses a fixture where the POS feature is switched OFF; on Anant
   it is ON (the waiter's board offers "Enter in POS"). So I cannot witness that
   precondition — I say so rather than pretending. What I CAN witness is the part the
   promise is actually about: does the menu hold still, and can I see the drinks.        */
import { test, expect } from "@playwright/test";
import { journal, look, arriveAsDiner, DWELL, roleContext, closeRole, PATRON } from "../lib-witness.mjs";

const RID = "097c229c-a1cb-4ba7-b603-800e46936133";
const TABLE = 12;                                   // a different table — nobody else's meal
const phone = dir => ({ viewport:{width:390,height:844}, hasTouch:true, isMobile:true,
                        recordVideo:{ dir, size:{width:390,height:844} } });

test("menu-stability", async ({ browser }) => {
  const jr = journal("menu-stability");
  jr.target({ app: "patron (mosaic_v2)", baseUrl: PATRON,
              restaurantId: typeof RID !== "undefined" ? RID : undefined,
              table: typeof TABLE !== "undefined" ? TABLE : undefined });
  jr.note("**Where:** Anant, table 12 — a quiet table, so I disturb nobody's meal.");
  jr.note("**Who:** just me, a diner reading the menu twice.");
  jr.note("_Covers what a person can see of two canaries: **pos-non-regression** (does the "
        + "menu hold still) and **bar-tender** (can a diner see the drinks band). The "
        + "canary's own first step — 'POS is OFF for this restaurant' — is a property of "
        + "its private fixture; on Anant POS is ON, so that step is not mine to witness._");

  const c = await roleContext(browser, jr, "patron");
  const p = await c.newPage();
  let verdict = "INCOMPLETE", why = "", first = 0;

  try {
    await jr.step("PATRON", "I open the menu and it actually has dishes on it", async id => {
      await arriveAsDiner(p, RID, TABLE, "mosaic_v2");
      const t = await look(p, jr, "patron", id, "menu first look");
      first = await p.locator('[data-testid^="m2-add-"]').count();
      expect(first, "a menu with nothing on it is not a menu").toBeGreaterThan(0);
      return `I can count ${first} dishes I could add. The page reads: ${t.slice(0, 140)}`;
    });

    await jr.step("PATRON", "I look away and look again — the same dishes are still there", async id => {
      await p.reload({ waitUntil: "domcontentloaded" });
      await p.waitForTimeout(DWELL + 3000);
      const again = await p.locator('[data-testid^="m2-add-"]').count();
      await look(p, jr, "patron", id, "menu second look");
      jr.note(`> **Does the menu hold still:** ${first} dishes the first time, ${again} the second.`);
      if (again < first)
        throw new Error(`the menu shrank while I was looking at it — ${first} dishes, then ${again}`);
      return `${again} dishes — ${again === first ? "exactly the same as before" : "more than before"}`;
    });

    await jr.soft("PATRON", "I can find the drinks on the menu, the way a thirsty person would", async id => {
      const t = (await p.locator("body").innerText()).replace(/\s+/g, " ");
      const drinks = ["drinks", "beer", "cocktail", "mocktail", "wine", "lassi", "soda"]
                      .filter(k => new RegExp(k, "i").test(t));
      await look(p, jr, "patron", id, "drinks band");
      if (!drinks.length)
        throw new Error("I looked over the whole menu and could not find anything to drink");
      jr.note(`> **Drinks band:** I can see ${drinks.join(", ")}. The bar-tender canary skips its `
            + "own cocktail steps because its fixture has no cocktails — on a real restaurant "
            + "menu the drinks are plainly there.");
      return `drinks I can see: ${drinks.join(", ")}`;
    });

    verdict = "WALKED"; why = "read the menu twice and found the drinks — that is the whole promise";
  } catch (e) {
    verdict = "STOPPED"; why = String(e.message || e).split("\n")[0].slice(0, 300);
  } finally {
    jr.finish(verdict, why);
    await closeRole(c, jr, "patron");
  }
});
