@testerpaykit/react 0.0.0-stage → 1.0.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 +49 -2
- package/dist/index.d.mts +876 -0
- package/dist/index.d.ts +876 -0
- package/dist/index.js +7909 -0
- package/dist/index.mjs +7829 -0
- package/package.json +55 -3
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,876 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { DeviceMetadata, AppMetadata, TesterPayKit } from '@testerpaykit/sdk';
|
|
3
|
+
export { ActionResult, AgentAction, WidgetInfoForLlm, discoverWidgets, executeAction, isSyntheticEvent, redactSensitive, resetWidgetIds } from '@testerpaykit/ai-tester';
|
|
4
|
+
|
|
5
|
+
interface TesterPayKitProviderProps {
|
|
6
|
+
apiKey: string;
|
|
7
|
+
projectId: string;
|
|
8
|
+
testerId: string;
|
|
9
|
+
deviceId: string;
|
|
10
|
+
deviceMetadata: DeviceMetadata;
|
|
11
|
+
appMetadata: AppMetadata;
|
|
12
|
+
baseURL?: string;
|
|
13
|
+
children: React.ReactNode;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* React Context Provider for TesterPayKit SDK.
|
|
17
|
+
*
|
|
18
|
+
* Wraps your app to provide TesterPayKit functionality via the useTesterPayKit hook.
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```tsx
|
|
22
|
+
* <TesterPayKitProvider
|
|
23
|
+
* apiKey="your-api-key"
|
|
24
|
+
* projectId="project-123"
|
|
25
|
+
* testerId="tester-456"
|
|
26
|
+
* deviceId="device-789"
|
|
27
|
+
* deviceMetadata={{ os: 'Web', osVersion: '1.0', ... }}
|
|
28
|
+
* appMetadata={{ bundleId: 'com.example.app', version: '1.0.0', ... }}
|
|
29
|
+
* >
|
|
30
|
+
* <App />
|
|
31
|
+
* </TesterPayKitProvider>
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
declare function TesterPayKitProvider({ apiKey, projectId, testerId, deviceId, deviceMetadata, appMetadata, baseURL, children, }: TesterPayKitProviderProps): React.JSX.Element;
|
|
35
|
+
/**
|
|
36
|
+
* React hook for accessing TesterPayKit SDK functionality.
|
|
37
|
+
*
|
|
38
|
+
* Must be used within a TesterPayKitProvider.
|
|
39
|
+
*
|
|
40
|
+
* @returns Object containing tracking methods and SDK instance
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* ```tsx
|
|
44
|
+
* function MyComponent() {
|
|
45
|
+
* const { trackScreenView, trackTap } = useTesterPayKit();
|
|
46
|
+
*
|
|
47
|
+
* useEffect(() => {
|
|
48
|
+
* trackScreenView('MyComponent');
|
|
49
|
+
* }, []);
|
|
50
|
+
*
|
|
51
|
+
* return (
|
|
52
|
+
* <button onClick={() => trackTap('MyComponent', 'submit-btn')}>
|
|
53
|
+
* Submit
|
|
54
|
+
* </button>
|
|
55
|
+
* );
|
|
56
|
+
* }
|
|
57
|
+
* ```
|
|
58
|
+
*/
|
|
59
|
+
declare function useTesterPayKit(): {
|
|
60
|
+
trackScreenView: (screenName: string, metadata?: Record<string, any>) => Promise<void>;
|
|
61
|
+
trackTap: (screenName: string, elementId?: string) => Promise<void>;
|
|
62
|
+
trackEvent: (eventType: string, metadata?: Record<string, any>) => Promise<void>;
|
|
63
|
+
trackError: (message: string, stack?: string) => Promise<void>;
|
|
64
|
+
sdk: TesterPayKit | null;
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* TpkBugReportButton — back-compat thin wrapper around TpkBugReportSheet.
|
|
69
|
+
*
|
|
70
|
+
* Renders its own circular FAB that opens/closes a TpkBugReportSheet.
|
|
71
|
+
* Existing consumers and all tests targeting tpk-bug-report-fab /
|
|
72
|
+
* tpk-bug-report-overlay / tpk-bug-* testids keep working unchanged.
|
|
73
|
+
*/
|
|
74
|
+
|
|
75
|
+
interface TpkBugReportButtonProps {
|
|
76
|
+
/** Initialised TesterPayKit SDK instance. */
|
|
77
|
+
sdk: TesterPayKit;
|
|
78
|
+
/**
|
|
79
|
+
* Screen / route label passed as `currentScreen` in the report.
|
|
80
|
+
* Falls back to `window.location.pathname` when omitted.
|
|
81
|
+
*/
|
|
82
|
+
currentScreen?: string;
|
|
83
|
+
/** Override the button label. Default: "Report a bug". */
|
|
84
|
+
label?: string;
|
|
85
|
+
/** Called after the report is enqueued (localId = outbox UUID). */
|
|
86
|
+
onSubmitted?: (localId: string) => void;
|
|
87
|
+
}
|
|
88
|
+
declare function TpkBugReportButton({ sdk, currentScreen, label, onSubmitted, }: TpkBugReportButtonProps): React.ReactElement;
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* TpkBugReportSheet — 4-step wizard for submitting rich bug reports.
|
|
92
|
+
*
|
|
93
|
+
* Step 1 — Typ & Schwere: type chips + severity selector
|
|
94
|
+
* Step 2 — Details: title*, description*, expected/actual behavior, frequency,
|
|
95
|
+
* affected feature + voice mic (prefills title+description)
|
|
96
|
+
* Step 3 — Reproduktion & Beleg: reproduction steps list + screenshot
|
|
97
|
+
* Step 4 — Überprüfen & Senden: read-only summary + submit
|
|
98
|
+
*
|
|
99
|
+
* Back-compat: all data-testid hooks from Phase 1/2 are preserved so
|
|
100
|
+
* existing screenshot + voice + annotate test suites keep passing.
|
|
101
|
+
*/
|
|
102
|
+
|
|
103
|
+
interface TpkBugReportSheetProps {
|
|
104
|
+
/** Initialised TesterPayKit SDK instance. */
|
|
105
|
+
sdk: TesterPayKit;
|
|
106
|
+
/** Screen / route label passed as `currentScreen` in the report. */
|
|
107
|
+
currentScreen?: string;
|
|
108
|
+
/** Whether the sheet is currently open. */
|
|
109
|
+
open: boolean;
|
|
110
|
+
/** Called when the user dismisses the sheet (Cancel or backdrop tap). */
|
|
111
|
+
onClose: () => void;
|
|
112
|
+
/** Called after the report is enqueued (localId = outbox UUID). */
|
|
113
|
+
onSubmitted?: (localId: string) => void;
|
|
114
|
+
/**
|
|
115
|
+
* Which step to start on (1-indexed, default 1).
|
|
116
|
+
* Pass 2 to jump directly to the Details step (e.g. after a long-press voice launch).
|
|
117
|
+
*/
|
|
118
|
+
initialStep?: number;
|
|
119
|
+
/**
|
|
120
|
+
* When true, automatically begin voice recording on mount at the Details step.
|
|
121
|
+
* The long-press release is a valid user-activation gesture for getUserMedia.
|
|
122
|
+
* If the mic throws / is denied, falls back to the idle mic state (never crashes).
|
|
123
|
+
*/
|
|
124
|
+
autoStartVoice?: boolean;
|
|
125
|
+
}
|
|
126
|
+
declare function TpkBugReportSheet({ sdk, currentScreen, open, onClose, onSubmitted, initialStep, autoStartVoice, }: TpkBugReportSheetProps): React.ReactElement | null;
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* TesterPayKit brand tokens — single source of truth for the widget set.
|
|
130
|
+
*
|
|
131
|
+
* Usage: import { tpkTheme } from './theme'
|
|
132
|
+
* All widget components consume these values so visual changes only happen here.
|
|
133
|
+
*/
|
|
134
|
+
interface TpkColors {
|
|
135
|
+
/** Brand purple — primary buttons, focus rings, AI-related accents */
|
|
136
|
+
primary: string;
|
|
137
|
+
/** Bug-red FAB — stays visible on any background including red error screens */
|
|
138
|
+
bugRed: string;
|
|
139
|
+
/** Card / sheet background */
|
|
140
|
+
surface: string;
|
|
141
|
+
/** Alternate surface — hover states, subtle rows */
|
|
142
|
+
surfaceAlt: string;
|
|
143
|
+
/** Primary text */
|
|
144
|
+
text: string;
|
|
145
|
+
/** Secondary / muted text */
|
|
146
|
+
textMuted: string;
|
|
147
|
+
/** Dividers and input borders */
|
|
148
|
+
border: string;
|
|
149
|
+
/** Success state (confirmation, green check) */
|
|
150
|
+
success: string;
|
|
151
|
+
/** Danger state (delete, critical error label) */
|
|
152
|
+
danger: string;
|
|
153
|
+
/** Dim backdrop when a modal / menu is open */
|
|
154
|
+
backdrop: string;
|
|
155
|
+
}
|
|
156
|
+
interface TpkRadius {
|
|
157
|
+
sm: number;
|
|
158
|
+
md: number;
|
|
159
|
+
lg: number;
|
|
160
|
+
}
|
|
161
|
+
interface TpkZIndex {
|
|
162
|
+
/** Widget overlay — sits above all host-app UI (incl. MUI Drawers, etc.) */
|
|
163
|
+
overlay: number;
|
|
164
|
+
/** Menu popup — above the overlay backdrop but below the FAB itself */
|
|
165
|
+
menu: number;
|
|
166
|
+
/** FAB button — topmost */
|
|
167
|
+
fab: number;
|
|
168
|
+
}
|
|
169
|
+
interface TpkTheme {
|
|
170
|
+
colors: TpkColors;
|
|
171
|
+
radius: TpkRadius;
|
|
172
|
+
shadow: string;
|
|
173
|
+
zIndex: TpkZIndex;
|
|
174
|
+
spacing: (multiplier: number) => number;
|
|
175
|
+
}
|
|
176
|
+
declare const tpkTheme: TpkTheme;
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* TesterPayKit i18n — translation dictionary + helpers.
|
|
180
|
+
*
|
|
181
|
+
* Default locale: 'de'. English is additive.
|
|
182
|
+
* makeT(locale) returns a t(key, params?) function.
|
|
183
|
+
* Falls back to 'de' for any key missing in the target locale.
|
|
184
|
+
* Supports simple {param} interpolation.
|
|
185
|
+
*/
|
|
186
|
+
type TpkLocale = 'de' | 'en';
|
|
187
|
+
declare const MESSAGES: Record<TpkLocale, Record<string, string>>;
|
|
188
|
+
/**
|
|
189
|
+
* Returns a translation function for the given locale.
|
|
190
|
+
* Falls back to 'de' for any key missing in the target locale.
|
|
191
|
+
* Replaces {param} placeholders with provided param values.
|
|
192
|
+
*/
|
|
193
|
+
declare function makeT(locale: TpkLocale): (key: string, params?: Record<string, string | number>) => string;
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* TpkTesterHub — branded FAB hub with a popup menu.
|
|
197
|
+
*
|
|
198
|
+
* Renders a fixed bottom-right bug-red circular FAB (white ring so it's
|
|
199
|
+
* visible on any background). Tap opens a card popup menu above the FAB
|
|
200
|
+
* with a dim backdrop. The FAB glyph rotates to ✕ while open.
|
|
201
|
+
*
|
|
202
|
+
* Menu items are defined as data so later phases can add new entries
|
|
203
|
+
* without modifying the render logic. See the TODO below for the
|
|
204
|
+
* planned extension items.
|
|
205
|
+
*
|
|
206
|
+
* TODO — future menu items (Phase 2+):
|
|
207
|
+
* - "📋 Meine Bugs" → opens the tester's submitted-bug list
|
|
208
|
+
* - "🔔 Benachrichtigungen" → opens the in-widget notification feed (with badge)
|
|
209
|
+
* - "📊 Session Details" → earnings + activity summary for the current session
|
|
210
|
+
* - "🔄 My Retests" → retest queue (when assigned retests > 0)
|
|
211
|
+
*/
|
|
212
|
+
|
|
213
|
+
interface TpkTesterHubProps {
|
|
214
|
+
/** Initialised TesterPayKit SDK instance. */
|
|
215
|
+
sdk: TesterPayKit;
|
|
216
|
+
/** Current screen / route label forwarded to bug reports. */
|
|
217
|
+
currentScreen?: string;
|
|
218
|
+
/**
|
|
219
|
+
* When provided, an "AI-Tester" menu item is shown. All three sub-fields
|
|
220
|
+
* are forwarded to TpkAiTester.
|
|
221
|
+
*/
|
|
222
|
+
aiTester?: {
|
|
223
|
+
apiBaseUrl: string;
|
|
224
|
+
coordinatorToken: string;
|
|
225
|
+
projectId: string;
|
|
226
|
+
};
|
|
227
|
+
/** Locale for all widget copy. Defaults to 'de'. */
|
|
228
|
+
locale?: TpkLocale;
|
|
229
|
+
/** Deep partial theme override. Merged on top of the default tpkTheme. */
|
|
230
|
+
theme?: Partial<TpkTheme>;
|
|
231
|
+
/**
|
|
232
|
+
* Gesture triggers for opening the bug report sheet.
|
|
233
|
+
* Both default to true. Set a key to false to disable that gesture.
|
|
234
|
+
*/
|
|
235
|
+
gestures?: {
|
|
236
|
+
threeFingerTap?: boolean;
|
|
237
|
+
shake?: boolean;
|
|
238
|
+
};
|
|
239
|
+
/**
|
|
240
|
+
* When true, renders a floating TpkTaskPanel alongside the hub.
|
|
241
|
+
* Opt-in (default false) because a floating panel is intrusive.
|
|
242
|
+
* The panel shows only when tasks exist.
|
|
243
|
+
*/
|
|
244
|
+
taskPanel?: boolean;
|
|
245
|
+
}
|
|
246
|
+
declare function TpkTesterHub({ sdk, currentScreen, aiTester, locale, theme, gestures, taskPanel, }: TpkTesterHubProps): React.ReactElement | null;
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* TpkTesterLauncher — the logged-out "springboard" wrapper around TpkTesterHub.
|
|
250
|
+
*
|
|
251
|
+
* On a public surface, NOT every visitor should get a working bug-report hub
|
|
252
|
+
* (a half-working tester widget on a promo is a reputation risk). This widget
|
|
253
|
+
* gates the hub behind a registered tester:
|
|
254
|
+
*
|
|
255
|
+
* logged out → small FAB → panel with three choices:
|
|
256
|
+
* • "Ich möchte Tester werden" → opens the tester signup page
|
|
257
|
+
* • "Ich bin Tester" → magic-link sign-in (email)
|
|
258
|
+
* • "Ausblenden" → hides the widget (persisted)
|
|
259
|
+
* logged in → the full TpkTesterHub (bug report, my bugs, …)
|
|
260
|
+
*
|
|
261
|
+
* TesterPayKit tester auth is PASSWORDLESS (magic-link): the email step asks
|
|
262
|
+
* the server to mail a single-use link that returns to this app's
|
|
263
|
+
* `callbackPath` carrying a token. The callback page calls
|
|
264
|
+
* sdk.consumeTesterMagicLink(token), persists the session, and reloads — at
|
|
265
|
+
* which point this launcher restores it and shows the hub. The token is
|
|
266
|
+
* re-applied AFTER the SDK's anonymous auth settles so the registered identity
|
|
267
|
+
* always wins over the anonymous telemetry one.
|
|
268
|
+
*/
|
|
269
|
+
|
|
270
|
+
interface TpkTesterLauncherProps {
|
|
271
|
+
/** Initialised TesterPayKit SDK instance. */
|
|
272
|
+
sdk: TesterPayKit;
|
|
273
|
+
/** Current screen / route label forwarded to the hub. */
|
|
274
|
+
currentScreen?: string;
|
|
275
|
+
/** Locale for all widget copy. Defaults to 'de'. */
|
|
276
|
+
locale?: TpkLocale;
|
|
277
|
+
/** Where "become a tester" sends the user. */
|
|
278
|
+
becomeTesterUrl?: string;
|
|
279
|
+
/** App route that consumes the magic-link token. Default '/tester/callback'. */
|
|
280
|
+
callbackPath?: string;
|
|
281
|
+
theme?: TpkTesterHubProps['theme'];
|
|
282
|
+
aiTester?: TpkTesterHubProps['aiTester'];
|
|
283
|
+
gestures?: TpkTesterHubProps['gestures'];
|
|
284
|
+
}
|
|
285
|
+
declare function TpkTesterLauncher(props: TpkTesterLauncherProps): React.JSX.Element | null;
|
|
286
|
+
|
|
287
|
+
/**
|
|
288
|
+
* TpkMyBugsScreen — slide-in panel showing the tester's submitted bug reports.
|
|
289
|
+
*
|
|
290
|
+
* Controlled via { sdk, open, onClose }. On open, fetches from
|
|
291
|
+
* sdk.getMyBugReports() and renders a branded list with colour-coded
|
|
292
|
+
* status badges. Tapping a row expands its description.
|
|
293
|
+
*/
|
|
294
|
+
|
|
295
|
+
interface TpkMyBugsScreenProps {
|
|
296
|
+
sdk: TesterPayKit;
|
|
297
|
+
open: boolean;
|
|
298
|
+
onClose: () => void;
|
|
299
|
+
}
|
|
300
|
+
declare function TpkMyBugsScreen({ sdk, open, onClose }: TpkMyBugsScreenProps): React.ReactElement | null;
|
|
301
|
+
|
|
302
|
+
/**
|
|
303
|
+
* TpkNotificationsScreen — slide-in panel showing the tester's notifications.
|
|
304
|
+
*
|
|
305
|
+
* Controlled via { sdk, open, onClose, onUnreadChange? }. On open, fetches
|
|
306
|
+
* from sdk.getNotifications(). Unread rows are visually distinct. Tapping a
|
|
307
|
+
* row marks it read; "Alle gelesen" marks all.
|
|
308
|
+
*/
|
|
309
|
+
|
|
310
|
+
interface TpkNotificationsScreenProps {
|
|
311
|
+
sdk: TesterPayKit;
|
|
312
|
+
open: boolean;
|
|
313
|
+
onClose: () => void;
|
|
314
|
+
/** Called with the new unread count after any read action. */
|
|
315
|
+
onUnreadChange?: (count: number) => void;
|
|
316
|
+
}
|
|
317
|
+
declare function TpkNotificationsScreen({ sdk, open, onClose, onUnreadChange, }: TpkNotificationsScreenProps): React.ReactElement | null;
|
|
318
|
+
|
|
319
|
+
/**
|
|
320
|
+
* TpkGeneralFeedbackDialog — lightweight single-screen feedback dialog.
|
|
321
|
+
*
|
|
322
|
+
* DACH-first copy (German default, English via TpkUiProvider). Provides:
|
|
323
|
+
* - 1–5 star rating
|
|
324
|
+
* - Category select (Allgemein / Feature-Wunsch / Verbesserung / Lob / Kritik)
|
|
325
|
+
* - Title field (max 100 chars)
|
|
326
|
+
* - Details textarea (max 1000 chars)
|
|
327
|
+
*
|
|
328
|
+
* Submits via sdk.submitBugReport({ type: 'generalFeedback', ... })
|
|
329
|
+
* with rating + feedbackCategory in metadata.
|
|
330
|
+
*/
|
|
331
|
+
|
|
332
|
+
interface TpkGeneralFeedbackDialogProps {
|
|
333
|
+
sdk: TesterPayKit;
|
|
334
|
+
open: boolean;
|
|
335
|
+
onClose: () => void;
|
|
336
|
+
onSubmitted?: (localId: string) => void;
|
|
337
|
+
/** Current screen / route label forwarded to the report. */
|
|
338
|
+
currentScreen?: string;
|
|
339
|
+
}
|
|
340
|
+
declare function TpkGeneralFeedbackDialog({ sdk, open, onClose, onSubmitted, currentScreen, }: TpkGeneralFeedbackDialogProps): React.ReactElement | null;
|
|
341
|
+
|
|
342
|
+
/**
|
|
343
|
+
* crashCapture — installs global window error handlers and persists the most
|
|
344
|
+
* recent uncaught error to localStorage under the key `tpk:pendingCrash`.
|
|
345
|
+
*
|
|
346
|
+
* SSR-safe: all window/localStorage accesses are guarded.
|
|
347
|
+
* Debounced: a burst of errors within 500 ms is coalesced into one entry.
|
|
348
|
+
*/
|
|
349
|
+
|
|
350
|
+
declare const PENDING_CRASH_KEY = "tpk:pendingCrash";
|
|
351
|
+
interface PendingCrash {
|
|
352
|
+
message: string;
|
|
353
|
+
stack: string;
|
|
354
|
+
screen: string;
|
|
355
|
+
ts: number;
|
|
356
|
+
}
|
|
357
|
+
declare function getPendingCrash(): PendingCrash | null;
|
|
358
|
+
declare function clearPendingCrash(): void;
|
|
359
|
+
/**
|
|
360
|
+
* Installs `window.error` and `unhandledrejection` listeners.
|
|
361
|
+
* Returns an uninstaller function.
|
|
362
|
+
*
|
|
363
|
+
* Safe to call in SSR: returns a no-op uninstaller when `window` is absent.
|
|
364
|
+
*/
|
|
365
|
+
declare function installCrashCapture(sdk: TesterPayKit): () => void;
|
|
366
|
+
|
|
367
|
+
/**
|
|
368
|
+
* TpkCrashDialog — displays a captured crash and lets the tester submit a report.
|
|
369
|
+
*
|
|
370
|
+
* Controlled: { sdk, crash, open, onClose, onSubmitted? }
|
|
371
|
+
* Red header. Shows error message + expandable stack trace (monospace).
|
|
372
|
+
* Optional "Was hast du gemacht?" notes textarea.
|
|
373
|
+
* Submit → sdk.submitBugReport({ type: 'crash', ... }) then clearPendingCrash().
|
|
374
|
+
* "Verwerfen" closes + clears.
|
|
375
|
+
*/
|
|
376
|
+
|
|
377
|
+
interface TpkCrashDialogProps {
|
|
378
|
+
sdk: TesterPayKit;
|
|
379
|
+
crash: PendingCrash | null;
|
|
380
|
+
open: boolean;
|
|
381
|
+
onClose: () => void;
|
|
382
|
+
onSubmitted?: (localId: string) => void;
|
|
383
|
+
}
|
|
384
|
+
declare function TpkCrashDialog({ sdk, crash, open, onClose, onSubmitted, }: TpkCrashDialogProps): React.ReactElement | null;
|
|
385
|
+
|
|
386
|
+
/**
|
|
387
|
+
* TpkSessionEndDialog — quick end-of-session prompt.
|
|
388
|
+
*
|
|
389
|
+
* Controlled: { sdk, open, onClose, onSubmitted? }
|
|
390
|
+
* - 1–5 star rating
|
|
391
|
+
* - Short comment (required)
|
|
392
|
+
* - "Was hast du getestet?" optional field
|
|
393
|
+
*
|
|
394
|
+
* Submit → sdk.submitBugReport({ type: 'generalFeedback', metadata: { rating, kind: 'session_end', tested } })
|
|
395
|
+
* then sdk.endSession('completed') (best-effort).
|
|
396
|
+
*/
|
|
397
|
+
|
|
398
|
+
interface TpkSessionEndDialogProps {
|
|
399
|
+
sdk: TesterPayKit;
|
|
400
|
+
open: boolean;
|
|
401
|
+
onClose: () => void;
|
|
402
|
+
onSubmitted?: (localId: string) => void;
|
|
403
|
+
}
|
|
404
|
+
declare function TpkSessionEndDialog({ sdk, open, onClose, onSubmitted, }: TpkSessionEndDialogProps): React.ReactElement | null;
|
|
405
|
+
|
|
406
|
+
/**
|
|
407
|
+
* TpkDebugLogsScreen — slide-in panel showing the SDK debug log ring buffer.
|
|
408
|
+
*
|
|
409
|
+
* Shows the most recent entries newest-first in a monospace list, with a
|
|
410
|
+
* refresh button, a "Leeren" (clear) button, an empty state, and a small
|
|
411
|
+
* info block at the top with sessionId + current earnings.
|
|
412
|
+
*/
|
|
413
|
+
|
|
414
|
+
interface TpkDebugLogsScreenProps {
|
|
415
|
+
sdk: TesterPayKit;
|
|
416
|
+
open: boolean;
|
|
417
|
+
onClose: () => void;
|
|
418
|
+
}
|
|
419
|
+
declare function TpkDebugLogsScreen({ sdk, open, onClose, }: TpkDebugLogsScreenProps): React.ReactElement | null;
|
|
420
|
+
|
|
421
|
+
/**
|
|
422
|
+
* TpkWorkboardScreen — slide-in panel showing the tester's assigned tasks
|
|
423
|
+
* plus the current build info.
|
|
424
|
+
*
|
|
425
|
+
* Controlled via { sdk, open, onClose }. On open, fetches sdk.getMyTasks()
|
|
426
|
+
* and optionally sdk.getMyPoints() (best-effort). Each task row has a
|
|
427
|
+
* "Starten" / "Erledigt" / ✓ action depending on its status.
|
|
428
|
+
*/
|
|
429
|
+
|
|
430
|
+
interface TpkWorkboardScreenProps {
|
|
431
|
+
sdk: TesterPayKit;
|
|
432
|
+
open: boolean;
|
|
433
|
+
onClose: () => void;
|
|
434
|
+
}
|
|
435
|
+
declare function TpkWorkboardScreen({ sdk, open, onClose }: TpkWorkboardScreenProps): React.ReactElement | null;
|
|
436
|
+
|
|
437
|
+
/**
|
|
438
|
+
* TpkRetestScreen — slide-in panel showing the tester's retest queue.
|
|
439
|
+
*
|
|
440
|
+
* Controlled via { sdk, open, onClose }. On open, fetches sdk.getMyRetests().
|
|
441
|
+
* Each row shows bug title + status badge + fix info if present. Two action
|
|
442
|
+
* buttons: "Bestätigt (behoben)" → sdk.verifyRetest(bugId) and
|
|
443
|
+
* "Wieder offen" → sdk.reopenRetest(bugId). Re-fetches after each action.
|
|
444
|
+
*
|
|
445
|
+
* A bug with acceptance steps is judged step by step first: "Bestätigt"
|
|
446
|
+
* stays disabled until every step passed, and the verdicts go along with
|
|
447
|
+
* verify / reopen.
|
|
448
|
+
*/
|
|
449
|
+
|
|
450
|
+
interface TpkRetestScreenProps {
|
|
451
|
+
sdk: TesterPayKit;
|
|
452
|
+
open: boolean;
|
|
453
|
+
onClose: () => void;
|
|
454
|
+
}
|
|
455
|
+
declare function TpkRetestScreen({ sdk, open, onClose }: TpkRetestScreenProps): React.ReactElement | null;
|
|
456
|
+
|
|
457
|
+
/**
|
|
458
|
+
* TpkSessionDetailsScreen — slide-in panel showing live session info.
|
|
459
|
+
*
|
|
460
|
+
* Pure local/live: no network calls needed. Shows session id, started-at,
|
|
461
|
+
* elapsed time, live earnings, and debug log count. A refresh button
|
|
462
|
+
* re-reads the live values from the SDK.
|
|
463
|
+
*/
|
|
464
|
+
|
|
465
|
+
interface TpkSessionDetailsScreenProps {
|
|
466
|
+
sdk: TesterPayKit;
|
|
467
|
+
open: boolean;
|
|
468
|
+
onClose: () => void;
|
|
469
|
+
}
|
|
470
|
+
declare function TpkSessionDetailsScreen({ sdk, open, onClose }: TpkSessionDetailsScreenProps): React.ReactElement | null;
|
|
471
|
+
|
|
472
|
+
/**
|
|
473
|
+
* TpkTaskPanel — floating, draggable checklist panel (Flutter parity).
|
|
474
|
+
*
|
|
475
|
+
* Renders NOTHING when getMyTasks() returns an empty list.
|
|
476
|
+
* When tasks exist: a fixed, draggable card (collapsed by default) showing
|
|
477
|
+
* "Aufgaben X/Y" + a progress bar. Expanding reveals task rows with
|
|
478
|
+
* "Starten" / "Erledigt" actions. Can be dismissed for the session.
|
|
479
|
+
*
|
|
480
|
+
* z-index is intentionally below the FAB menu so it doesn't overlap controls.
|
|
481
|
+
* Position is fixed, bottom-left (so it doesn't clash with bottom-right FAB).
|
|
482
|
+
*/
|
|
483
|
+
|
|
484
|
+
interface TpkTaskPanelProps {
|
|
485
|
+
sdk: TesterPayKit;
|
|
486
|
+
/** Called when user dismisses the panel. */
|
|
487
|
+
onClose?: () => void;
|
|
488
|
+
/** Called after a task action so the parent can refresh its badge. */
|
|
489
|
+
onTasksChanged?: () => void;
|
|
490
|
+
}
|
|
491
|
+
declare function TpkTaskPanel({ sdk, onClose, onTasksChanged }: TpkTaskPanelProps): React.ReactElement | null;
|
|
492
|
+
|
|
493
|
+
/**
|
|
494
|
+
* gestures.ts — lightweight gesture helpers for the TesterPayKit widget.
|
|
495
|
+
*
|
|
496
|
+
* All functions are SSR-safe (no-op when document/window is absent).
|
|
497
|
+
* Both installers return an uninstall function.
|
|
498
|
+
*/
|
|
499
|
+
/**
|
|
500
|
+
* Installs a document-level touchstart listener.
|
|
501
|
+
* When exactly 3 simultaneous touch points are detected, calls onTrigger.
|
|
502
|
+
* Debounced so rapid re-fires count as one gesture (300 ms window).
|
|
503
|
+
*
|
|
504
|
+
* @returns Uninstaller — call it to remove the listener.
|
|
505
|
+
*/
|
|
506
|
+
declare function installThreeFingerTap(onTrigger: () => void): () => void;
|
|
507
|
+
interface ShakeDetectionOptions {
|
|
508
|
+
/** Acceleration delta threshold (m/s²) that counts as a shake. Default: 15. */
|
|
509
|
+
threshold?: number;
|
|
510
|
+
/** Minimum ms between successive triggers. Default: 1500. */
|
|
511
|
+
cooldownMs?: number;
|
|
512
|
+
}
|
|
513
|
+
/**
|
|
514
|
+
* Requests iOS DeviceMotion permission (needed on Safari iOS 13+).
|
|
515
|
+
* Must be called from a user-gesture handler.
|
|
516
|
+
*
|
|
517
|
+
* Returns:
|
|
518
|
+
* - true if permission granted or not required (Android / desktop)
|
|
519
|
+
* - false if permission denied or DeviceMotionEvent unavailable
|
|
520
|
+
*/
|
|
521
|
+
declare function requestShakePermission(): Promise<boolean>;
|
|
522
|
+
/**
|
|
523
|
+
* Installs a window-level 'devicemotion' listener.
|
|
524
|
+
* When the device is shaken (acceleration delta > threshold), calls onTrigger.
|
|
525
|
+
* Respects a cooldown between triggers.
|
|
526
|
+
*
|
|
527
|
+
* iOS guard: if DeviceMotionEvent.requestPermission exists, this function does
|
|
528
|
+
* NOT call it automatically (it needs a user gesture). Attach the listener
|
|
529
|
+
* immediately on non-iOS; on iOS the listener fires only after the caller
|
|
530
|
+
* obtains permission via requestShakePermission() — which is fine because
|
|
531
|
+
* the native OS only delivers events after permission is granted.
|
|
532
|
+
*
|
|
533
|
+
* No-op + never throws when DeviceMotionEvent is absent (e.g. jsdom).
|
|
534
|
+
*
|
|
535
|
+
* @returns Uninstaller — call it to remove the listener.
|
|
536
|
+
*/
|
|
537
|
+
declare function installShakeDetection(onTrigger: () => void, opts?: ShakeDetectionOptions): () => void;
|
|
538
|
+
|
|
539
|
+
/**
|
|
540
|
+
* Web screenshot capture utility using html2canvas.
|
|
541
|
+
*
|
|
542
|
+
* Renders the current DOM to a canvas and returns a JPEG dataURL.
|
|
543
|
+
* Browser-only — returns null and logs a warning in non-browser environments
|
|
544
|
+
* or when html2canvas fails.
|
|
545
|
+
*
|
|
546
|
+
* Contract: Part B — web screenshot capture for TpkBugReportButton
|
|
547
|
+
*
|
|
548
|
+
* Auto-PII masking: any element carrying `data-tpk-sensitive` in the DOM
|
|
549
|
+
* (placed by <TpkSensitive> or by hand) is masked in the cloned document
|
|
550
|
+
* before rendering — nothing is sent to the canvas unredacted.
|
|
551
|
+
*/
|
|
552
|
+
/**
|
|
553
|
+
* Finds every `[data-tpk-sensitive]` element under `root`, applies the
|
|
554
|
+
* requested mask strategy, and returns the number of elements masked.
|
|
555
|
+
*
|
|
556
|
+
* Pure helper — operates on any object with `querySelectorAll`.
|
|
557
|
+
* Does NOT depend on html2canvas or a real browser: safe to unit-test in jsdom.
|
|
558
|
+
*
|
|
559
|
+
* @param root Any DOM subtree root (Document, Element, or jsdom equivalent).
|
|
560
|
+
* @returns Number of elements that were masked.
|
|
561
|
+
*/
|
|
562
|
+
declare function applySensitiveMasks(root: {
|
|
563
|
+
querySelectorAll: (sel: string) => ArrayLike<Element>;
|
|
564
|
+
}): number;
|
|
565
|
+
/**
|
|
566
|
+
* Capture the current page as a JPEG dataURL.
|
|
567
|
+
*
|
|
568
|
+
* @returns A JPEG dataURL string, or null if capture failed or unavailable.
|
|
569
|
+
*/
|
|
570
|
+
declare function captureScreenshot(): Promise<string | null>;
|
|
571
|
+
|
|
572
|
+
/**
|
|
573
|
+
* TpkSensitive — auto-PII masking marker for screenshots.
|
|
574
|
+
*
|
|
575
|
+
* Wrap any React element in <TpkSensitive> and it will be automatically
|
|
576
|
+
* blurred or blocked in every screenshot captured by captureScreenshot().
|
|
577
|
+
*
|
|
578
|
+
* @example
|
|
579
|
+
* <TpkSensitive>
|
|
580
|
+
* <input type="password" ... />
|
|
581
|
+
* </TpkSensitive>
|
|
582
|
+
*
|
|
583
|
+
* // block mode (opaque rectangle):
|
|
584
|
+
* <TpkSensitive mask="block">
|
|
585
|
+
* <span>{cardNumber}</span>
|
|
586
|
+
* </TpkSensitive>
|
|
587
|
+
*
|
|
588
|
+
* @remarks
|
|
589
|
+
* Non-React / third-party markup: add the attribute directly on any element:
|
|
590
|
+
* <div data-tpk-sensitive data-tpk-mask="block">...</div>
|
|
591
|
+
* captureScreenshot will mask those elements the same way.
|
|
592
|
+
*/
|
|
593
|
+
|
|
594
|
+
type TpkSensitiveMask = 'blur' | 'block';
|
|
595
|
+
interface TpkSensitiveProps {
|
|
596
|
+
/** Masking strategy. 'blur' (default) applies a 12 px gaussian blur.
|
|
597
|
+
* 'block' replaces the element with a solid opaque rectangle. */
|
|
598
|
+
mask?: TpkSensitiveMask;
|
|
599
|
+
children?: React.ReactNode;
|
|
600
|
+
}
|
|
601
|
+
/**
|
|
602
|
+
* Marker component. Renders a plain <span> with `data-tpk-sensitive`
|
|
603
|
+
* (and `data-tpk-mask`) so captureScreenshot can locate and mask it.
|
|
604
|
+
* Zero visual side-effect in normal rendering.
|
|
605
|
+
*/
|
|
606
|
+
declare function TpkSensitive({ mask, children }: TpkSensitiveProps): React.ReactElement;
|
|
607
|
+
|
|
608
|
+
/**
|
|
609
|
+
* Browser MediaRecorder helper for voice bug capture.
|
|
610
|
+
*
|
|
611
|
+
* Usage:
|
|
612
|
+
* const session = await startVoiceRecording();
|
|
613
|
+
* if (session.unsupported) { ... }
|
|
614
|
+
* // user records …
|
|
615
|
+
* const result = await session.stop();
|
|
616
|
+
* if (result) { sdk.extractBugFromVoice(result.base64, result.mimeType); }
|
|
617
|
+
*/
|
|
618
|
+
interface VoiceRecordingResult {
|
|
619
|
+
/** Raw base64 audio (no data: prefix). */
|
|
620
|
+
base64: string;
|
|
621
|
+
/** MIME type reported by MediaRecorder (e.g. 'audio/webm;codecs=opus'). */
|
|
622
|
+
mimeType: string;
|
|
623
|
+
/** Recording duration in milliseconds. */
|
|
624
|
+
durationMs: number;
|
|
625
|
+
}
|
|
626
|
+
interface VoiceRecordingSession {
|
|
627
|
+
/** Stop recording and resolve the result. Returns null if recording produced no data. */
|
|
628
|
+
stop: () => Promise<VoiceRecordingResult | null>;
|
|
629
|
+
}
|
|
630
|
+
interface VoiceRecordingUnsupported {
|
|
631
|
+
unsupported: true;
|
|
632
|
+
reason: string;
|
|
633
|
+
}
|
|
634
|
+
/**
|
|
635
|
+
* Start a voice recording session using the browser's MediaRecorder API.
|
|
636
|
+
*
|
|
637
|
+
* Returns a `VoiceRecordingUnsupported` discriminant when the environment
|
|
638
|
+
* does not support audio capture (SSR, no mic permission API, etc.) —
|
|
639
|
+
* it never throws.
|
|
640
|
+
*/
|
|
641
|
+
declare function startVoiceRecording(): Promise<VoiceRecordingSession | VoiceRecordingUnsupported>;
|
|
642
|
+
|
|
643
|
+
/**
|
|
644
|
+
* Browser screen recording helper using the Screen Capture API.
|
|
645
|
+
*
|
|
646
|
+
* Usage:
|
|
647
|
+
* const result = await startScreenRecording();
|
|
648
|
+
* if (result === 'unsupported') { ... }
|
|
649
|
+
* if (result === 'cancelled') { ... }
|
|
650
|
+
* const { stop } = result;
|
|
651
|
+
* // user clicks stop later…
|
|
652
|
+
* const recording = await stop(); // null if no data
|
|
653
|
+
*/
|
|
654
|
+
interface ScreenRecordingResult {
|
|
655
|
+
/** Raw base64 video data (no data: prefix). */
|
|
656
|
+
base64: string;
|
|
657
|
+
/** MIME type reported by MediaRecorder (e.g. 'video/webm'). */
|
|
658
|
+
mimeType: string;
|
|
659
|
+
/** Recording duration in milliseconds. */
|
|
660
|
+
durationMs: number;
|
|
661
|
+
/** Approximate byte size of the raw recording. */
|
|
662
|
+
sizeBytes: number;
|
|
663
|
+
}
|
|
664
|
+
interface ScreenRecordingSession {
|
|
665
|
+
/** Stop recording and resolve the result. Returns null if no data was produced. */
|
|
666
|
+
stop: () => Promise<ScreenRecordingResult | null>;
|
|
667
|
+
}
|
|
668
|
+
interface ScreenRecordingUnsupported {
|
|
669
|
+
unsupported: true;
|
|
670
|
+
reason: string;
|
|
671
|
+
}
|
|
672
|
+
/**
|
|
673
|
+
* Start a screen recording session using the browser's Screen Capture API.
|
|
674
|
+
*
|
|
675
|
+
* Returns:
|
|
676
|
+
* - `{ unsupported: true, reason }` when the environment does not support
|
|
677
|
+
* screen capture (SSR, old browser, no MediaRecorder).
|
|
678
|
+
* - `'cancelled'` when the user dismissed the OS screen-picker
|
|
679
|
+
* (getDisplayMedia rejects with NotAllowedError / name: 'NotAllowedError').
|
|
680
|
+
* - A `ScreenRecordingSession` with a `stop()` method when recording is underway.
|
|
681
|
+
*
|
|
682
|
+
* Never throws.
|
|
683
|
+
*/
|
|
684
|
+
declare function startScreenRecording(): Promise<ScreenRecordingSession | ScreenRecordingUnsupported | 'cancelled'>;
|
|
685
|
+
|
|
686
|
+
interface TpkAiTesterProps {
|
|
687
|
+
visible: boolean;
|
|
688
|
+
/** API base URL — same value the rest of the SDK uses for HTTP. */
|
|
689
|
+
apiBaseUrl: string;
|
|
690
|
+
/** Coordinator JWT — used for the initial POST to start the session. */
|
|
691
|
+
coordinatorToken: string;
|
|
692
|
+
/** Project UUID. */
|
|
693
|
+
projectId: string;
|
|
694
|
+
/** Configuration sent to the create-session endpoint. */
|
|
695
|
+
configuration?: {
|
|
696
|
+
durationMinutes?: number;
|
|
697
|
+
maxActions?: number;
|
|
698
|
+
strategy?: 'llm' | 'random' | 'hybrid';
|
|
699
|
+
focusAreas?: string[];
|
|
700
|
+
captureScreenshots?: boolean;
|
|
701
|
+
submitBugs?: boolean;
|
|
702
|
+
};
|
|
703
|
+
/** Called when the user clicks Stop or the session ends naturally. */
|
|
704
|
+
onClose: () => void;
|
|
705
|
+
/** Called once on session end with the final status payload. */
|
|
706
|
+
onSessionEnded?: (status: 'completed' | 'failed' | 'cancelled', sessionId: string | null) => void;
|
|
707
|
+
}
|
|
708
|
+
declare function TpkAiTester({ visible, apiBaseUrl, coordinatorToken, projectId, configuration, onClose, onSessionEnded, }: TpkAiTesterProps): React.ReactElement | null;
|
|
709
|
+
|
|
710
|
+
/**
|
|
711
|
+
* ScreenshotAnnotator — full-screen modal canvas editor for annotating
|
|
712
|
+
* screenshots before attaching them to a bug report.
|
|
713
|
+
*
|
|
714
|
+
* Tools: Pen · Arrow · Rectangle · Text · Blur/Pixelate (PII-redaction)
|
|
715
|
+
* Features: Undo / Redo · Color swatches + native color picker · Stroke width
|
|
716
|
+
*
|
|
717
|
+
* SSR-safe: all canvas/window access is guarded behind typeof window checks
|
|
718
|
+
* and null-context guards.
|
|
719
|
+
*/
|
|
720
|
+
|
|
721
|
+
interface ScreenshotAnnotatorProps {
|
|
722
|
+
/** Source screenshot as a data URL */
|
|
723
|
+
dataUrl: string;
|
|
724
|
+
/** Called with the annotated image data URL when the user saves */
|
|
725
|
+
onSave: (annotatedDataUrl: string) => void;
|
|
726
|
+
/** Called when the user cancels without saving */
|
|
727
|
+
onCancel: () => void;
|
|
728
|
+
}
|
|
729
|
+
declare function ScreenshotAnnotator({ dataUrl, onSave, onCancel, }: ScreenshotAnnotatorProps): React.ReactElement | null;
|
|
730
|
+
|
|
731
|
+
/**
|
|
732
|
+
* Pure (DOM-free) operation stack for the screenshot annotation editor.
|
|
733
|
+
*
|
|
734
|
+
* All types, the undo/redo stack, arrowhead geometry, and pixelate-region
|
|
735
|
+
* math live here so they can be unit-tested without a canvas.
|
|
736
|
+
*/
|
|
737
|
+
type ToolKind = 'pen' | 'arrow' | 'rect' | 'text' | 'blur';
|
|
738
|
+
interface Point {
|
|
739
|
+
x: number;
|
|
740
|
+
y: number;
|
|
741
|
+
}
|
|
742
|
+
interface StrokeStyle {
|
|
743
|
+
color: string;
|
|
744
|
+
width: number;
|
|
745
|
+
}
|
|
746
|
+
interface PenOp {
|
|
747
|
+
kind: 'pen';
|
|
748
|
+
points: Point[];
|
|
749
|
+
style: StrokeStyle;
|
|
750
|
+
}
|
|
751
|
+
interface ArrowOp {
|
|
752
|
+
kind: 'arrow';
|
|
753
|
+
from: Point;
|
|
754
|
+
to: Point;
|
|
755
|
+
style: StrokeStyle;
|
|
756
|
+
}
|
|
757
|
+
interface RectOp {
|
|
758
|
+
kind: 'rect';
|
|
759
|
+
from: Point;
|
|
760
|
+
to: Point;
|
|
761
|
+
style: StrokeStyle;
|
|
762
|
+
}
|
|
763
|
+
interface TextOp {
|
|
764
|
+
kind: 'text';
|
|
765
|
+
position: Point;
|
|
766
|
+
text: string;
|
|
767
|
+
style: StrokeStyle;
|
|
768
|
+
fontSize: number;
|
|
769
|
+
}
|
|
770
|
+
interface BlurOp {
|
|
771
|
+
kind: 'blur';
|
|
772
|
+
from: Point;
|
|
773
|
+
to: Point;
|
|
774
|
+
/** Pixel size for the pixelation block (default 12) */
|
|
775
|
+
blockSize: number;
|
|
776
|
+
}
|
|
777
|
+
type AnnotateOp = PenOp | ArrowOp | RectOp | TextOp | BlurOp;
|
|
778
|
+
interface OpStack {
|
|
779
|
+
ops: AnnotateOp[];
|
|
780
|
+
/** Operations that were undone (redo buffer) */
|
|
781
|
+
redoBuffer: AnnotateOp[];
|
|
782
|
+
}
|
|
783
|
+
declare function emptyStack(): OpStack;
|
|
784
|
+
declare function pushOp(stack: OpStack, op: AnnotateOp): OpStack;
|
|
785
|
+
declare function undo(stack: OpStack): OpStack;
|
|
786
|
+
declare function redo(stack: OpStack): OpStack;
|
|
787
|
+
/**
|
|
788
|
+
* Returns the two wing points for an arrowhead at `to` pointing from `from`.
|
|
789
|
+
* Returned as [wing1, wing2] in the same coordinate space.
|
|
790
|
+
*/
|
|
791
|
+
declare function arrowheadPoints(from: Point, to: Point, headLength?: number, headAngle?: number): [Point, Point];
|
|
792
|
+
/**
|
|
793
|
+
* Normalises a rect defined by two arbitrary corner points into a
|
|
794
|
+
* { x, y, width, height } with width and height always positive.
|
|
795
|
+
*/
|
|
796
|
+
declare function normaliseRect(from: Point, to: Point): {
|
|
797
|
+
x: number;
|
|
798
|
+
y: number;
|
|
799
|
+
width: number;
|
|
800
|
+
height: number;
|
|
801
|
+
};
|
|
802
|
+
/**
|
|
803
|
+
* Returns the list of pixel-block cells for a pixelate pass.
|
|
804
|
+
* Each cell is { x, y, width, height } — the grid of blocks that cover
|
|
805
|
+
* the region. Cells on the right/bottom edges may be narrower/shorter.
|
|
806
|
+
*
|
|
807
|
+
* This is pure math; the actual pixel-sampling runs on the canvas.
|
|
808
|
+
*/
|
|
809
|
+
declare function pixelateBlocks(from: Point, to: Point, blockSize: number): Array<{
|
|
810
|
+
x: number;
|
|
811
|
+
y: number;
|
|
812
|
+
width: number;
|
|
813
|
+
height: number;
|
|
814
|
+
}>;
|
|
815
|
+
|
|
816
|
+
/**
|
|
817
|
+
* TpkUiContext — internal context carrying locale + theme for all TPK widgets.
|
|
818
|
+
*
|
|
819
|
+
* TpkUiProvider({ locale?, theme?, children })
|
|
820
|
+
* - locale defaults to the browser language (de* → German, else English)
|
|
821
|
+
* - theme = deepMerge(tpkTheme, themeOverride)
|
|
822
|
+
* - exposes useTpkUi() hook
|
|
823
|
+
*
|
|
824
|
+
* Components work WITHOUT a provider: useTpkUi() returns 'de' + default theme.
|
|
825
|
+
* This ensures existing tests that render components without a provider keep passing.
|
|
826
|
+
*/
|
|
827
|
+
|
|
828
|
+
type TFunc = (key: string, params?: Record<string, string | number>) => string;
|
|
829
|
+
interface TpkUiContextValue {
|
|
830
|
+
t: TFunc;
|
|
831
|
+
locale: TpkLocale;
|
|
832
|
+
theme: TpkTheme;
|
|
833
|
+
}
|
|
834
|
+
interface TpkUiProviderProps {
|
|
835
|
+
locale?: TpkLocale;
|
|
836
|
+
theme?: Partial<TpkTheme>;
|
|
837
|
+
children: React.ReactNode;
|
|
838
|
+
}
|
|
839
|
+
declare function TpkUiProvider({ locale, theme, children }: TpkUiProviderProps): React.ReactElement;
|
|
840
|
+
/**
|
|
841
|
+
* Returns { t, locale, theme } from the nearest TpkUiProvider.
|
|
842
|
+
* Falls back to 'de' + default theme if no provider is present.
|
|
843
|
+
*/
|
|
844
|
+
declare function useTpkUi(): TpkUiContextValue;
|
|
845
|
+
|
|
846
|
+
/**
|
|
847
|
+
* TpkWidgetTour — first-launch onboarding shown ONCE.
|
|
848
|
+
*
|
|
849
|
+
* 3 swipeable cards (brand purple):
|
|
850
|
+
* Card 1 — "Dein Tester-Knopf" (the FAB)
|
|
851
|
+
* Card 2 — "Sprich den Bug" (voice — hero card)
|
|
852
|
+
* Card 3 — "Screenshot inklusive" (capture + annotate)
|
|
853
|
+
*
|
|
854
|
+
* Gated by localStorage key `tpk:tourSeen`.
|
|
855
|
+
* Use hasSeenTour() / markTourSeen() from this module.
|
|
856
|
+
*
|
|
857
|
+
* Props:
|
|
858
|
+
* onDone — called when the user finishes ("Los geht's") or skips.
|
|
859
|
+
* onSkip — optional alias; if provided, called on skip instead of onDone.
|
|
860
|
+
* onDone is still called after markTourSeen on both paths.
|
|
861
|
+
*/
|
|
862
|
+
|
|
863
|
+
/** SSR-safe: returns false if localStorage is unavailable. */
|
|
864
|
+
declare function hasSeenTour(): boolean;
|
|
865
|
+
/** SSR-safe: best-effort write. */
|
|
866
|
+
declare function markTourSeen(): void;
|
|
867
|
+
interface TpkWidgetTourProps {
|
|
868
|
+
/** Called after the tour finishes (last card) OR is skipped — in both cases markTourSeen() is called first. */
|
|
869
|
+
onDone: () => void;
|
|
870
|
+
/** Optional separate callback on skip. onDone is still called. */
|
|
871
|
+
onSkip?: () => void;
|
|
872
|
+
}
|
|
873
|
+
declare function TpkWidgetTour({ onDone, onSkip }: TpkWidgetTourProps): React.ReactElement;
|
|
874
|
+
|
|
875
|
+
export { MESSAGES, PENDING_CRASH_KEY, ScreenshotAnnotator, TesterPayKitProvider, TpkAiTester, TpkBugReportButton, TpkBugReportSheet, TpkCrashDialog, TpkDebugLogsScreen, TpkGeneralFeedbackDialog, TpkMyBugsScreen, TpkNotificationsScreen, TpkRetestScreen, TpkSensitive, TpkSessionDetailsScreen, TpkSessionEndDialog, TpkTaskPanel, TpkTesterHub, TpkTesterLauncher, TpkUiProvider, TpkWidgetTour, TpkWorkboardScreen, applySensitiveMasks, arrowheadPoints, captureScreenshot, clearPendingCrash, emptyStack, getPendingCrash, hasSeenTour, installCrashCapture, installShakeDetection, installThreeFingerTap, makeT, markTourSeen, normaliseRect, pixelateBlocks, pushOp, redo, requestShakePermission, startScreenRecording, startVoiceRecording, tpkTheme, undo, useTesterPayKit, useTpkUi };
|
|
876
|
+
export type { AnnotateOp, ArrowOp, BlurOp, OpStack, PenOp, PendingCrash, Point, RectOp, ScreenRecordingResult, ScreenRecordingSession, ScreenRecordingUnsupported, ScreenshotAnnotatorProps, ShakeDetectionOptions, StrokeStyle, TesterPayKitProviderProps, TextOp, ToolKind, TpkAiTesterProps, TpkBugReportButtonProps, TpkBugReportSheetProps, TpkColors, TpkCrashDialogProps, TpkDebugLogsScreenProps, TpkGeneralFeedbackDialogProps, TpkLocale, TpkMyBugsScreenProps, TpkNotificationsScreenProps, TpkRadius, TpkRetestScreenProps, TpkSensitiveMask, TpkSensitiveProps, TpkSessionDetailsScreenProps, TpkSessionEndDialogProps, TpkTaskPanelProps, TpkTesterHubProps, TpkTesterLauncherProps, TpkTheme, TpkWorkboardScreenProps, TpkZIndex, VoiceRecordingResult, VoiceRecordingSession, VoiceRecordingUnsupported };
|