Skip to content

Commit

Permalink
prototype: e2e multi-disaster-type setup AB#32771
Browse files Browse the repository at this point in the history
  • Loading branch information
jannisvisser committed Jan 22, 2025
1 parent f1ef7cc commit 20b24eb
Show file tree
Hide file tree
Showing 11 changed files with 92 additions and 80 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export class LinesDataService {
'GEOMETRYCOLLECTION(${line.wkt})')`,
};
});
await this.linesDataRepository.save(dataArray, { chunk: 100 });
await this.linesDataRepository.save(dataArray, { chunk: 1000 });
}

public async uploadCsv(
Expand Down
9 changes: 5 additions & 4 deletions tests/e2e/Pages/AggregatesComponent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ class AggregatesComponent extends DashboardPage {
await expect(this.aggregateSectionColumn).toContainText('National View');
}

async aggregatesAlementsDisplayedInNoTrigger() {
async aggregatesElementsDisplayedInNoTrigger() {
// Wait for the page to load
await this.page.waitForSelector('[data-testid="loader"]', {
state: 'hidden',
Expand All @@ -73,17 +73,18 @@ class AggregatesComponent extends DashboardPage {
const iconLayerCount = await this.aggregatesInfoIcon.count();

// Basic Assertions
expect(headerTextModified).toBe('National View 0 Predicted Flood(s)');
expect(headerTextModified).toBe('National View 0 Predicted Drought(s)'); // TODO: make Flood(s) disaster-type agnostic
await expect(this.aggreagtesTitleInfoIcon).toBeVisible();
expect(layerCount).toBe(5);
expect(iconLayerCount).toBe(5);
expect(layerCount).toBe(5); // TODO: this is UGA floods specific
expect(iconLayerCount).toBe(5); // TODO: this is UGA floods specific

// Loop through the layers and check if they are present with correct data
for (const affectedNumber of affectedNumbers) {
const affectedNumberText = await affectedNumber.textContent();
expect(affectedNumberText).toContain('0');
}
// Loop through the layers and check if they are present with correct names
// TODO: expectedLayersNames is UGA floods specific
for (const layerName of expectedLayersNames) {
const layerLocator = this.aggregatesLayerRow.locator(`text=${layerName}`);
await expect(layerLocator).toBeVisible();
Expand Down
12 changes: 7 additions & 5 deletions tests/e2e/Pages/ChatComponent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,9 @@ import * as os from 'os';
import { Locator, Page } from 'playwright';

import EnglishTranslations from '../../../interfaces/IBF-dashboard/src/assets/i18n/en.json';
import { NoTriggerDataSet } from '../testData/testData.enum';
import { DisasterTypeEnum } from '../tests/ScenarioNoTrigger.spec';
import DashboardPage from './DashboardPage';

const chatDialogueContentWelcomeNoTrigger =
EnglishTranslations['chat-component'][NoTriggerDataSet.DisasterType][
'no-event-no-trigger'
].welcome;
const chatDialogueWarnLabel =
EnglishTranslations['chat-component'].common['warn-label'].message;
const eventTooltipContent =
Expand Down Expand Up @@ -62,9 +58,11 @@ class ChatComponent extends DashboardPage {
async chatColumnIsVisibleForNoTriggerState({
firstName,
lastName,
disasterType,
}: {
firstName: string;
lastName: string;
disasterType: DisasterTypeEnum;
}) {
// String cleaning to remove <strong> tags and replace placeholders with actual values
const cleanedString = chatDialogueWarnLabel.replace(/<\/?strong>/g, '');
Expand All @@ -79,6 +77,10 @@ class ChatComponent extends DashboardPage {
const chatDialogueContent = cleanedString
.replace('{{ name }}', `${firstName} ${lastName}`)
.replace('{{lastModelRunDate}}', lastModelRunDate);

const chatDialogueContentWelcomeNoTrigger =
EnglishTranslations['chat-component'][disasterType]['no-event-no-trigger']
.welcome;
const chatDialogueContentNoAlerts =
chatDialogueContentWelcomeNoTrigger.replace(/<\/?strong>/g, '');

Expand Down
4 changes: 2 additions & 2 deletions tests/e2e/testData/testData.enum.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
export enum NoTriggerDataSet {
NoTriggerScenario = 'no-trigger',
DisasterType = 'floods', // Only 'floods' works for now
DisasterType = 'drought', // Only 'floods' works for now
CountryCode = 'UGA',
CountryName = 'Uganda',
UserMail = 'uganda@redcross.nl',
Expand All @@ -11,7 +11,7 @@ export enum NoTriggerDataSet {

export enum TriggerDataSet {
TriggerScenario = 'trigger',
DisasterType = 'floods', // Only 'floods' works for now
DisasterType = 'drought', // Only 'floods' works for now
CountryCode = 'UGA',
CountryName = 'Uganda',
UserMail = 'uganda@redcross.nl',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export default (
await dashboard.navigateToDisasterType(disasterType);
// Assertions
await aggregates.aggregateComponentIsVisible();
await aggregates.aggregatesAlementsDisplayedInNoTrigger();
await aggregates.aggregatesElementsDisplayedInNoTrigger();

// Reload the page to prepare for next test
await dashboard.page.goto('/');
Expand Down
3 changes: 2 additions & 1 deletion tests/e2e/tests/DashboardPage/DashboardPageVisible.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export default (
disasterType: string,
) => {
test(
qase(1, 'Dashboard page elements should be visible'),
qase(1, `Dashboard page elements should be visible - ${disasterType}`),
{
annotation: {
type: 'url',
Expand Down Expand Up @@ -47,6 +47,7 @@ export default (
await chat.chatColumnIsVisibleForNoTriggerState({
firstName: NoTriggerDataSet.firstName,
lastName: NoTriggerDataSet.lastName,
disasterType,
});
await aggregates.aggregateComponentIsVisible();
await map.mapComponentIsVisible();
Expand Down
11 changes: 9 additions & 2 deletions tests/e2e/tests/MapComponent/MapComponentGloFASStations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@ import { qase } from 'playwright-qase-reporter';
import { NoTriggerDataSet } from 'testData/testData.enum';

import { Components, Pages } from '../../helpers/interfaces';
import { DisasterTypeEnum } from '../ScenarioNoTrigger.spec';

export default (
pages: Partial<Pages>,
components: Partial<Components>,
disasterType: string,
disasterType: DisasterTypeEnum,
) => {
test(
qase(28, 'glofas_stations should be visible'),
qase(28, `glofas_stations should be visible - ${disasterType}`),
{
annotation: {
type: 'url',
Expand All @@ -25,6 +26,12 @@ export default (
throw new Error('pages and components not found');
}

// PROTOTYPE EXAMPLE of disaster-type specific test skip
if (disasterType !== DisasterTypeEnum.Floods) {
console.log('Skipping test for disaster type:', disasterType);
return;
}

// Navigate to disaster type the data was mocked for
await dashboard.navigateToDisasterType(disasterType);
// Assertions
Expand Down
5 changes: 3 additions & 2 deletions tests/e2e/tests/MapComponent/MapComponentInteractive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,18 @@ import { qase } from 'playwright-qase-reporter';
import { NoTriggerDataSet } from 'testData/testData.enum';

import { Components, Pages } from '../../helpers/interfaces';
import { DisasterTypeEnum } from '../ScenarioNoTrigger.spec';

// REFACTOR: break down the test into separate tests
// for legend, layer menu, and red cross branches

export default (
pages: Partial<Pages>,
components: Partial<Components>,
disasterType: string,
disasterType: DisasterTypeEnum,
) => {
test(
qase(7, 'Map component should be interactive'),
qase(7, `Map component should be interactive - ${disasterType}`),
{
annotation: {
type: 'url',
Expand Down
9 changes: 7 additions & 2 deletions tests/e2e/tests/MapComponent/MapComponentVisible.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@ import { qase } from 'playwright-qase-reporter';
import { NoTriggerDataSet } from 'testData/testData.enum';

import { Components, Pages } from '../../helpers/interfaces';
import { DisasterTypeEnum } from '../ScenarioNoTrigger.spec';

export default (
pages: Partial<Pages>,
components: Partial<Components>,
disasterType: string,
) => {
test(
qase(2, 'Map component elements should be visible'),
qase(2, `Map component elements should be visible - ${disasterType}`),
{
annotation: {
type: 'url',
Expand All @@ -32,7 +33,11 @@ export default (
countryName: NoTriggerDataSet.CountryName,
});
await map.mapComponentIsVisible();
await map.breadCrumbViewIsVisible({ nationalView: true });

// PROTOTYPE EXAMPLE of disaster-type specific assertion
if (disasterType === DisasterTypeEnum.Floods) {
await map.breadCrumbViewIsVisible({ nationalView: true });
}
await map.isLegendOpen({ legendOpen: true });
await map.isLayerMenuOpen({ layerMenuOpen: false });
await map.assertAdminBoundariesVisible();
Expand Down
111 changes: 53 additions & 58 deletions tests/e2e/tests/ScenarioNoTrigger.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,33 +11,24 @@ import { NoTriggerDataSet } from 'testData/testData.enum';

import { getAccessToken, mockData, 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<Pages> = {};
const components: Partial<Components> = {};

test.describe('Scenario: No Trigger', () => {
const disasterType = NoTriggerDataSet.DisasterType;
// ##TODO: move this somewhere else
export enum DisasterTypeEnum {
Floods = 'floods',
Drought = 'drought',
}

test.describe.only('Scenario: No Trigger', () => {
const disasterTypes = [DisasterTypeEnum.Floods, DisasterTypeEnum.Drought];
const countryCodeISO3 = NoTriggerDataSet.CountryCode;
const scenario = NoTriggerDataSet.NoTriggerScenario;

Expand All @@ -58,8 +49,16 @@ test.describe('Scenario: No Trigger', () => {
await resetDB(accessToken);

// Load a mock scenario
const date = new Date();
await mockData(disasterType, scenario, countryCodeISO3, accessToken, date);
for (const disasterType of disasterTypes) {
const date = new Date();
await mockData(
disasterType,
scenario,
countryCodeISO3,
accessToken,
date,
);
}

await page.goto('/');
// Login into the portal
Expand All @@ -73,43 +72,39 @@ test.describe('Scenario: No Trigger', () => {
await page.close();
});

test.describe('DashboardPage', () => {
DashboardPageVisible(pages, components, disasterType);
});

test.describe('MapComponent', () => {
MapComponentVisible(pages, components, disasterType);
MapComponentInteractive(pages, components, disasterType);
MapComponentLayersVisible(pages, components, disasterType);
MapComponentAlertThreshold(pages, components, disasterType);
MapComponentGloFASStations(pages, components, disasterType);
MapComponentGloFASStationsWarning(pages, components, disasterType);
});

test.describe('AggregatesComponent', () => {
AggregatesComponentVisible(pages, components, disasterType);
AggregateComponentTitleHover(pages, components, disasterType);
AggregateComponentButtonClick(pages, components, disasterType);
});

test.describe('ChatComponent', () => {
ChatComponentVisible(pages, components, disasterType);
ChatComponentButtonClick(pages, components, disasterType);
});

test.describe('DisasterTypeComponent', () => {
DisasterTypeComponentVisible(pages, components, disasterType);
DisasterTypeComponentSelect(pages, components);
});

test.describe('TimelineComponent', () => {
TimelineComponentVisible(pages, components, disasterType);
TimelineComponentDisabled(pages, components, disasterType);
});

// Do this last, as it logs out the user
test.describe('UserStateComponent', () => {
UserStateComponentVisible(pages, components, disasterType);
UserStateComponentLogout(pages, components, disasterType);
});
for (const disasterType of disasterTypes) {
test.describe('DashboardPage', () => {
DashboardPageVisible(pages, components, disasterType);
});
test.describe('MapComponent', () => {
MapComponentVisible(pages, components, disasterType);
// MapComponentInteractive(pages, components, disasterType);
// MapComponentLayersVisible(pages, components, disasterType);
// MapComponentAlertThreshold(pages, components, disasterType);
MapComponentGloFASStations(pages, components, disasterType);
// MapComponentGloFASStationsWarning(pages, components, disasterType);
});
// test.describe('AggregatesComponent', () => {
// AggregatesComponentVisible(pages, components, disasterType);
// AggregateComponentTitleHover(pages, components, disasterType);
// AggregateComponentButtonClick(pages, components, disasterType);
// });
// test.describe('ChatComponent', () => {
// ChatComponentVisible(pages, components, disasterType);
// ChatComponentButtonClick(pages, components, disasterType);
// });
// test.describe('DisasterTypeComponent', () => {
// DisasterTypeComponentVisible(pages, components, disasterType);
// DisasterTypeComponentSelect(pages, components);
// });
// test.describe('TimelineComponent', () => {
// TimelineComponentVisible(pages, components, disasterType);
// TimelineComponentDisabled(pages, components, disasterType);
// });
// // Do this last, as it logs out the user
// test.describe('UserStateComponent', () => {
// UserStateComponentVisible(pages, components, disasterType);
// UserStateComponentLogout(pages, components, disasterType);
// });
}
});
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export default (
components: Partial<Components>,
disasterType: string,
) => {
test(
test.only(
qase(14, 'Timeline should be disabled'),
{
annotation: {
Expand All @@ -31,7 +31,7 @@ export default (
await userState.headerComponentIsVisible({
countryName: NoTriggerDataSet.CountryName,
});
await timeline.timelineIsInactive();
await timeline.timelineIsInactive(); // TODO: make conditional on disaster-type

// Reload the page to prepare for next test
await dashboard.page.goto('/');
Expand Down

0 comments on commit 20b24eb

Please sign in to comment.