Zum Inhalt

embed/tests/e2e/pose-authoring.test.mjs

// E2E for pose-authoring: the ?authoring=1 copy-pose button's visibility
// gate. Real clipboard/pose-value verification is out of scope for headless
// E2E (see embed-smoke.test.mjs's rationale) — covered by the manual smoke
// in the pose-authoring design spec instead.
import { test, before, after } from 'node:test';
import assert from 'node:assert/strict';
import { spawn } from 'node:child_process';
import { setTimeout as wait } from 'node:timers/promises';
import puppeteer from 'puppeteer-core';
import { dirname, resolve } from 'node:path';
import { fileURLToPath } from 'node:url';

const HERE = dirname(fileURLToPath(import.meta.url));
const ROOT = resolve(HERE, '..', '..');          // embed/
const CHROME = '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome';
const PORT = 8132;
const URL_BASE = `http://localhost:${PORT}`;

let server = null;
let browser = null;

before(async () => {
  server = spawn('python3', ['-m', 'http.server', String(PORT)], {
    cwd: ROOT, stdio: ['ignore', 'pipe', 'pipe'],
  });
  for (let i = 0; i < 30; i++) {
    try { const r = await fetch(URL_BASE + '/'); if (r.ok) break; }
    catch { /* still booting */ }
    await wait(100);
  }
  browser = await puppeteer.launch({
    executablePath: CHROME, headless: 'new',
    args: ['--no-sandbox', '--disable-features=Translate', '--hide-scrollbars'],
  });
});

after(async () => {
  if (browser) await browser.close();
  if (server) { server.kill(); await wait(200); }
});

test('authoring=1 with broken src: copy-pose button stays hidden through the error state', async () => {
  const page = await browser.newPage();
  await page.goto(URL_BASE + '/?src=does-not-exist.sog&authoring=1',
                  { waitUntil: 'domcontentloaded' });
  await page.click('#gate');
  await page.waitForFunction(
    () => !document.getElementById('error-card').hidden, { timeout: 30000 });
  const hidden = await page.evaluate(
    () => document.getElementById('btn-copy-pose').hidden);
  assert.equal(hidden, true, 'copy-pose button hidden while load failed');
  await page.close();
});

test('without authoring param: copy-pose button stays hidden regardless of state', async () => {
  const page = await browser.newPage();
  await page.goto(URL_BASE + '/?src=does-not-exist.sog',
                  { waitUntil: 'domcontentloaded' });
  const beforeClick = await page.evaluate(
    () => document.getElementById('btn-copy-pose').hidden);
  assert.equal(beforeClick, true, 'hidden before any interaction');
  await page.click('#gate');
  await page.waitForFunction(
    () => !document.getElementById('error-card').hidden, { timeout: 30000 });
  const afterError = await page.evaluate(
    () => document.getElementById('btn-copy-pose').hidden);
  assert.equal(afterError, true, 'still hidden after error state');
  await page.close();
});