From d830ec17de80d76f9d154a1a937c556866b6e0cd Mon Sep 17 00:00:00 2001 From: Gulfaraz Rahman Date: Wed, 15 Jan 2025 13:13:11 +0100 Subject: [PATCH 1/3] refactor: use describe to group tests --- tests/e2e/helpers/interfaces.ts | 22 + tests/e2e/playwright.config.ts | 5 +- .../AggregateComponentButtonClick.ts | 31 ++ .../AggregateComponentEventCount.ts | 39 ++ .../AggregateComponentHeaderColour.ts | 37 ++ .../AggregateComponentTitleHover.ts | 31 ++ .../AggregatesComponentVisible.ts | 30 ++ .../ChatComponent/ChatComponentButtonClick.ts | 39 ++ .../ChatComponent/ChatComponentEventClick.ts | 38 ++ .../ChatComponent/ChatComponentEventCount.ts | 48 ++ .../ChatComponent/ChatComponentInfoPopover.ts | 37 ++ .../ChatComponent/ChatComponentVisible.ts | 36 ++ .../DashboardPage/DashboardPageVisible.ts | 45 ++ .../DisasterTypeComponentSelect.ts | 47 ++ .../DisasterTypeComponentVisible.ts | 34 ++ .../IBF-Dashboard/NoTriggerScenarios.spec.ts | 499 ------------------ .../IBF-Dashboard/TriggerScenarios.spec.ts | 271 ---------- .../MapComponentAlertThreshold.ts | 41 ++ .../MapComponent/MapComponentFloodExtent.ts | 40 ++ .../MapComponentGloFASStations.ts | 48 ++ .../MapComponentGloFASStationsTrigger.ts | 54 ++ .../MapComponentGloFASStationsWarning.ts | 54 ++ .../MapComponent/MapComponentInfoPopover.ts | 43 ++ .../MapComponent/MapComponentInteractive.ts | 56 ++ .../MapComponent/MapComponentLayersDefault.ts | 59 +++ .../MapComponent/MapComponentLayersVisible.ts | 48 ++ .../tests/MapComponent/MapComponentVisible.ts | 37 ++ tests/e2e/tests/ScenarioNoTrigger.spec.ts | 118 +++++ tests/e2e/tests/ScenarioTrigger.spec.ts | 86 +++ .../TimelineComponentDisabled.ts | 33 ++ .../TimelineComponentVisible.ts | 33 ++ .../UserStateComponentLogout.ts | 34 ++ .../UserStateComponentVisible.ts | 36 ++ 33 files changed, 1336 insertions(+), 773 deletions(-) create mode 100644 tests/e2e/helpers/interfaces.ts create mode 100644 tests/e2e/tests/AggregatesComponent/AggregateComponentButtonClick.ts create mode 100644 tests/e2e/tests/AggregatesComponent/AggregateComponentEventCount.ts create mode 100644 tests/e2e/tests/AggregatesComponent/AggregateComponentHeaderColour.ts create mode 100644 tests/e2e/tests/AggregatesComponent/AggregateComponentTitleHover.ts create mode 100644 tests/e2e/tests/AggregatesComponent/AggregatesComponentVisible.ts create mode 100644 tests/e2e/tests/ChatComponent/ChatComponentButtonClick.ts create mode 100644 tests/e2e/tests/ChatComponent/ChatComponentEventClick.ts create mode 100644 tests/e2e/tests/ChatComponent/ChatComponentEventCount.ts create mode 100644 tests/e2e/tests/ChatComponent/ChatComponentInfoPopover.ts create mode 100644 tests/e2e/tests/ChatComponent/ChatComponentVisible.ts create mode 100644 tests/e2e/tests/DashboardPage/DashboardPageVisible.ts create mode 100644 tests/e2e/tests/DisasterTypeComponent/DisasterTypeComponentSelect.ts create mode 100644 tests/e2e/tests/DisasterTypeComponent/DisasterTypeComponentVisible.ts delete mode 100644 tests/e2e/tests/IBF-Dashboard/NoTriggerScenarios.spec.ts delete mode 100644 tests/e2e/tests/IBF-Dashboard/TriggerScenarios.spec.ts create mode 100644 tests/e2e/tests/MapComponent/MapComponentAlertThreshold.ts create mode 100644 tests/e2e/tests/MapComponent/MapComponentFloodExtent.ts create mode 100644 tests/e2e/tests/MapComponent/MapComponentGloFASStations.ts create mode 100644 tests/e2e/tests/MapComponent/MapComponentGloFASStationsTrigger.ts create mode 100644 tests/e2e/tests/MapComponent/MapComponentGloFASStationsWarning.ts create mode 100644 tests/e2e/tests/MapComponent/MapComponentInfoPopover.ts create mode 100644 tests/e2e/tests/MapComponent/MapComponentInteractive.ts create mode 100644 tests/e2e/tests/MapComponent/MapComponentLayersDefault.ts create mode 100644 tests/e2e/tests/MapComponent/MapComponentLayersVisible.ts create mode 100644 tests/e2e/tests/MapComponent/MapComponentVisible.ts create mode 100644 tests/e2e/tests/ScenarioNoTrigger.spec.ts create mode 100644 tests/e2e/tests/ScenarioTrigger.spec.ts create mode 100644 tests/e2e/tests/TimelineComponent/TimelineComponentDisabled.ts create mode 100644 tests/e2e/tests/TimelineComponent/TimelineComponentVisible.ts create mode 100644 tests/e2e/tests/UserStateComponent/UserStateComponentLogout.ts create mode 100644 tests/e2e/tests/UserStateComponent/UserStateComponentVisible.ts diff --git a/tests/e2e/helpers/interfaces.ts b/tests/e2e/helpers/interfaces.ts new file mode 100644 index 0000000000..9701cd874b --- /dev/null +++ b/tests/e2e/helpers/interfaces.ts @@ -0,0 +1,22 @@ +import AggregatesComponent from 'Pages/AggregatesComponent'; +import ChatComponent from 'Pages/ChatComponent'; +import DashboardPage from 'Pages/DashboardPage'; +import DisasterTypeComponent from 'Pages/DisasterTypeComponent'; +import LoginPage from 'Pages/LoginPage'; +import MapComponent from 'Pages/MapComponent'; +import TimelineComponent from 'Pages/TimelineComponent'; +import UserStateComponent from 'Pages/UserStateComponent'; + +export interface Pages { + login: LoginPage; + dashboard: DashboardPage; +} + +export interface Components { + map: MapComponent; + userState: UserStateComponent; + aggregates: AggregatesComponent; + chat: ChatComponent; + disasterType: DisasterTypeComponent; + timeline: TimelineComponent; +} diff --git a/tests/e2e/playwright.config.ts b/tests/e2e/playwright.config.ts index 855b3929f7..86536096c8 100644 --- a/tests/e2e/playwright.config.ts +++ b/tests/e2e/playwright.config.ts @@ -11,9 +11,8 @@ export default defineConfig({ /* Run tests in files in parallel */ fullyParallel: false, /* Fail the build on CI if you accidentally left test.only in the source code. */ - forbidOnly: !!process.env.CI, - /* Retry on CI only */ - retries: 1, + forbidOnly: process.env.NODE_ENV !== 'development', + retries: 0, /* Opt out of parallel tests on CI. */ // reporter: [ // ['list'], diff --git a/tests/e2e/tests/AggregatesComponent/AggregateComponentButtonClick.ts b/tests/e2e/tests/AggregatesComponent/AggregateComponentButtonClick.ts new file mode 100644 index 0000000000..2d26e1e7ef --- /dev/null +++ b/tests/e2e/tests/AggregatesComponent/AggregateComponentButtonClick.ts @@ -0,0 +1,31 @@ +import test from '@playwright/test'; +import { qase } from 'playwright-qase-reporter'; + +import { Components, Pages } from '../../helpers/interfaces'; + +export default (pages: Partial, components: Partial) => { + test( + qase(13, 'Info button(s) should be clickable'), + { + annotation: { + type: 'url', + description: 'https://app.qase.io/project/IBF?case=13', + }, + }, + async () => { + const { dashboard } = pages; + const { aggregates } = components; + + if (!dashboard || !aggregates) { + throw new Error('pages and components not found'); + } + + // Navigate to disaster type the data was mocked for + await dashboard.navigateToFloodDisasterType(); + // Assertions + await aggregates.aggregateComponentIsVisible(); + await aggregates.validatesAggregatesInfoButtons(); + await aggregates.validateLayerPopoverExternalLink(); + }, + ); +}; diff --git a/tests/e2e/tests/AggregatesComponent/AggregateComponentEventCount.ts b/tests/e2e/tests/AggregatesComponent/AggregateComponentEventCount.ts new file mode 100644 index 0000000000..98822c19b3 --- /dev/null +++ b/tests/e2e/tests/AggregatesComponent/AggregateComponentEventCount.ts @@ -0,0 +1,39 @@ +import test, { expect } from '@playwright/test'; +import { qase } from 'playwright-qase-reporter'; +import { TriggerDataSet } from 'testData/testData.enum'; + +import { Components, Pages } from '../../helpers/interfaces'; + +export default (pages: Partial, components: Partial) => { + test( + qase(39, 'Number of events should be non-zero'), + { + annotation: { + type: 'url', + description: 'https://app.qase.io/project/IBF?case=39', + }, + }, + async () => { + const { dashboard } = pages; + const { aggregates, userState } = components; + + if (!dashboard || !aggregates || !userState) { + throw new Error('pages and components not found'); + } + + // Navigate to disaster type the data was mocked for + await dashboard.navigateToFloodDisasterType(); + // Assertions + await userState.headerComponentIsVisible({ + countryName: TriggerDataSet.CountryName, + }); + + // get the number of warning events and aggregated events + const aggregatesEventCount = + await aggregates.getNumberOfPredictedEvents(); + + // check if the number of warning events is equal to the number of aggregated events + expect(aggregatesEventCount).toBeGreaterThan(0); + }, + ); +}; diff --git a/tests/e2e/tests/AggregatesComponent/AggregateComponentHeaderColour.ts b/tests/e2e/tests/AggregatesComponent/AggregateComponentHeaderColour.ts new file mode 100644 index 0000000000..f9f5ed2772 --- /dev/null +++ b/tests/e2e/tests/AggregatesComponent/AggregateComponentHeaderColour.ts @@ -0,0 +1,37 @@ +import test from '@playwright/test'; +import { qase } from 'playwright-qase-reporter'; +import { TriggerDataSet } from 'testData/testData.enum'; + +import { Components, Pages } from '../../helpers/interfaces'; + +export default (pages: Partial, components: Partial) => { + test( + qase(40, 'Header colour should be purple'), + { + annotation: { + type: 'url', + description: 'https://app.qase.io/project/IBF?case=40', + }, + }, + async () => { + const { dashboard } = pages; + const { aggregates, userState } = components; + + if (!dashboard || !aggregates || !userState) { + throw new Error('pages and components not found'); + } + + // Navigate to disaster type the data was mocked for + await dashboard.navigateToFloodDisasterType(); + // Assertions + await userState.headerComponentIsVisible({ + countryName: TriggerDataSet.CountryName, + }); + + // Validate that the aggregates header is purple by class + await aggregates.validateColorOfAggregatesHeaderByClass({ + isTrigger: true, + }); + }, + ); +}; diff --git a/tests/e2e/tests/AggregatesComponent/AggregateComponentTitleHover.ts b/tests/e2e/tests/AggregatesComponent/AggregateComponentTitleHover.ts new file mode 100644 index 0000000000..dfcc951789 --- /dev/null +++ b/tests/e2e/tests/AggregatesComponent/AggregateComponentTitleHover.ts @@ -0,0 +1,31 @@ +import test from '@playwright/test'; +import { qase } from 'playwright-qase-reporter'; + +import { Components, Pages } from '../../helpers/interfaces'; + +export default (pages: Partial, components: Partial) => { + test( + qase(12, 'Title should change based on hovered map district'), + { + annotation: { + type: 'url', + description: 'https://app.qase.io/project/IBF?case=12', + }, + }, + async () => { + const { dashboard } = pages; + const { aggregates, map } = components; + + if (!dashboard || !aggregates || !map) { + throw new Error('pages and components not found'); + } + + // Navigate to disaster type the data was mocked for + await dashboard.navigateToFloodDisasterType(); + // Assertions + await aggregates.aggregateComponentIsVisible(); + await map.clickLayerCheckbox({ layerName: 'Glofas stations' }); + await map.assertAggregateTitleOnHoverOverMap(); + }, + ); +}; diff --git a/tests/e2e/tests/AggregatesComponent/AggregatesComponentVisible.ts b/tests/e2e/tests/AggregatesComponent/AggregatesComponentVisible.ts new file mode 100644 index 0000000000..ed44913445 --- /dev/null +++ b/tests/e2e/tests/AggregatesComponent/AggregatesComponentVisible.ts @@ -0,0 +1,30 @@ +import test from '@playwright/test'; +import { qase } from 'playwright-qase-reporter'; + +import { Components, Pages } from '../../helpers/interfaces'; + +export default (pages: Partial, components: Partial) => { + test( + qase(6, 'Aggregates component elements should be visible'), + { + annotation: { + type: 'url', + description: 'https://app.qase.io/project/IBF?case=6', + }, + }, + async () => { + const { dashboard } = pages; + const { aggregates } = components; + + if (!dashboard || !aggregates) { + throw new Error('pages and components not found'); + } + + // Navigate to disaster type the data was mocked for + await dashboard.navigateToFloodDisasterType(); + // Assertions + await aggregates.aggregateComponentIsVisible(); + await aggregates.aggregatesAlementsDisplayedInNoTrigger(); + }, + ); +}; diff --git a/tests/e2e/tests/ChatComponent/ChatComponentButtonClick.ts b/tests/e2e/tests/ChatComponent/ChatComponentButtonClick.ts new file mode 100644 index 0000000000..ac0df63748 --- /dev/null +++ b/tests/e2e/tests/ChatComponent/ChatComponentButtonClick.ts @@ -0,0 +1,39 @@ +import test from '@playwright/test'; +import { qase } from 'playwright-qase-reporter'; +import { NoTriggerDataSet } from 'testData/testData.enum'; + +import { Components, Pages } from '../../helpers/interfaces'; + +export default (pages: Partial, components: Partial) => { + test( + qase(11, 'Action buttons should be clickable'), + { + annotation: { + type: 'url', + description: 'https://app.qase.io/project/IBF?case=11', + }, + }, + async () => { + const { dashboard } = pages; + const { chat, userState } = components; + + if (!dashboard || !chat || !userState) { + throw new Error('pages and components not found'); + } + + // Navigate to disaster type the data was mocked for + await dashboard.navigateToFloodDisasterType(); + // Assertions + await userState.headerComponentIsVisible({ + countryName: NoTriggerDataSet.CountryName, + }); + await chat.allDefaultButtonsArePresent(); + await chat.clickAndAssertAboutButton(); + await chat.clickAndAssertGuideButton(); + await chat.clickAndAssertExportViewButton(); + await chat.clickAndAssertTriggerLogButton({ + url: `/log?countryCodeISO3=${NoTriggerDataSet.CountryCode}&disasterType=floods`, + }); + }, + ); +}; diff --git a/tests/e2e/tests/ChatComponent/ChatComponentEventClick.ts b/tests/e2e/tests/ChatComponent/ChatComponentEventClick.ts new file mode 100644 index 0000000000..5853b288b6 --- /dev/null +++ b/tests/e2e/tests/ChatComponent/ChatComponentEventClick.ts @@ -0,0 +1,38 @@ +import test from '@playwright/test'; +import { qase } from 'playwright-qase-reporter'; +import { TriggerDataSet } from 'testData/testData.enum'; + +import { Components, Pages } from '../../helpers/interfaces'; + +export default (pages: Partial, components: Partial) => { + test( + qase(44, 'Show prediction button should be clickable'), + { + annotation: { + type: 'url', + description: 'https://app.qase.io/project/IBF?case=44', + }, + }, + async () => { + const { dashboard } = pages; + const { chat, userState } = components; + + if (!dashboard || !chat || !userState) { + throw new Error('pages and components not found'); + } + + // Navigate to disaster type the data was mocked for + await dashboard.navigateToFloodDisasterType(); + // Assertions + await userState.headerComponentIsVisible({ + countryName: TriggerDataSet.CountryName, + }); + await chat.chatColumnIsVisibleForTriggerState({ + firstName: TriggerDataSet.firstName, + lastName: TriggerDataSet.lastName, + }); + await chat.allDefaultButtonsArePresent(); + await chat.predictionButtonsAreActive(); + }, + ); +}; diff --git a/tests/e2e/tests/ChatComponent/ChatComponentEventCount.ts b/tests/e2e/tests/ChatComponent/ChatComponentEventCount.ts new file mode 100644 index 0000000000..6df93aecfd --- /dev/null +++ b/tests/e2e/tests/ChatComponent/ChatComponentEventCount.ts @@ -0,0 +1,48 @@ +import test, { expect } from '@playwright/test'; +import { qase } from 'playwright-qase-reporter'; +import { TriggerDataSet } from 'testData/testData.enum'; + +import { Components, Pages } from '../../helpers/interfaces'; + +export default (pages: Partial, components: Partial) => { + test( + qase( + 43, + 'Number of events should match the number of events in aggregates component', + ), + { + annotation: { + type: 'url', + description: 'https://app.qase.io/project/IBF?case=43', + }, + }, + async () => { + const { dashboard } = pages; + const { chat, userState, aggregates } = components; + + if (!dashboard || !chat || !userState || !aggregates) { + throw new Error('pages and components not found'); + } + + // Navigate to disaster type the data was mocked for + await dashboard.navigateToFloodDisasterType(); + // Assertions + await userState.headerComponentIsVisible({ + countryName: TriggerDataSet.CountryName, + }); + await chat.chatColumnIsVisibleForTriggerState({ + firstName: TriggerDataSet.firstName, + lastName: TriggerDataSet.lastName, + }); + await chat.allDefaultButtonsArePresent(); + + // get the number of warning events and aggregated events + const chatEventCount = await chat.predictionButtonsAreActive(); + const aggregatesEventCount = + await aggregates.getNumberOfPredictedEvents(); + + // check if the number of warning events is equal to the number of aggregated events + expect(chatEventCount).toEqual(aggregatesEventCount); + }, + ); +}; diff --git a/tests/e2e/tests/ChatComponent/ChatComponentInfoPopover.ts b/tests/e2e/tests/ChatComponent/ChatComponentInfoPopover.ts new file mode 100644 index 0000000000..195fac9ab0 --- /dev/null +++ b/tests/e2e/tests/ChatComponent/ChatComponentInfoPopover.ts @@ -0,0 +1,37 @@ +import test from '@playwright/test'; +import { qase } from 'playwright-qase-reporter'; +import { TriggerDataSet } from 'testData/testData.enum'; + +import { Components, Pages } from '../../helpers/interfaces'; + +export default (pages: Partial, components: Partial) => { + test( + qase(45, 'Info icon should open popover on click'), + { + annotation: { + type: 'url', + description: 'https://app.qase.io/project/IBF?case=45', + }, + }, + async () => { + const { dashboard } = pages; + const { chat, userState } = components; + + if (!dashboard || !chat || !userState) { + throw new Error('pages and components not found'); + } + + // Navigate to disaster type the data was mocked for + await dashboard.navigateToFloodDisasterType(); + // Assertions + await userState.headerComponentIsVisible({ + countryName: TriggerDataSet.CountryName, + }); + await chat.chatColumnIsVisibleForTriggerState({ + firstName: TriggerDataSet.firstName, + lastName: TriggerDataSet.lastName, + }); + await chat.validateEventsInfoButtonsAreClickable(); + }, + ); +}; diff --git a/tests/e2e/tests/ChatComponent/ChatComponentVisible.ts b/tests/e2e/tests/ChatComponent/ChatComponentVisible.ts new file mode 100644 index 0000000000..54aaab266d --- /dev/null +++ b/tests/e2e/tests/ChatComponent/ChatComponentVisible.ts @@ -0,0 +1,36 @@ +import test from '@playwright/test'; +import { qase } from 'playwright-qase-reporter'; +import { NoTriggerDataSet } from 'testData/testData.enum'; + +import { Components, Pages } from '../../helpers/interfaces'; + +export default (pages: Partial, components: Partial) => { + test( + qase(5, 'Chat component elements should be visible'), + { + annotation: { + type: 'url', + description: 'https://app.qase.io/project/IBF?case=5', + }, + }, + async () => { + const { dashboard } = pages; + const { chat, userState } = components; + + if (!dashboard || !chat || !userState) { + throw new Error('pages and components not found'); + } + // Navigate to disaster type the data was mocked for + await dashboard.navigateToFloodDisasterType(); + // Assertions + await userState.headerComponentIsVisible({ + countryName: NoTriggerDataSet.CountryName, + }); + await chat.chatColumnIsVisibleForNoTriggerState({ + firstName: NoTriggerDataSet.firstName, + lastName: NoTriggerDataSet.lastName, + }); + await chat.allDefaultButtonsArePresent(); + }, + ); +}; diff --git a/tests/e2e/tests/DashboardPage/DashboardPageVisible.ts b/tests/e2e/tests/DashboardPage/DashboardPageVisible.ts new file mode 100644 index 0000000000..589bde4ce5 --- /dev/null +++ b/tests/e2e/tests/DashboardPage/DashboardPageVisible.ts @@ -0,0 +1,45 @@ +import test from '@playwright/test'; +import { qase } from 'playwright-qase-reporter'; +import { NoTriggerDataSet } from 'testData/testData.enum'; + +import { Components, Pages } from '../../helpers/interfaces'; + +export default (pages: Partial, components: Partial) => { + test( + qase(1, 'Dashboard page elements should be visible'), + { + annotation: { + type: 'url', + description: 'https://app.qase.io/project/IBF?case=1', + }, + }, + async () => { + const { dashboard } = pages; + const { chat, userState, aggregates, map, disasterType } = components; + + if ( + !dashboard || + !chat || + !userState || + !aggregates || + !map || + !disasterType + ) { + throw new Error('pages and components not found'); + } + // Navigate to disaster type the data was mocked for + await dashboard.navigateToFloodDisasterType(); + // Assertions + await userState.headerComponentIsVisible({ + countryName: NoTriggerDataSet.CountryName, + }); + await disasterType.topBarComponentIsVisible(); + await chat.chatColumnIsVisibleForNoTriggerState({ + firstName: NoTriggerDataSet.firstName, + lastName: NoTriggerDataSet.lastName, + }); + await aggregates.aggregateComponentIsVisible(); + await map.mapComponentIsVisible(); + }, + ); +}; diff --git a/tests/e2e/tests/DisasterTypeComponent/DisasterTypeComponentSelect.ts b/tests/e2e/tests/DisasterTypeComponent/DisasterTypeComponentSelect.ts new file mode 100644 index 0000000000..544baeb9f9 --- /dev/null +++ b/tests/e2e/tests/DisasterTypeComponent/DisasterTypeComponentSelect.ts @@ -0,0 +1,47 @@ +import test from '@playwright/test'; +import { qase } from 'playwright-qase-reporter'; +import { NoTriggerDataSet } from 'testData/testData.enum'; + +import { Components, Pages } from '../../helpers/interfaces'; + +// Test is skipped because it was flaky and more invastigation is needed to fix it +// Logged in PBI: https://dev.azure.com/redcrossnl/IBF/_workitems/edit/32127/ + +export default (pages: Partial, components: Partial) => { + test( + qase(10, 'Disaster types should be selectable'), + { + annotation: { + type: 'url', + description: 'https://app.qase.io/project/IBF?case=10', + }, + }, + async () => { + const { dashboard } = pages; + const { userState } = components; + + if (!dashboard || !userState) { + throw new Error('pages and components not found'); + } + + // Navigate between disaster types no matter the mock data + await dashboard.navigateToFloodDisasterType(); + await userState.headerComponentDisplaysCorrectDisasterType({ + countryName: NoTriggerDataSet.CountryName, + disasterName: 'floods', + }); + + await dashboard.navigateToDroughtDisasterType(); + await userState.headerComponentDisplaysCorrectDisasterType({ + countryName: NoTriggerDataSet.CountryName, + disasterName: 'drought', + }); + + await dashboard.navigateToHeavyRainDisasterType(); + await userState.headerComponentDisplaysCorrectDisasterType({ + countryName: NoTriggerDataSet.CountryName, + disasterName: 'heavy-rain', + }); + }, + ); +}; diff --git a/tests/e2e/tests/DisasterTypeComponent/DisasterTypeComponentVisible.ts b/tests/e2e/tests/DisasterTypeComponent/DisasterTypeComponentVisible.ts new file mode 100644 index 0000000000..54dafcc95b --- /dev/null +++ b/tests/e2e/tests/DisasterTypeComponent/DisasterTypeComponentVisible.ts @@ -0,0 +1,34 @@ +import test from '@playwright/test'; +import { qase } from 'playwright-qase-reporter'; +import { NoTriggerDataSet } from 'testData/testData.enum'; + +import { Components, Pages } from '../../helpers/interfaces'; + +export default (pages: Partial, components: Partial) => { + test( + qase(4, 'Disaster type component elements should be visible'), + { + annotation: { + type: 'url', + description: 'https://app.qase.io/project/IBF?case=4', + }, + }, + async () => { + const { dashboard } = pages; + const { userState, disasterType } = components; + + if (!dashboard || !userState || !disasterType) { + throw new Error('pages and components not found'); + } + + // Navigate to disaster type the data was mocked for + await dashboard.navigateToFloodDisasterType(); + // Assertions + await userState.headerComponentIsVisible({ + countryName: NoTriggerDataSet.CountryName, + }); + await disasterType.topBarComponentIsVisible(); + await disasterType.allDisasterTypeElementsArePresent(); + }, + ); +}; diff --git a/tests/e2e/tests/IBF-Dashboard/NoTriggerScenarios.spec.ts b/tests/e2e/tests/IBF-Dashboard/NoTriggerScenarios.spec.ts deleted file mode 100644 index 32423b58dc..0000000000 --- a/tests/e2e/tests/IBF-Dashboard/NoTriggerScenarios.spec.ts +++ /dev/null @@ -1,499 +0,0 @@ -import { Page, test } from '@playwright/test'; -import AggregatesComponent from 'Pages/AggregatesComponent'; -import ChatComponent from 'Pages/ChatComponent'; -import DashboardPage from 'Pages/DashboardPage'; -import DisasterTypeComponent from 'Pages/DisasterTypeComponent'; -import MapComponent from 'Pages/MapComponent'; -import TimelineComponent from 'Pages/TimelineComponent'; -import UserStateComponent from 'Pages/UserStateComponent'; -import { qase } from 'playwright-qase-reporter'; -import { NoTriggerDataSet } from 'testData/testData.enum'; - -import { - getAccessToken, - mockFloods, - resetDB, -} from '../../helpers/utility.helper'; -import LoginPage from '../../Pages/LoginPage'; - -let accessToken: string; -let sharedPage: Page; -// layers -let checkedLayers; -// Instances -let dashboard: DashboardPage; -let aggregates: AggregatesComponent; -let map: MapComponent; -let loginPage: LoginPage; -let chat: ChatComponent; -let userState: UserStateComponent; -let disasterType: DisasterTypeComponent; -let timeline: TimelineComponent; - -test.beforeAll(async ({ browser }) => { - sharedPage = await browser.newPage(); - // Initialize instances after sharedPage is assigned - dashboard = new DashboardPage(sharedPage); - aggregates = new AggregatesComponent(sharedPage); - map = new MapComponent(sharedPage); - loginPage = new LoginPage(sharedPage); - chat = new ChatComponent(sharedPage); - userState = new UserStateComponent(sharedPage); - disasterType = new DisasterTypeComponent(sharedPage); - timeline = new TimelineComponent(sharedPage); - - // Login - 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( - NoTriggerDataSet.NoTriggerScenario, - NoTriggerDataSet.CountryCode, - accessToken, - ); - - await sharedPage.goto('/'); - await loginPage.login( - NoTriggerDataSet.UserMail, - NoTriggerDataSet.UserPassword, - ); -}); - -test.afterEach(async () => { - await sharedPage.waitForTimeout(1000); -}); - -// AGGREGATES NO-TRIGGER TESTS -test( - qase( - 12, - 'Aggregates title should be dynamic upon hovering over map district', - ), - async ({ page }) => { - // Navigate to disaster type the data was mocked for - await dashboard.navigateToFloodDisasterType(); - // Assertions - await aggregates.aggregateComponentIsVisible(); - await map.clickLayerCheckbox({ layerName: 'Glofas stations' }); - await map.assertAggregateTitleOnHoverOverMap(); - await page.reload(); - }, -); - -// https://app.qase.io/project/IBF?case=6&previewMode=side&suite=7 -test( - qase(6, 'All Aggregate elements are present in no-trigger mode'), - async ({ page }) => { - // Navigate to disaster type the data was mocked for - await dashboard.navigateToFloodDisasterType(); - // Assertions - await aggregates.aggregateComponentIsVisible(); - await aggregates.aggregatesAlementsDisplayedInNoTrigger(); - await page.reload(); - }, -); - -// https://app.qase.io/project/IBF?case=13&previewMode=side&suite=7 -test( - qase(13, 'All Aggregate info buttons show on click information'), - async ({ page }) => { - // Navigate to disaster type the data was mocked for - await dashboard.navigateToFloodDisasterType(); - // Assertions - await aggregates.aggregateComponentIsVisible(); - await aggregates.validatesAggregatesInfoButtons(); - await aggregates.validateLayerPopoverExternalLink(); - await page.reload(); - }, -); - -// CHAT SECTION NO-TRIGGER TESTS -// https://app.qase.io/project/IBF?case=11&previewMode=side&suite=6 -test( - qase( - 11, - 'All Chat section action buttons can be selected in no-trigger mode', - ), - async ({ page }) => { - // Navigate to disaster type the data was mocked for - await dashboard.navigateToFloodDisasterType(); - // Assertions - await userState.headerComponentIsVisible({ - countryName: NoTriggerDataSet.CountryName, - }); - await chat.allDefaultButtonsArePresent(); - await chat.clickAndAssertAboutButton(); - await chat.clickAndAssertGuideButton(); - await chat.clickAndAssertExportViewButton(); - await chat.clickAndAssertTriggerLogButton({ - url: `/log?countryCodeISO3=${NoTriggerDataSet.CountryCode}&disasterType=floods`, - }); - await page.reload(); - }, -); - -// https://app.qase.io/project/IBF?case=5&previewMode=side&suite=6 -test( - qase(5, 'All Chat section elements are present in no-trigger mode'), - async ({ page }) => { - // Navigate to disaster type the data was mocked for - await dashboard.navigateToFloodDisasterType(); - // Assertions - await userState.headerComponentIsVisible({ - countryName: NoTriggerDataSet.CountryName, - }); - await chat.chatColumnIsVisibleForNoTriggerState({ - firstName: NoTriggerDataSet.firstName, - lastName: NoTriggerDataSet.lastName, - }); - await chat.allDefaultButtonsArePresent(); - await page.reload(); - }, -); - -// DASHBOARD NO-TRIGGER TESTS -// https://app.qase.io/project/IBF?case=1&previewMode=side&suite=2 -test( - qase(1, 'All Dashboard elements are present in no-trigger mode'), - async ({ page }) => { - // Navigate to disaster type the data was mocked for - await dashboard.navigateToFloodDisasterType(); - // Assertions - await userState.headerComponentIsVisible({ - countryName: NoTriggerDataSet.CountryName, - }); - await disasterType.topBarComponentIsVisible(); - await chat.chatColumnIsVisibleForNoTriggerState({ - firstName: NoTriggerDataSet.firstName, - lastName: NoTriggerDataSet.lastName, - }); - await aggregates.aggregateComponentIsVisible(); - await map.mapComponentIsVisible(); - await page.reload(); - }, -); - -// DISASTER TYPE NO-TRIGGER TESTS -// https://app.qase.io/project/IBF?case=4&previewMode=side&suite=5 -test( - qase(4, 'All Disaster Type elements are present in no-trigger mode'), - async ({ page }) => { - // Navigate to disaster type the data was mocked for - await dashboard.navigateToFloodDisasterType(); - // Assertions - await userState.headerComponentIsVisible({ - countryName: NoTriggerDataSet.CountryName, - }); - await disasterType.topBarComponentIsVisible(); - await disasterType.allDisasterTypeElementsArePresent(); - await page.reload(); - }, -); - -// Test is skipped because it was flaky and more invastigation is needed to fix it -// Logged in PBI: https://dev.azure.com/redcrossnl/IBF/_workitems/edit/32127/ -// https://app.qase.io/project/IBF?case=4&previewMode=side&suite=5 -test.skip( - qase(10, 'All Disaster Types can be selected in no-trigger mode'), - async ({ page }) => { - const dashboard = new DashboardPage(sharedPage); - const userState = new UserStateComponent(sharedPage); - - // Navigate between disaster types no matter the mock data - await dashboard.navigateToFloodDisasterType(); - await userState.headerComponentDisplaysCorrectDisasterType({ - countryName: NoTriggerDataSet.CountryName, - disasterName: 'floods', - }); - - await dashboard.navigateToDroughtDisasterType(); - await userState.headerComponentDisplaysCorrectDisasterType({ - countryName: NoTriggerDataSet.CountryName, - disasterName: 'drought', - }); - - await dashboard.navigateToHeavyRainDisasterType(); - await userState.headerComponentDisplaysCorrectDisasterType({ - countryName: NoTriggerDataSet.CountryName, - disasterName: 'heavy-rain', - }); - await page.reload(); - }, -); - -// MAP NO-TRIGGER TESTS -// https://app.qase.io/project/IBF?case=29&previewMode=side&suite=3 -test( - qase(29, '[No-trigger] Alert Threshold Reached is visible on the legend'), - async ({ 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(); - await map.isLegendOpen({ legendOpen: true }); - await map.assertLegendElementIsVisible({ - legendComponentName: 'Alert Threshold Reached', - }); - // Reset state in the end of the test - await page.reload(); - }, -); - -// https://app.qase.io/project/IBF?case=30&previewMode=side&suite=3 -test( - qase(30, '[No-trigger] No "Alert Threshold Reached" lines are visible'), - async ({ 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(); - await map.isLegendOpen({ legendOpen: true }); - await map.assertAlertThresholdLines({ visible: false }); - await page.reload(); - }, -); - -// https://app.qase.io/project/IBF?case=2&previewMode=side&suite=3 -test( - qase(2, 'All Map elements are present in no-trigger mode'), - async ({ page }) => { - // Navigate to disaster type the data was mocked for - await dashboard.navigateToFloodDisasterType(); - // Assertions - await userState.headerComponentIsVisible({ - countryName: NoTriggerDataSet.CountryName, - }); - await map.mapComponentIsVisible(); - await map.breadCrumbViewIsVisible({ nationalView: true }); - await map.isLegendOpen({ legendOpen: true }); - await map.isLayerMenuOpen({ layerMenuOpen: false }); - await map.assertAdminBoundariesVisible(); - await page.reload(); - }, -); - -// https://app.qase.io/project/IBF?case=32&previewMode=side&suite=3 -test( - qase(32, 'Check if (default) checked checkbox-layers show in map'), - async ({ 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 }); - - // Check if the default layers are visible - checkedLayers = await map.returnLayerCheckedCheckboxes(); - if (checkedLayers) { - await map.validateLayersAreVisibleByName({ layerNames: checkedLayers }); - } else { - throw new Error('No layers are visible'); - } - await page.reload(); - }, -); - -// https://app.qase.io/project/IBF?case=7&previewMode=side&suite=3 -test( - qase(7, 'Verify Map functionality for no-triggered mode'), - async ({ 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(); - - // Close the legend - await map.isLegendOpen({ legendOpen: true }); - await map.clickLegendHeader(); - await map.isLegendOpen({ legendOpen: false }); - - // Open the layer menu - await map.isLayerMenuOpen({ layerMenuOpen: false }); - await map.clickLayerMenu(); - await map.isLayerMenuOpen({ layerMenuOpen: true }); - - // Select and deselect the layer - await map.clickLayerMenu(); - await map.clickLayerCheckbox({ layerName: 'Red Cross branches' }); - await map.isLayerMenuOpen({ layerMenuOpen: true }); - - // Red Cross branches layer should be visible - await map.redCrossMarkersAreVisible(); - await page.reload(); - }, -); - -// https://app.qase.io/project/IBF?case=31&previewMode=side&suite=3 -test( - qase( - 31, - '[No-trigger] ONLY No trigger, medium warning, and low warning GloFAS stations should be visible', - ), - async ({ 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(); - await map.gloFASMarkersAreVisible(); - // Assert that the max warning GloFAS markers are not visible - await map.gloFASMarkersAreVisibleByWarning({ - glosfasStationStatus: 'glofas-station-max-trigger', - isVisible: false, - }); - await page.reload(); - }, -); - -// https://app.qase.io/project/IBF?case=28&previewMode=side&suite=3 -test( - qase( - 28, - '[No-trigger] GloFAS stations markers should be visible on "Legend", "Layer" and "Map"', - ), - async ({ 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(); - await map.isLegendOpen({ legendOpen: true }); - await map.isLayerMenuOpen({ layerMenuOpen: false }); - await map.clickLayerMenu(); - await map.verifyLayerCheckboxCheckedByName({ - layerName: 'Glofas stations', - }); - await map.assertLegendElementIsVisible({ - legendComponentName: 'GloFAS No action', - }); - - // GloFAS layer should be visible by default - await map.gloFASMarkersAreVisible(); - await page.reload(); - }, -); - -// 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 }) => { - // 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.validateInfoIconInteractions(); - await page.reload(); - }, -); - -// TIMELINE NO-TRIGGER TESTS -// https://app.qase.io/project/IBF?case=15&previewMode=side&suite=9 -test(qase(15, 'Timeline present in no trigger mode'), async ({ page }) => { - // Navigate to disaster type the data was mocked for - await dashboard.navigateToFloodDisasterType(); - // Assertions - await userState.headerComponentIsVisible({ - countryName: NoTriggerDataSet.CountryName, - }); - await timeline.timlineElementsAreVisible(); - await page.reload(); -}); - -// https://app.qase.io/project/IBF?case=14&previewMode=side&suite=9 -test( - qase(14, 'Timeline is deactivated in no-trigger mode'), - async ({ page }) => { - // Navigate to disaster type the data was mocked for - await dashboard.navigateToFloodDisasterType(); - // Assertions - await userState.headerComponentIsVisible({ - countryName: NoTriggerDataSet.CountryName, - }); - await timeline.timelineIsInactive(); - await page.reload(); - }, -); - -// USER STATE NO-TRIGGER TESTS -// https://app.qase.io/project/IBF?case=3&previewMode=side&suite=4 -test( - qase(3, 'All User State elements are present in no-trigger mode'), - async ({ page }) => { - // Navigate to disaster type the data was mocked for - await dashboard.navigateToFloodDisasterType(); - // Assertions - await userState.headerComponentIsVisible({ - countryName: NoTriggerDataSet.CountryName, - }); - await userState.allUserStateElementsAreVisible({ - firstName: NoTriggerDataSet.firstName, - lastName: NoTriggerDataSet.lastName, - }); - await page.reload(); - }, -); - -// https://app.qase.io/project/IBF?case=8&previewMode=side&suite=4 -test(qase(4, 'Log out from IBF-system'), async ({ page }) => { - // Navigate to disaster type the data was mocked for - await dashboard.navigateToFloodDisasterType(); - // Assertions - await userState.headerComponentIsVisible({ - countryName: NoTriggerDataSet.CountryName, - }); - await userState.logOut(); - await loginPage.loginScreenIsVisible(); - await page.reload(); -}); - -test.afterAll(async () => { - await sharedPage.close(); -}); diff --git a/tests/e2e/tests/IBF-Dashboard/TriggerScenarios.spec.ts b/tests/e2e/tests/IBF-Dashboard/TriggerScenarios.spec.ts deleted file mode 100644 index e267c7565d..0000000000 --- a/tests/e2e/tests/IBF-Dashboard/TriggerScenarios.spec.ts +++ /dev/null @@ -1,271 +0,0 @@ -import { expect, Page, test } from '@playwright/test'; -import AggregatesComponent from 'Pages/AggregatesComponent'; -import ChatComponent from 'Pages/ChatComponent'; -import DashboardPage from 'Pages/DashboardPage'; -import MapComponent from 'Pages/MapComponent'; -import UserStateComponent from 'Pages/UserStateComponent'; -import { qase } from 'playwright-qase-reporter'; -import { TriggerDataSet } from 'testData/testData.enum'; - -import { - getAccessToken, - mockFloods, - resetDB, -} from '../../helpers/utility.helper'; -import LoginPage from '../../Pages/LoginPage'; - -let accessToken: string; -let sharedPage: Page; -// Instances -let dashboard: DashboardPage; -let aggregates: AggregatesComponent; -let loginPage: LoginPage; -let chat: ChatComponent; -let userState: UserStateComponent; -let map: MapComponent; - -test.beforeAll(async ({ browser }) => { - sharedPage = await browser.newPage(); - // Initialize instances after sharedPage is assigned - dashboard = new DashboardPage(sharedPage); - aggregates = new AggregatesComponent(sharedPage); - loginPage = new LoginPage(sharedPage); - chat = new ChatComponent(sharedPage); - userState = new UserStateComponent(sharedPage); - map = new MapComponent(sharedPage); - - // Login - 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( - TriggerDataSet.TriggerScenario, - TriggerDataSet.CountryCode, - accessToken, - ); - - await sharedPage.goto('/'); - await loginPage.login(TriggerDataSet.UserMail, TriggerDataSet.UserPassword); -}); - -test.beforeEach(async () => { - await dashboard.waitForPageToBeLoadedAndStable(); -}); - -// AGGREGATES TRIGGER TESTS -// https://app.qase.io/project/IBF?case=39&previewMode=side&suite=7 -test( - qase(39, '[Trigger] Aggregated number of events should be non-zero'), - async ({ page }) => { - // Navigate to disaster type the data was mocked for - await dashboard.navigateToFloodDisasterType(); - // Assertions - await userState.headerComponentIsVisible({ - countryName: TriggerDataSet.CountryName, - }); - - // get the number of warning events and aggregated events - const aggregatesEventCount = await aggregates.getNumberOfPredictedEvents(); - - // check if the number of warning events is equal to the number of aggregated events - expect(aggregatesEventCount).toBeGreaterThan(0); - await page.reload(); - }, -); - -// https://app.qase.io/project/IBF?previewMode=side&suite=7&case=40 -test(qase(40, '[Trigger] header colour is purple'), async ({ page }) => { - // Navigate to disaster type the data was mocked for - await dashboard.navigateToFloodDisasterType(); - // Assertions - await userState.headerComponentIsVisible({ - countryName: TriggerDataSet.CountryName, - }); - - // Validate that the aggregates header is purple by class - await aggregates.validateColorOfAggregatesHeaderByClass({ - isTrigger: true, - }); - await page.reload(); -}); - -// CHAT SECTION TRIGGER TESTS -// https://app.qase.io/project/IBF?case=44&previewMode=side&suite=6 -test( - qase(44, '[Trigger] Show prediction button is clickable'), - async ({ page }) => { - // Navigate to disaster type the data was mocked for - await dashboard.navigateToFloodDisasterType(); - // Assertions - await userState.headerComponentIsVisible({ - countryName: TriggerDataSet.CountryName, - }); - await chat.chatColumnIsVisibleForTriggerState({ - firstName: TriggerDataSet.firstName, - lastName: TriggerDataSet.lastName, - }); - await chat.allDefaultButtonsArePresent(); - await chat.predictionButtonsAreActive(); - await page.reload(); - }, -); - -// https://app.qase.io/project/IBF?case=43&previewMode=side&suite=6 -test( - qase(43, '[Trigger] Amount of events should equal the aggregate number'), - async ({ page }) => { - // Navigate to disaster type the data was mocked for - await dashboard.navigateToFloodDisasterType(); - // Assertions - await userState.headerComponentIsVisible({ - countryName: TriggerDataSet.CountryName, - }); - await chat.chatColumnIsVisibleForTriggerState({ - firstName: TriggerDataSet.firstName, - lastName: TriggerDataSet.lastName, - }); - await chat.allDefaultButtonsArePresent(); - - // get the number of warning events and aggregated events - const chatEventCount = await chat.predictionButtonsAreActive(); - const aggregatesEventCount = await aggregates.getNumberOfPredictedEvents(); - - // check if the number of warning events is equal to the number of aggregated events - expect(chatEventCount).toEqual(aggregatesEventCount); - await page.reload(); - }, -); - -// https://app.qase.io/project/IBF?case=45&previewMode=side&suite=6 -test( - qase(45, '[Trigger] Info icon is clickable and opens popover'), - async ({ page }) => { - const dashboard = new DashboardPage(sharedPage); - const userState = new UserStateComponent(sharedPage); - const chat = new ChatComponent(sharedPage); - - // Navigate to disaster type the data was mocked for - await dashboard.navigateToFloodDisasterType(); - // Assertions - await userState.headerComponentIsVisible({ - countryName: TriggerDataSet.CountryName, - }); - await chat.chatColumnIsVisibleForTriggerState({ - firstName: TriggerDataSet.firstName, - lastName: TriggerDataSet.lastName, - }); - await chat.validateEventsInfoButtonsAreClickable(); - await page.reload(); - }, -); - -// MAP TRIGGER TESTS -// https://app.qase.io/project/IBF?previewMode=side&suite=3&tab=&case=37 -test( - qase( - 37, - '[Trigger] Map layer: "Flood extent" and "Exposed population" should be active by default', - ), - async ({ page }) => { - // Navigate to disaster type the data was mocked for - await dashboard.navigateToFloodDisasterType(); - // Assertions - await userState.headerComponentIsVisible({ - countryName: TriggerDataSet.CountryName, - }); - // Wait for the sharedPage to load - await dashboard.waitForLoaderToDisappear(); - - await map.mapComponentIsVisible(); - - await map.clickLayerMenu(); - await map.isLayerMenuOpen({ layerMenuOpen: true }); - await map.verifyLayerCheckboxCheckedByName({ - layerName: 'Flood extent', - }); - await map.verifyLayerRadioButtonCheckedByName({ - layerName: 'Exposed population', - }); - // Validate legend - await map.isLegendOpen({ legendOpen: true }); - await map.assertLegendElementIsVisible({ - legendComponentName: 'Flood extent', - }); - await map.assertLegendElementIsVisible({ - legendComponentName: 'Exposed population', - }); - // Validatge that the layer checked with radio button is visible on the map in this case 'Exposed population' only one such layer can be checked at a time - await map.validateAggregatePaneIsNotEmpty(); - // Validate rest of the map - await map.validateLayerIsVisibleInMapBySrcElement({ - layerName: 'flood_extent', - }); - await page.reload(); - }, -); - -// https://app.qase.io/project/IBF?previewMode=side&suite=3&tab=&case=35 -test( - qase( - 35, - '[Trigger] Flood extent legend is visible when flood extent layer is active', - ), - async ({ page }) => { - // Navigate to disaster type the data was mocked for - await dashboard.navigateToFloodDisasterType(); - // Assertions - await userState.headerComponentIsVisible({ - countryName: TriggerDataSet.CountryName, - }); - // Wait for the sharedPage to load - await dashboard.waitForLoaderToDisappear(); - - await map.mapComponentIsVisible(); - await map.isLegendOpen({ legendOpen: true }); - await map.assertLegendElementIsVisible({ - legendComponentName: 'Flood extent', - }); - await page.reload(); - }, -); - -// https://app.qase.io/project/IBF?case=38&previewMode=side&suite=3 -test( - qase( - 38, - '[Trigger] At least one red/orange/yellow GloFAS station should be visible', - ), - async ({ page }) => { - // Navigate to disaster type the data was mocked for - await dashboard.navigateToFloodDisasterType(); - // Assertions - await userState.headerComponentIsVisible({ - countryName: TriggerDataSet.CountryName, - }); - // Wait for the sharedPage to load - await dashboard.waitForLoaderToDisappear(); - - await map.mapComponentIsVisible(); - await map.isLegendOpen({ legendOpen: true }); - await map.isLayerMenuOpen({ layerMenuOpen: false }); - await map.clickLayerMenu(); - await map.verifyLayerCheckboxCheckedByName({ - layerName: 'Glofas stations', - }); - await map.assertLegendElementIsVisible({ - legendComponentName: 'GloFAS No action', - }); - - // At least one red/orange/yellow GloFAS station should be visible by default in trigger mode - await map.gloFASMarkersAreVisibleByWarning({ - glosfasStationStatus: 'glofas-station-max-trigger', - isVisible: true, - }); - await page.reload(); - }, -); - -test.afterAll(async () => { - await sharedPage.close(); -}); diff --git a/tests/e2e/tests/MapComponent/MapComponentAlertThreshold.ts b/tests/e2e/tests/MapComponent/MapComponentAlertThreshold.ts new file mode 100644 index 0000000000..6a67961d96 --- /dev/null +++ b/tests/e2e/tests/MapComponent/MapComponentAlertThreshold.ts @@ -0,0 +1,41 @@ +import test from '@playwright/test'; +import { qase } from 'playwright-qase-reporter'; +import { NoTriggerDataSet } from 'testData/testData.enum'; + +import { Components, Pages } from '../../helpers/interfaces'; + +export default (pages: Partial, components: Partial) => { + test( + qase(29, 'alert_threshold should be visible'), + { + annotation: { + type: 'url', + description: 'https://app.qase.io/project/IBF?case=29', + }, + }, + async () => { + const { dashboard } = pages; + const { userState, map } = components; + + if (!dashboard || !userState || !map) { + throw new Error('pages and components not found'); + } + + // 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(); + await map.isLegendOpen({ legendOpen: true }); + await map.assertLegendElementIsVisible({ + legendComponentName: 'Alert Threshold Reached', + }); + await map.assertAlertThresholdLines({ visible: false }); + }, + ); +}; diff --git a/tests/e2e/tests/MapComponent/MapComponentFloodExtent.ts b/tests/e2e/tests/MapComponent/MapComponentFloodExtent.ts new file mode 100644 index 0000000000..5d63b40639 --- /dev/null +++ b/tests/e2e/tests/MapComponent/MapComponentFloodExtent.ts @@ -0,0 +1,40 @@ +import test from '@playwright/test'; +import { qase } from 'playwright-qase-reporter'; +import { TriggerDataSet } from 'testData/testData.enum'; + +import { Components, Pages } from '../../helpers/interfaces'; + +export default (pages: Partial, components: Partial) => { + test( + qase(35, 'flood_extent legend should be visible'), + { + annotation: { + type: 'url', + description: 'https://app.qase.io/project/IBF?case=35', + }, + }, + async () => { + const { dashboard } = pages; + const { userState, map } = components; + + if (!dashboard || !userState || !map) { + throw new Error('pages and components not found'); + } + + // Navigate to disaster type the data was mocked for + await dashboard.navigateToFloodDisasterType(); + // Assertions + await userState.headerComponentIsVisible({ + countryName: TriggerDataSet.CountryName, + }); + // Wait for the sharedPage to load + await dashboard.waitForLoaderToDisappear(); + + await map.mapComponentIsVisible(); + await map.isLegendOpen({ legendOpen: true }); + await map.assertLegendElementIsVisible({ + legendComponentName: 'Flood extent', + }); + }, + ); +}; diff --git a/tests/e2e/tests/MapComponent/MapComponentGloFASStations.ts b/tests/e2e/tests/MapComponent/MapComponentGloFASStations.ts new file mode 100644 index 0000000000..6a54a432fe --- /dev/null +++ b/tests/e2e/tests/MapComponent/MapComponentGloFASStations.ts @@ -0,0 +1,48 @@ +import test from '@playwright/test'; +import { qase } from 'playwright-qase-reporter'; +import { NoTriggerDataSet } from 'testData/testData.enum'; + +import { Components, Pages } from '../../helpers/interfaces'; + +export default (pages: Partial, components: Partial) => { + test( + qase(28, 'glofas_stations should be visible'), + { + annotation: { + type: 'url', + description: 'https://app.qase.io/project/IBF?case=28', + }, + }, + async () => { + const { dashboard } = pages; + const { userState, map } = components; + + if (!dashboard || !userState || !map) { + throw new Error('pages and components not found'); + } + + // 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(); + await map.isLegendOpen({ legendOpen: true }); + await map.isLayerMenuOpen({ layerMenuOpen: false }); + await map.clickLayerMenu(); + await map.verifyLayerCheckboxCheckedByName({ + layerName: 'Glofas stations', + }); + await map.assertLegendElementIsVisible({ + legendComponentName: 'GloFAS No action', + }); + + // GloFAS layer should be visible by default + await map.gloFASMarkersAreVisible(); + }, + ); +}; diff --git a/tests/e2e/tests/MapComponent/MapComponentGloFASStationsTrigger.ts b/tests/e2e/tests/MapComponent/MapComponentGloFASStationsTrigger.ts new file mode 100644 index 0000000000..c07cda7788 --- /dev/null +++ b/tests/e2e/tests/MapComponent/MapComponentGloFASStationsTrigger.ts @@ -0,0 +1,54 @@ +import test from '@playwright/test'; +import { qase } from 'playwright-qase-reporter'; +import { TriggerDataSet } from 'testData/testData.enum'; + +import { Components, Pages } from '../../helpers/interfaces'; + +export default (pages: Partial, components: Partial) => { + test( + qase(38, 'Trigger GloFAS station(s) should be visible'), + { + annotation: { + type: 'url', + description: 'https://app.qase.io/project/IBF?case=38', + }, + }, + async () => { + const { dashboard } = pages; + const { userState, map } = components; + + if (!dashboard || !userState || !map) { + throw new Error('pages and components not found'); + } + + // Navigate to disaster type the data was mocked for + await dashboard.navigateToFloodDisasterType(); + // Assertions + await userState.headerComponentIsVisible({ + countryName: TriggerDataSet.CountryName, + }); + // Wait for the page to load + await dashboard.waitForLoaderToDisappear(); + + await map.mapComponentIsVisible(); + await map.isLegendOpen({ legendOpen: true }); + await map.isLayerMenuOpen({ layerMenuOpen: false }); + await map.clickLayerMenu(); + await map.verifyLayerCheckboxCheckedByName({ + layerName: 'Glofas stations', + }); + await map.assertLegendElementIsVisible({ + legendComponentName: 'GloFAS No action', + }); + + // GloFAS layer should be visible by default + await map.gloFASMarkersAreVisible(); + + // Assert that the max warning GloFAS markers are not visible + await map.gloFASMarkersAreVisibleByWarning({ + glosfasStationStatus: 'glofas-station-max-trigger', + isVisible: true, + }); + }, + ); +}; diff --git a/tests/e2e/tests/MapComponent/MapComponentGloFASStationsWarning.ts b/tests/e2e/tests/MapComponent/MapComponentGloFASStationsWarning.ts new file mode 100644 index 0000000000..8c2830e2ab --- /dev/null +++ b/tests/e2e/tests/MapComponent/MapComponentGloFASStationsWarning.ts @@ -0,0 +1,54 @@ +import test from '@playwright/test'; +import { qase } from 'playwright-qase-reporter'; +import { NoTriggerDataSet } from 'testData/testData.enum'; + +import { Components, Pages } from '../../helpers/interfaces'; + +export default (pages: Partial, components: Partial) => { + test( + qase(31, 'Trigger GloFAS station(s) should not be visible'), + { + annotation: { + type: 'url', + description: 'https://app.qase.io/project/IBF?case=31', + }, + }, + async () => { + const { dashboard } = pages; + const { userState, map } = components; + + if (!dashboard || !userState || !map) { + throw new Error('pages and components not found'); + } + + // 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(); + await map.isLegendOpen({ legendOpen: true }); + await map.isLayerMenuOpen({ layerMenuOpen: false }); + await map.clickLayerMenu(); + await map.verifyLayerCheckboxCheckedByName({ + layerName: 'Glofas stations', + }); + await map.assertLegendElementIsVisible({ + legendComponentName: 'GloFAS No action', + }); + + // GloFAS layer should be visible by default + await map.gloFASMarkersAreVisible(); + + // Assert that the max warning GloFAS markers are not visible + await map.gloFASMarkersAreVisibleByWarning({ + glosfasStationStatus: 'glofas-station-max-trigger', + isVisible: false, + }); + }, + ); +}; diff --git a/tests/e2e/tests/MapComponent/MapComponentInfoPopover.ts b/tests/e2e/tests/MapComponent/MapComponentInfoPopover.ts new file mode 100644 index 0000000000..9a198367ec --- /dev/null +++ b/tests/e2e/tests/MapComponent/MapComponentInfoPopover.ts @@ -0,0 +1,43 @@ +import test from '@playwright/test'; +import { qase } from 'playwright-qase-reporter'; +import { NoTriggerDataSet } from 'testData/testData.enum'; + +import { Components, Pages } from '../../helpers/interfaces'; + +export default (pages: Partial, components: Partial) => { + test( + qase(33, 'Info icon should open popover on click'), + { + annotation: { + type: 'url', + description: 'https://app.qase.io/project/IBF?case=33', + }, + }, + async () => { + const { dashboard } = pages; + const { userState, map } = components; + + if (!dashboard || !userState || !map) { + throw new Error('pages and components not found'); + } + + // 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.validateInfoIconInteractions(); + }, + ); +}; diff --git a/tests/e2e/tests/MapComponent/MapComponentInteractive.ts b/tests/e2e/tests/MapComponent/MapComponentInteractive.ts new file mode 100644 index 0000000000..396b95ce1a --- /dev/null +++ b/tests/e2e/tests/MapComponent/MapComponentInteractive.ts @@ -0,0 +1,56 @@ +import test from '@playwright/test'; +import { qase } from 'playwright-qase-reporter'; +import { NoTriggerDataSet } from 'testData/testData.enum'; + +import { Components, Pages } from '../../helpers/interfaces'; + +// REFACTOR: break down the test into separate tests +// for legend, layer menu, and red cross branches + +export default (pages: Partial, components: Partial) => { + test( + qase(7, 'Map component should be interactive'), + { + annotation: { + type: 'url', + description: 'https://app.qase.io/project/IBF?case=7', + }, + }, + async () => { + const { dashboard } = pages; + const { userState, map } = components; + + if (!dashboard || !userState || !map) { + throw new Error('pages and components not found'); + } + + // 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(); + + // Close the legend + await map.isLegendOpen({ legendOpen: true }); + await map.clickLegendHeader(); + await map.isLegendOpen({ legendOpen: false }); + + // Open the layer menu + await map.isLayerMenuOpen({ layerMenuOpen: false }); + await map.clickLayerMenu(); + await map.isLayerMenuOpen({ layerMenuOpen: true }); + + // Select and deselect the layer + await map.clickLayerMenu(); + await map.clickLayerCheckbox({ layerName: 'Red Cross branches' }); + await map.isLayerMenuOpen({ layerMenuOpen: true }); + + // Red Cross branches layer should be visible + await map.redCrossMarkersAreVisible(); + }, + ); +}; diff --git a/tests/e2e/tests/MapComponent/MapComponentLayersDefault.ts b/tests/e2e/tests/MapComponent/MapComponentLayersDefault.ts new file mode 100644 index 0000000000..dfc4f8ec38 --- /dev/null +++ b/tests/e2e/tests/MapComponent/MapComponentLayersDefault.ts @@ -0,0 +1,59 @@ +import test from '@playwright/test'; +import { qase } from 'playwright-qase-reporter'; +import { TriggerDataSet } from 'testData/testData.enum'; + +import { Components, Pages } from '../../helpers/interfaces'; + +export default (pages: Partial, components: Partial) => { + test( + qase(37, 'flood_extent and exposed_population should be active by default'), + { + annotation: { + type: 'url', + description: 'https://app.qase.io/project/IBF?case=37', + }, + }, + async () => { + const { dashboard } = pages; + const { userState, map } = components; + + if (!dashboard || !userState || !map) { + throw new Error('pages and components not found'); + } + + // Navigate to disaster type the data was mocked for + await dashboard.navigateToFloodDisasterType(); + // Assertions + await userState.headerComponentIsVisible({ + countryName: TriggerDataSet.CountryName, + }); + // Wait for the sharedPage to load + await dashboard.waitForLoaderToDisappear(); + + await map.mapComponentIsVisible(); + + await map.clickLayerMenu(); + await map.isLayerMenuOpen({ layerMenuOpen: true }); + await map.verifyLayerCheckboxCheckedByName({ + layerName: 'Flood extent', + }); + await map.verifyLayerRadioButtonCheckedByName({ + layerName: 'Exposed population', + }); + // Validate legend + await map.isLegendOpen({ legendOpen: true }); + await map.assertLegendElementIsVisible({ + legendComponentName: 'Flood extent', + }); + await map.assertLegendElementIsVisible({ + legendComponentName: 'Exposed population', + }); + // Validate that the layer checked with radio button is visible on the map in this case 'Exposed population' only one such layer can be checked at a time + await map.validateAggregatePaneIsNotEmpty(); + // Validate rest of the map + await map.validateLayerIsVisibleInMapBySrcElement({ + layerName: 'flood_extent', + }); + }, + ); +}; diff --git a/tests/e2e/tests/MapComponent/MapComponentLayersVisible.ts b/tests/e2e/tests/MapComponent/MapComponentLayersVisible.ts new file mode 100644 index 0000000000..3806953de2 --- /dev/null +++ b/tests/e2e/tests/MapComponent/MapComponentLayersVisible.ts @@ -0,0 +1,48 @@ +import test from '@playwright/test'; +import { qase } from 'playwright-qase-reporter'; +import { NoTriggerDataSet } from 'testData/testData.enum'; + +import { Components, Pages } from '../../helpers/interfaces'; + +export default (pages: Partial, components: Partial) => { + test( + qase(32, 'Map should show active layers'), + { + annotation: { + type: 'url', + description: 'https://app.qase.io/project/IBF?case=32', + }, + }, + async () => { + const { dashboard } = pages; + const { userState, map } = components; + + if (!dashboard || !userState || !map) { + throw new Error('pages and components not found'); + } + + // 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 }); + + // Check if the default layers are visible + const activeLayers = await map.returnLayerCheckedCheckboxes(); + if (activeLayers) { + await map.validateLayersAreVisibleByName({ layerNames: activeLayers }); + } else { + throw new Error('No layers are visible'); + } + }, + ); +}; diff --git a/tests/e2e/tests/MapComponent/MapComponentVisible.ts b/tests/e2e/tests/MapComponent/MapComponentVisible.ts new file mode 100644 index 0000000000..48f86fe0b2 --- /dev/null +++ b/tests/e2e/tests/MapComponent/MapComponentVisible.ts @@ -0,0 +1,37 @@ +import test from '@playwright/test'; +import { qase } from 'playwright-qase-reporter'; +import { NoTriggerDataSet } from 'testData/testData.enum'; + +import { Components, Pages } from '../../helpers/interfaces'; + +export default (pages: Partial, components: Partial) => { + test( + qase(2, 'Map component elements should be visible'), + { + annotation: { + type: 'url', + description: 'https://app.qase.io/project/IBF?case=2', + }, + }, + async () => { + const { dashboard } = pages; + const { userState, map } = components; + + if (!dashboard || !userState || !map) { + throw new Error('pages and components not found'); + } + + // Navigate to disaster type the data was mocked for + await dashboard.navigateToFloodDisasterType(); + // Assertions + await userState.headerComponentIsVisible({ + countryName: NoTriggerDataSet.CountryName, + }); + await map.mapComponentIsVisible(); + await map.breadCrumbViewIsVisible({ nationalView: true }); + await map.isLegendOpen({ legendOpen: true }); + await map.isLayerMenuOpen({ layerMenuOpen: false }); + await map.assertAdminBoundariesVisible(); + }, + ); +}; diff --git a/tests/e2e/tests/ScenarioNoTrigger.spec.ts b/tests/e2e/tests/ScenarioNoTrigger.spec.ts new file mode 100644 index 0000000000..9d9cf7f1ae --- /dev/null +++ b/tests/e2e/tests/ScenarioNoTrigger.spec.ts @@ -0,0 +1,118 @@ +import { Page, test } from '@playwright/test'; +import { Components, Pages } from 'helpers/interfaces'; +import AggregatesComponent from 'Pages/AggregatesComponent'; +import ChatComponent from 'Pages/ChatComponent'; +import DashboardPage from 'Pages/DashboardPage'; +import DisasterTypeComponent from 'Pages/DisasterTypeComponent'; +import MapComponent from 'Pages/MapComponent'; +import TimelineComponent from 'Pages/TimelineComponent'; +import UserStateComponent from 'Pages/UserStateComponent'; +import { NoTriggerDataSet } from 'testData/testData.enum'; + +import { getAccessToken, mockFloods, resetDB } from '../helpers/utility.helper'; +import LoginPage from '../Pages/LoginPage'; +import AggregateComponentButtonClick from './AggregatesComponent/AggregateComponentButtonClick'; +import AggregateComponentTitleHover from './AggregatesComponent/AggregateComponentTitleHover'; +import AggregatesComponentVisible from './AggregatesComponent/AggregatesComponentVisible'; +import ChatComponentButtonClick from './ChatComponent/ChatComponentButtonClick'; +import ChatComponentVisible from './ChatComponent/ChatComponentVisible'; +import DashboardPageVisible from './DashboardPage/DashboardPageVisible'; +import DisasterTypeComponentSelect from './DisasterTypeComponent/DisasterTypeComponentSelect'; +import DisasterTypeComponentVisible from './DisasterTypeComponent/DisasterTypeComponentVisible'; +import MapComponentAlertThreshold from './MapComponent/MapComponentAlertThreshold'; +import MapComponentGloFASStations from './MapComponent/MapComponentGloFASStations'; +import MapComponentGloFASStationsWarning from './MapComponent/MapComponentGloFASStationsWarning'; +import MapComponentInteractive from './MapComponent/MapComponentInteractive'; +import MapComponentLayersVisible from './MapComponent/MapComponentLayersVisible'; +import MapComponentVisible from './MapComponent/MapComponentVisible'; +import TimelineComponentDisabled from './TimelineComponent/TimelineComponentDisabled'; +import TimelineComponentVisible from './TimelineComponent/TimelineComponentVisible'; +import UserStateComponentLogout from './UserStateComponent/UserStateComponentLogout'; +import UserStateComponentVisible from './UserStateComponent/UserStateComponentVisible'; + +let accessToken: string; +let page: Page; +// Declare pages and components +const pages: Partial = {}; +const components: Partial = {}; + +test.describe('Scenario: No Trigger', () => { + test.beforeAll(async ({ browser }) => { + page = await browser.newPage(); + // Initialize pages and components after sharedPage is assigned + pages.login = new LoginPage(page); + pages.dashboard = new DashboardPage(page); + components.map = new MapComponent(page); + components.userState = new UserStateComponent(page); + components.aggregates = new AggregatesComponent(page); + components.chat = new ChatComponent(page); + components.disasterType = new DisasterTypeComponent(page); + components.timeline = new TimelineComponent(page); + + // Reset the database + accessToken = await getAccessToken(); + await resetDB(accessToken); + + // Load a mock scenario + // We should maybe create one mock for all different disaster types for now we can just use floods + await mockFloods( + NoTriggerDataSet.NoTriggerScenario, + NoTriggerDataSet.CountryCode, + accessToken, + ); + + await page.goto('/'); + // Login into the portal + await pages.login.login( + NoTriggerDataSet.UserMail, + NoTriggerDataSet.UserPassword, + ); + }); + + test.beforeEach(async ({ page }) => { + await page.reload(); + }); + + test.afterAll(async () => { + await page.close(); + }); + + test.describe('DashboardPage', () => { + DashboardPageVisible(pages, components); + }); + + test.describe('MapComponent', () => { + MapComponentVisible(pages, components); + MapComponentInteractive(pages, components); + MapComponentLayersVisible(pages, components); + MapComponentAlertThreshold(pages, components); + MapComponentGloFASStations(pages, components); + MapComponentGloFASStationsWarning(pages, components); + }); + + test.describe('UserStateComponent', () => { + UserStateComponentVisible(pages, components); + UserStateComponentLogout(pages, components); + }); + + test.describe('AggregatesComponent', () => { + AggregatesComponentVisible(pages, components); + AggregateComponentTitleHover(pages, components); + AggregateComponentButtonClick(pages, components); + }); + + test.describe('ChatComponent', () => { + ChatComponentVisible(pages, components); + ChatComponentButtonClick(pages, components); + }); + + test.describe('DisasterTypeComponent', () => { + DisasterTypeComponentVisible(pages, components); + DisasterTypeComponentSelect(pages, components); + }); + + test.describe('TimelineComponent', () => { + TimelineComponentVisible(pages, components); + TimelineComponentDisabled(pages, components); + }); +}); diff --git a/tests/e2e/tests/ScenarioTrigger.spec.ts b/tests/e2e/tests/ScenarioTrigger.spec.ts new file mode 100644 index 0000000000..7cbdac976d --- /dev/null +++ b/tests/e2e/tests/ScenarioTrigger.spec.ts @@ -0,0 +1,86 @@ +import { Page, test } from '@playwright/test'; +import { Components, Pages } from 'helpers/interfaces'; +import AggregatesComponent from 'Pages/AggregatesComponent'; +import ChatComponent from 'Pages/ChatComponent'; +import DashboardPage from 'Pages/DashboardPage'; +import DisasterTypeComponent from 'Pages/DisasterTypeComponent'; +import MapComponent from 'Pages/MapComponent'; +import TimelineComponent from 'Pages/TimelineComponent'; +import UserStateComponent from 'Pages/UserStateComponent'; +import { TriggerDataSet } from 'testData/testData.enum'; + +import { getAccessToken, mockFloods, resetDB } from '../helpers/utility.helper'; +import LoginPage from '../Pages/LoginPage'; +import AggregateComponentEventCount from './AggregatesComponent/AggregateComponentEventCount'; +import AggregateComponentHeaderColour from './AggregatesComponent/AggregateComponentHeaderColour'; +import ChatComponentEventClick from './ChatComponent/ChatComponentEventClick'; +import ChatComponentEventCount from './ChatComponent/ChatComponentEventCount'; +import ChatComponentInfoPopover from './ChatComponent/ChatComponentInfoPopover'; +import MapComponentFloodExtent from './MapComponent/MapComponentFloodExtent'; +import MapComponentGloFASStationsTrigger from './MapComponent/MapComponentGloFASStationsTrigger'; +import MapComponentLayersDefault from './MapComponent/MapComponentLayersDefault'; + +let accessToken: string; +let page: Page; +// Declare pages and components +const pages: Partial = {}; +const components: Partial = {}; + +test.describe('Scenario: Trigger', () => { + test.beforeAll(async ({ browser }) => { + page = await browser.newPage(); + // Initialize pages and components after sharedPage is assigned + pages.login = new LoginPage(page); + pages.dashboard = new DashboardPage(page); + components.map = new MapComponent(page); + components.userState = new UserStateComponent(page); + components.aggregates = new AggregatesComponent(page); + components.chat = new ChatComponent(page); + components.disasterType = new DisasterTypeComponent(page); + components.timeline = new TimelineComponent(page); + + // Reset the database + accessToken = await getAccessToken(); + await resetDB(accessToken); + + // Load a mock scenario + // We should maybe create one mock for all different disaster types for now we can just use floods + await mockFloods( + TriggerDataSet.TriggerScenario, + TriggerDataSet.CountryCode, + accessToken, + ); + + await page.goto('/'); + // Login into the portal + await pages.login.login( + TriggerDataSet.UserMail, + TriggerDataSet.UserPassword, + ); + }); + + test.beforeEach(async ({ page }) => { + await page.goto('/'); + }); + + test.afterAll(async () => { + await page.close(); + }); + + test.describe('MapComponent', () => { + MapComponentLayersDefault(pages, components); + MapComponentFloodExtent(pages, components); + MapComponentGloFASStationsTrigger(pages, components); + }); + + test.describe('AggregatesComponent', () => { + AggregateComponentEventCount(pages, components); + AggregateComponentHeaderColour(pages, components); + }); + + test.describe('ChatComponent', () => { + ChatComponentEventClick(pages, components); + ChatComponentEventCount(pages, components); + ChatComponentInfoPopover(pages, components); + }); +}); diff --git a/tests/e2e/tests/TimelineComponent/TimelineComponentDisabled.ts b/tests/e2e/tests/TimelineComponent/TimelineComponentDisabled.ts new file mode 100644 index 0000000000..f5c0c77886 --- /dev/null +++ b/tests/e2e/tests/TimelineComponent/TimelineComponentDisabled.ts @@ -0,0 +1,33 @@ +import test from '@playwright/test'; +import { qase } from 'playwright-qase-reporter'; +import { NoTriggerDataSet } from 'testData/testData.enum'; + +import { Components, Pages } from '../../helpers/interfaces'; + +export default (pages: Partial, components: Partial) => { + test( + qase(14, 'Timeline should be disabled'), + { + annotation: { + type: 'url', + description: 'https://app.qase.io/project/IBF?case=14', + }, + }, + async () => { + const { dashboard } = pages; + const { userState, timeline } = components; + + if (!dashboard || !userState || !timeline) { + throw new Error('pages and components not found'); + } + + // Navigate to disaster type the data was mocked for + await dashboard.navigateToFloodDisasterType(); + // Assertions + await userState.headerComponentIsVisible({ + countryName: NoTriggerDataSet.CountryName, + }); + await timeline.timelineIsInactive(); + }, + ); +}; diff --git a/tests/e2e/tests/TimelineComponent/TimelineComponentVisible.ts b/tests/e2e/tests/TimelineComponent/TimelineComponentVisible.ts new file mode 100644 index 0000000000..d7748624c3 --- /dev/null +++ b/tests/e2e/tests/TimelineComponent/TimelineComponentVisible.ts @@ -0,0 +1,33 @@ +import test from '@playwright/test'; +import { qase } from 'playwright-qase-reporter'; +import { NoTriggerDataSet } from 'testData/testData.enum'; + +import { Components, Pages } from '../../helpers/interfaces'; + +export default (pages: Partial, components: Partial) => { + test( + qase(15, 'Timeline component elements should be visible'), + { + annotation: { + type: 'url', + description: 'https://app.qase.io/project/IBF?case=15', + }, + }, + async () => { + const { dashboard } = pages; + const { userState, timeline } = components; + + if (!dashboard || !userState || !timeline) { + throw new Error('pages and components not found'); + } + + // Navigate to disaster type the data was mocked for + await dashboard.navigateToFloodDisasterType(); + // Assertions + await userState.headerComponentIsVisible({ + countryName: NoTriggerDataSet.CountryName, + }); + await timeline.timlineElementsAreVisible(); + }, + ); +}; diff --git a/tests/e2e/tests/UserStateComponent/UserStateComponentLogout.ts b/tests/e2e/tests/UserStateComponent/UserStateComponentLogout.ts new file mode 100644 index 0000000000..b57441bfc9 --- /dev/null +++ b/tests/e2e/tests/UserStateComponent/UserStateComponentLogout.ts @@ -0,0 +1,34 @@ +import test from '@playwright/test'; +import { qase } from 'playwright-qase-reporter'; +import { NoTriggerDataSet } from 'testData/testData.enum'; + +import { Components, Pages } from '../../helpers/interfaces'; + +export default (pages: Partial, components: Partial) => { + test( + qase(4, 'Logout should load login page'), + { + annotation: { + type: 'url', + description: 'https://app.qase.io/project/IBF?case=4', + }, + }, + async () => { + const { login, dashboard } = pages; + const { userState } = components; + + if (!login || !dashboard || !userState) { + throw new Error('pages and components not found'); + } + + // Navigate to disaster type the data was mocked for + await dashboard.navigateToFloodDisasterType(); + // Assertions + await userState.headerComponentIsVisible({ + countryName: NoTriggerDataSet.CountryName, + }); + await userState.logOut(); + await login.loginScreenIsVisible(); + }, + ); +}; diff --git a/tests/e2e/tests/UserStateComponent/UserStateComponentVisible.ts b/tests/e2e/tests/UserStateComponent/UserStateComponentVisible.ts new file mode 100644 index 0000000000..f0a0a20baa --- /dev/null +++ b/tests/e2e/tests/UserStateComponent/UserStateComponentVisible.ts @@ -0,0 +1,36 @@ +import test from '@playwright/test'; +import { qase } from 'playwright-qase-reporter'; +import { NoTriggerDataSet } from 'testData/testData.enum'; + +import { Components, Pages } from '../../helpers/interfaces'; + +export default (pages: Partial, components: Partial) => { + test( + qase(3, 'User state component elements should be visible'), + { + annotation: { + type: 'url', + description: 'https://app.qase.io/project/IBF?case=3', + }, + }, + async () => { + const { dashboard } = pages; + const { userState } = components; + + if (!dashboard || !userState) { + throw new Error('pages and components not found'); + } + + // Navigate to disaster type the data was mocked for + await dashboard.navigateToFloodDisasterType(); + // Assertions + await userState.headerComponentIsVisible({ + countryName: NoTriggerDataSet.CountryName, + }); + await userState.allUserStateElementsAreVisible({ + firstName: NoTriggerDataSet.firstName, + lastName: NoTriggerDataSet.lastName, + }); + }, + ); +}; From 2c5ec06d134f8eb223ae1091b30dd3adc6fbd5b5 Mon Sep 17 00:00:00 2001 From: Gulfaraz Rahman Date: Wed, 15 Jan 2025 13:21:46 +0100 Subject: [PATCH 2/3] test: use 1 index --- tests/e2e/Pages/MapComponent.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/e2e/Pages/MapComponent.ts b/tests/e2e/Pages/MapComponent.ts index f98964e689..1e84d3ab5a 100644 --- a/tests/e2e/Pages/MapComponent.ts +++ b/tests/e2e/Pages/MapComponent.ts @@ -372,7 +372,7 @@ class MapComponent extends DashboardPage { if (isVisible) { const markersCount = await glofasMarker.count(); - const nthSelector = this.getRandomInt(0, markersCount - 1); + const nthSelector = this.getRandomInt(1, markersCount); expect(markersCount).toBeGreaterThan(0); await expect(glofasMarker.nth(nthSelector)).toBeVisible(); From 91c86a044d08fee656aa6344b4915efa7128dab3 Mon Sep 17 00:00:00 2001 From: Gulfaraz Rahman Date: Wed, 15 Jan 2025 13:29:50 +0100 Subject: [PATCH 3/3] refactor: use goto instead of reload --- tests/e2e/tests/ScenarioNoTrigger.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/e2e/tests/ScenarioNoTrigger.spec.ts b/tests/e2e/tests/ScenarioNoTrigger.spec.ts index 9d9cf7f1ae..b314c423e5 100644 --- a/tests/e2e/tests/ScenarioNoTrigger.spec.ts +++ b/tests/e2e/tests/ScenarioNoTrigger.spec.ts @@ -70,7 +70,7 @@ test.describe('Scenario: No Trigger', () => { }); test.beforeEach(async ({ page }) => { - await page.reload(); + await page.goto('/'); }); test.afterAll(async () => {