From 5ad9e715a2c52db97db01283905430c195a6c94d Mon Sep 17 00:00:00 2001 From: Ian Mayo Date: Thu, 3 Apr 2025 13:53:39 +0100 Subject: [PATCH 1/6] Add undo-item class and e2e tests for feature editing and undo functionality --- src/components/UndoModal/index.tsx | 1 + tests/flows/feature-edit-undo-flow.spec.ts | 90 ++++++++++++++++++++++ 2 files changed, 91 insertions(+) create mode 100644 tests/flows/feature-edit-undo-flow.spec.ts diff --git a/src/components/UndoModal/index.tsx b/src/components/UndoModal/index.tsx index 10512bce..dd2a5eaf 100644 --- a/src/components/UndoModal/index.tsx +++ b/src/components/UndoModal/index.tsx @@ -191,6 +191,7 @@ export const UndoModal: React.FC = ({ dataSource={undoHistory} renderItem={(item, index) => ( { if (index === selectedUndoIndex) { // If clicking the same item again, treat it as deselection diff --git a/tests/flows/feature-edit-undo-flow.spec.ts b/tests/flows/feature-edit-undo-flow.spec.ts new file mode 100644 index 00000000..4ab34c22 --- /dev/null +++ b/tests/flows/feature-edit-undo-flow.spec.ts @@ -0,0 +1,90 @@ +import { test, expect } from '@playwright/test' + +test('Feature editing should update properties panel and undo system', async ({ page }) => { + const plotName = 'Feature Edit Flow Test' + + // Setup: Create a sample plot + await page.goto('/') + await page.waitForSelector('button:has-text("Sample plot")') + await page.click('button:has-text("Sample plot")') + await page.waitForSelector('div.ant-modal-content') + await page.locator('input.ant-input').fill(plotName) + await page.locator('button:has-text("OK")').click() + await page.waitForSelector('.flexlayout__tab_button_content') + + // Step 1: Select a feature in the layer panel + const featureName = 'VAN GALEN' + const featureInTree = page.locator(`span:has-text("${featureName}")`).first() + await expect(featureInTree).toBeVisible() + await featureInTree.click() + + // Step 2: Verify the Properties panel updates to show the selected feature + const propertiesPanel = page.locator('.core-form-animated') + await expect(propertiesPanel).toBeVisible() + + // Verify the name field in properties panel shows the selected feature name + const nameField = propertiesPanel.locator('input[id="trackPropertiesForm_name"]') + await expect(nameField).toHaveValue(featureName) + + // Check Save button is currently disabled + await expect(propertiesPanel.locator('button:has-text("Save")')).toBeDisabled() + + // Check Reset button is currently disabled + await expect(propertiesPanel.locator('button:has-text("Reset")')).toBeDisabled() + + // Step 3: Edit the feature's name in the property panel + const newName = 'RENAMED FEATURE' + await nameField.clear() + await nameField.fill(newName) + await page.keyboard.press('Enter') + + // Wait for the UI to update + await page.waitForTimeout(200) + + // Check Save and Reset buttons are enabled + await expect(propertiesPanel.locator('button:has-text("Save")')).not.toBeDisabled() + await expect(propertiesPanel.locator('button:has-text("Reset")')).not.toBeDisabled() + + // Press Save on the form + await propertiesPanel.locator('button:has-text("Save")').click() + + // Wait for the UI to update + await page.waitForTimeout(200) + + // Check Save and Reset buttons are disabled + await expect(propertiesPanel.locator('button:has-text("Save")')).toBeDisabled() + await expect(propertiesPanel.locator('button:has-text("Reset")')).toBeDisabled() + + // Step 4: Verify the feature name is updated in the layer panel + const updatedFeature = page.locator(`span:has-text("${newName}")`).first() + await expect(updatedFeature).toBeVisible() + + // Step 5: Verify the undo button is enabled after the edit + const undoRedoButton = page.locator('.undo-redo-button') + await expect(undoRedoButton).not.toBeDisabled() + + // Step 6: Open the undo modal + await undoRedoButton.click() + + // Step 7: Verify the undo modal appears with the correct description + const undoModal = page.locator('.ant-modal-content').filter({ hasText: 'Select a version' }) + await expect(undoModal).toBeVisible() + + // Check that the undo description mentions the name attribute + const undoDescription = undoModal.locator('.undo-item').first() + await expect(undoDescription).toContainText('name') + + // Step 8: Perform the undo and verify the feature name reverts + await undoModal.locator('.ant-list-items').locator('.ant-list-item').first().click() + await page.locator('button:has-text("Restore Version")').click() + + // Wait for the UI to update + await page.waitForTimeout(200) + + // Step 9: Verify original name is restored in both the layer panel and properties panel + await expect(featureInTree).toBeVisible() + await expect(updatedFeature).not.toBeVisible() + + // Verify the name field in properties panel shows the original name + await expect(nameField).toHaveValue(featureName) +}) From 00dd59fbf4fd121abe68d549c45d62944cdfb4e1 Mon Sep 17 00:00:00 2001 From: Ian Mayo Date: Thu, 3 Apr 2025 13:55:38 +0100 Subject: [PATCH 2/6] minor extension to test --- tests/flows/feature-edit-undo-flow.spec.ts | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/tests/flows/feature-edit-undo-flow.spec.ts b/tests/flows/feature-edit-undo-flow.spec.ts index 4ab34c22..8c597ce8 100644 --- a/tests/flows/feature-edit-undo-flow.spec.ts +++ b/tests/flows/feature-edit-undo-flow.spec.ts @@ -87,4 +87,25 @@ test('Feature editing should update properties panel and undo system', async ({ // Verify the name field in properties panel shows the original name await expect(nameField).toHaveValue(featureName) + + // Step 10: Open the undo modal again to perform a Redo operation + await undoRedoButton.click() + await expect(undoModal).toBeVisible() + + // Step 11: Select the second item in the list (which would be the Redo operation) + const redoItem = undoModal.locator('.ant-list-items').locator('.ant-list-item').nth(1) + await redoItem.click() + + // Step 12: Perform the Redo by clicking Restore Version + await page.locator('button:has-text("Restore Version")').click() + + // Wait for the UI to update + await page.waitForTimeout(200) + + // Step 13: Verify the feature name is changed back to the new name + await expect(updatedFeature).toBeVisible() + await expect(featureInTree).not.toBeVisible() + + // Verify the name field in properties panel shows the new name again + await expect(nameField).toHaveValue(newName) }) From 95cd1cce7b346f1b64be071664ad5673c0d2d340 Mon Sep 17 00:00:00 2001 From: Ian Mayo Date: Thu, 3 Apr 2025 14:15:01 +0100 Subject: [PATCH 3/6] Fix undo modal test by selecting first list item instead of second --- tests/flows/feature-edit-undo-flow.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/flows/feature-edit-undo-flow.spec.ts b/tests/flows/feature-edit-undo-flow.spec.ts index 8c597ce8..0f242b24 100644 --- a/tests/flows/feature-edit-undo-flow.spec.ts +++ b/tests/flows/feature-edit-undo-flow.spec.ts @@ -93,7 +93,7 @@ test('Feature editing should update properties panel and undo system', async ({ await expect(undoModal).toBeVisible() // Step 11: Select the second item in the list (which would be the Redo operation) - const redoItem = undoModal.locator('.ant-list-items').locator('.ant-list-item').nth(1) + const redoItem = undoModal.locator('.ant-list-items').locator('.ant-list-item').first() await redoItem.click() // Step 12: Perform the Redo by clicking Restore Version From 03f8d76fee0687449d57f853949a204ce7879674 Mon Sep 17 00:00:00 2001 From: Ian Mayo Date: Fri, 4 Apr 2025 10:23:20 +0100 Subject: [PATCH 4/6] expand parent node(s) if necessary --- tests/layers/paste-features.spec.ts | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/tests/layers/paste-features.spec.ts b/tests/layers/paste-features.spec.ts index bae13a20..85854d46 100644 --- a/tests/layers/paste-features.spec.ts +++ b/tests/layers/paste-features.spec.ts @@ -57,6 +57,10 @@ test('Pasting features in Layers component', async ({ browser }) => { // Select a reference point const referencePoint = page.locator('.ant-tree-title:has-text("NEW SONO")').first() + if (!await referencePoint.isVisible()) { + await pointsNode.click() + await page.waitForTimeout(100) + } await referencePoint.click() await copyButton.click() @@ -96,7 +100,13 @@ test('Pasting features in Layers component', async ({ browser }) => { // // Wait for the points to be visible await page.waitForTimeout(100) - // // Verify that there's at least one point visible after pasting + // if points is collapsed const pointsAfterPaste = page.locator('span:has-text("NEW SONO")').first() + if (!await pointsNode.isVisible()) { + await pointsNode.click() + await page.waitForTimeout(100) + } + + // // Verify that there's at least one point visible after pasting await expect(pointsAfterPaste).toBeVisible() }) From 325a7c160262dd629ecf118c70ca3846fc4155dd Mon Sep 17 00:00:00 2001 From: Ian Mayo Date: Fri, 4 Apr 2025 10:26:14 +0100 Subject: [PATCH 5/6] Add PR comment with Playwright test results link in GitHub Actions workflow --- .github/workflows/playwright-tests.yml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/.github/workflows/playwright-tests.yml b/.github/workflows/playwright-tests.yml index 316f701b..6865bd4e 100644 --- a/.github/workflows/playwright-tests.yml +++ b/.github/workflows/playwright-tests.yml @@ -47,3 +47,21 @@ jobs: name: playwright-report path: playwright-report/ retention-days: 30 + + # Add PR comment with test results link + - name: Add PR comment with test results link + if: always() && github.event_name == 'pull_request' + uses: actions/github-script@v7 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const artifactUrl = `https://github.com/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}/artifacts`; + const commentBody = `:test_tube: **Playwright Test Results**\n\nThe test results for this PR are available [here](${artifactUrl}).\n\nClick on the \`playwright-report\` artifact to download and view the detailed HTML report.`; + + github.rest.issues.createComment({ + "issue_number": context.issue.number, + "owner": context.repo.owner, + "repo": context.repo.repo, + "body": commentBody + }); + From a18db433b6ae9fc112444e2045f63e0717464c41 Mon Sep 17 00:00:00 2001 From: Ian Mayo Date: Fri, 4 Apr 2025 11:22:37 +0100 Subject: [PATCH 6/6] try alternate method for providing link --- .github/workflows/playwright-tests.yml | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/.github/workflows/playwright-tests.yml b/.github/workflows/playwright-tests.yml index 6865bd4e..6091f348 100644 --- a/.github/workflows/playwright-tests.yml +++ b/.github/workflows/playwright-tests.yml @@ -48,20 +48,14 @@ jobs: path: playwright-report/ retention-days: 30 - # Add PR comment with test results link - - name: Add PR comment with test results link - if: always() && github.event_name == 'pull_request' - uses: actions/github-script@v7 + - name: Comment PR with Report Link + if: github.event_name == 'pull_request' + uses: thollander/actions-comment-pull-request@v2 with: - github-token: ${{ secrets.GITHUB_TOKEN }} - script: | - const artifactUrl = `https://github.com/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}/artifacts`; - const commentBody = `:test_tube: **Playwright Test Results**\n\nThe test results for this PR are available [here](${artifactUrl}).\n\nClick on the \`playwright-report\` artifact to download and view the detailed HTML report.`; - - github.rest.issues.createComment({ - "issue_number": context.issue.number, - "owner": context.repo.owner, - "repo": context.repo.repo, - "body": commentBody - }); + message: | + ✅ Playwright tests completed. + + 📄 [Download HTML report](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}) + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}