From 4dbbf0b42391e1c8280fc4180844f886407913d2 Mon Sep 17 00:00:00 2001 From: piotrk39 Date: Mon, 25 Nov 2024 14:24:11 +0100 Subject: [PATCH 1/3] Add test base and assertion --- .../layer-control-info-popover.component.html | 2 +- tests/e2e/Pages/MapComponent.ts | 42 ++++++++++++- ...consAreInteractiveInLayerComponent.spec.ts | 63 +++++++++++++++++++ 3 files changed, 105 insertions(+), 2 deletions(-) create mode 100644 tests/e2e/tests/Map/InfoIconsAreInteractiveInLayerComponent.spec.ts diff --git a/interfaces/IBF-dashboard/src/app/components/layer-control-info-popover/layer-control-info-popover.component.html b/interfaces/IBF-dashboard/src/app/components/layer-control-info-popover/layer-control-info-popover.component.html index 8dd4e0d9f..c23ea7ca5 100644 --- a/interfaces/IBF-dashboard/src/app/components/layer-control-info-popover/layer-control-info-popover.component.html +++ b/interfaces/IBF-dashboard/src/app/components/layer-control-info-popover/layer-control-info-popover.component.html @@ -5,7 +5,7 @@ name="close-circle" size="large" (click)="closePopover()" - data-test="close-matrix-icon" + data-testid="close-matrix-icon" class="popover-close-button" > diff --git a/tests/e2e/Pages/MapComponent.ts b/tests/e2e/Pages/MapComponent.ts index 3fa76edfe..084fdfc1f 100644 --- a/tests/e2e/Pages/MapComponent.ts +++ b/tests/e2e/Pages/MapComponent.ts @@ -21,6 +21,8 @@ class MapComponent extends DashboardPage { readonly redCrossMarker: Locator; readonly gloFASMarker: Locator; readonly alerThresholdLines: Locator; + readonly closeButtonIcon: Locator; + readonly layerInfoContent: Locator; constructor(page: Page) { super(page); @@ -50,6 +52,8 @@ class MapComponent extends DashboardPage { this.alerThresholdLines = this.page.locator( '[stroke="var(--ion-color-ibf-outline-red)"]', ); + this.closeButtonIcon = this.page.getByTestId('close-matrix-icon'); + this.layerInfoContent = this.page.getByTestId('layer-info-content'); } async mapComponentIsVisible() { @@ -194,6 +198,42 @@ class MapComponent extends DashboardPage { return availableLayers; } + async asserAllInfoIconsIntercations() { + const getLayerRow = this.page.getByTestId('matrix-layer-name'); + const layerCount = await getLayerRow.count(); + console.log('layerCount: ', layerCount); + + const availableLayers = []; + for (let i = 0; i < layerCount; i++) { + try { + const layerRow = getLayerRow.nth(i); + if (await layerRow.isVisible()) { + const nameAttribute = await getLayerRow.nth(i).textContent(); + console.log(i); + if (nameAttribute) { + availableLayers.push(nameAttribute.trim()); + } + console.log('availableLayers: ', availableLayers[i]); + await this.page + .locator('ion-item') + .filter({ hasText: availableLayers[i] }) + .getByRole('button') + .click(); + await expect( + this.page + .locator('ion-card-header') + .filter({ hasText: availableLayers[i] }), + ).toHaveText(availableLayers[i]); + await expect(this.layerInfoContent).toBeVisible(); + await this.closeButtonIcon.click(); + } + } catch (error) { + // Handle errors without stopping the loop + } + } + return availableLayers; + } + async assertAggregateTitleOnHoverOverMap() { // Declare component const aggregates = new AggregatesComponent(this.page); @@ -203,7 +243,7 @@ class MapComponent extends DashboardPage { await this.page.waitForLoadState('domcontentloaded'); await this.page.waitForSelector('.leaflet-interactive'); - // Assert the that Aggregates title is visible and does not contain the text 'National View' + // Assert that Aggregates title is visible and does not contain the text 'National View' await this.adminBoundry.first().hover(); await expect(aggregates.aggregatesTitleHeader).not.toContainText( diff --git a/tests/e2e/tests/Map/InfoIconsAreInteractiveInLayerComponent.spec.ts b/tests/e2e/tests/Map/InfoIconsAreInteractiveInLayerComponent.spec.ts new file mode 100644 index 000000000..8445ea9b1 --- /dev/null +++ b/tests/e2e/tests/Map/InfoIconsAreInteractiveInLayerComponent.spec.ts @@ -0,0 +1,63 @@ +import { test } from '@playwright/test'; +import DashboardPage from 'Pages/DashboardPage'; +import MapComponent from 'Pages/MapComponent'; +import UserStateComponent from 'Pages/UserStateComponent'; +import { qase } from 'playwright-qase-reporter'; +import { NoTriggerDataSet } from 'testData/testData.enum'; + +import { FloodsScenario } from '../../../../services/API-service/src/scripts/enum/mock-scenario.enum'; +import { + getAccessToken, + mockFloods, + resetDB, +} from '../../helpers/utility.helper'; +import LoginPage from '../../Pages/LoginPage'; + +let accessToken: string; + +test.beforeEach(async ({ page }) => { + // Login + const loginPage = new LoginPage(page); + accessToken = await getAccessToken(); + await resetDB(accessToken); + + // We should maybe create one mock for all different disaster types for now we can just use floods + await mockFloods( + FloodsScenario.NoTrigger, + NoTriggerDataSet.CountryCode, + accessToken, + ); + + await page.goto('/'); + await loginPage.login( + NoTriggerDataSet.UserMail, + NoTriggerDataSet.UserPassword, + ); +}); + +test( + qase(33, 'Interaction with info icon in map layer component'), + async ({ page }) => { + const dashboard = new DashboardPage(page); + const userState = new UserStateComponent(page); + const map = new MapComponent(page); + + // Navigate to disaster type the data was mocked for + await dashboard.navigateToFloodDisasterType(); + // Assertions + await userState.headerComponentIsVisible({ + countryName: NoTriggerDataSet.CountryName, + }); + // Wait for the page to load + await dashboard.waitForLoaderToDisappear(); + await map.mapComponentIsVisible(); + + // Open the layer menu + await map.isLayerMenuOpen({ layerMenuOpen: false }); + await map.clickLayerMenu(); + await map.isLayerMenuOpen({ layerMenuOpen: true }); + + // Assert layer info icons to be intercative and contain basic required info + await map.asserAllInfoIconsIntercations(); + }, +); From 19a84da4af9a2f8bf532d3d19e78c89cf22f4ec5 Mon Sep 17 00:00:00 2001 From: piotrk39 Date: Mon, 25 Nov 2024 14:47:38 +0100 Subject: [PATCH 2/3] Update assertion and separate click info button function --- tests/e2e/Pages/MapComponent.ts | 48 +++++++++++-------- ...consAreInteractiveInLayerComponent.spec.ts | 2 +- 2 files changed, 28 insertions(+), 22 deletions(-) diff --git a/tests/e2e/Pages/MapComponent.ts b/tests/e2e/Pages/MapComponent.ts index 084fdfc1f..fa07cbf6c 100644 --- a/tests/e2e/Pages/MapComponent.ts +++ b/tests/e2e/Pages/MapComponent.ts @@ -160,6 +160,15 @@ class MapComponent extends DashboardPage { } } + async clickInfoButtonByName({ layerName }: { layerName: string }) { + await this.page + .locator(`ion-item`) + .filter({ hasText: layerName }) + .getByRole('button') + .first() + .click(); + } + async retryGetAttribute(locator: Locator, attribute: string, retries = 3) { for (let attempt = 0; attempt < retries; attempt++) { try { @@ -198,40 +207,37 @@ class MapComponent extends DashboardPage { return availableLayers; } - async asserAllInfoIconsIntercations() { + async assertAllInfoIconsIntercations() { const getLayerRow = this.page.getByTestId('matrix-layer-name'); const layerCount = await getLayerRow.count(); - console.log('layerCount: ', layerCount); - const availableLayers = []; for (let i = 0; i < layerCount; i++) { try { + await this.page.waitForTimeout(200); const layerRow = getLayerRow.nth(i); if (await layerRow.isVisible()) { - const nameAttribute = await getLayerRow.nth(i).textContent(); - console.log(i); + const nameAttribute = await layerRow.textContent(); if (nameAttribute) { - availableLayers.push(nameAttribute.trim()); + const trimmedName = nameAttribute.trim(); + + await this.clickInfoButtonByName({ layerName: trimmedName }); + await expect( + this.page + .locator('ion-card-header') + .filter({ hasText: trimmedName }), + ).toBeVisible(); + await expect(this.layerInfoContent).toBeVisible(); + await this.closeButtonIcon.click(); } - console.log('availableLayers: ', availableLayers[i]); - await this.page - .locator('ion-item') - .filter({ hasText: availableLayers[i] }) - .getByRole('button') - .click(); - await expect( - this.page - .locator('ion-card-header') - .filter({ hasText: availableLayers[i] }), - ).toHaveText(availableLayers[i]); - await expect(this.layerInfoContent).toBeVisible(); - await this.closeButtonIcon.click(); } } catch (error) { - // Handle errors without stopping the loop + if (error instanceof Error) { + console.error('Error: ', error.message); + } else { + console.error('Unexpected error: ', error); + } } } - return availableLayers; } async assertAggregateTitleOnHoverOverMap() { diff --git a/tests/e2e/tests/Map/InfoIconsAreInteractiveInLayerComponent.spec.ts b/tests/e2e/tests/Map/InfoIconsAreInteractiveInLayerComponent.spec.ts index 8445ea9b1..3295f6f35 100644 --- a/tests/e2e/tests/Map/InfoIconsAreInteractiveInLayerComponent.spec.ts +++ b/tests/e2e/tests/Map/InfoIconsAreInteractiveInLayerComponent.spec.ts @@ -58,6 +58,6 @@ test( await map.isLayerMenuOpen({ layerMenuOpen: true }); // Assert layer info icons to be intercative and contain basic required info - await map.asserAllInfoIconsIntercations(); + await map.assertAllInfoIconsIntercations(); }, ); From 5f4b6a3b37ab32b14009c3bce6fc6e775c0051d1 Mon Sep 17 00:00:00 2001 From: piotrk39 Date: Mon, 25 Nov 2024 16:25:24 +0100 Subject: [PATCH 3/3] Fix typo and add link to qase --- tests/e2e/Pages/MapComponent.ts | 2 +- .../tests/Map/InfoIconsAreInteractiveInLayerComponent.spec.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/e2e/Pages/MapComponent.ts b/tests/e2e/Pages/MapComponent.ts index fa07cbf6c..d41dca7c8 100644 --- a/tests/e2e/Pages/MapComponent.ts +++ b/tests/e2e/Pages/MapComponent.ts @@ -207,7 +207,7 @@ class MapComponent extends DashboardPage { return availableLayers; } - async assertAllInfoIconsIntercations() { + async validateInfoIconInteractions() { const getLayerRow = this.page.getByTestId('matrix-layer-name'); const layerCount = await getLayerRow.count(); diff --git a/tests/e2e/tests/Map/InfoIconsAreInteractiveInLayerComponent.spec.ts b/tests/e2e/tests/Map/InfoIconsAreInteractiveInLayerComponent.spec.ts index 3295f6f35..1213810b1 100644 --- a/tests/e2e/tests/Map/InfoIconsAreInteractiveInLayerComponent.spec.ts +++ b/tests/e2e/tests/Map/InfoIconsAreInteractiveInLayerComponent.spec.ts @@ -34,7 +34,7 @@ test.beforeEach(async ({ page }) => { NoTriggerDataSet.UserPassword, ); }); - +// https://app.qase.io/project/IBF?previewMode=side&suite=3&tab=&case=33 test( qase(33, 'Interaction with info icon in map layer component'), async ({ page }) => { @@ -58,6 +58,6 @@ test( await map.isLayerMenuOpen({ layerMenuOpen: true }); // Assert layer info icons to be intercative and contain basic required info - await map.assertAllInfoIconsIntercations(); + await map.validateInfoIconInteractions(); }, );