From 57820d57ebb551ab9b1eeed6024625e70c878d85 Mon Sep 17 00:00:00 2001 From: Ricardo Costeira Date: Thu, 12 Nov 2026 02:17:42 +0100 Subject: [PATCH] fix: reset stop comment submit after saving --- public/app.js | 1 + scripts/review-pane-browser.mjs | 34 +++++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/public/app.js b/public/app.js index ca4f2f2..0b53fb9 100644 --- a/public/app.js +++ b/public/app.js @@ -6627,6 +6627,7 @@ async function saveStepComment(event) { toast(commentId ? "Stop comment updated" : "Stop comment added"); } catch (error) { toast(error.message); + } finally { submit.disabled = false; } } diff --git a/scripts/review-pane-browser.mjs b/scripts/review-pane-browser.mjs index 5845101..7e6d59b 100644 --- a/scripts/review-pane-browser.mjs +++ b/scripts/review-pane-browser.mjs @@ -50,6 +50,40 @@ try { const saved = (await snapshot()).comments.find(comment => comment.body === 'Keep this stop comment draft'); assert.equal(saved?.stepId, originalStep.id, 'A draft remains attached to its original stop after navigation'); initial.comments.push(saved); + + const secondStep = initial.outline.phases.flatMap(phase => phase.steps)[1]; + const stopForm = page.locator('#step-comment-form'); + const stopSubmit = stopForm.locator('[type="submit"]'); + await page.locator('#comment-stop').click(); + await page.locator('#step-comment-input').fill('Comment on another stop'); + assert.equal(await stopSubmit.isEnabled(), true, 'Saving a stop comment must leave the form reusable'); + await stopSubmit.click(); + await stopForm.waitFor({ state: 'hidden' }); + const second = (await snapshot()).comments.find(comment => comment.body === 'Comment on another stop'); + assert.equal(second?.stepId, secondStep.id, 'The next comment belongs to the newly selected stop'); + initial.comments.push(second); + + await page.locator(`#comment-list [data-comment-id="${saved.id}"] [data-action="edit"]`).click(); + assert.equal(await page.locator('#step-comment-input').inputValue(), saved.body); + assert.equal(await stopSubmit.isEnabled(), true, 'An existing stop comment can be edited after adding another'); + await page.locator('#step-comment-input').fill('Updated original stop comment'); + await page.route(`**/api/comments/${saved.id}`, route => route.request().method() === 'PATCH' + ? route.fulfill({ status: 500, json: { error: 'Test stop comment failure' } }) : route.continue(), { times: 1 }); + await Promise.all([ + page.waitForResponse(response => response.request().method() === 'PATCH' && response.url().endsWith(`/api/comments/${saved.id}`) && response.status() === 500), + stopSubmit.click(), + ]); + await stopForm.locator('[type="submit"]:enabled').waitFor(); + assert.equal(await stopForm.isVisible(), true, 'A failed save leaves the draft open for retry'); + assert.equal(await page.locator('#step-comment-input').inputValue(), 'Updated original stop comment'); + await stopSubmit.click(); + await stopForm.waitFor({ state: 'hidden' }); + const edited = (await snapshot()).comments.find(comment => comment.id === saved.id); + assert.equal(edited?.body, 'Updated original stop comment'); + assert.equal(edited?.stepId, originalStep.id); + assert.equal(await stopSubmit.isEnabled(), true, 'Editing also leaves the form reusable'); + console.log('PASS stop comments: consecutive stops, editing and failed-save retry'); + await tab('Tour').click(); await page.locator('#previous-step').click(); await page.waitForFunction(() => document.querySelector('#step-count').textContent.includes('(Step 1)') && !document.querySelector('#next-step').disabled); console.log('PASS sidebar: separate panels, keyboard tabs, counts, drafts, scroll and tour progress retained');