Skip to content

Commit

Permalink
11503 e2e tests for process editor (#12976)
Browse files Browse the repository at this point in the history
* add first test for process editor and logic to click inside bpmn

* removing spinner and implementing drag on editor

* refactoring logic

* Almost working

* implementing more on new test

* writing more tests

* adding tests for actions

* Remove feature flag for endEvent in process and update url to docs

* adding changed files

* Completing test for CustomEndEvent

* removing unused comments

* fixing feedback from PR

* removing css variable
  • Loading branch information
wrt95 authored Jun 24, 2024
1 parent fe90360 commit eb2d47f
Show file tree
Hide file tree
Showing 16 changed files with 991 additions and 45 deletions.
8 changes: 4 additions & 4 deletions frontend/language/src/nb.json
Original file line number Diff line number Diff line change
Expand Up @@ -763,12 +763,12 @@
"process_editor.configuration_panel.edit_policy_alert_message": "Du må ha tilgangsregler som dekker alle oppgaver. Gå til Tilganger for å sjekke om du har en regel som dekker denne oppgaven. Hvis du ikke har en regel for oppgaven, kan du enten lage en ny regel eller inkludere denne oppgaven i en regel som allerede finnes.",
"process_editor.configuration_panel.edit_policy_open_policy_editor_button": "Gå til Tilganger",
"process_editor.configuration_panel.edit_policy_open_policy_editor_heading": "Åpne Tilganger for å redigere tilgangsregler",
"process_editor.configuration_panel_actions_action_label": "Handling {{ actionIndex }}: {{ actionName }}",
"process_editor.configuration_panel_actions_action_label": "Handling {{actionIndex}}: {{actionName}}",
"process_editor.configuration_panel_actions_action_type_help_text": "Hjelpetekst for valg av handlingstype",
"process_editor.configuration_panel_actions_add_new": "Legg til ny handling",
"process_editor.configuration_panel_actions_combobox_description": "Velg en predefinert handling eller definer din egen ved å skrive inn navnet som fritekst i feltet",
"process_editor.configuration_panel_actions_custom_action": "Skriv en egendefinert handling",
"process_editor.configuration_panel_actions_delete_action": "Slett {{ actionName }}-handlingen",
"process_editor.configuration_panel_actions_delete_action": "Slett {{actionName}}-handlingen",
"process_editor.configuration_panel_actions_set_server_action_info": "Handlingen skal utføres uten å endre status på prosessen. Dette alternativet er kun tilgjengelig for egendefinerte handlinger.",
"process_editor.configuration_panel_actions_set_server_action_label": "Handlingen skal ikke påvirke prosessen",
"process_editor.configuration_panel_actions_title": "Handlinger",
Expand Down Expand Up @@ -824,7 +824,7 @@
"process_editor.configuration_panel_select_data_model": "Velg en datamodell",
"process_editor.configuration_panel_set_data_model": "Datamodell:",
"process_editor.configuration_panel_set_data_model_link": "Legg til datamodell",
"process_editor.configuration_panel_set_data_types_to_sign": "Datyper som skal signeres:",
"process_editor.configuration_panel_set_data_types_to_sign": "Datatyper som skal signeres:",
"process_editor.configuration_panel_signing_task": "Oppgave: Signering",
"process_editor.configuration_view_panel_id_label": "ID: {{id}}",
"process_editor.configuration_view_panel_name_label": "Navn: ",
Expand All @@ -848,7 +848,7 @@
"process_editor.sync_error_layout_sets_data_type": "En feil oppsto under synkronisering av datatype i filen 'layoutsets.json'. Vennligst forsikre deg om at 'layoutsets.json' kun inneholder gyldig JSON-struktur og prøv igjen.",
"process_editor.sync_error_layout_sets_task_id": "En feil oppsto under synkronisering av oppgave-ID i filen 'layoutsets.json'. Vennligst forsikre deg om at 'layoutsets.json' kun inneholder gyldig JSON-struktur og prøv igjen.",
"process_editor.sync_error_policy_file_task_id": "En feil oppsto under synkronisering av oppgave-ID i filen 'policy.json'. Vennligst forsikre deg om at 'policy.json' kun inneholder gyldig JSON-struktur og prøv igjen.",
"process_editor.too_old_version_helptext_content": "Du har nå versjon {{ version }} av app-biblioteket vårt.\n\nVi lanserer muligheten til å redigere prosessen sammen med versjon 8 av biblioteket. Når du har oppgradert til versjon 8, får du funksjonalitet for å redigere prosessen.\n\nFør det kan du bare se prosessen og eventuelle oppsett som er knyttet til den.",
"process_editor.too_old_version_helptext_content": "Du har nå versjon {{version}} av app-biblioteket vårt.\n\nVi lanserer muligheten til å redigere prosessen sammen med versjon 8 av biblioteket. Når du har oppgradert til versjon 8, får du funksjonalitet for å redigere prosessen.\n\nFør det kan du bare se prosessen og eventuelle oppsett som er knyttet til den.",
"process_editor.too_old_version_helptext_title": "Informasjon om hvorfor prosessen ikke kan redigeres",
"process_editor.too_old_version_title": "Prosessen kan ikke redigeres",
"process_editor.unknown_heading_error_message": "Obs, noe gikk galt!",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ class SupportedPaletteProvider {
className: 'bpmn-icon-task-generic bpmn-icon-data-task',
title: translate('Create Altinn Data Task'),
action: {
click: createCustomTask('data'),
dragstart: createCustomTask('data'),
},
},
Expand All @@ -171,6 +172,7 @@ class SupportedPaletteProvider {
title: translate('Create Altinn Feedback Task'),
className: 'bpmn-icon-task-generic bpmn-icon-feedback-task',
action: {
click: createCustomTask('feedback'),
dragstart: createCustomTask('feedback'),
},
},
Expand All @@ -179,6 +181,7 @@ class SupportedPaletteProvider {
className: 'bpmn-icon-task-generic bpmn-icon-signing-task',
title: translate('Create Altinn signing Task'),
action: {
click: createCustomSigningTask(),
dragstart: createCustomSigningTask(),
},
},
Expand All @@ -187,6 +190,7 @@ class SupportedPaletteProvider {
className: 'bpmn-icon-task-generic bpmn-icon-confirmation-task',
title: translate('Create Altinn Confirm Task'),
action: {
click: createCustomConfirmationTask(),
dragstart: createCustomConfirmationTask(),
},
},
Expand All @@ -195,6 +199,7 @@ class SupportedPaletteProvider {
className: `bpmn-icon-task-generic ${shouldDisplayFeature('displayPaymentTaskProcessEditor') ? 'bpmn-icon-payment-task' : 'payment-is-hidden-based-on-feature-toggle'}`,
title: translate('Payment'),
action: {
click: createCustomPaymentTask(),
dragstart: createCustomPaymentTask(),
},
},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,3 @@
.container {
visibility: hidden;
}

.spinner {
display: flex;
flex: 1;
justify-content: center;
align-content: center;
}

.editorContainer {
border: 1px solid var(--fds-semantic-border-neutral-default);
border-radius: 5px;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,6 @@ jest.mock('../../../hooks/useBpmnEditor', () => ({

describe('BPMNEditor', () => {
afterEach(jest.clearAllMocks);
it('render spinner when pendingApiOperations is true', () => {
renderBpmnEditor({ pendingApiOperations: true });

screen.getByText(textMock('process_editor.loading'));
});

it('does not render spinner when pendingApiOperations is false', () => {
renderBpmnEditor({ pendingApiOperations: false });
Expand Down
Original file line number Diff line number Diff line change
@@ -1,28 +1,10 @@
import React from 'react';
import classes from './BPMNEditor.module.css';
import { useBpmnEditor } from '../../../hooks/useBpmnEditor';

import './BPMNEditor.css';
import { useBpmnApiContext } from '../../../contexts/BpmnApiContext';
import { StudioSpinner } from '@studio/components';
import { useTranslation } from 'react-i18next';

export const BPMNEditor = (): React.ReactElement => {
const { t } = useTranslation();
const { canvasRef } = useBpmnEditor();
const { pendingApiOperations } = useBpmnApiContext();

return (
<>
{pendingApiOperations && (
<div className={classes.spinner}>
<StudioSpinner spinnerTitle={t('process_editor.loading')} />
</div>
)}
<div
className={pendingApiOperations ? classes.container : classes.editorContainer}
ref={canvasRef}
></div>
</>
);
return <div className={classes.editorContainer} ref={canvasRef}></div>;
};
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export const EditActions = () => {
<>
{actionElements.map((actionElement: ModdleElement, index: number) => (
<EditAction
key={actionElement.action}
key={actionElement.action + index.toString()}
actionElementToEdit={actionElement}
availablePredefinedActions={availablePredefinedActions}
bpmnDetails={bpmnDetails}
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions frontend/testing/playwright/enum/AppNames.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ export enum AppNames {
SETTINGS_MODAL_APP = 'settings-modal-app-test',
UI_EDITOR_APP = 'ui-editor-app-test',
TEXT_EDITOR_APP = 'text-editor-app-test',
PROCESS_EDITOR_APP = 'process-editor-app-test',
}
1 change: 1 addition & 0 deletions frontend/testing/playwright/enum/TestNames.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@ export enum TestNames {
GIT_SYNC = 'git-sync',
SETTINGS_MODAL = 'settings-modal',
TEXT_EDITOR = 'text-editor',
PROCESS_EDITOR = 'process-editor',
}
20 changes: 20 additions & 0 deletions frontend/testing/playwright/helpers/BpmnJSQuery.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import type { Page } from '@playwright/test';

type SvgElement = 'svg' | 'g';

export class BpmnJSQuery {
public readonly page: Page;

constructor(page: Page) {
this.page = page;
}

/**
* Gets the BPMN element by its 'data-element-id'
*/
public async getTaskByIdAndType(id: string, type: SvgElement): Promise<string> {
const elementSelector = `${type}[data-element-id="${id}"]`;
await this.page.waitForSelector(elementSelector);
return elementSelector;
}
}
9 changes: 4 additions & 5 deletions frontend/testing/playwright/pages/DataModelPage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,11 +113,10 @@ export class DataModelPage extends BasePage {
}

public async checkThatSuccessAlertIsVisibleOnScreen(): Promise<void> {
await this.page
.getByRole('alert', {
name: this.textMock('schema_editor.data_model_generation_success_message'),
})
.isVisible();
const alert = this.page.getByText(
this.textMock('schema_editor.data_model_generation_success_message'),
);
await expect(alert).toBeVisible();
}

public async checkThatDataModelOptionExists(option: string): Promise<void> {
Expand Down
106 changes: 106 additions & 0 deletions frontend/testing/playwright/pages/GiteaPage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import type { LanguageCode } from '../enum/LanguageCode';
import { BasePage } from '../helpers/BasePage';
import type { Environment } from '../helpers/StudioEnvironment';
import type { Page } from '@playwright/test';
import { type BpmnTaskType } from '../types/BpmnTaskType';
import { expect } from '@playwright/test';

// Since this page is Gitea's page, it's not using the nb/en.json files, which are used in the frontend.
const giteaPageTexts: Record<string, string> = {
Expand All @@ -12,6 +14,8 @@ const giteaPageTexts: Record<string, string> = {
dataModelBindings: 'dataModelBindings',
config: 'config',
texts: 'texts',
process: 'process',
applicationmetadata: 'applicationmetadata',
};

export class GiteaPage extends BasePage {
Expand Down Expand Up @@ -105,4 +109,106 @@ export class GiteaPage extends BasePage {
public async verifyTextIdAndValue(id: string, value: string): Promise<void> {
await this.page.getByText(`"id": "${id}", "value": "${value}"`, { exact: true }).isVisible();
}

public async clickOnProcessFilesButton(): Promise<void> {
await this.page.getByRole('link', { name: giteaPageTexts['process'], exact: true }).click();
}

public async clickOnProcessBpmnFile(): Promise<void> {
await this.page.getByRole('link', { name: `${giteaPageTexts['process']}.bpmn` }).click();
}

public async verifyThatTheNewTaskIsVisible(id: string, task: BpmnTaskType): Promise<void> {
const text = this.page.getByText(`<bpmn:task id="${id}" name="Altinn ${task} task">`);
await expect(text).toBeVisible();
}

public async verifyThatTheNewTaskIsHidden(id: string, task: BpmnTaskType): Promise<void> {
await this.page.getByText(`<bpmn:task id="${id}" name="Altinn ${task} task">`).isHidden();
}

public async verifySequenceFlowDirection(fromId: string, toId: string): Promise<void> {
const firstPartOfText = this.page.getByText('<bpmn:sequenceFlow id="Flow_');
await expect(firstPartOfText).toBeVisible();

const secondPartOfText = this.page.getByText(`" sourceRef="${fromId}" targetRef="${toId}" />`);
await expect(secondPartOfText).toBeVisible();
}

public async clickOnApplicationMetadataFile(): Promise<void> {
await this.page
.getByRole('link', { name: `${giteaPageTexts['applicationmetadata']}.json` })
.click();
}

public async verifyIdInDataModel(id: string, dataModel: string): Promise<void> {
const text = `
"id": "${dataModel}",
"allowedContentTypes": [
"application/xml"
],
"appLogic": {
"autoCreate": true,
"classRef": "Altinn.App.Models.${dataModel}.${dataModel}",
"allowAnonymousOnStateless": false,
"autoDeleteOnProcessEnd": false
},
"taskId": "${id}",
"maxCount": 1,
"minCount": 1,
"enablePdfCreation": true,
"enableFileScan": false,
"validationErrorOnPendingFileScan": false,
"enabledFileAnalysers": [],
"enabledFileValidators": []
`;
const textLocator = this.page.getByText(text);
expect(textLocator).toBeVisible();
}

public async verifyThatActionIsVisible(action: string): Promise<void> {
await this.page.getByText(`<altinn:action>${action}</altinn:action>`).isVisible();
}

public async verifyThatActionIsHidden(action: string): Promise<void> {
await this.page.getByText(`<altinn:action>${action}</altinn:action>`).isHidden();
}

public async verifyThatTaskIsHidden(task: string): Promise<void> {
await this.page.getByText(`<altinn:taskType>${task}</altinn:taskType>`).isHidden();
}

public async verifyThatTaskIsVisible(task: string): Promise<void> {
await this.page.getByText(`<altinn:taskType>${task}</altinn:taskType>`).isVisible();
}

public async verifyThatDataTypeToSignIsHidden(dataTypeToSign: string): Promise<void> {
const text = `
<altinn:signatureConfig>
<altinn:dataTypesToSign>
<altinn:dataType>${dataTypeToSign}</altinn:dataType>
</altinn:dataTypesToSign>
</altinn:signatureConfig>
`;
await this.page.getByText(text).isHidden();
}

public async verifyThatDataTypeToSignIsVisible(dataTypeToSign: string): Promise<void> {
const text = `
<altinn:signatureConfig>
<altinn:dataTypesToSign>
<altinn:dataType>${dataTypeToSign}</altinn:dataType>
</altinn:dataTypesToSign>
</altinn:signatureConfig>
`;
await this.page.getByText(text).isVisible();
}

public async verifyThatCustomReceiptIsNotVisible(): Promise<void> {
await this.page.getByText('"taskId": "CustomReceipt"').isHidden();
}

public async verifyThatCustomReceiptIsVisible(): Promise<void> {
await this.page.getByText('"taskId": "CustomReceipt"').isVisible();
}
}
Loading

0 comments on commit eb2d47f

Please sign in to comment.