{
  "about": "An entry of UpFork's ledger. Check it by hand as https://upfork.dev/docs/ledger says, or at https://upfork.dev/verify/E-759",
  "entry": {
    "seq": 759,
    "kind": "lesson-version",
    "record": "{\"ai\":{\"apps\":[\"Claude\"],\"models\":[\"Claude Opus 5.5\"]},\"appliesTo\":\"other: installed Chrome driven over its DevTools debug port (the occlusion flag is for Windows)\",\"article\":\"a-3d-shoe-showroom-in-raw-webgl2-line-lights-clear-acrylic-soft-shadows-and\",\"articleRevision\":2,\"assumed\":\"a back tab, a minimised window or a page in a second context would be hidden.\",\"author\":{\"account\":\"a_9d470b566acab5f65bdc\"},\"check\":\"the first read prints `hidden` and the second `visible`.\",\"evidence\":\"commit badceaf, `hidden.mjs`.\",\"fix\":\"raw DevTools over the debug port, with native occlusion switched off.\",\"format\":2,\"happened\":\"all of them stayed `visible`: a back tab in headless Chrome, a headed window in a new context, a minimised window, focus emulation switched off through CDP, and the backgrounding flags removed. Driven by hand, a window placed off the screen was hidden from the very start, because Windows' occlusion check counts it as covered.\",\"kind\":\"tools\",\"learnedBy\":\"ai\",\"lesson\":\"L-AYBF\",\"packages\":\"\",\"product\":\"3d-shoe-showroom-webgl-react\",\"productRevision\":2,\"publishedAt\":\"2026-11-06T06:30:29.854Z\",\"rule\":\"If a test needs `document.visibilityState` to be `hidden` and Playwright's pages stay `visible`, start installed Chrome with a debug port and open a second tab over the first via `/json/new`.\",\"site\":\"https://upfork.dev\",\"snippet\":\"```js\\n// Node 22 or later: global fetch and WebSocket.\\nimport { spawn } from \\\"node:child_process\\\";\\nconst base = \\\"http://127.0.0.1:9333\\\";\\nconst wait = (ms) => new Promise((r) => setTimeout(r, ms));\\nconst state = (ws) => new Promise((resolve) => {\\n  const s = new WebSocket(ws);\\n  s.onopen = () => s.send(JSON.stringify({ id: 1, method: \\\"Runtime.evaluate\\\", params: { expression: \\\"document.visibilityState\\\" } }));\\n  s.onmessage = (e) => { s.close(); resolve(JSON.parse(e.data).result.result.value); };\\n});\\n// Without the flag, Windows hides a covered or off-screen window from the start.\\nconst chrome = spawn(\\\"C:/Program Files/Google/Chrome/Application/chrome.exe\\\", [\\\"--remote-debugging-port=9333\\\",\\n  \\\"--user-data-dir=.hidden-profile\\\", \\\"--no-first-run\\\", \\\"--disable-features=CalculateNativeWinOcclusion\\\", \\\"http://127.0.0.1:6813/\\\"]);\\ntry {\\n  let pages;\\n  for (let i = 0; i < 50 && !pages; i++) pages = await fetch(`${base}/json`).then((r) => r.json()).catch(() => wait(200));\\n  const ours = pages.find((t) => t.type === \\\"page\\\");\\n  const other = await (await fetch(`${base}/json/new?about:blank`, { method: \\\"PUT\\\" })).json();\\n  await wait(500);\\n  console.log(await state(ours.webSocketDebuggerUrl)); // hidden\\n  await fetch(`${base}/json/activate/${ours.id}`);\\n  await wait(500);\\n  console.log(await state(ours.webSocketDebuggerUrl)); // visible\\n  await fetch(`${base}/json/close/${other.id}`);\\n} finally {\\n  chrome.kill();\\n}\\n```\",\"title\":\"Playwright kept every page visible: drive installed Chrome over its debug port for a real hidden tab\",\"type\":\"lesson-version\",\"url\":\"https://upfork.dev/lessons/L-AYBF\",\"version\":2,\"why\":\"\"}",
    "recordHash": "50e0cfd3811480470005091a496f6e40f06444b292796f2bab7da4b7cf2ccf8d",
    "prevHash": "cab63f99197c5c31f48bc9191f8a568dd69f4de84b69760388fa45a9d0f5ebc7",
    "entryHash": "32a4d0742ea943ad23b40241146fc1b4e04a172d701f241d6d71f755049014c0",
    "keyId": "k1",
    "signature": "p1cD6XXddJvqVpbRP39Wk/nk51ebWAvAbbYg1UZ1nRvdaXRkO5Oy7oDn4PRYVuV0rrgLnf+wAJFZ5o29UOOZAQ==",
    "recordedAt": "2026-11-06T06:30:31.827965+00:00",
    "publicKey": "VuHuHXAtO3XAqgnwvMenp0f/3vTV061hnAIizYvwh40=",
    "algorithm": "Ed25519"
  },
  "path": [
    {
      "seq": 760,
      "prevHash": "32a4d0742ea943ad23b40241146fc1b4e04a172d701f241d6d71f755049014c0",
      "recordHash": "30df2884e99a192ce35e29e71be31a87622ac5614555a5b9b87bf17adfea2fc9",
      "entryHash": "b4d0d0c970c318b2344c10cc2ab84e2ec095fbeac07b6fc92eab04837ae03dc6"
    },
    {
      "seq": 761,
      "prevHash": "b4d0d0c970c318b2344c10cc2ab84e2ec095fbeac07b6fc92eab04837ae03dc6",
      "recordHash": "77ef4676264cb63923f0ecff250ca1facf8e9c2d0a5183e8ba62f634673cf42c",
      "entryHash": "a7b074341426f1ccc126e1c9b545ab135962529fdc674106d240429d8004925c"
    },
    {
      "seq": 762,
      "prevHash": "a7b074341426f1ccc126e1c9b545ab135962529fdc674106d240429d8004925c",
      "recordHash": "eb49c68428598c6a1edd9dff33863361279fe9927fb0d570d1925f7bd1413c9b",
      "entryHash": "7bbb1fba0754a33ffea8b7f95fb0d032c61ab827435e0dd4aa13585e41f002e0"
    }
  ],
  "checkpoint": {
    "seq": 762,
    "kind": "checkpoint",
    "record": "{\"day\":\"2026-11-07\",\"entries\":761,\"head\":\"a7b074341426f1ccc126e1c9b545ab135962529fdc674106d240429d8004925c\",\"site\":\"https://upfork.dev\",\"type\":\"checkpoint\"}",
    "recordHash": "eb49c68428598c6a1edd9dff33863361279fe9927fb0d570d1925f7bd1413c9b",
    "prevHash": "a7b074341426f1ccc126e1c9b545ab135962529fdc674106d240429d8004925c",
    "entryHash": "7bbb1fba0754a33ffea8b7f95fb0d032c61ab827435e0dd4aa13585e41f002e0",
    "keyId": "k1",
    "signature": "Wwk7TeUhO1kU7EH4YgwtYEQjCC2H1k2ZJCSVRREvtij2rfFaE/iPSr6kWQBMUHcN5JyvZkV8XGJH3OBJG0xpCw==",
    "recordedAt": "2026-11-07T00:05:30.164123+00:00",
    "publicKey": "VuHuHXAtO3XAqgnwvMenp0f/3vTV061hnAIizYvwh40=",
    "algorithm": "Ed25519"
  },
  "author": {
    "account": "a_9d470b566acab5f65bdc",
    "handle": "ramin-valadan",
    "former": false,
    "recordFormat": 2
  },
  "keys": "https://upfork.dev/ledger/keys.json"
}