@firstlook-uat/sdk
v0.9.15
Published
FirstLook — UAT testing SDK for web applications
Maintainers
Readme
@firstlook/sdk
A framework-agnostic UAT (User Acceptance Testing) SDK for web applications. Embed quest-driven test flows, session recording, voice annotations, and shake-to-report bug reporting into any web app with a single script tag or npm import.
Installation
# npm
npm install @firstlook/sdk
# yarn
yarn add @firstlook/sdk
# pnpm
pnpm add @firstlook/sdkQuick Start
npm / ES Module
import { FirstLookSDK } from "@firstlook/sdk";
const sdk = new FirstLookSDK();
await sdk.init({
projectId: "proj_xxx",
apiKey: "flk_xxx",
userId: "[email protected]",
});
sdk.activate();
await sdk.startSession([
{ id: "q1", title: "Add to Cart", description: "Add any item to the cart", order: 1 },
{ id: "q2", title: "Checkout", description: "Complete the checkout flow", order: 2, blocking: true },
]);CDN / UMD
<script src="https://unpkg.com/@firstlook/sdk/dist/firstlook.umd.js"></script>
<script>
const sdk = new FirstLook.FirstLookSDK();
sdk.init({
projectId: "proj_xxx",
apiKey: "flk_xxx",
userId: "[email protected]",
}).then(() => sdk.activate());
</script>Configuration
All options are passed to sdk.init(). Only projectId, apiKey, and userId are required.
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| projectId | string | required | Project ID from the FirstLook dashboard |
| apiKey | string | required | API key for authentication |
| userId | string | required | Unique identifier for the current tester |
| role | string | undefined | Optional role label (e.g. "admin", "tester") |
| context | Record<string, unknown> | {} | Arbitrary metadata attached to the session |
| endpoint | string | Production URL | Custom endpoint for session data upload |
| triggers.tapCount | number | 5 | Number of taps to open the debug menu |
| triggers.deepLink | boolean | true | Enable deep link activation (?firstlook=1) |
| triggers.shake | boolean | true | Enable shake-to-activate on mobile |
| triggers.customCheck | () => boolean | undefined | Custom function to auto-activate on init |
| security.watermark | boolean | true | Show dynamic watermark during recording |
| security.maskSelectors | string[] | ['input[type="password"]', '[data-sensitive]', '[data-mask]', '.uat-mask'] | CSS selectors for fields to mask |
| recording.domSnapshot | boolean | true | Enable DOM mutation recording |
| recording.voice | boolean | true | Enable voice recording |
| recording.maxDuration | number | 600 | Max recording duration in seconds |
| recording.snapshotInterval | number | 1000 | DOM snapshot interval in milliseconds |
API Reference
init(config: FirstLookConfig): Promise<void>
Initialize the SDK. Sets up triggers, IndexedDB storage, and Shadow DOM host. Does not activate the UI.
activate(): void
Manually activate the SDK UI, bypassing configured triggers. Must be called after init().
startSession(quests: Quest[]): Promise<string>
Start a UAT session with a list of quests. Returns the generated session ID. The SDK must be in the active state.
startSessionFromRemote(questSetId: string): Promise<string>
Fetch quest definitions from the API by quest set ID, then start a session. Returns the session ID.
endSession(): Promise<SessionData | null>
End the current recording session. Stops all recorders, persists data to IndexedDB, and enqueues the session for upload. Returns the session data or null if no session was active.
on(type: SDKEventType | "*", listener: SDKEventListener): () => void
Subscribe to SDK events. Returns an unsubscribe function.
Available event types: sdk:initialized, sdk:activated, sdk:deactivated, session:started, session:ended, quest:started, quest:completed, quest:failed, quest:blocked, recording:started, recording:stopped, report:submitted, error.
const unsubscribe = sdk.on("session:ended", (event) => {
console.log("Session ended:", event.sessionId);
});
// Later...
unsubscribe();getState(): SDKState
Returns the current SDK state: "idle" | "initialized" | "active" | "recording" | "finished".
destroy(): void
Completely destroy the SDK instance. Removes all DOM elements, stops recorders, clears timers, and resets state to idle.
Quest Format
Each quest in the quests array must conform to:
interface Quest {
id: string; // Unique quest identifier
title: string; // Short display title
description: string; // Instructions for the tester
order: number; // Sequence order (1-based)
blocking?: boolean; // If true, failure blocks subsequent quests
}License
MIT
