From 737524b01fd168c080cc77584bbc5c45a30b677a Mon Sep 17 00:00:00 2001
From: rmccar <42928680+rmccar@users.noreply.github.com>
Date: Wed, 6 Nov 2024 08:39:08 +0000
Subject: [PATCH 1/5] Document id param on autosuggest component (#3413)
---
src/components/autosuggest/_macro-options.md | 1 +
src/components/back-to-top/_macro-options.md | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/components/autosuggest/_macro-options.md b/src/components/autosuggest/_macro-options.md
index f0f0dd6f36..e169e62837 100644
--- a/src/components/autosuggest/_macro-options.md
+++ b/src/components/autosuggest/_macro-options.md
@@ -17,3 +17,4 @@
| resultsTitleId | string | true | ID for the results title. The ID is used in the results `aria-labelledby` to provide context for the results |
| input | `Input` [_(ref)_](/components/input) | true | Configuration object for the input |
| language | string | false | The ISO 639-1 Code will override the default language in page. Please note that only 'en', 'cy' and 'ni' is currently supported |
+| id | string | false | The `id` of the input |
diff --git a/src/components/back-to-top/_macro-options.md b/src/components/back-to-top/_macro-options.md
index aa3f9bcbf0..412c791034 100644
--- a/src/components/back-to-top/_macro-options.md
+++ b/src/components/back-to-top/_macro-options.md
@@ -1,4 +1,4 @@
| Name | Type | Required | Description |
| ----------- | ------ | -------- | -------------------------------------------------------------- |
| description | string | false | The text label added to the button. Defaults to "Back to Top" |
-| anchor | string | false | The 'id' of the element the button jumps to. Defaults to "Top" |
+| anchor | string | false | The `id` of the element the button jumps to. Defaults to "Top" |
From 2bdd1f1eebab601b88c4d8f8ca370a177a47efca Mon Sep 17 00:00:00 2001
From: rmccar <42928680+rmccar@users.noreply.github.com>
Date: Wed, 6 Nov 2024 09:50:43 +0000
Subject: [PATCH 2/5] Fix lighthouse hub and spoke test (#3410)
---
src/components/summary/_macro-options.md | 12 ++++++------
src/components/summary/_macro.njk | 8 ++++----
2 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/src/components/summary/_macro-options.md b/src/components/summary/_macro-options.md
index 52c01010b1..5b468576bb 100644
--- a/src/components/summary/_macro-options.md
+++ b/src/components/summary/_macro-options.md
@@ -53,12 +53,12 @@
## SummaryAction
-| Name | Type | Required | Description |
-| ------------------ | ------ | -------- | ------------------------------------------------------------------------------------------- |
-| text | string | true | Text for the action link |
-| url | string | true | The URL for the HTML `href` attribute of the link used to change the value of the row item |
-| attributes | object | false | HTML attributes (for example, data attributes) to add to the action link |
-| visuallyHiddenText | string | false | Visually hidden text in a span under the action link to add more context for screen readers |
+| Name | Type | Required | Description |
+| ------------------ | ------ | -------- | -------------------------------------------------------------------------------------------------------------------------------- |
+| text | string | true | Text for the action link |
+| url | string | true | The URL for the HTML `href` attribute of the link used to change the value of the row item |
+| attributes | object | false | HTML attributes (for example, data attributes) to add to the action link |
+| visuallyHiddenText | string | false | Visually hidden text in a span under the action link to add more context for screen readers, , defaults the text in `text` param |
## SummaryLink
diff --git a/src/components/summary/_macro.njk b/src/components/summary/_macro.njk
index 33ba88d346..8d3708d08d 100644
--- a/src/components/summary/_macro.njk
+++ b/src/components/summary/_macro.njk
@@ -112,10 +112,10 @@
class="ons-summary__button"
{% if action.attributes %}{% for attribute, value in (action.attributes.items() if action.attributes is mapping and action.attributes.items else action.attributes) %}{{ ' ' }}{{ attribute }}="{{ value }}"{% endfor %}{% endif %}
>
-
- {{- action.text -}}
-
- {{ action.visuallyHiddenText }}
+ {{- action.text -}}
+ {{ action.visuallyHiddenText | default (action.text) }}
{% endfor %}
From 7d9b0ac76b7eaae83567ceae036fd4ceb1f29c38 Mon Sep 17 00:00:00 2001
From: Precious Onyenaucheya
<86783201+precious-onyenaucheya-ons@users.noreply.github.com>
Date: Thu, 7 Nov 2024 15:31:53 +0000
Subject: [PATCH 3/5] Update Fuse.js configuration to adjust search threshold
(#3288)
* increase search threshold
* update threshold
* add option to extend search
* update logic
* update autosggest
* update validation
* Update src/components/autosuggest/example-autosuggest-country.njk
Co-authored-by: rmccar <42928680+rmccar@users.noreply.github.com>
* Update src/components/autosuggest/autosuggest.ui.js
Co-authored-by: rmccar <42928680+rmccar@users.noreply.github.com>
* rename to resultsThreshold
* update
* update
* update test
* update fuse config
* update param type in md file
* update from tenary to if else statement block
* update fuse version
* fix issue with search
* fix failing tests
* remove log
---------
Co-authored-by: rmccar <42928680+rmccar@users.noreply.github.com>
---
package.json | 2 +-
src/components/autosuggest/_macro-options.md | 41 ++++++++--------
src/components/autosuggest/_macro.njk | 1 +
src/components/autosuggest/_macro.spec.js | 8 +++-
src/components/autosuggest/autosuggest.ui.js | 48 +++++++++++++++----
.../example-autosuggest-country.njk | 3 +-
src/components/autosuggest/fuse-config.js | 9 +++-
src/js/analytics.js | 2 +-
yarn.lock | 39 +++------------
9 files changed, 85 insertions(+), 68 deletions(-)
diff --git a/package.json b/package.json
index 3555c80139..1d843290b9 100644
--- a/package.json
+++ b/package.json
@@ -84,7 +84,7 @@
"express": "^4.17.1",
"front-matter": "^4.0.2",
"fs-extra": "^11.1.1",
- "fuse.js": "^3.6.1",
+ "fuse.js": "^7.0.0",
"glob": "^10.2.3",
"gulp": "^4.0.2",
"gulp-babel": "^8.0.0",
diff --git a/src/components/autosuggest/_macro-options.md b/src/components/autosuggest/_macro-options.md
index e169e62837..90f8b166ab 100644
--- a/src/components/autosuggest/_macro-options.md
+++ b/src/components/autosuggest/_macro-options.md
@@ -1,20 +1,21 @@
-| Name | Type | Required | Description |
-| ------------------- | ------------------------------------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
-| autosuggestData | string | false | URL of the JSON file with the autosuggest data that needs to be searched. Required if not using the address index api |
-| allowMultiple | boolean | false | Allows the component to accept multiple selections |
-| instructions | string | true | Instructions on how to use the autosuggest that will be read out by screen readers |
-| ariaYouHaveSelected | string | true | Aria message to tell the user that they have selected an answer |
-| ariaMinChars | string | true | Aria message to tell the user how many characters they need to enter before autosuggest will start |
-| minChars | integer | false | Minimum number of characters to run a query. Default is 3 |
-| ariaOneResult | string | true | Aria message to tell the user there is only one suggestion left |
-| ariaNResults | string | true | Aria message to tell the user how many suggestions are left |
-| ariaLimitedResults | string | true | Aria message to tell the user if the results have been limited and what they are limited to |
-| moreResults | string | true | Aria message to tell the user to continue to type to refine suggestions |
-| noResults | string | true | message to tell the user there are no results |
-| tooManyResults | string | false | message to tell the user there are too many results to display and the user should refine the search. This is only required when using the address index api |
-| typeMore | string | true | message to encourage the user to enter more characters to get suggestions |
-| resultsTitle | string | true | Title of results to be displayed on screen at the top of the results |
-| resultsTitleId | string | true | ID for the results title. The ID is used in the results `aria-labelledby` to provide context for the results |
-| input | `Input` [_(ref)_](/components/input) | true | Configuration object for the input |
-| language | string | false | The ISO 639-1 Code will override the default language in page. Please note that only 'en', 'cy' and 'ni' is currently supported |
-| id | string | false | The `id` of the input |
+| Name | Type | Required | Description |
+| ------------------- | ------------------------------------ | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| autosuggestData | string | false | URL of the JSON file with the autosuggest data that needs to be searched. Required if not using the address index api |
+| allowMultiple | boolean | false | Allows the component to accept multiple selections |
+| instructions | string | true | Instructions on how to use the autosuggest that will be read out by screen readers |
+| ariaYouHaveSelected | string | true | Aria message to tell the user that they have selected an answer |
+| ariaMinChars | string | true | Aria message to tell the user how many characters they need to enter before autosuggest will start |
+| minChars | integer | false | Minimum number of characters to run a query. Default is 3 |
+| ariaOneResult | string | true | Aria message to tell the user there is only one suggestion left |
+| ariaNResults | string | true | Aria message to tell the user how many suggestions are left |
+| ariaLimitedResults | string | true | Aria message to tell the user if the results have been limited and what they are limited to |
+| moreResults | string | true | Aria message to tell the user to continue to type to refine suggestions |
+| noResults | string | true | message to tell the user there are no results |
+| tooManyResults | string | false | message to tell the user there are too many results to display and the user should refine the search. This is only required when using the address index api |
+| typeMore | string | true | message to encourage the user to enter more characters to get suggestions |
+| resultsTitle | string | true | Title of results to be displayed on screen at the top of the results |
+| resultsTitleId | string | true | ID for the results title. The ID is used in the results `aria-labelledby` to provide context for the results |
+| input | `Input` [_(ref)_](/components/input) | true | Configuration object for the input |
+| language | string | false | The ISO 639-1 Code will override the default language in page. Please note that only 'en', 'cy' and 'ni' is currently supported |
+| resultsThreshold | float | false | Option to adjust the search threshold and fuzziness. Accepts a range from 0 to 1, where 0 provides the closest match and 1 allows for more distant matches. Defaults to 0.2. |
+| id | string | false | The `id` of the input |
diff --git a/src/components/autosuggest/_macro.njk b/src/components/autosuggest/_macro.njk
index b8c2f4c52f..a5d18997e6 100644
--- a/src/components/autosuggest/_macro.njk
+++ b/src/components/autosuggest/_macro.njk
@@ -15,6 +15,7 @@
data-results-title="{{ params.resultsTitle }}"
data-no-results="{{ params.noResults }}"
data-type-more="{{ params.typeMore }}"
+ {% if params.resultsThreshold %}data-result-threshold="{{ params.resultsThreshold }}"{% endif %}
{% if params.apiDomain %}data-api-domain="{{ params.apiDomain }}"{% endif %}
{% if params.apiDomainBearerToken %}data-authorization-token="{{ params.apiDomainBearerToken }}"{% endif %}
{% if params.apiManualQueryParams == true %}data-query-params=""{% endif %}
diff --git a/src/components/autosuggest/_macro.spec.js b/src/components/autosuggest/_macro.spec.js
index efac0908e7..ee9c897fdf 100644
--- a/src/components/autosuggest/_macro.spec.js
+++ b/src/components/autosuggest/_macro.spec.js
@@ -32,6 +32,11 @@ const EXAMPLE_AUTOSUGGEST = {
typeMore: 'Continue entering to get suggestions',
};
+const EXAMPLE_AUTOSUGGEST_WITH_RESULTS_THRESHOLD = {
+ ...EXAMPLE_AUTOSUGGEST,
+ resultsThreshold: 0.5,
+};
+
describe('macro: autosuggest', () => {
it('passes jest-axe checks', async () => {
const $ = cheerio.load(renderComponent('autosuggest', EXAMPLE_AUTOSUGGEST));
@@ -47,7 +52,7 @@ describe('macro: autosuggest', () => {
});
it('has the provided data attributes', () => {
- const $ = cheerio.load(renderComponent('autosuggest', EXAMPLE_AUTOSUGGEST));
+ const $ = cheerio.load(renderComponent('autosuggest', EXAMPLE_AUTOSUGGEST_WITH_RESULTS_THRESHOLD));
const $element = $('.ons-autosuggest');
expect($element.attr('data-allow-multiple')).toBeUndefined();
@@ -63,6 +68,7 @@ describe('macro: autosuggest', () => {
expect($element.attr('data-no-results')).toBe('No suggestions found. You can enter your own answer');
expect($element.attr('data-results-title')).toBe('Suggestions');
expect($element.attr('data-type-more')).toBe('Continue entering to get suggestions');
+ expect($element.attr('data-result-threshold')).toBe('0.5');
});
it('has the `data-allow-multiple` attribute when `allowMultiple` is `true`', () => {
diff --git a/src/components/autosuggest/autosuggest.ui.js b/src/components/autosuggest/autosuggest.ui.js
index 1a19883df5..74cce5e8a0 100644
--- a/src/components/autosuggest/autosuggest.ui.js
+++ b/src/components/autosuggest/autosuggest.ui.js
@@ -37,6 +37,7 @@ export default class AutosuggestUI {
errorAPI,
errorAPILinkText,
typeMore,
+ customResultsThreshold,
}) {
// DOM Elements
this.context = context;
@@ -65,6 +66,7 @@ export default class AutosuggestUI {
this.errorAPI = errorAPI || context.getAttribute('data-error-api');
this.errorAPILinkText = errorAPILinkText || context.getAttribute('data-error-api-link-text');
this.typeMore = typeMore || context.getAttribute('data-type-more');
+ this.customResultsThreshold = customResultsThreshold || context.getAttribute('data-result-threshold');
this.language = context.getAttribute('data-lang');
this.allowMultiple = context.getAttribute('data-allow-multiple') || false;
this.listboxId = this.listbox.getAttribute('id');
@@ -293,9 +295,30 @@ export default class AutosuggestUI {
async fetchSuggestions(sanitisedQuery, data) {
this.abortFetch();
- const results = await runFuse(sanitisedQuery, data, this.lang, this.resultLimit);
+
+ const threshold =
+ this.customResultsThreshold != null && this.customResultsThreshold >= 0 && this.customResultsThreshold <= 1
+ ? this.customResultsThreshold
+ : 0.2;
+
+ let distance;
+ if (threshold >= 0.6) {
+ distance = 500;
+ } else if (threshold >= 0.4) {
+ distance = 300;
+ } else {
+ distance = 100;
+ }
+
+ const results = await runFuse(sanitisedQuery, data, this.lang, threshold, distance);
+
results.forEach((result) => {
- result.sanitisedText = sanitiseAutosuggestText(result[this.lang], this.sanitisedQueryReplaceChars);
+ const resultItem = result.item ?? result;
+
+ result.sanitisedText = sanitiseAutosuggestText(
+ resultItem[this.lang] ?? resultItem['formattedAddress'],
+ this.sanitisedQueryReplaceChars,
+ );
});
return {
status: this.responseStatus,
@@ -345,16 +368,18 @@ export default class AutosuggestUI {
this.listbox.innerHTML = '';
if (this.results) {
this.resultOptions = this.results.map((result, index) => {
- let innerHTML = this.emboldenMatch(result[this.lang], this.query);
+ const resultItem = result.item ?? result;
+
+ let innerHTML = this.emboldenMatch(resultItem[this.lang] ?? resultItem['formattedAddress'], this.query);
const listElement = document.createElement('li');
listElement.className = classAutosuggestOption;
listElement.setAttribute('id', `${this.listboxId}__option--${index}`);
listElement.setAttribute('role', 'option');
- if (result.category) {
+ if (resultItem.category) {
innerHTML =
innerHTML +
- `${result.category}`;
+ `${resultItem.category}`;
}
listElement.innerHTML = innerHTML;
listElement.addEventListener('click', () => {
@@ -485,16 +510,19 @@ export default class AutosuggestUI {
if (this.results.length) {
this.settingResult = true;
const result = this.results[index || this.highlightedResultIndex || 0];
+ const resultItem = result.item ?? result;
+ const resultValue = resultItem[this.lang] ?? resultItem['formattedAddress'];
+
this.resultSelected = true;
if (this.allowMultiple === 'true') {
- let value = this.storeExistingSelections(result[this.lang]);
+ let value = this.storeExistingSelections(resultValue);
result.displayText = value;
- } else if (result.url) {
- result.displayText = result[this.lang];
- window.location = result.url;
+ } else if (resultItem.url) {
+ result.displayText = resultValue;
+ window.location = resultItem.url;
} else {
- result.displayText = result[this.lang];
+ result.displayText = resultValue;
}
this.onSelect(result).then(() => (this.settingResult = false));
diff --git a/src/components/autosuggest/example-autosuggest-country.njk b/src/components/autosuggest/example-autosuggest-country.njk
index ddf071ddb0..3358178ad1 100644
--- a/src/components/autosuggest/example-autosuggest-country.njk
+++ b/src/components/autosuggest/example-autosuggest-country.njk
@@ -24,7 +24,8 @@
"resultsTitleId": "country-of-birth-suggestions",
"autosuggestData": "/examples/data/country-of-birth.json",
"noResults": "No suggestions found. You can enter your own answer",
- "typeMore": "Continue entering to get suggestions"
+ "typeMore": "Continue entering to get suggestions",
+ "resultsThreshold": 0.2
})
}}
diff --git a/src/components/autosuggest/fuse-config.js b/src/components/autosuggest/fuse-config.js
index 2b7724a47e..70dade58b6 100644
--- a/src/components/autosuggest/fuse-config.js
+++ b/src/components/autosuggest/fuse-config.js
@@ -1,14 +1,19 @@
import Fuse from 'fuse.js';
-export default function runFuse(query, data, searchFields) {
+export default function runFuse(query, data, searchFields, threshold, distance) {
const options = {
shouldSort: true,
- threshold: 0.2,
+ threshold: threshold,
+ distance: distance,
keys: [
{
name: searchFields,
weight: 0.9,
},
+ {
+ name: 'formattedAddress',
+ weight: 0.9,
+ },
{
name: 'tags',
weight: 0.1,
diff --git a/src/js/analytics.js b/src/js/analytics.js
index 1e6ac1cd86..3bc1d3dad7 100644
--- a/src/js/analytics.js
+++ b/src/js/analytics.js
@@ -44,7 +44,7 @@ export default function initAnalytics() {
document.body.addEventListener('click', ({ target }) => {
if (target.getAttribute('data-ga') === 'click') {
return trackElement(target, 'click');
- } else if (target.parentElement.getAttribute('data-ga') === 'click') {
+ } else if (target.parentElement?.getAttribute('data-ga') === 'click') {
return trackElement(target.parentElement, 'click');
}
});
diff --git a/yarn.lock b/yarn.lock
index 208423613e..56930019ef 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -5655,10 +5655,10 @@ functions-have-names@^1.2.3:
resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834"
integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==
-fuse.js@^3.6.1:
- version "3.6.1"
- resolved "https://registry.yarnpkg.com/fuse.js/-/fuse.js-3.6.1.tgz#7de85fdd6e1b3377c23ce010892656385fd9b10c"
- integrity sha512-hT9yh/tiinkmirKrlv4KWOjztdoZo1mx9Qh4KvWqC7isoXwdUY3PNWUxceF4/qO9R6riA2C29jdTOeQOIROjgw==
+fuse.js@^7.0.0:
+ version "7.0.0"
+ resolved "https://registry.yarnpkg.com/fuse.js/-/fuse.js-7.0.0.tgz#6573c9fcd4c8268e403b4fc7d7131ffcf99a9eb2"
+ integrity sha512-14F4hBIxqKvD4Zz/XjDc3y94mNZN6pRv3U13Udo0lNLCWRBUsrMv2xwcF/y/Z5sV6+FQW+/ow68cHpm4sunt8Q==
gensync@^1.0.0-beta.2:
version "1.0.0-beta.2"
@@ -11308,7 +11308,7 @@ string-length@^4.0.1:
char-regex "^1.0.2"
strip-ansi "^6.0.0"
-"string-width-cjs@npm:string-width@^4.2.0":
+"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
version "4.2.3"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
@@ -11326,15 +11326,6 @@ string-width@^1.0.1, string-width@^1.0.2:
is-fullwidth-code-point "^1.0.0"
strip-ansi "^3.0.0"
-string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
- version "4.2.3"
- resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
- integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
- dependencies:
- emoji-regex "^8.0.0"
- is-fullwidth-code-point "^3.0.0"
- strip-ansi "^6.0.1"
-
string-width@^5.0.1, string-width@^5.1.2:
version "5.1.2"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794"
@@ -11403,7 +11394,7 @@ string_decoder@~1.1.1:
dependencies:
safe-buffer "~5.1.0"
-"strip-ansi-cjs@npm:strip-ansi@^6.0.1":
+"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1:
version "6.0.1"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
@@ -11424,13 +11415,6 @@ strip-ansi@^4.0.0:
dependencies:
ansi-regex "^3.0.0"
-strip-ansi@^6.0.0, strip-ansi@^6.0.1:
- version "6.0.1"
- resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
- integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
- dependencies:
- ansi-regex "^5.0.1"
-
strip-ansi@^7.0.0, strip-ansi@^7.0.1, strip-ansi@^7.1.0:
version "7.1.0"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45"
@@ -12811,7 +12795,7 @@ which@^2.0.1:
dependencies:
isexe "^2.0.0"
-"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0":
+"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
@@ -12828,15 +12812,6 @@ wrap-ansi@^2.0.0:
string-width "^1.0.1"
strip-ansi "^3.0.1"
-wrap-ansi@^7.0.0:
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
- integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
- dependencies:
- ansi-styles "^4.0.0"
- string-width "^4.1.0"
- strip-ansi "^6.0.0"
-
wrap-ansi@^8.1.0:
version "8.1.0"
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214"
From af04adf9a8e96d0b9a114d9ae4dca304f53b4285 Mon Sep 17 00:00:00 2001
From: SriHV <123635670+SriHV@users.noreply.github.com>
Date: Fri, 8 Nov 2024 16:37:00 +0000
Subject: [PATCH 4/5] Refactor Address output component test file to new format
(#3308)
* modified test cases as per the ticket
* changes in the given statements
* changes as per comments
* commiting latest changes
* Changes as per comments
* removing no params example
* Update src/components/address-output/_test_examples.js
Co-authored-by: rmccar <42928680+rmccar@users.noreply.github.com>
* Update src/components/address-output/_macro.spec.js
Co-authored-by: rmccar <42928680+rmccar@users.noreply.github.com>
* Update src/components/address-output/_macro.spec.js
Co-authored-by: rmccar <42928680+rmccar@users.noreply.github.com>
* Update src/components/address-output/_macro.spec.js
Co-authored-by: rmccar <42928680+rmccar@users.noreply.github.com>
* Update src/components/address-output/_macro.spec.js
Co-authored-by: rmccar <42928680+rmccar@users.noreply.github.com>
* Update src/components/address-output/_macro.spec.js
Co-authored-by: rmccar <42928680+rmccar@users.noreply.github.com>
* Update src/components/address-output/_macro.spec.js
Co-authored-by: rmccar <42928680+rmccar@users.noreply.github.com>
* Update src/components/address-output/_macro.spec.js
Co-authored-by: rmccar <42928680+rmccar@users.noreply.github.com>
* Update src/components/address-output/_macro.spec.js
Co-authored-by: rmccar <42928680+rmccar@users.noreply.github.com>
* Update src/components/address-output/_macro.spec.js
Co-authored-by: rmccar <42928680+rmccar@users.noreply.github.com>
* Update src/components/address-output/_macro.spec.js
Co-authored-by: rmccar <42928680+rmccar@users.noreply.github.com>
* Update src/components/address-output/_macro.spec.js
Co-authored-by: rmccar <42928680+rmccar@users.noreply.github.com>
* Update src/components/address-output/_macro.spec.js
Co-authored-by: rmccar <42928680+rmccar@users.noreply.github.com>
* Update src/components/address-output/_macro.spec.js
Co-authored-by: rmccar <42928680+rmccar@users.noreply.github.com>
* Update src/components/address-output/_macro.spec.js
Co-authored-by: rmccar <42928680+rmccar@users.noreply.github.com>
* Update src/components/address-output/_macro.spec.js
Co-authored-by: rmccar <42928680+rmccar@users.noreply.github.com>
* Update src/components/address-output/_macro.spec.js
Co-authored-by: rmccar <42928680+rmccar@users.noreply.github.com>
* Update src/components/address-output/_macro.spec.js
Co-authored-by: rmccar <42928680+rmccar@users.noreply.github.com>
* Update src/components/address-output/_macro.spec.js
Co-authored-by: rmccar <42928680+rmccar@users.noreply.github.com>
* Update src/components/address-output/_macro.spec.js
Co-authored-by: rmccar <42928680+rmccar@users.noreply.github.com>
* Update src/components/address-output/_macro.spec.js
Co-authored-by: rmccar <42928680+rmccar@users.noreply.github.com>
---------
Co-authored-by: Alessio Venturini <112873190+alessioventuriniAND@users.noreply.github.com>
Co-authored-by: rmccar <42928680+rmccar@users.noreply.github.com>
---
src/components/address-output/_macro.spec.js | 195 +++++++++++-------
.../address-output/_test_examples.js | 8 +
2 files changed, 129 insertions(+), 74 deletions(-)
create mode 100644 src/components/address-output/_test_examples.js
diff --git a/src/components/address-output/_macro.spec.js b/src/components/address-output/_macro.spec.js
index d94484c316..692cf12432 100644
--- a/src/components/address-output/_macro.spec.js
+++ b/src/components/address-output/_macro.spec.js
@@ -5,94 +5,141 @@ import * as cheerio from 'cheerio';
import axe from '../../tests/helpers/axe';
import { renderComponent } from '../../tests/helpers/rendering';
-const EXAMPLE_ADDRESS_OUTPUT_FULL = {
- unit: 'Unit 5',
- organisation: 'Trescos',
- line1: 'Abingdon Road',
- line2: 'Goathill',
- town: 'Barry',
- postcode: 'AB12 6UH',
-};
-
-const EXAMPLE_ADDRESS_OUTPUT_NONE = {};
-
-describe('macro: address-output', () => {
- it('passes jest-axe checks', async () => {
- const $ = cheerio.load(renderComponent('address-output', EXAMPLE_ADDRESS_OUTPUT_FULL));
-
- const results = await axe($.html());
- expect(results).toHaveNoViolations();
- });
+import { EXAMPLE_ADDRESS_OUTPUT_FULL } from './_test_examples';
- it('has additionally provided container style classes', () => {
- const $ = cheerio.load(
- renderComponent('address-output', {
- ...EXAMPLE_ADDRESS_OUTPUT_FULL,
- classes: 'extra-class another-extra-class',
- }),
- );
+describe('FOR: Macro: Address-output', () => {
+ describe('GIVEN: Params: none', () => {
+ describe('WHEN: no parameters are provided', () => {
+ const $ = cheerio.load(renderComponent('address-output', {}));
- expect($('.ons-address-output').hasClass('extra-class')).toBe(true);
- expect($('.ons-address-output').hasClass('another-extra-class')).toBe(true);
+ test('THEN: renders no lines', () => {
+ expect($('.ons-address-output__lines *').length).toBe(0);
+ });
+ });
});
- it('renders no lines when no parameters are provided', () => {
- const $ = cheerio.load(renderComponent('address-output', EXAMPLE_ADDRESS_OUTPUT_NONE));
-
- expect($('.ons-address-output__lines *').length).toBe(0);
+ describe('GIVEN: Params: classes', () => {
+ describe('WHEN: classes are provided', () => {
+ const $ = cheerio.load(
+ renderComponent('address-output', {
+ ...EXAMPLE_ADDRESS_OUTPUT_FULL,
+ classes: 'extra-class another-extra-class',
+ }),
+ );
+
+ test('THEN: renders with additional classes provided', async () => {
+ expect($('.ons-address-output').hasClass('extra-class')).toBe(true);
+ expect($('.ons-address-output').hasClass('another-extra-class')).toBe(true);
+ });
+ });
});
- it.each([
- ['all address lines', EXAMPLE_ADDRESS_OUTPUT_FULL],
- ['single line', { unit: 'Unit 5' }],
- ])('renders `unit` with %s', (_, params) => {
- const $ = cheerio.load(renderComponent('address-output', params));
+ describe('GIVEN: Params: All params', () => {
+ describe('WHEN: all address line params are provided', () => {
+ const $ = cheerio.load(renderComponent('address-output', EXAMPLE_ADDRESS_OUTPUT_FULL));
- expect($('.ons-address-output__unit').text().trim()).toBe('Unit 5');
- });
+ test('THEN: jest-axe tests pass', async () => {
+ const results = await axe($.html());
+ expect(results).toHaveNoViolations();
+ });
- it.each([
- ['all address lines', EXAMPLE_ADDRESS_OUTPUT_FULL],
- ['single line', { organisation: 'Trescos' }],
- ])('renders `organisation` with %s', (_, params) => {
- const $ = cheerio.load(renderComponent('address-output', params));
+ test('THEN: renders unit with provided text', () => {
+ expect($('.ons-address-output__unit').text().trim()).toBe('Unit 5');
+ });
- expect($('.ons-address-output__organisation').text().trim()).toBe('Trescos');
- });
+ test('THEN: renders organisation line with correct text', () => {
+ expect($('.ons-address-output__organisation').text().trim()).toBe('Trescos');
+ });
- it.each([
- ['all address lines', EXAMPLE_ADDRESS_OUTPUT_FULL],
- ['single line', { line1: 'Abingdon Road' }],
- ])('renders `line1` with %s', (_, params) => {
- const $ = cheerio.load(renderComponent('address-output', params));
+ test('THEN: renders line1 line with correct text', () => {
+ expect($('.ons-address-output__line1').text().trim()).toBe('Abingdon Road');
+ });
- expect($('.ons-address-output__line1').text().trim()).toBe('Abingdon Road');
- });
+ test('THEN: renders line2 line with correct text', () => {
+ expect($('.ons-address-output__line2').text().trim()).toBe('Goathill');
+ });
- it.each([
- ['all address lines', EXAMPLE_ADDRESS_OUTPUT_FULL],
- ['single line', { line2: 'Goathill' }],
- ])('renders `line2` with %s', (_, params) => {
- const $ = cheerio.load(renderComponent('address-output', params));
+ test('THEN: renders the town line with correct text', () => {
+ expect($('.ons-address-output__town').text().trim()).toBe('Barry');
+ });
- expect($('.ons-address-output__line2').text().trim()).toBe('Goathill');
+ test('THEN: renders the postcode line with correct text', () => {
+ expect($('.ons-address-output__postcode').text().trim()).toBe('AB12 6UH');
+ });
+ });
});
- it.each([
- ['all address lines', EXAMPLE_ADDRESS_OUTPUT_FULL],
- ['single line', { town: 'Barry' }],
- ])('renders `town` with %s', (_, params) => {
- const $ = cheerio.load(renderComponent('address-output', params));
-
- expect($('.ons-address-output__town').text().trim()).toBe('Barry');
- });
-
- it.each([
- ['all address lines', EXAMPLE_ADDRESS_OUTPUT_FULL],
- ['single line', { postcode: 'AB12 6UH' }],
- ])('renders `postcode` with %s', (_, params) => {
- const $ = cheerio.load(renderComponent('address-output', params));
-
- expect($('.ons-address-output__postcode').text().trim()).toBe('AB12 6UH');
+ describe('GIVEN: Params: single param', () => {
+ describe('WHEN: the unit address line is the only parameter provided', () => {
+ const $ = cheerio.load(
+ renderComponent('address-output', {
+ unit: 'Unit 5',
+ }),
+ );
+
+ test('THEN: renders unit line with correct text', () => {
+ expect($('.ons-address-output__unit').text().trim()).toBe('Unit 5');
+ });
+ });
+
+ describe('WHEN: the organisation address line is the only parameter provided', () => {
+ const $ = cheerio.load(
+ renderComponent('address-output', {
+ organisation: 'Trescos',
+ }),
+ );
+
+ test('THEN: renders organisation line with correct text', () => {
+ expect($('.ons-address-output__organisation').text().trim()).toBe('Trescos');
+ });
+ });
+
+ describe('WHEN: the line1 address line is the only parameter provided', () => {
+ const $ = cheerio.load(
+ renderComponent('address-output', {
+ line1: 'Abingdon Road',
+ }),
+ );
+
+ test('THEN: renders line1 line with correct text', () => {
+ expect($('.ons-address-output__line1').text().trim()).toBe('Abingdon Road');
+ });
+ });
+
+ describe('WHEN: the line2 address line is the only parameter provided', () => {
+ const $ = cheerio.load(
+ renderComponent('address-output', {
+ line2: 'Goathill',
+ }),
+ );
+
+ test('THEN: renders line2 line with correct text', () => {
+ expect($('.ons-address-output__line2').text().trim()).toBe('Goathill');
+ });
+ });
+
+ describe('WHEN: the town address line is the only parameter provided', () => {
+ const $ = cheerio.load(
+ renderComponent('address-output', {
+ town: 'Barry',
+ }),
+ );
+
+ test('THEN: renders town line with correct text', () => {
+ expect($('.ons-address-output__town').text().trim()).toBe('Barry');
+ });
+ });
+
+ describe('WHEN: the postcode address line is the only parameter provided', () => {
+ const $ = cheerio.load(
+ renderComponent('address-output', {
+ postcode: 'AB12 6UH',
+ }),
+ );
+
+ test('THEN: renders postcode line with correct text', () => {
+ expect($('.ons-address-output__postcode').text().trim()).toBe('AB12 6UH');
+ });
+ });
});
});
diff --git a/src/components/address-output/_test_examples.js b/src/components/address-output/_test_examples.js
new file mode 100644
index 0000000000..08bb96889f
--- /dev/null
+++ b/src/components/address-output/_test_examples.js
@@ -0,0 +1,8 @@
+export const EXAMPLE_ADDRESS_OUTPUT_FULL = {
+ unit: 'Unit 5',
+ organisation: 'Trescos',
+ line1: 'Abingdon Road',
+ line2: 'Goathill',
+ town: 'Barry',
+ postcode: 'AB12 6UH',
+};
From c31346c9296625328a1f0df183e4f72c0bbe1bd0 Mon Sep 17 00:00:00 2001
From: rmccar <42928680+rmccar@users.noreply.github.com>
Date: Fri, 8 Nov 2024 22:26:47 +0000
Subject: [PATCH 5/5] Fix flakey macro tests (#3414)
---
.../address-input/autosuggest.address.spec.js | 30 ++++++++++---------
.../timeout-modal/timeout-modal.spec.js | 2 +-
2 files changed, 17 insertions(+), 15 deletions(-)
diff --git a/src/components/address-input/autosuggest.address.spec.js b/src/components/address-input/autosuggest.address.spec.js
index 9c2636d988..42f8e0c9d6 100644
--- a/src/components/address-input/autosuggest.address.spec.js
+++ b/src/components/address-input/autosuggest.address.spec.js
@@ -189,7 +189,7 @@ describe('script: address-input', () => {
await setTestPage('/test', renderComponent('address-input', EXAMPLE_ADDRESS_INPUT_WITH_API));
await setTimeout(50);
- expect(apiFaker.getRequestCount('/addresses/eq?input=cf142&limit=10')).toBe(1);
+ expect(await apiFaker.getRequestCount('/addresses/eq?input=cf142&limit=10')).toBe(1);
});
describe('when api status is okay', () => {
@@ -257,8 +257,9 @@ describe('script: address-input', () => {
await page.$eval('.ons-js-autosuggest-input', (node) => (node.value = '196 coll'));
await page.type('.ons-js-autosuggest-input', 'e');
+ await setTimeout(50);
- expect(apiFaker.getRequestCount('/addresses/eq?input=196%20colle&limit=10')).toBe(1);
+ expect(await apiFaker.getRequestCount('/addresses/eq?input=196%20colle&limit=10')).toBe(1);
});
describe('when the value is a full postcode', () => {
@@ -267,14 +268,15 @@ describe('script: address-input', () => {
await page.$eval('.ons-js-autosuggest-input', (node) => (node.value = 'CF14 2N'));
await page.type('.ons-js-autosuggest-input', 'T');
+
+ await setTimeout(100);
});
it('provides expected parameters to the address API where `limit` is 100', async () => {
- expect(apiFaker.getRequestCount('/addresses/eq?input=cf14%202nt&limit=100&groupfullpostcodes=combo')).toBe(1);
+ expect(await apiFaker.getRequestCount('/addresses/eq?input=cf14%202nt&limit=100&groupfullpostcodes=combo')).toBe(1);
});
it('has expected suggestion entries', async () => {
- await setTimeout(100);
const suggestions = await page.$$eval('.ons-autosuggest__option', (nodes) => nodes.map((node) => node.textContent.trim()));
expect(suggestions).toEqual(['196 College Road, Birmingham, B44 8HF', '196 College Road, Whitchurch, Cardiff, CF14 2NZ']);
});
@@ -314,7 +316,7 @@ describe('script: address-input', () => {
it('provides expected parameters to the address API', async () => {
expect(
- apiFaker.getRequestCount(
+ await apiFaker.getRequestCount(
'/addresses/eq?input=penlline%20road%20whitchurch%20cardiff%20cf14%202nz&limit=100&groupfullpostcodes=combo',
),
).toBe(1);
@@ -336,7 +338,7 @@ describe('script: address-input', () => {
});
it('makes expected request when a suggestion is selected', async () => {
- expect(apiFaker.getRequestCount('/addresses/eq/uprn/100070332099?addresstype=paf')).toBe(1);
+ expect(await apiFaker.getRequestCount('/addresses/eq/uprn/100070332099?addresstype=paf')).toBe(1);
});
it('populates manual input fields with address from selection', async () => {
@@ -360,7 +362,7 @@ describe('script: address-input', () => {
});
it('provides expected parameters to the address API', async () => {
- expect(apiFaker.getRequestCount('/addresses/eq?input=cf14%202&limit=10')).toBe(1);
+ expect(await apiFaker.getRequestCount('/addresses/eq?input=cf14%202&limit=10')).toBe(1);
});
it('has expected suggestion entries', async () => {
@@ -380,7 +382,7 @@ describe('script: address-input', () => {
it('makes expected request', async () => {
expect(
- apiFaker.getRequestCount(
+ await apiFaker.getRequestCount(
'/addresses/eq/bucket?postcode=CF14%202AA&streetname=Penlline%20Road&townname=Whitchurch&groupfullpostcodes=combo',
),
).toBe(1);
@@ -611,7 +613,9 @@ describe('script: address-input', () => {
await page.$eval('.ons-js-autosuggest-input', (node) => (node.value = '196 coll'));
await page.type('.ons-js-autosuggest-input', 'e');
- expect(apiFaker.getRequestCount('/addresses/eq?input=196%20colle&limit=10&favourwelsh=true')).toBe(1);
+ await setTimeout(50);
+
+ expect(await apiFaker.getRequestCount('/addresses/eq?input=196%20colle&limit=10&favourwelsh=true')).toBe(1);
});
});
@@ -629,7 +633,7 @@ describe('script: address-input', () => {
});
it('then the retrieveAddress function will be called', async () => {
- expect(apiFaker.getRequestCount('/addresses/eq/uprn/100070332099?addresstype=paf')).toBe(1);
+ expect(await apiFaker.getRequestCount('/addresses/eq/uprn/100070332099?addresstype=paf')).toBe(1);
});
});
@@ -735,10 +739,9 @@ describe('script: address-input', () => {
it('provides expected parameters to the address API', async () => {
await page.$eval('.ons-js-autosuggest-input', (node) => (node.value = '196 coll'));
await page.type('.ons-js-autosuggest-input', 'e');
-
await setTimeout(50);
- expect(apiFaker.getRequestCount(searchEndpoint)).toBe(1);
+ expect(await apiFaker.getRequestCount(searchEndpoint)).toBe(1);
});
it('requests further information for the selected address from the API with the expected parameters', async () => {
@@ -746,10 +749,9 @@ describe('script: address-input', () => {
await page.type('.ons-js-autosuggest-input', 'e', { delay: 20 });
await page.keyboard.press('ArrowDown');
await page.keyboard.press('Enter');
-
await setTimeout(50);
- expect(apiFaker.getRequestCount(uprnEndpoint)).toBe(1);
+ expect(await apiFaker.getRequestCount(uprnEndpoint)).toBe(1);
});
});
});
diff --git a/src/components/timeout-modal/timeout-modal.spec.js b/src/components/timeout-modal/timeout-modal.spec.js
index fa2538ff96..b5b59e070d 100644
--- a/src/components/timeout-modal/timeout-modal.spec.js
+++ b/src/components/timeout-modal/timeout-modal.spec.js
@@ -216,7 +216,7 @@ describe('script: timeout modal', () => {
it('closes the modal', async () => {
const modalIsVisible = await page.$eval('.ons-modal', (node) => node.classList.contains('ons-u-db'));
- await setTimeout(50);
+ await setTimeout(100);
expect(modalIsVisible).toBe(false);
});