2026-07-08 14:27:32 +03:00
|
|
|
import { describe, expect, it, vi } from 'vitest'
|
Remove code-sync (sync command, --watch, implicit drains); link the video overview page
- Drop the sync command, preview --watch/--no-watch/--no-sync, --record-kill-window, and the queued-edit drains before test/export/preview. Editor edits now live in the web editor and are not written back to sources.
- Delete codeSync, applyCodegen, editorOptionsSync, devWatch, codegenFailureLog and their specs; trim devListen to register/sync-state/deregister.
- preview is always one-shot; generated CI workflows run plain screenci preview.
- CLI links point at the video overview page: preview prints /project/<pid>/video/<vid>, a single-video export prints ...?export=<recordId>, multi-video runs keep the run pages. Held-video notices deep-link ?editor.
- Rewrite docs, skill files, and the narration guidance: narrate the flow rather than each click, use the product's own vocabulary, and fill forms with fictitious example data (Emma Carter, emma@aperturebio.com).
2026-09-01 23:32:36 +03:00
|
|
|
import type { DevListenConfig, DevListenDeps } from './src/devListen'
|
2026-07-08 14:27:32 +03:00
|
|
|
import {
|
|
|
|
|
DevAuthError,
|
|
|
|
|
deregisterDevListener,
|
|
|
|
|
registerDevListener,
|
Remove code-sync (sync command, --watch, implicit drains); link the video overview page
- Drop the sync command, preview --watch/--no-watch/--no-sync, --record-kill-window, and the queued-edit drains before test/export/preview. Editor edits now live in the web editor and are not written back to sources.
- Delete codeSync, applyCodegen, editorOptionsSync, devWatch, codegenFailureLog and their specs; trim devListen to register/sync-state/deregister.
- preview is always one-shot; generated CI workflows run plain screenci preview.
- CLI links point at the video overview page: preview prints /project/<pid>/video/<vid>, a single-video export prints ...?export=<recordId>, multi-video runs keep the run pages. Held-video notices deep-link ?editor.
- Rewrite docs, skill files, and the narration guidance: narrate the flow rather than each click, use the product's own vocabulary, and fill forms with fictitious example data (Emma Carter, emma@aperturebio.com).
2026-09-01 23:32:36 +03:00
|
|
|
reportDevSyncState,
|
2026-07-08 14:27:32 +03:00
|
|
|
} from './src/devListen'
|
|
|
|
|
|
|
|
|
|
const config: DevListenConfig = {
|
|
|
|
|
apiUrl: 'http://localhost:8787',
|
2026-08-13 12:18:18 +03:00
|
|
|
credential: { header: 'X-ScreenCI-Secret', value: 'org-secret' },
|
2026-07-08 14:27:32 +03:00
|
|
|
projectName: 'demo',
|
|
|
|
|
machineName: 'laptop',
|
2026-07-11 21:52:29 +03:00
|
|
|
}
|
|
|
|
|
|
2026-07-08 14:27:32 +03:00
|
|
|
function jsonResponse(body: unknown, status = 200): Response {
|
|
|
|
|
return new Response(JSON.stringify(body), {
|
|
|
|
|
status,
|
|
|
|
|
headers: { 'Content-Type': 'application/json' },
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function makeDeps(overrides: Partial<DevListenDeps> = {}): DevListenDeps & {
|
|
|
|
|
fetchMock: ReturnType<typeof vi.fn>
|
|
|
|
|
} {
|
|
|
|
|
const fetchMock = vi.fn(async () => jsonResponse({ ok: true }))
|
|
|
|
|
return {
|
|
|
|
|
fetchFn: fetchMock as unknown as typeof fetch,
|
|
|
|
|
fetchMock,
|
|
|
|
|
sleep: vi.fn(async () => {}),
|
|
|
|
|
logger: { info: vi.fn(), warn: vi.fn(), error: vi.fn() },
|
|
|
|
|
...overrides,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
describe('registerDevListener', () => {
|
2026-09-04 11:31:03 +03:00
|
|
|
it('sends the org credential and the machine name', async () => {
|
2026-07-08 14:27:32 +03:00
|
|
|
const deps = makeDeps()
|
2026-07-22 00:33:31 +03:00
|
|
|
deps.fetchMock.mockResolvedValueOnce(jsonResponse({ listenerId: 'lst_1' }))
|
2026-07-08 14:27:32 +03:00
|
|
|
|
|
|
|
|
const result = await registerDevListener(config, deps)
|
|
|
|
|
|
2026-07-22 00:33:31 +03:00
|
|
|
expect(result).toEqual({ listenerId: 'lst_1' })
|
2026-07-08 14:27:32 +03:00
|
|
|
const [url, init] = deps.fetchMock.mock.calls[0] as [string, RequestInit]
|
|
|
|
|
expect(url).toBe('http://localhost:8787/cli/dev/register')
|
|
|
|
|
const headers = init.headers as Record<string, string>
|
|
|
|
|
expect(headers['X-ScreenCI-Secret']).toBe('org-secret')
|
|
|
|
|
expect(JSON.parse(init.body as string)).toEqual({
|
|
|
|
|
projectName: 'demo',
|
|
|
|
|
machineName: 'laptop',
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
it('throws DevAuthError on a 401', async () => {
|
|
|
|
|
const deps = makeDeps()
|
|
|
|
|
deps.fetchMock.mockResolvedValueOnce(
|
2026-07-12 16:39:20 +03:00
|
|
|
jsonResponse({ error: 'Invalid editor token' }, 401)
|
2026-07-08 14:27:32 +03:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
await expect(registerDevListener(config, deps)).rejects.toBeInstanceOf(
|
|
|
|
|
DevAuthError
|
|
|
|
|
)
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
|
Remove code-sync (sync command, --watch, implicit drains); link the video overview page
- Drop the sync command, preview --watch/--no-watch/--no-sync, --record-kill-window, and the queued-edit drains before test/export/preview. Editor edits now live in the web editor and are not written back to sources.
- Delete codeSync, applyCodegen, editorOptionsSync, devWatch, codegenFailureLog and their specs; trim devListen to register/sync-state/deregister.
- preview is always one-shot; generated CI workflows run plain screenci preview.
- CLI links point at the video overview page: preview prints /project/<pid>/video/<vid>, a single-video export prints ...?export=<recordId>, multi-video runs keep the run pages. Held-video notices deep-link ?editor.
- Rewrite docs, skill files, and the narration guidance: narrate the flow rather than each click, use the product's own vocabulary, and fill forms with fictitious example data (Emma Carter, emma@aperturebio.com).
2026-09-01 23:32:36 +03:00
|
|
|
describe('reportDevSyncState', () => {
|
|
|
|
|
it('reports the syncing video names for the listener', async () => {
|
2026-07-08 14:27:32 +03:00
|
|
|
const deps = makeDeps()
|
Remove code-sync (sync command, --watch, implicit drains); link the video overview page
- Drop the sync command, preview --watch/--no-watch/--no-sync, --record-kill-window, and the queued-edit drains before test/export/preview. Editor edits now live in the web editor and are not written back to sources.
- Delete codeSync, applyCodegen, editorOptionsSync, devWatch, codegenFailureLog and their specs; trim devListen to register/sync-state/deregister.
- preview is always one-shot; generated CI workflows run plain screenci preview.
- CLI links point at the video overview page: preview prints /project/<pid>/video/<vid>, a single-video export prints ...?export=<recordId>, multi-video runs keep the run pages. Held-video notices deep-link ?editor.
- Rewrite docs, skill files, and the narration guidance: narrate the flow rather than each click, use the product's own vocabulary, and fill forms with fictitious example data (Emma Carter, emma@aperturebio.com).
2026-09-01 23:32:36 +03:00
|
|
|
await reportDevSyncState(config, deps, 'lst_1', ['Intro video'])
|
2026-08-24 15:12:52 +03:00
|
|
|
const [url, init] = deps.fetchMock.mock.calls[0] as [string, RequestInit]
|
Remove code-sync (sync command, --watch, implicit drains); link the video overview page
- Drop the sync command, preview --watch/--no-watch/--no-sync, --record-kill-window, and the queued-edit drains before test/export/preview. Editor edits now live in the web editor and are not written back to sources.
- Delete codeSync, applyCodegen, editorOptionsSync, devWatch, codegenFailureLog and their specs; trim devListen to register/sync-state/deregister.
- preview is always one-shot; generated CI workflows run plain screenci preview.
- CLI links point at the video overview page: preview prints /project/<pid>/video/<vid>, a single-video export prints ...?export=<recordId>, multi-video runs keep the run pages. Held-video notices deep-link ?editor.
- Rewrite docs, skill files, and the narration guidance: narrate the flow rather than each click, use the product's own vocabulary, and fill forms with fictitious example data (Emma Carter, emma@aperturebio.com).
2026-09-01 23:32:36 +03:00
|
|
|
expect(url).toBe('http://localhost:8787/cli/dev/sync-state')
|
|
|
|
|
expect(JSON.parse(init.body as string)).toEqual({
|
|
|
|
|
projectName: 'demo',
|
|
|
|
|
listenerId: 'lst_1',
|
|
|
|
|
syncingVideoNames: ['Intro video'],
|
2026-07-08 14:27:32 +03:00
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
|
Remove code-sync (sync command, --watch, implicit drains); link the video overview page
- Drop the sync command, preview --watch/--no-watch/--no-sync, --record-kill-window, and the queued-edit drains before test/export/preview. Editor edits now live in the web editor and are not written back to sources.
- Delete codeSync, applyCodegen, editorOptionsSync, devWatch, codegenFailureLog and their specs; trim devListen to register/sync-state/deregister.
- preview is always one-shot; generated CI workflows run plain screenci preview.
- CLI links point at the video overview page: preview prints /project/<pid>/video/<vid>, a single-video export prints ...?export=<recordId>, multi-video runs keep the run pages. Held-video notices deep-link ?editor.
- Rewrite docs, skill files, and the narration guidance: narrate the flow rather than each click, use the product's own vocabulary, and fill forms with fictitious example data (Emma Carter, emma@aperturebio.com).
2026-09-01 23:32:36 +03:00
|
|
|
it('tolerates an empty 2xx body', async () => {
|
2026-07-08 14:27:32 +03:00
|
|
|
const deps = makeDeps()
|
Remove code-sync (sync command, --watch, implicit drains); link the video overview page
- Drop the sync command, preview --watch/--no-watch/--no-sync, --record-kill-window, and the queued-edit drains before test/export/preview. Editor edits now live in the web editor and are not written back to sources.
- Delete codeSync, applyCodegen, editorOptionsSync, devWatch, codegenFailureLog and their specs; trim devListen to register/sync-state/deregister.
- preview is always one-shot; generated CI workflows run plain screenci preview.
- CLI links point at the video overview page: preview prints /project/<pid>/video/<vid>, a single-video export prints ...?export=<recordId>, multi-video runs keep the run pages. Held-video notices deep-link ?editor.
- Rewrite docs, skill files, and the narration guidance: narrate the flow rather than each click, use the product's own vocabulary, and fill forms with fictitious example data (Emma Carter, emma@aperturebio.com).
2026-09-01 23:32:36 +03:00
|
|
|
deps.fetchMock.mockResolvedValueOnce(new Response('', { status: 200 }))
|
2026-07-08 14:27:32 +03:00
|
|
|
await expect(
|
Remove code-sync (sync command, --watch, implicit drains); link the video overview page
- Drop the sync command, preview --watch/--no-watch/--no-sync, --record-kill-window, and the queued-edit drains before test/export/preview. Editor edits now live in the web editor and are not written back to sources.
- Delete codeSync, applyCodegen, editorOptionsSync, devWatch, codegenFailureLog and their specs; trim devListen to register/sync-state/deregister.
- preview is always one-shot; generated CI workflows run plain screenci preview.
- CLI links point at the video overview page: preview prints /project/<pid>/video/<vid>, a single-video export prints ...?export=<recordId>, multi-video runs keep the run pages. Held-video notices deep-link ?editor.
- Rewrite docs, skill files, and the narration guidance: narrate the flow rather than each click, use the product's own vocabulary, and fill forms with fictitious example data (Emma Carter, emma@aperturebio.com).
2026-09-01 23:32:36 +03:00
|
|
|
reportDevSyncState(config, deps, 'lst_1', [])
|
|
|
|
|
).resolves.toBeUndefined()
|
2026-07-12 00:04:38 +03:00
|
|
|
})
|
2026-07-08 14:27:32 +03:00
|
|
|
})
|
|
|
|
|
|
Remove code-sync (sync command, --watch, implicit drains); link the video overview page
- Drop the sync command, preview --watch/--no-watch/--no-sync, --record-kill-window, and the queued-edit drains before test/export/preview. Editor edits now live in the web editor and are not written back to sources.
- Delete codeSync, applyCodegen, editorOptionsSync, devWatch, codegenFailureLog and their specs; trim devListen to register/sync-state/deregister.
- preview is always one-shot; generated CI workflows run plain screenci preview.
- CLI links point at the video overview page: preview prints /project/<pid>/video/<vid>, a single-video export prints ...?export=<recordId>, multi-video runs keep the run pages. Held-video notices deep-link ?editor.
- Rewrite docs, skill files, and the narration guidance: narrate the flow rather than each click, use the product's own vocabulary, and fill forms with fictitious example data (Emma Carter, emma@aperturebio.com).
2026-09-01 23:32:36 +03:00
|
|
|
describe('deregisterDevListener', () => {
|
2026-07-08 14:27:32 +03:00
|
|
|
it('deregisters with the listener id', async () => {
|
|
|
|
|
const deps = makeDeps()
|
|
|
|
|
await deregisterDevListener(config, deps, 'lst_1')
|
|
|
|
|
const [url, init] = deps.fetchMock.mock.calls[0] as [string, RequestInit]
|
|
|
|
|
expect(url).toBe('http://localhost:8787/cli/dev/deregister')
|
|
|
|
|
expect(JSON.parse(init.body as string).listenerId).toBe('lst_1')
|
|
|
|
|
})
|
|
|
|
|
})
|