From b81d1636501909e6b4b00f7e41c7b6b33eee0acc Mon Sep 17 00:00:00 2001 From: Nuwan Date: Sun, 8 Feb 2026 12:41:10 +0530 Subject: [PATCH] test(18-01): add INT-02 Save settings API verification test - Add test for save button making PUT /sessions/{id} API call - Verify payload includes description and privacy fields (musician_access, approval_required) - Use page.route() to intercept and capture API request - Verify modal closes after successful save - Fix locators to use privacy select instead of modal header text (avoids toast collision) --- .../session-settings/session-settings.spec.ts | 71 ++++++++++++++++--- 1 file changed, 60 insertions(+), 11 deletions(-) diff --git a/jam-ui/test/session-settings/session-settings.spec.ts b/jam-ui/test/session-settings/session-settings.spec.ts index aa9ce9aa0..4919aff99 100644 --- a/jam-ui/test/session-settings/session-settings.spec.ts +++ b/jam-ui/test/session-settings/session-settings.spec.ts @@ -15,25 +15,74 @@ test.describe('Session Settings Modal', () => { // Click the Settings button await settingsButton.click(); - // Verify modal opens with "Session Settings" header - const modalHeader = page.locator('text=Session Settings'); - await expect(modalHeader).toBeVisible({ timeout: 5000 }); - - // Verify form elements are visible - // Privacy select dropdown + // Verify modal opens - use privacy select as the indicator (unique to modal) + // The modal header text "Session Settings" can also appear in toasts const privacySelect = page.locator('[data-testid="session-privacy"]'); - await expect(privacySelect).toBeVisible(); + await expect(privacySelect).toBeVisible({ timeout: 5000 }); // Description textarea const descriptionTextarea = page.locator('textarea[name="description"]'); await expect(descriptionTextarea).toBeVisible(); - // Save button - const saveButton = page.locator('button:has-text("Save")'); + // Save button within the modal + const saveButton = page.locator('.modal-footer button:has-text("Save")'); await expect(saveButton).toBeVisible(); - // Cancel button - const cancelButton = page.locator('button:has-text("Cancel")'); + // Cancel button within the modal + const cancelButton = page.locator('.modal-footer button:has-text("Cancel")'); await expect(cancelButton).toBeVisible(); }); + + test('INT-02: Save settings makes PUT /sessions/{id} API call', async ({ page }) => { + // Setup API interception to capture the PUT request + let capturedRequest: { url: string; method: string; body: any } | null = null; + + await page.route('**/api/sessions/*', async (route, request) => { + if (request.method() === 'PUT') { + capturedRequest = { + url: request.url(), + method: request.method(), + body: JSON.parse(request.postData() || '{}') + }; + } + await route.continue(); + }); + + // Open Settings modal + const settingsButton = page.locator('img[alt="Settings"]'); + await settingsButton.click(); + + // Wait for modal to open - use privacy select as the indicator (unique to modal) + const privacySelect = page.locator('[data-testid="session-privacy"]'); + await expect(privacySelect).toBeVisible({ timeout: 5000 }); + + // Modify form values + // Change privacy to public (value="1" based on SESSION_PRIVACY_MAP) + await privacySelect.selectOption('1'); + + // Change description + const descriptionTextarea = page.locator('textarea[name="description"]'); + await descriptionTextarea.fill('Updated test description'); + + // Click Save button within the modal + const saveButton = page.locator('.modal-footer button:has-text("Save")'); + await saveButton.click(); + + // Wait for API call to complete + await page.waitForTimeout(2000); + + // Verify API call was made + expect(capturedRequest).not.toBeNull(); + expect(capturedRequest?.method).toBe('PUT'); + expect(capturedRequest?.url).toMatch(/\/api\/sessions\/[a-f0-9-]+$/); + expect(capturedRequest?.body).toHaveProperty('description', 'Updated test description'); + + // Verify privacy-related fields are included in the payload + // When privacy is "public" (value=1): musician_access=true, approval_required=false + expect(capturedRequest?.body).toHaveProperty('musician_access'); + expect(capturedRequest?.body).toHaveProperty('approval_required'); + + // Verify modal closes after save - check privacy select is no longer visible + await expect(privacySelect).not.toBeVisible({ timeout: 5000 }); + }); });