Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rewrite error messages #1370

Merged
merged 26 commits into from
Dec 2, 2024
Merged
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
38ffe08
Handle error messages correctly in address component
lotorvik Nov 25, 2024
36d3b84
Always use addRef for components
lotorvik Nov 25, 2024
450589e
Stop using formio addMessage, let ReactSelect handle its own error me…
lotorvik Nov 26, 2024
25af550
Fix for react select ref
lotorvik Nov 26, 2024
ea14ec9
Add some logging
lotorvik Nov 26, 2024
d408e66
Fix for error messages in byggeren
lotorvik Nov 27, 2024
a38d0fa
Try to make driving list test more stable
lotorvik Nov 27, 2024
c38984c
Try to make driving list test more stable
lotorvik Nov 27, 2024
920259f
Try to make driving list test more stable
lotorvik Nov 27, 2024
a691c88
Try to make driving list test more stable
lotorvik Nov 28, 2024
b1570ce
Try to make driving list test more stable
lotorvik Nov 28, 2024
7d5a3a7
Try to make driving list test more stable
lotorvik Nov 28, 2024
911fa06
Try to make driving list test more stable
lotorvik Nov 28, 2024
11f17e0
Merge branch 'refs/heads/master' into address-error-message
lotorvik Nov 28, 2024
8810737
Try to make driving list test more stable
lotorvik Nov 28, 2024
815413e
Test artifacts for failed tests
lotorvik Nov 28, 2024
ac984c8
Test artifacts for failed tests
lotorvik Nov 28, 2024
94bf7e6
Test artifacts for failed tests
lotorvik Nov 28, 2024
52b7b7f
Test artifacts for failed tests
lotorvik Nov 28, 2024
c5e76d0
Try to make driving list test more stable
lotorvik Nov 28, 2024
4504cf3
Update driving list to new format
lotorvik Nov 28, 2024
c8954f8
Test trigger new build
lotorvik Nov 28, 2024
4f1917a
Remove test timeout
lotorvik Nov 29, 2024
d79b16e
Update FormioReactComponent.tsx
lotorvik Dec 2, 2024
3a8dd55
Update BaseComponent.ts
lotorvik Dec 2, 2024
0537460
Component logger did not have warn...
lotorvik Dec 2, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .github/workflows/cypress-tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,13 @@ jobs:
config: video=false
env:
FYLLUT_BACKEND_LOGLEVEL: ${{ runner.debug == '1' && 'debug' || 'error' }}
- name: Upload screenshots
uses: actions/upload-artifact@v4
if: failure()
with:
name: cypress-screenshots
path: ${{ github.workspace }}/packages/fyllut/cypress/screenshots/*


cypress-run-bygger:
runs-on: ubuntu-latest-8-cores
Expand Down
5 changes: 4 additions & 1 deletion packages/bygger/cypress/e2e/form-builder.spec.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -173,8 +173,11 @@ describe('Form Builder', () => {
cy.get('[data-testid="editorSaveButton"]').click();
});

// This error comes from Component.highlightInvalidComponents in Formio
it('should show error message stating duplicate API key', () => {
cy.findByText('API Key is not unique: personopplysninger').should('exist');
// We get one error message on TextField and one from formio in Panel.
// The Panel component uses old templates, that is the reason the error is not correct format.
cy.findAllByText('API Key is not unique: personopplysninger').should('have.length', 2);
});

it('should not remove panel when changing components key to something else', () => {
Expand Down
2 changes: 2 additions & 0 deletions packages/bygger/src/formio/builder/WebformBuilder.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ class WebformBuilder extends NavFormioJs.Builders.builders.webform {

super.editComponent(component, parent, isNew, isJsonEdit, original, flags);

this.editForm.editFormDialog = true;

if (isJsonEdit) {
this.editForm.form = {
...this.editForm.form,
Expand Down
2 changes: 2 additions & 0 deletions packages/bygger/src/formio/builder/WizardBuilder.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,8 @@ class WizardBuilder extends NavFormioJs.Builders.builders.wizard {

super.editComponent(component, parent, isNew, isJsonEdit, original, flags);

this.editForm.editFormDialog = true;

if (isJsonEdit) {
this.editForm.form = {
...this.editForm.form,
Expand Down
2 changes: 2 additions & 0 deletions packages/fyllut/cypress/e2e/components/datagrid.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,15 @@ describe('Datagrid', () => {
cy.visit('/fyllut/datagridReact?sub=digital');
cy.defaultWaits();
cy.clickStart();
cy.wait('@createMellomlagring');
cy.findByRole('checkbox', { name: 'Avkryssingsboks inni datagrid (valgfritt)' }).check();
cy.findByRole('textbox', { name: 'Dato inni datagrid' }).type('15.01.2022');
cy.findByRole('combobox', { name: 'Nedtrekksmeny inni datagrid' }).type('F{enter}');
cy.findByRole('radio', { name: 'Nei' }).check();
cy.findByRole('textbox', { name: 'Tekstområde inni datagrid' }).type('Lorem Ipsum');
cy.findByRole('textbox', { name: 'Tekstfelt inni datagrid' }).type('Hund');
cy.clickSaveAndContinue();
cy.wait('@updateMellomlagring');
cy.findByRoleWhenAttached('heading', { level: 2, name: 'Oppsummering' }).should('exist');
cy.findByRoleWhenAttached('link', { name: TEXTS.grensesnitt.summaryPage.editAnswers }).should('exist').click();

Expand Down
117 changes: 64 additions & 53 deletions packages/fyllut/cypress/e2e/components/driving-list.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,54 +20,9 @@ describe('DrivingList', () => {
cy.configMocksServer();
});

beforeEach(() => {
cy.defaultIntercepts();
cy.defaultInterceptsMellomlagring();
cy.defaultInterceptsExternal();
cy.mocksRestoreRouteVariants();
});

after(() => {
cy.mocksRestoreRouteVariants();
});

describe('paper', () => {
it('should fill out form and show data in summary', () => {
cy.visit(`/fyllut/testdrivinglist?sub=paper`);
cy.defaultWaits();
cy.clickStart();

cy.findByRole('textbox', { name: DATE_PICKER_LABEL }).should('exist').type('15.05.2023{esc}');
cy.findByRole('group', { name: PARKING_LABEL })
.should('exist')
.within(() => {
cy.findAllByRole('radio').should('have.length', 2);
cy.findByRole('radio', { name: 'Ja' }).should('exist').check();
});

cy.findByRole('button', { name: '15. mai 2023 - 21. mai 2023' }).click();

cy.findByRole('group', { name: DAY_PICKER_LABEL_WITH_PARKING })
.should('exist')
.within(() => {
cy.findAllByRole('checkbox').should('have.length', 7);
cy.findByRole('checkbox', { name: 'mandag 15. mai 2023' }).should('exist').check();
cy.findByRole('checkbox', { name: 'søndag 21. mai 2023' }).should('exist').check();
cy.findAllByRole('textbox', { name: PARKING_EXPENSES_LABEL }).eq(0).should('exist').type('100');
});

cy.clickNextStep();

// Summary
cy.get('dl')
.first()
.within(() => {
cy.get('dt').eq(0).should('contain.text', 'Legg til kjøreliste for en eller flere perioder');

cy.findAllByRole('listitem').should('have.length', 2);
cy.findByText('mandag 15. mai 2023, parkeringsutgift: 100 kr').should('exist');
cy.findByText('søndag 21. mai 2023').should('exist');
});
beforeEach(() => {
cy.defaultIntercepts();
});

it('should show errors', () => {
Expand All @@ -76,9 +31,13 @@ describe('DrivingList', () => {
cy.clickStart();

// Should fill out form
cy.findByRole('textbox', { name: DATE_PICKER_LABEL }).should('exist');
cy.findByRole('group', { name: 'Skal du registrere parkering?' }).should('exist');
cy.clickNextStep();
cy.get('[data-cy=error-summary]')

cy.findByRole('heading', { name: 'For å gå videre må du rette opp følgende:' })
.should('exist')
.parent()
.within(() => {
cy.findByRole('link', { name: `Du må fylle ut: ${DATE_PICKER_LABEL}` })
.should('exist')
Expand All @@ -94,23 +53,62 @@ describe('DrivingList', () => {
cy.findByRole('textbox', { name: PARKING_EXPENSES_LABEL }).clear();
cy.findByRole('textbox', { name: PARKING_EXPENSES_LABEL }).type('text');
cy.clickNextStep();
cy.get('[data-cy=error-summary]')
cy.findByRole('heading', { name: 'For å gå videre må du rette opp følgende:' })
.should('exist')
.parent()
.within(() => {
cy.findByRole('link', { name: 'Parkeringsutgiftene for 15.05.2023 må være et gyldig beløp' })
.should('exist')
.click();
});

cy.findByRole('textbox', { name: PARKING_EXPENSES_LABEL }).should('have.focus').type('{selectall}78');
cy.get('[data-cy=error-summary]').should('not.exist');
cy.findByRole('heading', { name: 'For å gå videre må du rette opp følgende:' }).should('not.exist');

// Parking expenses should not show even with value over 100
cy.findByRole('textbox', { name: PARKING_EXPENSES_LABEL }).should('exist').type('101');
cy.clickNextStep();
cy.findByRole('heading', { name: 'Oppsummering' }).should('exist');
});

it('should fill out form and show data in summary', () => {
cy.visit(`/fyllut/testdrivinglist?sub=paper`);
cy.defaultWaits();
cy.clickStart();

cy.findByRole('textbox', { name: DATE_PICKER_LABEL }).should('exist').type('15.05.2023{esc}');
cy.findByRole('group', { name: PARKING_LABEL })
.should('exist')
.within(() => {
cy.findAllByRole('radio').should('have.length', 2);
cy.findByRole('radio', { name: 'Ja' }).should('exist').check();
});

cy.findByRole('button', { name: '15. mai 2023 - 21. mai 2023' }).click();

cy.findByRole('group', { name: DAY_PICKER_LABEL_WITH_PARKING })
.should('exist')
.within(() => {
cy.findAllByRole('checkbox').should('have.length', 7);
cy.findByRole('checkbox', { name: 'mandag 15. mai 2023' }).should('exist').check();
cy.findByRole('checkbox', { name: 'søndag 21. mai 2023' }).should('exist').check();
cy.findAllByRole('textbox', { name: PARKING_EXPENSES_LABEL }).eq(0).should('exist').type('100');
});

cy.clickNextStep();

// Summary
cy.get('dl')
.first()
.within(() => {
cy.get('dt').eq(0).should('contain.text', 'Legg til kjøreliste for en eller flere perioder');

cy.findAllByRole('listitem').should('have.length', 2);
cy.findByText('mandag 15. mai 2023, parkeringsutgift: 100 kr').should('exist');
cy.findByText('søndag 21. mai 2023').should('exist');
});
});

it('should add and remove periods', () => {
cy.visit(`/fyllut/testdrivinglist?sub=paper`);
cy.defaultWaits();
Expand All @@ -137,11 +135,19 @@ describe('DrivingList', () => {
});

describe('digital', () => {
beforeEach(() => {
cy.mocksRestoreRouteVariants();
cy.defaultInterceptsMellomlagring();
cy.defaultInterceptsExternal();
cy.defaultIntercepts();
});

it('should fill out form and show data in summary', () => {
cy.visit(`/fyllut/testdrivinglist?sub=digital`);
cy.defaultWaits();
cy.clickStart();
cy.wait('@getActivities');
cy.wait('@createMellomlagring');

cy.findByRole('group', { name: ACTIVITIES_LABEL })
.should('exist')
Expand Down Expand Up @@ -201,10 +207,11 @@ describe('DrivingList', () => {
});

it('should fill out mellomlagret values', () => {
cy.visit(`/fyllut/testdrivinglist/veiledning?sub=digital&innsendingsId=8495201b-71fd-4a95-82f8-d224d32237e5`);
cy.mocksUseRouteVariant('get-soknad:success-driving-list');
cy.visit(`/fyllut/testdrivinglist/veiledning?sub=digital&innsendingsId=8495201b-71fd-4a95-82f8-d224d32237e5`);
cy.defaultWaits();
cy.wait('@getActivities');
cy.wait('@getMellomlagring');

cy.findByRole('radio', { name: 'Arbeidstrening: 01. januar 2024 - 31. august 2024' }).should('be.checked');

Expand All @@ -220,10 +227,11 @@ describe('DrivingList', () => {
});

it('should load driving list without dates', () => {
cy.visit(`/fyllut/testdrivinglist/veiledning?sub=digital&innsendingsId=a66e8932-ce2a-41c1-932b-716fc487813b`);
cy.mocksUseRouteVariant('get-soknad:success-driving-list-no-dates');
cy.visit(`/fyllut/testdrivinglist/veiledning?sub=digital&innsendingsId=a66e8932-ce2a-41c1-932b-716fc487813b`);
cy.defaultWaits();
cy.wait('@getActivities');
cy.wait('@getMellomlagring');

cy.findByRole('radio', { name: 'Arbeidstrening: 01. januar 2024 - 31. august 2024' }).should('be.checked');

Expand All @@ -241,6 +249,7 @@ describe('DrivingList', () => {
cy.visit(`/fyllut/testdrivinglist/veiledning?sub=digital`);
cy.defaultWaits();
cy.wait('@getActivities');
cy.wait('@createMellomlagring');

cy.findByRole('radio', { name: 'Arbeidstrening: 01. januar 2099 - 31. august 2099' }).check();

Expand All @@ -260,6 +269,7 @@ describe('DrivingList', () => {

cy.clickStart();
cy.wait('@getActivities');
cy.wait('@createMellomlagring');

cy.clickSaveAndContinue();
cy.get('[data-cy=error-summary]')
Expand Down Expand Up @@ -295,11 +305,12 @@ describe('DrivingList', () => {
});

it('should render alert when there are no activities and error when trying to continue', () => {
cy.mocksUseRouteVariant('get-activities:success-empty');
cy.visit(`/fyllut/testdrivinglist?sub=digital`);
cy.defaultWaits();
cy.mocksUseRouteVariant('get-activities:success-empty');
cy.clickStart();
cy.wait('@getActivities');
cy.wait('@createMellomlagring');

cy.get('.navds-alert').within(() => {
cy.findByText(TEXTS.statiske.drivingList.noVedtakHeading).should('exist');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -213,14 +213,16 @@ class BaseComponent extends FormioReactComponent {

if (messages) {
if (Array.isArray(messages)) {
if (messages.length > 1) {
this.logger.info(`Should never get more then one message, got ${messages.length}.`, { messages });
lotorvik marked this conversation as resolved.
Show resolved Hide resolved
}
messages.forEach((componentError: ComponentError) => {
lotorvik marked this conversation as resolved.
Show resolved Hide resolved
this.addError(componentError.message, this.getId());
});
} else {
this.addError(messages, this.getId());
}
}

this.rerender();
}

Expand All @@ -245,8 +247,16 @@ class BaseComponent extends FormioReactComponent {
return this.componentErrors.find((error) => error.elementId === elementId)?.message;
}

/**
* nextPageClicked: When user click next page in Fyllut (except last page)
* submitted: When user click next page in Fyllut (last page)
* builderMode: When user is in the regular form builder
* editFormDialog: When user have open a form dialog in the form builder
*/
showErrorMessages() {
return this.root.currentPage?.showErrormessages || this.root.submitted;
return (
this.root.currentPage?.nextPageClicked || this.root.submitted || this.builderMode || this.root.editFormDialog
);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,15 @@ class FormioReactComponent extends (ReactComponent as unknown as IReactComponent
return this._reactRefs[name];
}

/**
* Add message render the error messages Form.io template.
*/
addMessages(messages) {
this.logger.info('Trying to addMessages with Formio.io old template. Should use new error messages instead', {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warn

messages,
});
}

/**
* @return Currently focused component.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,16 +34,7 @@ class DrivingList extends BaseComponent {

onValueChange(value) {
super.handleChange(value);

// If next button has been clicked (submitted), check the whole form for errors
if (this.root.submitted) {
this.checkValidity();
} else {
this.rerender();
}
}
override get errors() {
return this.componentErrors;
this.rerender();
}

addErrorOfType(metadataId: DrivingListMetadataId, errorType: DrivingListErrorType) {
Expand All @@ -52,8 +43,13 @@ class DrivingList extends BaseComponent {
}
}

override checkValidity(): boolean {
checkComponentValidity(data, dirty, row, _options = {}) {
this.removeAllErrors();

if (this.shouldSkipValidation(data, dirty, row)) {
return true;
}

const componentData = this.getValue() as DrivingListSubmission;

if (this.isSubmissionPaper()) {
Expand Down Expand Up @@ -95,19 +91,15 @@ class DrivingList extends BaseComponent {

this.rerender();

if (this.componentErrors.length > 0) {
return false;
}

return true;
return this.componentErrors.length === 0;
}

updateValues(multipleValues: DrivingListValues) {
this.onValueChange({ ...this.getValue(), ...multipleValues });
}

renderReact(element) {
// TODO: Delete DrivingListProvider and use prop drilling instead
// TODO: Delete DrivingListProvider and use prop drilling instead.
element.render(
<ComponentUtilsProvider component={this}>
<DrivingListProvider updateValues={this.updateValues.bind(this)} values={this.getValue()}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,5 +66,5 @@ export const showAddButton = (values?: DrivingListSubmission) => {
};

export const showRemoveButton = (values?: DrivingListSubmission) => {
return values?.periods?.length && values?.periods?.length > 1;
return values?.periods?.length ? values?.periods?.length > 1 : false;
};
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ Wizard.prototype.attachHeader = function () {

// Copy of nextPage() from formio.js/src/Wizard.js, but without custom emit and scroll to errors
const validateAndGoToNextPage = (emitPage) => {
this.currentPage.showErrormessages = true;
this.currentPage.nextPageClicked = true;

if (this.options.readOnly) {
return this.beforePage(true).then(() => {
Expand Down