@@ -19,6 +19,40 @@ test.describe("Default Assistant Admin Page", () => {
19
19
await page . waitForURL (
20
20
"http://localhost:3000/admin/configuration/default-assistant"
21
21
) ;
22
+
23
+ // Attach basic API logging for this spec
24
+ page . on ( "response" , async ( resp ) => {
25
+ const url = resp . url ( ) ;
26
+ if ( url . includes ( "/api/admin/default-assistant" ) ) {
27
+ const method = resp . request ( ) . method ( ) ;
28
+ const status = resp . status ( ) ;
29
+ let body = "" ;
30
+ try {
31
+ body = await resp . text ( ) ;
32
+ } catch { }
33
+ console . log (
34
+ `[api:response] ${ method } ${ url } => ${ status } body=${ body ?. slice ( 0 , 300 ) } `
35
+ ) ;
36
+ }
37
+ } ) ;
38
+
39
+ // Proactively log tool availability and current config
40
+ try {
41
+ const toolsResp = await page . request . get (
42
+ "http://localhost:3000/api/admin/default-assistant/available-tools"
43
+ ) ;
44
+ const cfgResp = await page . request . get (
45
+ "http://localhost:3000/api/admin/default-assistant/configuration"
46
+ ) ;
47
+ console . log (
48
+ `[/available-tools] status=${ toolsResp . status ( ) } body=${ ( await toolsResp . text ( ) ) . slice ( 0 , 400 ) } `
49
+ ) ;
50
+ console . log (
51
+ `[/configuration] status=${ cfgResp . status ( ) } body=${ ( await cfgResp . text ( ) ) . slice ( 0 , 400 ) } `
52
+ ) ;
53
+ } catch ( e ) {
54
+ console . log ( `[setup] Failed to fetch initial admin config: ${ String ( e ) } ` ) ;
55
+ }
22
56
} ) ;
23
57
24
58
test ( "should load default assistant page for admin users" , async ( {
@@ -28,7 +62,8 @@ test.describe("Default Assistant Admin Page", () => {
28
62
await expect (
29
63
page . getByRole ( "heading" , { name : "Default Assistant" } )
30
64
) . toBeVisible ( ) ;
31
- await expect ( page . locator ( "text=Actions" ) ) . toBeVisible ( ) ;
65
+ // Avoid strict mode collision from multiple "Actions" elements
66
+ await expect ( page . getByText ( "Instructions" , { exact : true } ) ) . toBeVisible ( ) ;
32
67
await expect ( page . getByText ( "Instructions" , { exact : true } ) ) . toBeVisible ( ) ;
33
68
} ) ;
34
69
@@ -44,10 +79,32 @@ test.describe("Default Assistant Admin Page", () => {
44
79
45
80
// Get initial state
46
81
const initialState = await searchToggle . getAttribute ( "data-state" ) ;
82
+ const isDisabled = await searchToggle . isDisabled ( ) . catch ( ( ) => false ) ;
83
+ console . log (
84
+ `[toggle] Internal Search initial data-state=${ initialState } disabled=${ isDisabled } `
85
+ ) ;
47
86
48
87
// Toggle it
49
88
await searchToggle . click ( ) ;
50
89
90
+ // Wait for PATCH to complete (or log if it didn't happen)
91
+ const patchResp = await Promise . race ( [
92
+ page . waitForResponse (
93
+ ( r ) =>
94
+ r . url ( ) . includes ( "/api/admin/default-assistant" ) &&
95
+ r . request ( ) . method ( ) === "PATCH" ,
96
+ { timeout : 8000 }
97
+ ) ,
98
+ page . waitForTimeout ( 8500 ) . then ( ( ) => null ) ,
99
+ ] ) ;
100
+ if ( patchResp ) {
101
+ console . log (
102
+ `[toggle] Internal Search PATCH status=${ patchResp . status ( ) } body=${ ( await patchResp . text ( ) ) . slice ( 0 , 300 ) } `
103
+ ) ;
104
+ } else {
105
+ console . log ( `[toggle] Internal Search did not observe PATCH response` ) ;
106
+ }
107
+
51
108
// Wait for the change to persist
52
109
await page . waitForTimeout ( 1000 ) ;
53
110
@@ -62,6 +119,7 @@ test.describe("Default Assistant Admin Page", () => {
62
119
. locator ( '[role="switch"]' )
63
120
. first ( ) ;
64
121
const newState = await searchToggleAfter . getAttribute ( "data-state" ) ;
122
+ console . log ( `[toggle] Internal Search after reload data-state=${ newState } ` ) ;
65
123
66
124
// State should have changed
67
125
expect ( initialState ) . not . toBe ( newState ) ;
@@ -83,9 +141,29 @@ test.describe("Default Assistant Admin Page", () => {
83
141
84
142
// Get initial state
85
143
const initialState = await webSearchToggle . getAttribute ( "data-state" ) ;
144
+ const isDisabled = await webSearchToggle . isDisabled ( ) . catch ( ( ) => false ) ;
145
+ console . log (
146
+ `[toggle] Web Search initial data-state=${ initialState } disabled=${ isDisabled } `
147
+ ) ;
86
148
87
149
// Toggle it
88
150
await webSearchToggle . click ( ) ;
151
+ const patchResp = await Promise . race ( [
152
+ page . waitForResponse (
153
+ ( r ) =>
154
+ r . url ( ) . includes ( "/api/admin/default-assistant" ) &&
155
+ r . request ( ) . method ( ) === "PATCH" ,
156
+ { timeout : 8000 }
157
+ ) ,
158
+ page . waitForTimeout ( 8500 ) . then ( ( ) => null ) ,
159
+ ] ) ;
160
+ if ( patchResp ) {
161
+ console . log (
162
+ `[toggle] Web Search PATCH status=${ patchResp . status ( ) } body=${ ( await patchResp . text ( ) ) . slice ( 0 , 300 ) } `
163
+ ) ;
164
+ } else {
165
+ console . log ( `[toggle] Web Search did not observe PATCH response` ) ;
166
+ }
89
167
90
168
// Wait for the change to persist
91
169
await page . waitForTimeout ( 1000 ) ;
@@ -101,6 +179,7 @@ test.describe("Default Assistant Admin Page", () => {
101
179
. locator ( '[role="switch"]' )
102
180
. first ( ) ;
103
181
const newState = await webSearchToggleAfter . getAttribute ( "data-state" ) ;
182
+ console . log ( `[toggle] Web Search after reload data-state=${ newState } ` ) ;
104
183
105
184
// State should have changed
106
185
expect ( initialState ) . not . toBe ( newState ) ;
@@ -122,9 +201,29 @@ test.describe("Default Assistant Admin Page", () => {
122
201
123
202
// Get initial state
124
203
const initialState = await imageGenToggle . getAttribute ( "data-state" ) ;
204
+ const isDisabled = await imageGenToggle . isDisabled ( ) . catch ( ( ) => false ) ;
205
+ console . log (
206
+ `[toggle] Image Generation initial data-state=${ initialState } disabled=${ isDisabled } `
207
+ ) ;
125
208
126
209
// Toggle it
127
210
await imageGenToggle . click ( ) ;
211
+ const patchResp = await Promise . race ( [
212
+ page . waitForResponse (
213
+ ( r ) =>
214
+ r . url ( ) . includes ( "/api/admin/default-assistant" ) &&
215
+ r . request ( ) . method ( ) === "PATCH" ,
216
+ { timeout : 8000 }
217
+ ) ,
218
+ page . waitForTimeout ( 8500 ) . then ( ( ) => null ) ,
219
+ ] ) ;
220
+ if ( patchResp ) {
221
+ console . log (
222
+ `[toggle] Image Generation PATCH status=${ patchResp . status ( ) } body=${ ( await patchResp . text ( ) ) . slice ( 0 , 300 ) } `
223
+ ) ;
224
+ } else {
225
+ console . log ( `[toggle] Image Generation did not observe PATCH response` ) ;
226
+ }
128
227
129
228
// Wait for the change to persist
130
229
await page . waitForTimeout ( 1000 ) ;
@@ -140,6 +239,9 @@ test.describe("Default Assistant Admin Page", () => {
140
239
. locator ( '[role="switch"]' )
141
240
. first ( ) ;
142
241
const newState = await imageGenToggleAfter . getAttribute ( "data-state" ) ;
242
+ console . log (
243
+ `[toggle] Image Generation after reload data-state=${ newState } `
244
+ ) ;
143
245
144
246
// State should have changed
145
247
expect ( initialState ) . not . toBe ( newState ) ;
@@ -167,6 +269,22 @@ test.describe("Default Assistant Admin Page", () => {
167
269
// Save changes
168
270
const saveButton = page . locator ( "text=Save Instructions" ) ;
169
271
await saveButton . click ( ) ;
272
+ const patchResp = await Promise . race ( [
273
+ page . waitForResponse (
274
+ ( r ) =>
275
+ r . url ( ) . includes ( "/api/admin/default-assistant" ) &&
276
+ r . request ( ) . method ( ) === "PATCH" ,
277
+ { timeout : 8000 }
278
+ ) ,
279
+ page . waitForTimeout ( 8500 ) . then ( ( ) => null ) ,
280
+ ] ) ;
281
+ if ( patchResp ) {
282
+ console . log (
283
+ `[prompt] Save PATCH status=${ patchResp . status ( ) } body=${ ( await patchResp . text ( ) ) . slice ( 0 , 300 ) } `
284
+ ) ;
285
+ } else {
286
+ console . log ( `[prompt] Did not observe PATCH response on save` ) ;
287
+ }
170
288
171
289
// Wait for success message
172
290
await expect (
@@ -208,6 +326,14 @@ test.describe("Default Assistant Admin Page", () => {
208
326
await textarea . fill ( "Temporary text" ) ;
209
327
const tempSaveButton = page . locator ( "text=Save Instructions" ) ;
210
328
await tempSaveButton . click ( ) ;
329
+ const patchResp1 = await page . waitForResponse (
330
+ ( r ) =>
331
+ r . url ( ) . includes ( "/api/admin/default-assistant" ) &&
332
+ r . request ( ) . method ( ) === "PATCH"
333
+ ) ;
334
+ console . log (
335
+ `[prompt-empty] Temp save PATCH status=${ patchResp1 . status ( ) } body=${ ( await patchResp1 . text ( ) ) . slice ( 0 , 300 ) } `
336
+ ) ;
211
337
await expect (
212
338
page . locator ( "text=Instructions updated successfully!" )
213
339
) . toBeVisible ( ) ;
@@ -220,6 +346,14 @@ test.describe("Default Assistant Admin Page", () => {
220
346
// Save changes
221
347
const saveButton = page . locator ( "text=Save Instructions" ) ;
222
348
await saveButton . click ( ) ;
349
+ const patchResp2 = await page . waitForResponse (
350
+ ( r ) =>
351
+ r . url ( ) . includes ( "/api/admin/default-assistant" ) &&
352
+ r . request ( ) . method ( ) === "PATCH"
353
+ ) ;
354
+ console . log (
355
+ `[prompt-empty] Save empty PATCH status=${ patchResp2 . status ( ) } body=${ ( await patchResp2 . text ( ) ) . slice ( 0 , 300 ) } `
356
+ ) ;
223
357
224
358
// Wait for success message
225
359
await expect (
@@ -241,6 +375,14 @@ test.describe("Default Assistant Admin Page", () => {
241
375
await textareaAfter . fill ( initialValue ) ;
242
376
const saveButtonAfter = page . locator ( "text=Save Instructions" ) ;
243
377
await saveButtonAfter . click ( ) ;
378
+ const patchResp3 = await page . waitForResponse (
379
+ ( r ) =>
380
+ r . url ( ) . includes ( "/api/admin/default-assistant" ) &&
381
+ r . request ( ) . method ( ) === "PATCH"
382
+ ) ;
383
+ console . log (
384
+ `[prompt-empty] Restore PATCH status=${ patchResp3 . status ( ) } body=${ ( await patchResp3 . text ( ) ) . slice ( 0 , 300 ) } `
385
+ ) ;
244
386
await expect (
245
387
page . locator ( "text=Instructions updated successfully!" )
246
388
) . toBeVisible ( ) ;
@@ -272,6 +414,14 @@ test.describe("Default Assistant Admin Page", () => {
272
414
// Save changes
273
415
const saveButton = page . locator ( "text=Save Instructions" ) ;
274
416
await saveButton . click ( ) ;
417
+ const patchResp = await page . waitForResponse (
418
+ ( r ) =>
419
+ r . url ( ) . includes ( "/api/admin/default-assistant" ) &&
420
+ r . request ( ) . method ( ) === "PATCH"
421
+ ) ;
422
+ console . log (
423
+ `[prompt-long] Save PATCH status=${ patchResp . status ( ) } body=${ ( await patchResp . text ( ) ) . slice ( 0 , 300 ) } `
424
+ ) ;
275
425
276
426
// Wait for success message
277
427
await expect (
@@ -287,6 +437,14 @@ test.describe("Default Assistant Admin Page", () => {
287
437
if ( initialValue !== currentValue ) {
288
438
await textarea . fill ( initialValue ) ;
289
439
await saveButton . click ( ) ;
440
+ const patchRespRestore = await page . waitForResponse (
441
+ ( r ) =>
442
+ r . url ( ) . includes ( "/api/admin/default-assistant" ) &&
443
+ r . request ( ) . method ( ) === "PATCH"
444
+ ) ;
445
+ console . log (
446
+ `[prompt-long] Restore PATCH status=${ patchRespRestore . status ( ) } body=${ ( await patchRespRestore . text ( ) ) . slice ( 0 , 300 ) } `
447
+ ) ;
290
448
await expect (
291
449
page . locator ( "text=Instructions updated successfully!" )
292
450
) . toBeVisible ( ) ;
@@ -315,7 +473,7 @@ test.describe("Default Assistant Admin Page", () => {
315
473
// Use browser console to send invalid tool IDs
316
474
// This simulates what would happen if someone tried to bypass the UI
317
475
const response = await page . evaluate ( async ( ) => {
318
- const res = await fetch ( "/api/admin/default-assistant/ " , {
476
+ const res = await fetch ( "/api/admin/default-assistant" , {
319
477
method : "PATCH" ,
320
478
headers : { "Content-Type" : "application/json" } ,
321
479
body : JSON . stringify ( {
@@ -328,6 +486,21 @@ test.describe("Default Assistant Admin Page", () => {
328
486
body : await res . text ( ) ,
329
487
} ;
330
488
} ) ;
489
+ // Also try via page.request (uses storageState) to capture status in case page fetch fails
490
+ try {
491
+ const alt = await page . request . patch (
492
+ "http://localhost:3000/api/admin/default-assistant" ,
493
+ {
494
+ data : { tool_ids : [ "InvalidTool" , "AnotherInvalidTool" ] } ,
495
+ headers : { "Content-Type" : "application/json" } ,
496
+ }
497
+ ) ;
498
+ console . log (
499
+ `[invalid-tools] page.request.patch status=${ alt . status ( ) } body=${ ( await alt . text ( ) ) . slice ( 0 , 300 ) } `
500
+ ) ;
501
+ } catch ( e ) {
502
+ console . log ( `[invalid-tools] page.request.patch error: ${ String ( e ) } ` ) ;
503
+ }
331
504
332
505
// Check that the request failed with 400 or 422 (validation error)
333
506
expect ( response . ok ) . toBe ( false ) ;
0 commit comments