@product7/feedback-sdk 1.6.8 → 1.7.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.
@@ -0,0 +1,398 @@
1
+ # Survey Widget — QA Test Cases
2
+
3
+ ## Overview
4
+ This document covers manual test cases for verifying the survey widget functionality across all supported survey types (NPS, CSAT, CES, Custom, and Multi-page).
5
+
6
+ ---
7
+
8
+ ## Prerequisites
9
+
10
+ - SDK is initialized with a valid `workspace` and `userContext`
11
+ - `init()` has been called successfully (session token received)
12
+ - Browser DevTools open to monitor network requests and console
13
+
14
+ ---
15
+
16
+ ## Test Environment Setup
17
+
18
+ ```js
19
+ const sdk = new FeedbackSDK({
20
+ workspace: 'your-workspace',
21
+ userContext: { user_id: 'qa_user_01', email: 'qa@example.com' }
22
+ });
23
+ await sdk.init();
24
+ ```
25
+
26
+ ---
27
+
28
+ ## TC-01: NPS Survey — Basic Display
29
+
30
+ **Objective:** Verify NPS survey renders correctly with 11-point scale.
31
+
32
+ **Steps:**
33
+ 1. Call `sdk.showSurvey({ surveyType: 'nps', ratingScale: 11, title: 'How likely are you to recommend us?', lowLabel: 'Not likely', highLabel: 'Very likely' })`
34
+ 2. Observe the survey widget on screen
35
+
36
+ **Expected Results:**
37
+ - [ ] Survey widget appears at the configured position (default: bottom-right)
38
+ - [ ] Title text is displayed: "How likely are you to recommend us?"
39
+ - [ ] 11 score buttons are shown, numbered 0 through 10
40
+ - [ ] "Not likely" label appears below the leftmost button
41
+ - [ ] "Very likely" label appears below the rightmost button
42
+ - [ ] A close (✕) button is visible in the top-right corner of the widget
43
+
44
+ ---
45
+
46
+ ## TC-02: NPS Survey — Score Selection
47
+
48
+ **Objective:** Verify score buttons highlight correctly on selection.
49
+
50
+ **Steps:**
51
+ 1. Show NPS survey (as in TC-01)
52
+ 2. Click score button **7**
53
+ 3. Click score button **9**
54
+
55
+ **Expected Results:**
56
+ - [ ] After clicking 7: button 7 is visually highlighted/selected
57
+ - [ ] After clicking 9: button 9 is highlighted, button 7 is no longer highlighted
58
+ - [ ] Only one button is selected at a time
59
+
60
+ ---
61
+
62
+ ## TC-03: NPS Survey — Submission
63
+
64
+ **Objective:** Verify NPS survey submits the selected score.
65
+
66
+ **Steps:**
67
+ 1. Show NPS survey with `showSubmitButton: true` and a valid `surveyId`
68
+ 2. Click score button **8**
69
+ 3. Click the **Submit** button
70
+ 4. Observe network tab
71
+
72
+ **Expected Results:**
73
+ - [ ] A POST request is sent to `/widget/surveys/{surveyId}/responses`
74
+ - [ ] Request payload contains `rating: 8`
75
+ - [ ] Survey widget closes after submission
76
+ - [ ] A success notification ("Thank you for your feedback!") appears briefly
77
+ - [ ] `survey:submitted` event is fired (verify in console with `sdk.on('survey:submitted', console.log)`)
78
+
79
+ ---
80
+
81
+ ## TC-04: NPS Survey — Submit Without Score
82
+
83
+ **Objective:** Verify error message when submitting with no score selected.
84
+
85
+ **Steps:**
86
+ 1. Show NPS survey with `showSubmitButton: true`
87
+ 2. Do NOT click any score button
88
+ 3. Click the **Submit** button
89
+
90
+ **Expected Results:**
91
+ - [ ] Error message "Please select a rating" appears inside the widget
92
+ - [ ] Survey does NOT close
93
+ - [ ] No API request is made
94
+ - [ ] Error disappears after ~3 seconds
95
+
96
+ ---
97
+
98
+ ## TC-05: NPS Survey — Auto-submit on Select
99
+
100
+ **Objective:** Verify survey auto-submits when `autoSubmitOnSelect: true`.
101
+
102
+ **Steps:**
103
+ 1. Call `sdk.showSurvey({ surveyType: 'nps', autoSubmitOnSelect: true, surveyId: 'survey-id' })`
104
+ 2. Click any score button
105
+
106
+ **Expected Results:**
107
+ - [ ] Survey submits immediately upon clicking a score (no submit button click needed)
108
+ - [ ] POST request is sent with the selected score
109
+ - [ ] Survey closes and success notification shows
110
+
111
+ ---
112
+
113
+ ## TC-06: CSAT Survey — Display and Selection
114
+
115
+ **Objective:** Verify CSAT survey renders emoji buttons correctly.
116
+
117
+ **Steps:**
118
+ 1. Call `sdk.showSurvey({ surveyType: 'csat', title: 'How satisfied are you?' })`
119
+ 2. Click the 4th emoji (😊)
120
+
121
+ **Expected Results:**
122
+ - [ ] 5 emoji buttons are displayed (😞 😟 😐 🙂 😄)
123
+ - [ ] Clicked emoji is visually selected/highlighted
124
+ - [ ] Other emojis are deselected
125
+ - [ ] Score corresponds to position (1–5)
126
+
127
+ ---
128
+
129
+ ## TC-07: CES Survey — Display and Selection
130
+
131
+ **Objective:** Verify CES survey renders effort scale buttons.
132
+
133
+ **Steps:**
134
+ 1. Call `sdk.showSurvey({ surveyType: 'ces', title: 'How easy was it?' })`
135
+ 2. Click **Easy**
136
+
137
+ **Expected Results:**
138
+ - [ ] 5 buttons displayed: Very Difficult / Difficult / Neutral / Easy / Very Easy
139
+ - [ ] Clicked button is highlighted
140
+ - [ ] Other buttons are deselected
141
+
142
+ ---
143
+
144
+ ## TC-08: Survey with Feedback Text Input
145
+
146
+ **Objective:** Verify optional feedback textarea appears and value is submitted.
147
+
148
+ **Steps:**
149
+ 1. Show any survey with `showFeedbackInput: true` and `showSubmitButton: true`
150
+ 2. Select a score
151
+ 3. Type "Great product!" in the feedback textarea
152
+ 4. Click Submit
153
+
154
+ **Expected Results:**
155
+ - [ ] Textarea is visible below the score selection
156
+ - [ ] Typed text appears in the textarea
157
+ - [ ] Submitted payload includes `feedback: "Great product!"`
158
+
159
+ ---
160
+
161
+ ## TC-09: Survey Dismiss — Close Button
162
+
163
+ **Objective:** Verify close button dismisses the survey.
164
+
165
+ **Steps:**
166
+ 1. Show any survey
167
+ 2. Click the ✕ (close) button
168
+
169
+ **Expected Results:**
170
+ - [ ] Survey widget fades out and is removed from the DOM
171
+ - [ ] `survey:dismissed` event is fired
172
+ - [ ] If `onDismiss` callback was provided, it is called
173
+ - [ ] If a valid `surveyId` was set, a POST request is sent to `/widget/surveys/{surveyId}/dismiss`
174
+
175
+ ---
176
+
177
+ ## TC-10: Survey Dismiss — Escape Key
178
+
179
+ **Objective:** Verify pressing Escape closes the survey.
180
+
181
+ **Steps:**
182
+ 1. Show any survey
183
+ 2. Press the **Escape** key on the keyboard
184
+
185
+ **Expected Results:**
186
+ - [ ] Survey closes (same behaviour as TC-09)
187
+ - [ ] `survey:dismissed` event fires
188
+
189
+ ---
190
+
191
+ ## TC-11: Survey — Disabled State
192
+
193
+ **Objective:** Verify survey is suppressed when `enabled: false`.
194
+
195
+ **Steps:**
196
+ 1. Call `sdk.showSurvey({ surveyType: 'nps', enabled: false })`
197
+
198
+ **Expected Results:**
199
+ - [ ] No survey widget appears in the DOM
200
+ - [ ] `showSurvey()` returns `null`
201
+ - [ ] `survey:suppressed` event is fired with `reason: 'disabled'`
202
+
203
+ ---
204
+
205
+ ## TC-12: Survey — Position Variants
206
+
207
+ **Objective:** Verify survey renders in each supported position.
208
+
209
+ **Steps:**
210
+ 1. Test each position: `bottom-right`, `bottom-left`, `center`
211
+ 2. Call `sdk.showSurvey({ surveyType: 'nps', position: '<position>' })`
212
+
213
+ **Expected Results:**
214
+ | Position | Expected Appearance |
215
+ |---|---|
216
+ | `bottom-right` | Widget anchored to bottom-right corner |
217
+ | `bottom-left` | Widget anchored to bottom-left corner |
218
+ | `center` | Widget centered on screen with backdrop overlay |
219
+
220
+ - [ ] For `center`: backdrop overlay is displayed behind the widget
221
+ - [ ] Clicking the backdrop (center mode) closes the survey
222
+
223
+ ---
224
+
225
+ ## TC-13: Survey — Theme Variants
226
+
227
+ **Objective:** Verify light and dark themes apply correctly.
228
+
229
+ **Steps:**
230
+ 1. Test `theme: 'light'` and `theme: 'dark'`
231
+
232
+ **Expected Results:**
233
+ - [ ] Light theme: white/light background, dark text
234
+ - [ ] Dark theme: dark background, light text
235
+ - [ ] Theme class is applied to the survey element
236
+
237
+ ---
238
+
239
+ ## TC-14: Multi-page Survey — Navigation
240
+
241
+ **Objective:** Verify multi-page survey navigates between pages correctly.
242
+
243
+ **Setup:**
244
+ ```js
245
+ sdk.showSurvey({
246
+ surveyId: 'multi-page-id',
247
+ pages: [
248
+ { id: 'p1', type: 'rating', title: 'Rate our product', position: 0, ratingConfig: { scale: 5 } },
249
+ { id: 'p2', type: 'text', title: 'Any comments?', position: 1 },
250
+ ]
251
+ });
252
+ ```
253
+
254
+ **Steps:**
255
+ 1. Observe page 1
256
+ 2. Click a rating button
257
+ 3. Click **Next**
258
+ 4. Observe page 2
259
+ 5. Click **Back**
260
+ 6. Observe page 1 again
261
+
262
+ **Expected Results:**
263
+ - [ ] Page 1 shows "Page 1 of 2" progress indicator
264
+ - [ ] Action button on page 1 reads "Next"
265
+ - [ ] After clicking Next: page 2 loads, progress shows "Page 2 of 2"
266
+ - [ ] Page 2 has a **Back** button
267
+ - [ ] Action button on page 2 reads "Submit"
268
+ - [ ] After clicking Back: page 1 is shown again
269
+
270
+ ---
271
+
272
+ ## TC-15: Multi-page Survey — Validation
273
+
274
+ **Objective:** Verify each page validates input before advancing.
275
+
276
+ **Steps (Rating page):**
277
+ 1. Display multi-page survey on page 1 (rating type)
278
+ 2. Click **Next** without selecting a rating
279
+
280
+ **Expected Results:**
281
+ - [ ] Error message "Please select a rating" appears
282
+ - [ ] Survey does NOT advance to page 2
283
+
284
+ **Steps (Text page):**
285
+ 1. Advance to a text-type page
286
+ 2. Click **Submit** without entering any text
287
+
288
+ **Expected Results:**
289
+ - [ ] Error message "Please enter an answer" appears
290
+ - [ ] Survey does NOT submit
291
+
292
+ **Steps (Multiple choice page):**
293
+ 1. Advance to a multiple-choice page
294
+ 2. Click **Submit** without selecting any option
295
+
296
+ **Expected Results:**
297
+ - [ ] Error message "Please select an option" appears
298
+
299
+ ---
300
+
301
+ ## TC-16: Multi-page Survey — Full Submission
302
+
303
+ **Objective:** Verify complete multi-page survey submits all page answers.
304
+
305
+ **Steps:**
306
+ 1. Display the multi-page survey (TC-14 setup)
307
+ 2. On page 1: select a rating, click **Next**
308
+ 3. On page 2: type a comment, click **Submit**
309
+ 4. Check network request
310
+
311
+ **Expected Results:**
312
+ - [ ] POST to `/widget/surveys/{surveyId}/responses` is made
313
+ - [ ] Payload `answers.page_answers` contains entries for both pages
314
+ - [ ] Success notification appears after submission
315
+
316
+ ---
317
+
318
+ ## TC-17: getActiveSurveys() — Fetch and Display
319
+
320
+ **Objective:** Verify active surveys can be fetched and shown programmatically.
321
+
322
+ **Steps:**
323
+ 1. Call `const surveys = await sdk.getActiveSurveys()`
324
+ 2. Log result to console
325
+ 3. Call `sdk.showSurveyById(surveys[0].surveyId)`
326
+
327
+ **Expected Results:**
328
+ - [ ] `getActiveSurveys()` returns an array of survey objects
329
+ - [ ] Each survey has `surveyId`, `surveyType`, `title` fields
330
+ - [ ] `showSurveyById()` successfully renders the matching survey
331
+ - [ ] Correct survey type is shown (NPS/CSAT/CES matches the fetched type)
332
+
333
+ ---
334
+
335
+ ## TC-18: showSurveyById() — Survey Not Found
336
+
337
+ **Objective:** Verify error handling when survey ID doesn't exist.
338
+
339
+ **Steps:**
340
+ 1. Call `await sdk.showSurveyById('nonexistent-id')`
341
+
342
+ **Expected Results:**
343
+ - [ ] Promise rejects with an error message containing "not found"
344
+ - [ ] No survey widget appears in the DOM
345
+
346
+ ---
347
+
348
+ ## TC-19: Survey — onSubmit Callback
349
+
350
+ **Objective:** Verify `onSubmit` callback receives the correct response object.
351
+
352
+ **Steps:**
353
+ 1. Call:
354
+ ```js
355
+ sdk.showSurvey({
356
+ surveyType: 'nps',
357
+ ratingScale: 11,
358
+ showSubmitButton: true,
359
+ onSubmit: (response) => console.log('onSubmit:', response)
360
+ });
361
+ ```
362
+ 2. Select score 9 and click Submit
363
+ 3. Check console output
364
+
365
+ **Expected Results:**
366
+ - [ ] `onSubmit` is called once
367
+ - [ ] `response.type` is `'nps'`
368
+ - [ ] `response.score` is `9`
369
+ - [ ] `response.timestamp` is a valid ISO date string
370
+
371
+ ---
372
+
373
+ ## TC-20: Survey — SDK Not Initialized Guard
374
+
375
+ **Objective:** Verify SDK throws when survey methods are called before `init()`.
376
+
377
+ **Steps:**
378
+ 1. Create SDK instance but do NOT call `init()`
379
+ 2. Call `sdk.showSurvey({ surveyType: 'nps' })`
380
+
381
+ **Expected Results:**
382
+ - [ ] Error is thrown: "SDK must be initialized before showing surveys. Call init() first."
383
+ - [ ] No network requests are made
384
+
385
+ ---
386
+
387
+ ## Regression Checklist
388
+
389
+ After any change to survey code, verify:
390
+
391
+ - [ ] All 4 survey types render without console errors (NPS, CSAT, CES, Custom)
392
+ - [ ] Score selection works for each type
393
+ - [ ] Submit sends correct payload to the API
394
+ - [ ] Dismiss/close cleans up the DOM (no lingering elements)
395
+ - [ ] Multi-page navigation works forward and backward
396
+ - [ ] `survey:shown`, `survey:submitted`, `survey:dismissed`, `survey:suppressed` events all fire at the right time
397
+ - [ ] `autoSubmitOnSelect: true` does not show submit button
398
+ - [ ] `enabled: false` prevents the survey from rendering