From f942ba9e6ea535af57b7fd0a52a647479cb05a86 Mon Sep 17 00:00:00 2001
From: rmccar <42928680+rmccar@users.noreply.github.com>
Date: Tue, 19 Mar 2024 09:13:51 +0000
Subject: [PATCH] Fix single inputs not clearing for mutually exclusive fields
(#3091)
---
.../multiple-input-fields/_macro.njk | 12 +-
.../mutually-exclusive.date.spec.js | 128 +++++++++++++++++-
.../mutually-exclusive.duration.spec.js | 121 +++++++++++++++++
3 files changed, 248 insertions(+), 13 deletions(-)
diff --git a/src/components/multiple-input-fields/_macro.njk b/src/components/multiple-input-fields/_macro.njk
index aeae347571..55a2837402 100644
--- a/src/components/multiple-input-fields/_macro.njk
+++ b/src/components/multiple-input-fields/_macro.njk
@@ -2,15 +2,15 @@
{% from "components/fieldset/_macro.njk" import onsFieldset %}
{% macro onsMultipleInputFields(params) %}
- {% if params.numberOfFields > 1 %}
- {% set fields %}
+ {% set fields %}
+ {% if params.numberOfFields > 1 %}
{{ params.fields | safe }}
- {% endset %}
- {% else %}
- {{ params.fields | safe }}
- {% endif %}
+ {% else %}
+ {{ params.fields | safe }}
+ {% endif %}
+ {% endset %}
{% if params.mutuallyExclusive %}
{% call onsMutuallyExclusive({
diff --git a/src/components/mutually-exclusive/mutually-exclusive.date.spec.js b/src/components/mutually-exclusive/mutually-exclusive.date.spec.js
index b6708612ca..7646133196 100644
--- a/src/components/mutually-exclusive/mutually-exclusive.date.spec.js
+++ b/src/components/mutually-exclusive/mutually-exclusive.date.spec.js
@@ -31,7 +31,35 @@ const EXAMPLE_MUTUALLY_EXCLUSIVE_DATE_PARAMS = {
deselectExclusiveOptionAdjective: 'deselected',
exclusiveOptions: [
{
- id: 'date-exclusive-exclusive-option',
+ id: 'date-exclusive-option',
+ name: 'no-paid-job',
+ value: 'no-paid-job',
+ label: {
+ text: 'I have never had a paid job',
+ },
+ },
+ ],
+ },
+};
+
+const EXAMPLE_MUTUALLY_EXCLUSIVE_DATE_SINGLE_PARAMS = {
+ id: 'date-mutually-exclusive',
+ legendOrLabel: 'What year was your last MOT?',
+ description: 'For example, 2018',
+ year: {
+ label: {
+ text: 'Year',
+ },
+ name: 'year-exclusive',
+ },
+ mutuallyExclusive: {
+ or: 'Or',
+ deselectMessage: 'Selecting this will clear the date if one has been inputted',
+ deselectGroupAdjective: 'cleared',
+ deselectExclusiveOptionAdjective: 'deselected',
+ exclusiveOptions: [
+ {
+ id: 'date-exclusive-option',
name: 'no-paid-job',
value: 'no-paid-job',
label: {
@@ -57,11 +85,11 @@ describe('script: mutually-exclusive', () => {
describe('when the user clicks the mutually exclusive option', () => {
beforeEach(async () => {
- await page.click('#date-exclusive-exclusive-option');
+ await page.click('#date-exclusive-option');
});
it('then the mutually exclusive option should be checked', async () => {
- const isChecked = await page.$eval('#date-exclusive-exclusive-option', (node) => node.checked);
+ const isChecked = await page.$eval('#date-exclusive-option', (node) => node.checked);
expect(isChecked).toBe(true);
});
@@ -85,7 +113,7 @@ describe('script: mutually-exclusive', () => {
describe('Given the user has checked the mutually exclusive exclusive option', () => {
beforeEach(async () => {
- await page.click('#date-exclusive-exclusive-option');
+ await page.click('#date-exclusive-option');
});
describe('when the user populates the dateInput', () => {
@@ -95,8 +123,8 @@ describe('script: mutually-exclusive', () => {
await page.type('#date-mutually-exclusive-year', '2018');
});
- it('then the mutually exclusive option should be checked', async () => {
- const isChecked = await page.$eval('#date-exclusive-exclusive-option', (node) => node.checked);
+ it('then the mutually exclusive option should be unchecked', async () => {
+ const isChecked = await page.$eval('#date-exclusive-option', (node) => node.checked);
expect(isChecked).toBe(false);
});
@@ -127,7 +155,93 @@ describe('script: mutually-exclusive', () => {
describe('when the user clicks the mutually exclusive option', () => {
beforeEach(async () => {
- await page.click('#date-exclusive-exclusive-option');
+ await page.click('#date-exclusive-option');
+ });
+
+ it('then the aria alert shouldnt say anything', async () => {
+ await page.waitForTimeout(SCREEN_READER_TIMEOUT_DELAY);
+
+ const alertText = await page.$eval('.ons-js-exclusive-alert', (node) => node.textContent);
+ expect(alertText).toBe('');
+ });
+ });
+ });
+ });
+ describe('date-year', () => {
+ beforeEach(async () => {
+ await setTestPage('/test', renderComponent('date-input', EXAMPLE_MUTUALLY_EXCLUSIVE_DATE_SINGLE_PARAMS));
+ });
+
+ describe('Given the user populated the date input', () => {
+ beforeEach(async () => {
+ await page.type('#date-mutually-exclusive-year', '2018');
+ });
+
+ describe('when the user clicks the mutually exclusive option', () => {
+ beforeEach(async () => {
+ await page.click('#date-exclusive-option');
+ });
+
+ it('then the mutually exclusive option should be checked', async () => {
+ const isChecked = await page.$eval('#date-exclusive-option', (node) => node.checked);
+ expect(isChecked).toBe(true);
+ });
+
+ it('then the date input should be cleared', async () => {
+ const yearValue = await page.$eval('#date-mutually-exclusive-year', (node) => node.value);
+ expect(yearValue).toBe('');
+ });
+
+ it('then the aria alert should tell the user that the date input has been cleared', async () => {
+ await page.waitForTimeout(SCREEN_READER_TIMEOUT_DELAY);
+
+ const alertText = await page.$eval('.ons-js-exclusive-alert', (node) => node.textContent);
+ expect(alertText).toBe('What year was your last MOT? cleared.');
+ });
+ });
+ });
+
+ describe('Given the user has checked the mutually exclusive exclusive option', () => {
+ beforeEach(async () => {
+ await page.click('#date-exclusive-option');
+ });
+
+ describe('when the user populates the dateInput', () => {
+ beforeEach(async () => {
+ await page.type('#date-mutually-exclusive-year', '2018');
+ });
+
+ it('then the mutually exclusive option should be unchecked', async () => {
+ const isChecked = await page.$eval('#date-exclusive-option', (node) => node.checked);
+ expect(isChecked).toBe(false);
+ });
+
+ it('then the aria alert should tell the user that the exclusive option has been unchecked', async () => {
+ await page.waitForTimeout(SCREEN_READER_TIMEOUT_DELAY);
+
+ const alertText = await page.$eval('.ons-js-exclusive-alert', (node) => node.textContent);
+ expect(alertText).toBe('I have never had a paid job deselected.');
+ });
+ });
+ });
+
+ describe('Given the user has not populated the date input or checked the exclusive option', () => {
+ describe('when the user populates the date input', () => {
+ beforeEach(async () => {
+ await page.type('#date-mutually-exclusive-year', '2018');
+ });
+
+ it('then the aria alert shouldnt say anything', async () => {
+ await page.waitForTimeout(SCREEN_READER_TIMEOUT_DELAY);
+
+ const alertText = await page.$eval('.ons-js-exclusive-alert', (node) => node.textContent);
+ expect(alertText).toBe('');
+ });
+ });
+
+ describe('when the user clicks the mutually exclusive option', () => {
+ beforeEach(async () => {
+ await page.click('#date-exclusive-option');
});
it('then the aria alert shouldnt say anything', async () => {
diff --git a/src/components/mutually-exclusive/mutually-exclusive.duration.spec.js b/src/components/mutually-exclusive/mutually-exclusive.duration.spec.js
index eb1ab785ff..d2981a8129 100644
--- a/src/components/mutually-exclusive/mutually-exclusive.duration.spec.js
+++ b/src/components/mutually-exclusive/mutually-exclusive.duration.spec.js
@@ -48,6 +48,40 @@ const EXAMPLE_MUTUALLY_EXCLUSIVE_DURATION_PARAMS = {
},
};
+const EXAMPLE_MUTUALLY_EXCLUSIVE_DURATION_SINGLE_PARAMS = {
+ id: 'address-duration',
+ legendOrLabel: 'How long have you lived at this address?',
+ description: 'If you have lived at this address for less than a year then enter 0 into the year input.',
+ field1: {
+ id: 'address-duration-years',
+ name: 'address-duration-years',
+ suffix: {
+ text: 'Years',
+ id: 'address-duration-years-suffix',
+ },
+ attributes: {
+ min: 0,
+ max: 100,
+ },
+ },
+ mutuallyExclusive: {
+ or: 'Or',
+ deselectMessage: 'Selecting this will clear the date if one has been inputted',
+ deselectGroupAdjective: 'cleared',
+ deselectExclusiveOptionAdjective: 'deselected',
+ exclusiveOptions: [
+ {
+ id: 'duration-exclusive-option',
+ name: 'no-duration',
+ value: 'no-duration',
+ label: {
+ text: 'I have not moved in to this address yet',
+ },
+ },
+ ],
+ },
+};
+
describe('script: mutually-exclusive', () => {
describe('duration', () => {
beforeEach(async () => {
@@ -140,4 +174,91 @@ describe('script: mutually-exclusive', () => {
});
});
});
+
+ describe('duration-single', () => {
+ beforeEach(async () => {
+ await setTestPage('/test', renderComponent('duration', EXAMPLE_MUTUALLY_EXCLUSIVE_DURATION_SINGLE_PARAMS));
+ });
+
+ describe('Given the user populated the duration', () => {
+ beforeEach(async () => {
+ await page.type('#address-duration-years', '2');
+ });
+
+ describe('when the user clicks the mutually exclusive option', () => {
+ beforeEach(async () => {
+ await page.click('#duration-exclusive-option');
+ });
+
+ it('then the mutually exclusive option should be checked', async () => {
+ const isChecked = await page.$eval('#duration-exclusive-option', (node) => node.checked);
+ expect(isChecked).toBe(true);
+ });
+
+ it('then the inputs should be cleared', async () => {
+ const yearsValue = await page.$eval('#address-duration-years', (node) => node.value);
+ expect(yearsValue).toBe('');
+ });
+
+ it('then the aria alert should tell the user that the inputs have been cleared', async () => {
+ await page.waitForTimeout(SCREEN_READER_TIMEOUT_DELAY);
+
+ const alertText = await page.$eval('.ons-js-exclusive-alert', (node) => node.textContent);
+ expect(alertText).toBe('How long have you lived at this address? cleared.');
+ });
+ });
+ });
+
+ describe('Given the user has checked the mutually exclusive exclusive option', () => {
+ beforeEach(async () => {
+ await page.click('#duration-exclusive-option');
+ });
+
+ describe('when the user populates the duration fields', () => {
+ beforeEach(async () => {
+ await page.type('#address-duration-years', '2');
+ });
+
+ it('then the exclusive option should be unchecked', async () => {
+ const isChecked = await page.$eval('#duration-exclusive-option', (node) => node.checked);
+ expect(isChecked).toBe(false);
+ });
+
+ it('then the aria alert should tell the user that the exclusive option has been unchecked', async () => {
+ await page.waitForTimeout(SCREEN_READER_TIMEOUT_DELAY);
+
+ const alertText = await page.$eval('.ons-js-exclusive-alert', (node) => node.textContent);
+ expect(alertText).toBe('I have not moved in to this address yet deselected.');
+ });
+ });
+ });
+
+ describe('Given the user has not populated the duration inputs or checked the exclusive option', () => {
+ describe('when the user populates the duration inputs', () => {
+ beforeEach(async () => {
+ await page.type('#address-duration-years', '2');
+ });
+
+ it('then the aria alert shouldnt say anything', async () => {
+ await page.waitForTimeout(SCREEN_READER_TIMEOUT_DELAY);
+
+ const alertText = await page.$eval('.ons-js-exclusive-alert', (node) => node.textContent);
+ expect(alertText).toBe('');
+ });
+ });
+
+ describe('when the user clicks the mutually exclusive option', () => {
+ beforeEach(async () => {
+ await page.click('#duration-exclusive-option');
+ });
+
+ it('then the aria alert shouldnt say anything', async () => {
+ await page.waitForTimeout(SCREEN_READER_TIMEOUT_DELAY);
+
+ const alertText = await page.$eval('.ons-js-exclusive-alert', (node) => node.textContent);
+ expect(alertText).toBe('');
+ });
+ });
+ });
+ });
});