From 4cfe48861f3c479db0726a08886db663733aee15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alice=20R=C3=BChl?= Date: Thu, 24 Oct 2024 13:06:10 +0200 Subject: [PATCH 1/5] Add first test to the aoi specification --- .../map/controls/aoi/preset-selector.tsx | 4 +- .../map/analysis-message-control.tsx | 4 +- test/playwright/tests/exploreAoi.spec.ts | 55 +++++++++++++++++++ 3 files changed, 61 insertions(+), 2 deletions(-) create mode 100644 test/playwright/tests/exploreAoi.spec.ts diff --git a/app/scripts/components/common/map/controls/aoi/preset-selector.tsx b/app/scripts/components/common/map/controls/aoi/preset-selector.tsx index fe0f1a508..92b8901e2 100644 --- a/app/scripts/components/common/map/controls/aoi/preset-selector.tsx +++ b/app/scripts/components/common/map/controls/aoi/preset-selector.tsx @@ -88,7 +88,9 @@ const SelectorWrapper = styled.div` position: relative; `; -const PresetSelect = styled.select` +const PresetSelect = styled.select.attrs({ + 'data-testid': 'preset-selector' + })` max-width: 200px; height: ${selectorHeight}; color: transparent; diff --git a/app/scripts/components/exploration/components/map/analysis-message-control.tsx b/app/scripts/components/exploration/components/map/analysis-message-control.tsx index 25517b22e..973ae0dce 100644 --- a/app/scripts/components/exploration/components/map/analysis-message-control.tsx +++ b/app/scripts/components/exploration/components/map/analysis-message-control.tsx @@ -78,7 +78,9 @@ const MessageStatusIndicator = styled.div` } }} `; -const MessageContent = styled.div` +const MessageContent = styled.div.attrs({ + 'data-testid': 'analysis-message' + })` line-height: 1.5rem; max-height: 1.5rem; diff --git a/test/playwright/tests/exploreAoi.spec.ts b/test/playwright/tests/exploreAoi.spec.ts new file mode 100644 index 000000000..9c7096f37 --- /dev/null +++ b/test/playwright/tests/exploreAoi.spec.ts @@ -0,0 +1,55 @@ +import { test, expect } from '../pages/basePage'; + +test.describe('Area of Interest (AOI) Analysis', () => { + test.beforeEach( + async ({ page, explorePage, consentBanner, datasetSelectorComponent }) => { + let pageErrorCalled = false; + // Log all uncaught errors to the terminal to be visible in trace + page.on('pageerror', (exception) => { + console.log(`Uncaught exception: "${JSON.stringify(exception)}"`); + pageErrorCalled = true; + }); + + const mapboxResponsePromise = page.waitForResponse( + /api\.mapbox.com\/v4\/mapbox\.mapbox-streets-v8/i + ); + + // Given that I am on the map view (explore page) + await page.goto('/exploration'); + await consentBanner.acceptButton.click(); + await datasetSelectorComponent.addFirstDataset(); + await explorePage.closeFeatureTour(); + } + ); + + test('User selects a pre-defined AOI', async ({ page }) => { + // When I select the "Analyze an area" tool (Dropdown menu) + const toolbar = page.getByTestId('preset-selector'); + // And choose one of the listed regions + await toolbar.selectOption('Hawaii'); + + // Then map should display the selected area as the AOI + // const aoi = await page.$('selector-for-aoi'); // Adjust the selector as needed + // expect(aoi).not.toBeNull(); + + // // And the AOI should not be editable when clicking on it + // await page.click('selector-for-aoi'); // Adjust the selector as needed + // const isEditable = await page.$eval('selector-for-aoi', el => console.log(el)); // Adjust the selector as needed + // expect(isEditable).toBe(false); + + // And the analysis message should display the size of the area + const analysisMessage = await page + .getByTestId('analysis-message') + .textContent() + + expect(analysisMessage).toContain('An area of 17 K km2 is selected.'); + + // And the 'Delete all areas' button should be shown + const deleteButton = await page.$('text=Delete all areas'); + expect(deleteButton).not.toBeNull(); + + // And the 'Run analysis' button should be shown + const runButton = await page.$('text=Run analysis'); + expect(runButton).not.toBeNull(); + }); +}); From 3b41dad93e2cf760560a03f01b84f0cfe6a0ff1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alice=20R=C3=BChl?= Date: Thu, 24 Oct 2024 17:56:33 +0200 Subject: [PATCH 2/5] Add instructions to the setup documentation on how to run the tests --- docs/development/SETUP.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/docs/development/SETUP.md b/docs/development/SETUP.md index 0a6aaea5c..ee91da3d2 100644 --- a/docs/development/SETUP.md +++ b/docs/development/SETUP.md @@ -62,6 +62,20 @@ VEDA-UI includes a GitHub action for checking TypeScript and lint errors. If you #### Pre-commit Hook Additionally, there's a pre-commit hook that performs the same error checks. This helps developers identify and address issues at an earlier stage. If you need to bypass the check (to make a local temporary commit etc.), include the `--no-verify`` flag in your commit command. +### Testing + +## Unit tests + +`yarn test` + +## End-to-end tests +Make sure the development server is running (`yarn serve`) + +`yarn test:e2e --ui` + +Alternatively, you can install the playwright extension for vs code (ms-playwright.playwright) and run the tests directly from there. It allows to run the tests in watch mode, open the browser or trace viewer, set breakpoints,... +Again, make sure that the development server is running (`yarn serve`). + ## Deployment To prepare the app for deployment run: From 1ee6025c404c6e6d947cf4e06455d0be9248a7e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alice=20R=C3=BChl?= Date: Mon, 28 Oct 2024 11:20:02 +0100 Subject: [PATCH 3/5] Use more specific locator, using test id --- test/playwright/pages/explorePage.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/playwright/pages/explorePage.ts b/test/playwright/pages/explorePage.ts index 5ba74c44c..f9720568d 100644 --- a/test/playwright/pages/explorePage.ts +++ b/test/playwright/pages/explorePage.ts @@ -14,7 +14,7 @@ export default class ExplorePage { this.mapboxCanvas = this.page.getByLabel('Map', { exact: true }); this.firstDatasetItem = this.page.getByRole('article'); this.closeFeatureTourButton = this.page.getByRole('button', { name: 'Close feature tour' }); - this.presetSelector = this.page.locator('#preset-selector'); + this.presetSelector = this.page.getByTestId('preset-selector'); } async closeFeatureTour() { From 15636b84440c898c843d66596a57b56143c0742f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alice=20R=C3=BChl?= Date: Mon, 28 Oct 2024 11:31:04 +0100 Subject: [PATCH 4/5] Improve aoi tests make steps appear in report, use better locators and validators, add expectations verbose, ... --- test/playwright/tests/exploreAoi.spec.ts | 61 +++++++++++++----------- 1 file changed, 33 insertions(+), 28 deletions(-) diff --git a/test/playwright/tests/exploreAoi.spec.ts b/test/playwright/tests/exploreAoi.spec.ts index 9c7096f37..3a89d9a3d 100644 --- a/test/playwright/tests/exploreAoi.spec.ts +++ b/test/playwright/tests/exploreAoi.spec.ts @@ -23,33 +23,38 @@ test.describe('Area of Interest (AOI) Analysis', () => { ); test('User selects a pre-defined AOI', async ({ page }) => { - // When I select the "Analyze an area" tool (Dropdown menu) - const toolbar = page.getByTestId('preset-selector'); - // And choose one of the listed regions - await toolbar.selectOption('Hawaii'); - - // Then map should display the selected area as the AOI - // const aoi = await page.$('selector-for-aoi'); // Adjust the selector as needed - // expect(aoi).not.toBeNull(); - - // // And the AOI should not be editable when clicking on it - // await page.click('selector-for-aoi'); // Adjust the selector as needed - // const isEditable = await page.$eval('selector-for-aoi', el => console.log(el)); // Adjust the selector as needed - // expect(isEditable).toBe(false); - - // And the analysis message should display the size of the area - const analysisMessage = await page - .getByTestId('analysis-message') - .textContent() - - expect(analysisMessage).toContain('An area of 17 K km2 is selected.'); - - // And the 'Delete all areas' button should be shown - const deleteButton = await page.$('text=Delete all areas'); - expect(deleteButton).not.toBeNull(); - - // And the 'Run analysis' button should be shown - const runButton = await page.$('text=Run analysis'); - expect(runButton).not.toBeNull(); + await test.step('When I select the "Analyze an area" tool (Dropdown menu)', async () => { + const toolbar = page.getByTestId('preset-selector'); + + await test.step('And choose one of the listed regions', async () => { + toolbar.selectOption('Hawaii'); + }); + }); + + await test.step('Then the map should display the selected area as the AOI', async () => { + // const aoi = await page.$('selector-for-aoi'); // Adjust the selector as needed + // expect(aoi).not.toBeNull(); + + await test.step('And the AOI should not be editable when clicking on it', async () => { + // await page.click('selector-for-aoi'); // Adjust the selector as needed + // const isEditable = await page.$eval('selector-for-aoi', el => console.log(el)); // Adjust the selector as needed + // expect(isEditable).toBe(false); + }); + }); + + await expect( + page.getByTestId('analysis-message'), + 'And the analysis message should display the size of the area' + ).toHaveText(/An area of 17 K km2/i); + + await expect( + page.getByRole('button', { name: 'Delete all areas' }), + 'And the "Delete all areas" button should be shown' + ).toBeVisible(); + + await expect( + page.getByRole('button', { name: 'Run analysis' }), + 'And the "Run analysis" button should be shown' + ).toBeVisible(); }); }); From 80ea196d5f53f61b17772e3f34f7712edcc8b450 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alice=20R=C3=BChl?= Date: Thu, 31 Oct 2024 12:04:07 +0100 Subject: [PATCH 5/5] Add another scenario to the AOI test --- test/playwright/tests/exploreAoi.spec.ts | 28 +++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/test/playwright/tests/exploreAoi.spec.ts b/test/playwright/tests/exploreAoi.spec.ts index 3a89d9a3d..936f3acaa 100644 --- a/test/playwright/tests/exploreAoi.spec.ts +++ b/test/playwright/tests/exploreAoi.spec.ts @@ -32,13 +32,11 @@ test.describe('Area of Interest (AOI) Analysis', () => { }); await test.step('Then the map should display the selected area as the AOI', async () => { - // const aoi = await page.$('selector-for-aoi'); // Adjust the selector as needed - // expect(aoi).not.toBeNull(); + // How to check if the pre-defined AOI is created? Can we access the canvas, or methods of mbDraw? await test.step('And the AOI should not be editable when clicking on it', async () => { - // await page.click('selector-for-aoi'); // Adjust the selector as needed - // const isEditable = await page.$eval('selector-for-aoi', el => console.log(el)); // Adjust the selector as needed - // expect(isEditable).toBe(false); + // How to check that the drawing mode did not change for the AOI? + // Can we access the canvas, or methods of mbDraw? }); }); @@ -57,4 +55,24 @@ test.describe('Area of Interest (AOI) Analysis', () => { 'And the "Run analysis" button should be shown' ).toBeVisible(); }); + + test('User draws AOI when pre-defined AOI exists', async ({ page }) => { + await test.step('Given that there is a pre-defined AOI on the map', async () => { + const toolbar = page.getByTestId('preset-selector'); + await toolbar.selectOption('Hawaii'); + }); + + await test.step('When I click on a pen tool to draw custom AOI', async () => { + await page.getByRole('button', { name: 'Draw AOI' }).click(); + }); + + await test.step('Then the AOI from pre-defined AOIs should be deleted', async () => { + // How to check if the pre-defined AOI is deleted? Can we access the canvas, or methods of mbDraw? + }); + + await test.step('And the pre-defined selector should be reset and display the placeholder text', async () => { + const toolbar = page.getByTestId('preset-selector'); + expect(toolbar).toHaveValue('Analyze an area'); + }); + }); });