Back to Body Journal
SOURCE / PINNED RELEASE

Made of little things.

Body Journal

Release
e8049f8da4e2…
Author-recorded commit
61c04bf0e8aa…
License
LICENSE
Author’s source reference
nostr://npub182jczunncwe0jn6frpqwq3e0qjws7yqqnc3auccqv9nte2dnd63scjm4rf/wss%3A%2F%2Fgit.napplet.soy%2F/n-6c4554844c7

Archive hash verified: 4369d778da046a8b…. The source-to-build association is the author’s claim; it has not been independently rebuilt.

tests/prototype-smoke.mjs
import { seedSyntheticCase } from "./synthetic-case-ui.mjs";
import assert from "node:assert/strict";
import { createRequire } from "node:module";
import { execFileSync } from "node:child_process";
import { resolve } from "node:path";
import { realpathSync } from "node:fs";
import { mkdir, writeFile } from "node:fs/promises";
const require = createRequire(
  realpathSync("node_modules/@napplet/conformance-cli/package.json"),
);
const { chromium } = require("playwright");
const browserInfo = JSON.parse(
  execFileSync("soyli", ["browser", "path", "--json"], { encoding: "utf8" }),
);
const executablePath = browserInfo.executables.find(
  (e) => e.name === "chromium" && e.installed,
)?.path;
assert.ok(executablePath, "soyLI cached Chromium is available");
const url = process.argv[2];
assert.ok(url, "Pass the URL printed by soyli dev");
const output = resolve(".napplet-space/prototype-checks");
await mkdir(output, { recursive: true });
const browser = await chromium.launch({ executablePath, headless: true });
const results = [];
try {
  const context = await browser.newContext({
    viewport: { width: 1400, height: 1000 },
    deviceScaleFactor: 1,
  });
  const page = await context.newPage();
  const errors = [];
  page.on("pageerror", (e) => errors.push(e.message));
  await page.goto(url);
  const iframe = page.locator("iframe");
  await iframe.waitFor();
  let frame = await (await iframe.elementHandle()).contentFrame();
  async function size(w, h) {
    await page.setViewportSize({
      width: Math.max(w, 500),
      height: Math.max(h, 500),
    });
    await iframe.evaluate(
      (el, { w, h }) => {
        el.style.cssText = `position:fixed;left:0;top:0;width:${w}px;height:${h}px;min-height:0;max-height:none;border:0;z-index:9999`;
      },
      { w, h },
    );
    await frame.waitForFunction(
      ({ w, h }) => innerWidth === w && innerHeight === h,
      { w, h },
    );
    if (w > 760 && h > 440 && (await frame.locator("#mapPage").isVisible())) {
      const widths = await frame
        .locator("#mapPage")
        .evaluate((el) =>
          [...el.children].map((p) => p.getBoundingClientRect().width),
        );
      [0.23, 0.47, 0.3].forEach((fraction, i) =>
        assert.ok(
          Math.abs(widths[i] - w * fraction) < 1,
          `${w}px: requested sidebar/body proportions`,
        ),
      );
    }
  }
  await size(1200, 800);
  await frame.getByRole("button", { name: "Sitting", exact: true }).click();
  await seedSyntheticCase(frame);
  assert.match(
    await frame.locator(".observation-note").innerText(),
    /standing/,
    "The synthetic setup resets a previously changed pose before anchoring",
  );
  assert.equal(await frame.locator("#concernCount").innerText(), "2");
  assert.equal(await frame.locator("#webglFallback").isVisible(), false);
  assert.equal(
    await frame.locator("#bodyViewport").getAttribute("data-model"),
    "mpfb-skin-1",
  );
  await frame.locator("#toast").waitFor({ state: "hidden" });
  // Each form belongs to its own disclosure, with keyboard and saved collapse state.
  const first = frame.locator('[data-concern="1"]');
  assert.equal(await first.getAttribute("aria-expanded"), "true");
  assert.equal(
    await first.locator("xpath=../../..").locator("#location").inputValue(),
    "Left knee · front",
  );
  await first.focus();
  await first.press("Enter");
  assert.equal(await frame.locator(".concern-editor").count(), 0);
  assert.equal(
    await first.evaluate((el) => document.activeElement === el),
    true,
    "Collapsing retains keyboard focus",
  );
  await frame.waitForFunction(
    () =>
      document.querySelector("#sessionStatus").textContent === "Session saved",
  );
  await page.reload();
  await iframe.waitFor();
  frame = await (await iframe.elementHandle()).contentFrame();
  await frame.locator('#app[data-ready="true"]').waitFor();
  await size(1200, 800);
  assert.equal(
    await frame.locator(".concern-editor").count(),
    0,
    "Collapsed state survives reload",
  );
  assert.equal(
    await frame.locator('[data-concern="1"]').getAttribute("aria-expanded"),
    "false",
  );
  await frame.locator('[data-concern="1"]').press("Space");
  assert.equal(
    await frame.locator("#location").inputValue(),
    "Left knee · front",
  );
  await frame.locator('[data-concern="2"]').click();
  await frame
    .locator("#description")
    .fill("Synthetic accordion persistence check.");
  await frame.locator('[data-concern="1"]').click();
  await frame.locator('[data-concern="2"]').click();
  assert.equal(
    await frame.locator("#description").inputValue(),
    "Synthetic accordion persistence check.",
  );
  assert.equal(await frame.locator(".concern-editor").count(), 1);
  await frame.locator('[data-concern="1"]').click();
  await frame.locator(".concerns-panel").evaluate((el) => (el.scrollTop = 0));
  results.push(
    "Observation accordions: inline forms, keyboard toggling, saved collapse state, retained data and 23/47/30 desktop columns",
  );
  await page.screenshot({ path: resolve(output, "desktop.png") });
  results.push("1200x800: rendered sample, WebGL canvas, two concerns");
  await frame.getByRole("button", { name: "Sitting", exact: true }).click();
  assert.match(await frame.locator(".observation-note").innerText(), /sitting/);
  await frame.getByRole("button", { name: "Standing", exact: true }).click();
  await frame.locator("#height").fill("190");
  await frame.locator("#weight").fill("110");
  assert.equal(await frame.locator("#heightValue").innerText(), "190");
  assert.equal(await frame.locator("#weightValue").innerText(), "110");
  await frame.locator("#height").fill("172");
  await frame.locator("#weight").fill("70");
  const pinBefore = await frame.locator(".body-pin").boundingBox();
  assert.ok(pinBefore);
  await frame.getByRole("button", { name: "Sitting", exact: true }).click();
  await frame.getByRole("button", { name: "Lying down", exact: true }).click();
  await page.screenshot({ path: resolve(output, "pose-debug.png") });

  const pinAfter = await frame.locator(".body-pin").boundingBox();
  assert.ok(pinAfter);
  assert.ok(
    Math.hypot(pinAfter.x - pinBefore.x, pinAfter.y - pinBefore.y) > 0.1,
    "Surface pin follows changed pose",
  );
  await frame.getByRole("button", { name: "Standing", exact: true }).click();
  await frame.locator('[data-view="front"]').click();
  await frame
    .getByRole("button", { name: "Mark a concern", exact: true })
    .click();
  const poseCanvas = await frame.locator("canvas").boundingBox();
  let foot;
  outer: for (const y of [0.9, 0.89, 0.91, 0.88, 0.92])
    for (const x of [0.55, 0.54, 0.56, 0.53, 0.57, 0.52, 0.58, 0.59]) {
      const point = {
        x: poseCanvas.x + poseCanvas.width * x,
        y: poseCanvas.y + poseCanvas.height * y,
      };
      await page.mouse.move(point.x, point.y);
      if (
        /^Left (foot|ankle|forefoot|heel|toes)/.test(
          await frame.locator("#sceneHint").innerText(),
        )
      ) {
        foot = point;
        break outer;
      }
    }
  assert.ok(foot, "Locate the rendered foot after responsive canvas layout");
  await frame.getByRole("button", { name: "Adjust pose", exact: true }).click();
  const beforeDrag = await frame.locator(".body-pin").boundingBox();
  await page.mouse.move(foot.x, foot.y);
  await page.mouse.down();
  await page.mouse.move(foot.x + 40, foot.y - 65, { steps: 12 });
  await page.mouse.up();
  const afterDrag = await frame.locator(".body-pin").boundingBox();
  assert.ok(
    Math.hypot(afterDrag.x - beforeDrag.x, afterDrag.y - beforeDrag.y) > 10,
    "Dragging the visible foot adjusts the limb and its knee mark",
  );
  await page.screenshot({ path: resolve(output, "limb-pose.png") });
  await frame.getByRole("button", { name: "Standing", exact: true }).click();
  await frame.locator("#newConcern").click();
  await frame.getByRole("button", { name: "Sitting", exact: true }).click();
  assert.match(
    await frame.locator(".concern-tab.active small").innerText(),
    /Standing/,
    "Preparing a new concern preserves the previous concern pose",
  );
  await frame.getByRole("button", { name: "Standing", exact: true }).click();
  const canvas = await frame.locator("canvas").boundingBox();
  assert.ok(canvas);
  await page.mouse.move(
    canvas.x + canvas.width / 2 + 8,
    canvas.y + canvas.height * 0.39,
  );
  await page.mouse.down();
  await page.mouse.move(
    canvas.x + canvas.width / 2 + 17,
    canvas.y + canvas.height * 0.42,
    { steps: 8 },
  );
  await page.mouse.up();
  assert.equal(await frame.locator("#concernCount").innerText(), "3");
  assert.equal(
    await frame.locator("#severityValue").innerText(),
    "—",
    "New concerns do not invent a severity",
  );
  await frame.locator("#severity").fill("7");
  await frame
    .locator("#description")
    .fill("Synthetic test: pulling sensation during movement.");
  await frame.locator("#onset").selectOption({ label: "Today" });
  await frame.locator("#undoMark").click();
  results.push(
    "Painting creates one concern per stroke; description/onset edits; undo; pin follows pose; live measurements",
  );
  await frame.locator("#connectionsButton").click();
  assert.equal(await frame.locator("#apiKey").count(), 0);
  await frame.locator('[data-ai="paid"]').click();
  await frame.locator("#paidKey").fill("a".repeat(64));
  await frame.locator('[data-ai="save-service"]').click();
  await frame.locator("#closeModal").click();
  results.push(
    "Real host SDK storage saves only paid-service metadata; no provider keys in the napplet",
  );
  await frame.locator("#draftsButton").click();
  await frame.locator('[data-draft="save"]').click();
  await frame.waitForFunction(() =>
    document
      .querySelector(".draft-status")
      .textContent.includes("Session saved"),
  );
  await frame.locator("#closeModal").click();
  await frame
    .locator("#description")
    .fill("Synthetic test: pulling, updated before reload.");
  await frame.waitForFunction(
    () =>
      document.querySelector("#sessionStatus").textContent === "Session saved",
  );
  await page.reload();
  await iframe.waitFor();
  frame = await (await iframe.elementHandle()).contentFrame();
  await frame.locator('#app[data-ready="true"]').waitFor();
  await size(1200, 800);
  assert.equal(await frame.locator("#concernCount").innerText(), "3");
  assert.equal(
    await frame.locator("#description").inputValue(),
    "Synthetic test: pulling, updated before reload.",
  );
  await frame.locator("#connectionsButton").click();
  await frame.locator("[data-ai=paid]").click();
  assert.equal(
    await frame.locator("#paidKey").inputValue(),
    "a".repeat(64),
    "Paid service returns from host storage",
  );
  await frame.locator("#closeModal").click();
  results.push(
    "Actual hosted reload restores autosaved concerns and paid-service metadata",
  );
  await frame.locator('[data-page="context"]').first().click();
  await frame
    .locator("#conditions")
    .fill("Synthetic background for UI testing.");
  assert.ok(await frame.locator("#contextAttachment").isVisible());
  await frame.locator("#nextButton").click();
  await frame.waitForFunction(
    () =>
      document.querySelector("#sessionStatus").textContent === "Session saved",
  );
  await page.reload();
  await iframe.waitFor();
  frame = await (await iframe.elementHandle()).contentFrame();
  await frame.locator('#app[data-ready="true"]').waitFor();
  await size(1200, 800);
  assert.equal(
    await frame.locator("#reviewPage").isVisible(),
    true,
    "Continue button persists the current step",
  );
  assert.match(
    await frame.locator("#reviewPage").innerText(),
    /Synthetic test: pulling/,
  );
  assert.match(
    await frame.locator("#reviewPage").innerText(),
    /Synthetic background/,
  );
  await frame.locator('[data-ai="request"]').click();
  await frame.locator('[data-ai="select"]').waitFor();
  await frame.locator("#closeModal").click();
  await page.screenshot({ path: resolve(output, "review.png") });
  results.push(
    "Context, photo entry point, deterministic summary and shell model-selection entry",
  );
  await frame.locator("#nextButton").click();
  await frame.locator(".concerns-panel").evaluate((el) => (el.scrollTop = 0));
  for (const [w, h] of [
    [900, 600],
    [320, 560],
    [200, 160],
    [1600, 1000],
  ]) {
    await size(w, h);
    if (w < 280 || h < 280)
      assert.equal(await frame.locator(".minimum-notice").isVisible(), true);
    else {
      assert.equal(await frame.locator("#nextButton").isVisible(), true);
      assert.equal(
        await frame.evaluate(
          () => document.documentElement.scrollWidth <= innerWidth,
        ),
        true,
      );
    }
    await page.screenshot({ path: resolve(output, `frame-${w}x${h}.png`) });
    results.push(
      `${w}x${h}: actual frame dimensions verified, layout captured`,
    );
  }
  await size(900, 600);
  // Host theme change via its own control. Bring host UI back temporarily.
  await iframe.evaluate((el) => (el.style.cssText = ""));
  await page.getByRole("button", { name: /Appearance:/ }).click();
  const light = await frame.evaluate(() =>
    getComputedStyle(document.documentElement)
      .getPropertyValue("--emphasis")
      .trim(),
  );
  await page.getByRole("button", { name: /Appearance:/ }).click();
  const dark = await frame.evaluate(() =>
    getComputedStyle(document.documentElement)
      .getPropertyValue("--emphasis")
      .trim(),
  );
  assert.equal(light, "#c43c20");
  assert.equal(light, dark);
  results.push("Host light/dark controls preserve app-owned palette");
  assert.deepEqual(errors, []);
  await context.close();
  const touch = await browser.newContext({
    viewport: { width: 390, height: 844 },
    hasTouch: true,
    isMobile: true,
    deviceScaleFactor: 1,
  });
  const phone = await touch.newPage();
  await phone.goto(url);
  const phoneIframe = phone.locator("iframe");
  await phoneIframe.waitFor();
  const phoneFrame = await (await phoneIframe.elementHandle()).contentFrame();
  async function phoneSize(w, h) {
    await phone.setViewportSize({ width: w, height: h });
    await phoneIframe.evaluate(
      (el, { w, h }) =>
        (el.style.cssText = `position:fixed;left:0;top:0;width:${w}px;height:${h}px;min-height:0;border:0;z-index:9999`),
      { w, h },
    );
    await phoneFrame.waitForFunction(
      ({ w, h }) => innerWidth === w && innerHeight === h,
      { w, h },
    );
  }
  await phoneSize(390, 844);
  await phoneFrame.locator('[data-panel="concerns"]').tap();
  await phoneFrame.locator("#chooseRegion").tap();
  await phoneFrame.locator('[data-region="Left knee"]').tap();
  assert.equal(await phoneFrame.locator("#concernCount").innerText(), "1");
  await phoneFrame.locator('[data-panel="body"]').tap();
  await phoneFrame.getByRole("button", { name: "Sitting", exact: true }).tap();
  await phone.screenshot({ path: resolve(output, "mobile.png") });
  await phoneSize(360, 640);
  await phoneFrame.locator('[data-panel="concerns"]').tap();
  await phoneFrame.locator("#generalConcern").tap();
  await phoneFrame.locator('[data-region="Nausea"]').tap();
  assert.equal(await phoneFrame.locator("#concernCount").innerText(), "2");
  await phoneFrame.locator("#connectionsButton").tap();
  assert.equal(await phoneFrame.locator("#apiKey").count(), 0);
  await phone.screenshot({ path: resolve(output, "ai-options-mobile.png") });
  await phoneFrame.locator("#closeModal").tap();
  await phoneSize(844, 390);
  await phone.screenshot({ path: resolve(output, "mobile-landscape.png") });
  assert.equal(await phoneFrame.locator("#nextButton").isVisible(), true);
  results.push(
    "Touch emulation: 390x844, 360x640 and 844x390; body-region selection, pose, general concern, orientation change",
  );
  await touch.close();
  // Additional opaque sandbox with no injected optional capabilities; same built bytes.
  const absent = await browser.newContext({
    viewport: { width: 900, height: 600 },
  });
  const absentPage = await absent.newPage();
  const html = await (
    await import("node:fs/promises")
  ).readFile(resolve("dist/index.html"), "utf8");
  await absentPage.setContent(
    '<iframe sandbox="allow-scripts" style="position:fixed;inset:0;width:900px;height:600px;border:0"></iframe>',
  );
  await absentPage
    .locator("iframe")
    .evaluate((el, html) => (el.srcdoc = html), html);
  const absentFrame = await (
    await absentPage.locator("iframe").elementHandle()
  ).contentFrame();
  await seedSyntheticCase(absentFrame);
  await absentFrame.locator("#connectionsButton").click();
  assert.equal(
    await absentFrame.locator("[data-ai=select]").isDisabled(),
    true,
  );
  results.push(
    "Opaque iframe without optional domains: app works and AI chooser explains unsupported shell",
  );
  await absent.close();
  await writeFile(
    resolve(output, "results.json"),
    JSON.stringify({ url, results, errors }, null, 2),
  );
  console.log(JSON.stringify({ results, errors }, null, 2));
} finally {
  await browser.close();
}