@firstlook-uat/sdk 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +139 -0
- package/dist/firstlook.es.js +1598 -0
- package/dist/firstlook.es.js.map +1 -0
- package/dist/firstlook.umd.js +441 -0
- package/dist/firstlook.umd.js.map +1 -0
- package/package.json +52 -0
package/README.md
ADDED
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
# @firstlook/sdk
|
|
2
|
+
|
|
3
|
+
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.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# npm
|
|
9
|
+
npm install @firstlook/sdk
|
|
10
|
+
|
|
11
|
+
# yarn
|
|
12
|
+
yarn add @firstlook/sdk
|
|
13
|
+
|
|
14
|
+
# pnpm
|
|
15
|
+
pnpm add @firstlook/sdk
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Quick Start
|
|
19
|
+
|
|
20
|
+
### npm / ES Module
|
|
21
|
+
|
|
22
|
+
```ts
|
|
23
|
+
import { FirstLookSDK } from "@firstlook/sdk";
|
|
24
|
+
|
|
25
|
+
const sdk = new FirstLookSDK();
|
|
26
|
+
|
|
27
|
+
await sdk.init({
|
|
28
|
+
projectId: "proj_xxx",
|
|
29
|
+
apiKey: "flk_xxx",
|
|
30
|
+
userId: "tester@example.com",
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
sdk.activate();
|
|
34
|
+
|
|
35
|
+
await sdk.startSession([
|
|
36
|
+
{ id: "q1", title: "Add to Cart", description: "Add any item to the cart", order: 1 },
|
|
37
|
+
{ id: "q2", title: "Checkout", description: "Complete the checkout flow", order: 2, blocking: true },
|
|
38
|
+
]);
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### CDN / UMD
|
|
42
|
+
|
|
43
|
+
```html
|
|
44
|
+
<script src="https://unpkg.com/@firstlook/sdk/dist/firstlook.umd.js"></script>
|
|
45
|
+
<script>
|
|
46
|
+
const sdk = new FirstLook.FirstLookSDK();
|
|
47
|
+
sdk.init({
|
|
48
|
+
projectId: "proj_xxx",
|
|
49
|
+
apiKey: "flk_xxx",
|
|
50
|
+
userId: "tester@example.com",
|
|
51
|
+
}).then(() => sdk.activate());
|
|
52
|
+
</script>
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Configuration
|
|
56
|
+
|
|
57
|
+
All options are passed to `sdk.init()`. Only `projectId`, `apiKey`, and `userId` are required.
|
|
58
|
+
|
|
59
|
+
| Option | Type | Default | Description |
|
|
60
|
+
|--------|------|---------|-------------|
|
|
61
|
+
| `projectId` | `string` | *required* | Project ID from the FirstLook dashboard |
|
|
62
|
+
| `apiKey` | `string` | *required* | API key for authentication |
|
|
63
|
+
| `userId` | `string` | *required* | Unique identifier for the current tester |
|
|
64
|
+
| `role` | `string` | `undefined` | Optional role label (e.g. `"admin"`, `"tester"`) |
|
|
65
|
+
| `context` | `Record<string, unknown>` | `{}` | Arbitrary metadata attached to the session |
|
|
66
|
+
| `endpoint` | `string` | Production URL | Custom endpoint for session data upload |
|
|
67
|
+
| `triggers.tapCount` | `number` | `5` | Number of taps to open the debug menu |
|
|
68
|
+
| `triggers.deepLink` | `boolean` | `true` | Enable deep link activation (`?firstlook=1`) |
|
|
69
|
+
| `triggers.shake` | `boolean` | `true` | Enable shake-to-activate on mobile |
|
|
70
|
+
| `triggers.customCheck` | `() => boolean` | `undefined` | Custom function to auto-activate on init |
|
|
71
|
+
| `security.watermark` | `boolean` | `true` | Show dynamic watermark during recording |
|
|
72
|
+
| `security.maskSelectors` | `string[]` | `['input[type="password"]', '[data-sensitive]', '[data-mask]', '.uat-mask']` | CSS selectors for fields to mask |
|
|
73
|
+
| `recording.domSnapshot` | `boolean` | `true` | Enable DOM mutation recording |
|
|
74
|
+
| `recording.voice` | `boolean` | `true` | Enable voice recording |
|
|
75
|
+
| `recording.maxDuration` | `number` | `600` | Max recording duration in seconds |
|
|
76
|
+
| `recording.snapshotInterval` | `number` | `1000` | DOM snapshot interval in milliseconds |
|
|
77
|
+
|
|
78
|
+
## API Reference
|
|
79
|
+
|
|
80
|
+
### `init(config: FirstLookConfig): Promise<void>`
|
|
81
|
+
|
|
82
|
+
Initialize the SDK. Sets up triggers, IndexedDB storage, and Shadow DOM host. Does **not** activate the UI.
|
|
83
|
+
|
|
84
|
+
### `activate(): void`
|
|
85
|
+
|
|
86
|
+
Manually activate the SDK UI, bypassing configured triggers. Must be called after `init()`.
|
|
87
|
+
|
|
88
|
+
### `startSession(quests: Quest[]): Promise<string>`
|
|
89
|
+
|
|
90
|
+
Start a UAT session with a list of quests. Returns the generated session ID. The SDK must be in the `active` state.
|
|
91
|
+
|
|
92
|
+
### `startSessionFromRemote(questSetId: string): Promise<string>`
|
|
93
|
+
|
|
94
|
+
Fetch quest definitions from the API by quest set ID, then start a session. Returns the session ID.
|
|
95
|
+
|
|
96
|
+
### `endSession(): Promise<SessionData | null>`
|
|
97
|
+
|
|
98
|
+
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.
|
|
99
|
+
|
|
100
|
+
### `on(type: SDKEventType | "*", listener: SDKEventListener): () => void`
|
|
101
|
+
|
|
102
|
+
Subscribe to SDK events. Returns an unsubscribe function.
|
|
103
|
+
|
|
104
|
+
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`.
|
|
105
|
+
|
|
106
|
+
```ts
|
|
107
|
+
const unsubscribe = sdk.on("session:ended", (event) => {
|
|
108
|
+
console.log("Session ended:", event.sessionId);
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
// Later...
|
|
112
|
+
unsubscribe();
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### `getState(): SDKState`
|
|
116
|
+
|
|
117
|
+
Returns the current SDK state: `"idle"` | `"initialized"` | `"active"` | `"recording"` | `"finished"`.
|
|
118
|
+
|
|
119
|
+
### `destroy(): void`
|
|
120
|
+
|
|
121
|
+
Completely destroy the SDK instance. Removes all DOM elements, stops recorders, clears timers, and resets state to `idle`.
|
|
122
|
+
|
|
123
|
+
## Quest Format
|
|
124
|
+
|
|
125
|
+
Each quest in the `quests` array must conform to:
|
|
126
|
+
|
|
127
|
+
```ts
|
|
128
|
+
interface Quest {
|
|
129
|
+
id: string; // Unique quest identifier
|
|
130
|
+
title: string; // Short display title
|
|
131
|
+
description: string; // Instructions for the tester
|
|
132
|
+
order: number; // Sequence order (1-based)
|
|
133
|
+
blocking?: boolean; // If true, failure blocks subsequent quests
|
|
134
|
+
}
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
## License
|
|
138
|
+
|
|
139
|
+
MIT
|