← Public packages
@kody/browser-run
Call Cloudflare Browser Run Quick Actions and reuse shared sessions with createBrowserContext.
src/smoke-test.ts
113 lines · 3.4 KB · TypeScriptimport { boolean, object, optional, parse, string } from 'remix/data-schema'
import {
ACCOUNT_ID_HELP,
DEFAULT_API_TOKEN_SECRET,
DOCS_HOME,
TOKEN_SETUP_URL,
pickAuth,
secretSetupUrl,
} from './client.ts'
import listSessions from './sessions/list.ts'
import overview from './index.ts'
const smokeInput = object(
{
accountId: optional(string()),
apiTokenSecret: optional(string()),
/** When true (default if accountId missing), skip live CF calls. */
dryRun: optional(boolean()),
},
{ unknownKeys: 'error' },
)
/**
* Read-only smoke test: returns setup guidance when secrets/accountId are
* missing; otherwise lists sessions (or dry-runs the list). Prefer this after
* publish to verify wiring without launching browsers or Quick Actions.
*
* @param raw.accountId - Cloudflare account id (optional for dry guidance)
* @param raw.dryRun - Force dry guidance / list dryRun
* @param raw.apiTokenSecret - Optional alternate secret name
* @returns `{ ok, mode, … }` with clear next steps when not fully configured
*
* @example
* import smokeTest from 'kody:@kody/browser-run/smoke-test'
* const result = await smokeTest()
* // => { ok: true, mode: 'setup-guidance', … } or live session list
*/
export default async function smokeTest(raw: unknown = {}) {
const input = parse(smokeInput, raw ?? {})
const auth = pickAuth(input)
const secretName = auth.apiTokenSecret || DEFAULT_API_TOKEN_SECRET
const accountId = (input.accountId || '').trim()
const forceDry = input.dryRun === true || !accountId
const meta = await overview()
if (forceDry && !accountId) {
return {
ok: true,
mode: 'setup-guidance' as const,
package: meta.name,
docs: DOCS_HOME,
secret: {
name: secretName,
setupUrl: secretSetupUrl(secretName),
defaultSetupUrl: TOKEN_SETUP_URL,
permission: 'Browser Rendering - Edit',
host: 'api.cloudflare.com',
},
accountIdHelp: ACCOUNT_ID_HELP,
nextSteps: [
`Save user secret \`${secretName}\` with allowed host api.cloudflare.com: ${secretSetupUrl(secretName)}`,
`Pass accountId on live calls. ${ACCOUNT_ID_HELP}`,
'Then: import smokeTest from "kody:@kody/browser-run/smoke-test"; await smokeTest({ accountId })',
'Default automation path: kody:@kody/browser-run/open-isolated',
],
exports: meta.exports,
pitOfSuccess: meta.pitOfSuccess,
}
}
if (input.dryRun === true) {
const preview = await listSessions({
accountId,
apiTokenSecret: auth.apiTokenSecret,
dryRun: true,
})
return {
ok: true,
mode: 'list-dry-run' as const,
preview,
pitOfSuccess: meta.pitOfSuccess,
}
}
try {
const listed = await listSessions({
accountId,
apiTokenSecret: auth.apiTokenSecret,
})
return {
ok: true,
mode: 'list-sessions' as const,
accountId,
count: listed.count,
sessions: listed.sessions,
pitOfSuccess: meta.pitOfSuccess,
note: 'Live list succeeded. Prefer open-isolated for shared automation; Quick Actions for one-shots.',
}
} catch (error) {
const message = error instanceof Error ? error.message : String(error)
return {
ok: false,
mode: 'list-failed' as const,
accountId,
error: message,
setupUrl: secretSetupUrl(secretName),
accountIdHelp: ACCOUNT_ID_HELP,
hint:
'Ensure cloudflareApiToken (or apiTokenSecret) exists, host api.cloudflare.com is allowed, token has Browser Rendering - Edit, and accountId is correct.',
}
}
}