YT/queue View source ↗

Interactive demo · zero uploads

Schedule logic,
without the upload.

Replay validation, audience, visibility, scheduling, verification, and resume state against synthetic fixtures. YouTube Studio is never opened.

60-second deterministic replay

Inspect each scheduling decision.

The mock adapter preserves the live manifest contract and produces evidence for every item without loading a browser client.

Problem

A successful upload is not proof of a correct schedule.

Studio changes the number of wizard steps by channel, disables controls during processing, and accepts wall-clock dates in the channel timezone. A premature click can leave a private draft; an unchecked field can schedule the wrong moment.

The scheduler models the batch independently from Studio, makes audience and visibility explicit, reads date and time back before finalization, and persists completed keys for safe resume.

Architecture

Deterministic orchestration around a volatile UI.

Only the injected live adapter knows selectors or CDP. Validation, sequencing, failure behavior, and reporting stay testable without YouTube.

Manifest

File, title, description, audience, visibility, and optional wall-clock target are explicit inputs.

Batch core

Stable keys drive order, deduplication, pacing, stop-on-error behavior, and event evidence.

Studio adapter

Owns CDP file injection, variable wizard steps, enabled-state waits, and native controls.

Verification

Requested date and time are compared with Studio readback before the final button is allowed.

Workflow

Seven stages guard the terminal click.

The adapter moves forward only when the previous platform state is observable.

  1. 01ValidateMedia, title, values, and stable key.
  2. 02UploadInject media through CDP.
  3. 03DetailsTitle and description.
  4. 04AudienceMade-for-kids choice is explicit.
  5. 05VisibilitySchedule or public/private/unlisted.
  6. 06VerifyRead date and time back.
  7. 07PersistFinalize, save key, then pace.
Enabled-state gate

aria-disabled is polled before Next or Done. This prevents a silent private draft while processing is incomplete.

Timezone contract

The manifest carries a wall-clock value interpreted in the configured channel timezone; the adapter does not silently convert it.

Mismatch abort

A readback mismatch throws before Done, directly preventing publication at an unintended time.

Real, linked code

The critical guards are small and reviewable.

These excerpts are taken from the public implementation.

ENABLED-STATE GATEupload.mjs ↗
while (Date.now() - start < timeoutMs) {
  if (await el.count()) {
    const aria = await el.getAttribute('aria-disabled');
    if (aria !== 'true') {
      await el.click();
      return;
    }
  }
  await sleep(1000);
}

The automation waits for Studio's real control state instead of assuming that a visible button is actionable.

SCHEDULE READBACKupload.mjs ↗
const rb = await page.evaluate(() => ({
  date: document.querySelector('#datepicker-trigger')
    ?.innerText.trim(),
  time: document.querySelector(
    'tp-yt-paper-input#textbox input'
  )?.value
}));

if (rb.date !== dateLabel || rb.time !== timeLabel) {
  throw new Error('schedule mismatch');
}

Finalization is impossible when the platform does not echo the exact requested wall-clock target.

RESUME BEFORE ADAPTERbatch-core.mjs ↗
if (doneSet.has(key)) {
  results.push({ key, status: 'skipped', steps: [] });
  onEvent({ type: 'skipped', key, done: [...doneSet] });
  continue;
}

A completed item never reaches the upload adapter on a resumed run.

Execution boundary

The public path has no upload capability.

Demo mode is a separate import graph, backed by a local mock and static evidence.

DEMO

npm run demo

  • Synthetic fixture
  • Deterministic adapter
  • No media bytes transmitted
  • No Playwright, CDP, login, or Studio
LIVE

npm run batch

  • Operator-owned media and channel
  • Attached Chrome profile
  • Native upload and schedule UI
  • Explicit consequential command

Quality and limitations

Evidence for the core; caution for the platform edge.

0demo uploads
5offline core tests
3synthetic fixture items
1terminal schedule guard

Run locally

Generate the offline evidence.

No login or API key is required for demo mode.

npm install
npm run demo
npm test
npm run test:site

# equivalent explicit CLI
node src/demo.mjs \
  --fixture manifest.example.json \
  --output site