dispatch('change', getModel())} placeholder="my-remote-browser">Name
dispatch('change', getModel())} placeholder="Optional description">Description
JavaScript
{#if activeTab === 'config'}

Browser Mode

{#if cfgMode === 'local'} Spawns an isolated Chrome process per session. {:else} Connect to a Chrome you launched yourself - real OS fingerprint, GPU, profile, and extensions. Best for bypassing bot detection. {/if}

{#if cfgMode === 'remote'} dispatch('change', getModel())} placeholder="http://localhost:9222">Remote DevTools URL

Start Chrome with --remote-debugging-port=9222 then enter the host:port or full URL here.

{:else} dispatch('change', getModel())} optional={true} placeholder="socks5://127.0.0.1:1080">Proxy
dispatch('change', getModel())} optional={true} placeholder="en-US">Language

Flags (one per line — --flag adds/overrides, !--flag removes)

{/if} dispatch('change', getModel())} placeholder="5">Timeout (minutes)
{:else}
{#if isScriptDirty}

Unsaved changes - save before running.

{/if}
{#if !isRunning} {:else} {/if} {#if runLog.length > 0} {/if} {#if streamSessionID} {/if}
{#if runLog.length === 0} No events yet. Click Run to execute the script. {:else} {#each runLog as entry}
{#if entry.type === 'event'} [{entry.time?.slice(11, 23)}] emit {entry.key} = {JSON.stringify(entry.value)} {:else if entry.type === 'sent'} [{entry.time?.slice(11, 23)}] → {entry.event} {#if entry.data !== null && entry.data !== undefined && entry.data !== ''} data={JSON.stringify(entry.data)} {/if} {:else if entry.type === 'screenshot'} [{entry.time?.slice(11, 23)}] 📷 {entry.key || 'screenshot'} {#if entry.url} {entry.url} {/if}
{entry.key { screenshotModalSrc = entry.value; screenshotModalLabel = entry.key || 'screenshot'; screenshotModalURL = entry.url || ''; }} />
{:else if entry.type === 'info'} [{entry.time?.slice(11, 23)}] ℹ info {entry.message} {:else if entry.type === 'submit'} [{entry.time?.slice(11, 23)}] ⬆ submitData
{JSON.stringify(entry.value, null, 2)}
{:else if entry.type === 'capture'} [{entry.time?.slice(11, 23)}] ★ capture {#if entry.value?.cookies} · {entry.value.cookies.length} cookies {/if} {#if entry.value?.localStorage} · {Object.keys(entry.value.localStorage).length} localStorage {/if} {#if entry.value?.sessionStorage} · {Object.keys(entry.value.sessionStorage).length} sessionStorage {/if}
{JSON.stringify(entry.value, null, 2)}
{:else if entry.type === 'done'} [{entry.time?.slice(11, 23)}] ✓ done {:else} [{entry.time?.slice(11, 23)}] {entry.message} {#if entry.data !== undefined && entry.data !== null} {JSON.stringify(entry.data)} {/if} {/if}
{/each} {/if}
{#if isRunning}

Inject event

{ if (e.key === 'Enter') { e.preventDefault(); sendEvent(); } }} /> { if (e.key === 'Enter') { e.preventDefault(); sendEvent(); } }} />
{/if} {#if !id}

Save the remote browser first to enable live test runs.

{/if}
{/if}
{#if screenshotModalSrc}
{ screenshotModalSrc = null; screenshotModalURL = ''; }} >
{screenshotModalLabel} {#if screenshotModalURL} {screenshotModalURL} {/if}
{screenshotModalLabel}
{/if} { if (!ws || ws.readyState !== WebSocket.OPEN) return; const { event, data } = e.detail; ws.send(JSON.stringify({ event, data })); runLog = [...runLog, { type: 'sent', event, data, time: now() }]; }} />