@ons/design-system 70.0.6 → 70.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -17
- package/components/access-code/_macro.spec.js +145 -145
- package/components/access-code/access-code.dom.js +5 -5
- package/components/access-code/access-code.js +16 -16
- package/components/access-code/access-code.scss +22 -22
- package/components/access-code/access-code.spec.js +17 -17
- package/components/accordion/_macro.spec.js +154 -154
- package/components/accordion/accordion.dom.js +10 -10
- package/components/accordion/accordion.js +50 -50
- package/components/accordion/accordion.spec.js +104 -104
- package/components/address-input/_macro.spec.js +420 -420
- package/components/address-input/autosuggest.address.dom.js +5 -5
- package/components/address-input/autosuggest.address.error.js +77 -77
- package/components/address-input/autosuggest.address.js +357 -357
- package/components/address-input/autosuggest.address.setter.js +95 -95
- package/components/address-input/autosuggest.address.spec.js +668 -651
- package/components/address-input/example-address-input-editable.njk +1 -1
- package/components/address-input/example-address-input.njk +1 -1
- package/components/address-output/_address-output.scss +3 -3
- package/components/address-output/_macro.spec.js +84 -84
- package/components/autosuggest/_autosuggest.scss +114 -114
- package/components/autosuggest/_macro.spec.js +255 -255
- package/components/autosuggest/autosuggest.dom.js +5 -5
- package/components/autosuggest/autosuggest.helpers.js +11 -11
- package/components/autosuggest/autosuggest.helpers.spec.js +73 -73
- package/components/autosuggest/autosuggest.js +20 -20
- package/components/autosuggest/autosuggest.spec.js +542 -536
- package/components/autosuggest/autosuggest.ui.js +478 -475
- package/components/autosuggest/fuse-config.js +17 -17
- package/components/back-to-top/_back-to-top.scss +27 -27
- package/components/back-to-top/_macro.spec.js +49 -49
- package/components/back-to-top/back-to-top.dom.js +5 -5
- package/components/back-to-top/back-to-top.js +52 -52
- package/components/back-to-top/back-to-top.spec.js +106 -106
- package/components/back-to-top/example-back-to-top.njk +6 -6
- package/components/breadcrumbs/_breadcrumbs.scss +63 -65
- package/components/breadcrumbs/_macro.spec.js +91 -91
- package/components/browser-banner/_browser-banner.scss +23 -23
- package/components/browser-banner/_macro.spec.js +92 -92
- package/components/button/_button.scss +482 -483
- package/components/button/_macro.spec.js +363 -363
- package/components/button/button.dom.js +15 -15
- package/components/button/button.js +53 -53
- package/components/button/button.spec.js +248 -240
- package/components/call-to-action/_call-to-action.scss +5 -5
- package/components/call-to-action/_macro.spec.js +28 -28
- package/components/card/_card.scss +23 -23
- package/components/card/_macro.spec.js +180 -180
- package/components/char-check-limit/_macro.spec.js +48 -48
- package/components/char-check-limit/character-check.js +58 -58
- package/components/char-check-limit/character-check.spec.js +173 -173
- package/components/char-check-limit/character-limit.js +40 -40
- package/components/checkboxes/_checkbox-macro.spec.js +355 -355
- package/components/checkboxes/_checkbox.scss +180 -180
- package/components/checkboxes/_checkboxes.scss +37 -27
- package/components/checkboxes/_macro.spec.js +261 -261
- package/components/checkboxes/checkbox-with-autoselect.js +32 -32
- package/components/checkboxes/checkbox-with-fieldset.js +21 -21
- package/components/checkboxes/checkboxes-with-reveal.js +10 -10
- package/components/checkboxes/checkboxes.dom.js +27 -27
- package/components/checkboxes/checkboxes.spec.js +183 -183
- package/components/content-pagination/_content-pagination.scss +41 -41
- package/components/content-pagination/_macro.spec.js +159 -159
- package/components/cookies-banner/_cookies-banner.scss +22 -22
- package/components/cookies-banner/_macro.spec.js +177 -177
- package/components/cookies-banner/cookies-banner.dom.js +7 -7
- package/components/cookies-banner/cookies-banner.js +76 -76
- package/components/cookies-banner/cookies-banner.spec.js +72 -68
- package/components/date-input/_macro.spec.js +338 -338
- package/components/description-list/_description-list.scss +23 -23
- package/components/description-list/_macro.spec.js +144 -144
- package/components/details/_details.scss +109 -109
- package/components/details/_macro.spec.js +132 -132
- package/components/details/details.dom.js +6 -6
- package/components/details/details.js +60 -60
- package/components/details/details.spec.js +106 -106
- package/components/document-list/_macro.spec.js +444 -444
- package/components/document-list/document-list.scss +145 -149
- package/components/download-resources/_download-resources.scss +109 -108
- package/components/download-resources/download-resources.js +907 -900
- package/components/download-resources/download-resources.spec.js +461 -461
- package/components/duration/_macro.spec.js +291 -291
- package/components/error/_macro.spec.js +72 -72
- package/components/external-link/_external-link.scss +19 -19
- package/components/external-link/_macro.spec.js +68 -68
- package/components/feedback/_feedback.scss +31 -31
- package/components/feedback/_macro.spec.js +72 -72
- package/components/field/_field-group.scss +10 -10
- package/components/field/_field.scss +16 -16
- package/components/field/_macro.spec.js +80 -80
- package/components/fieldset/_fieldset.scss +27 -27
- package/components/fieldset/_macro.spec.js +161 -161
- package/components/footer/_footer.scss +45 -45
- package/components/footer/_macro.spec.js +452 -452
- package/components/header/_header.scss +202 -202
- package/components/header/_macro.spec.js +833 -829
- package/components/helpers/_grid.scss +4 -4
- package/components/hero/_hero.scss +48 -48
- package/components/hero/_macro.spec.js +59 -59
- package/components/icon/_icon.scss +44 -44
- package/components/icon/_macro.spec.js +110 -110
- package/components/image/_image.scss +11 -11
- package/components/image/_macro.spec.js +81 -81
- package/components/input/_input-type.scss +86 -89
- package/components/input/_input.scss +123 -124
- package/components/input/_macro.spec.js +604 -604
- package/components/input/character-check.dom.js +5 -5
- package/components/input/input.dom.js +5 -5
- package/components/input/input.js +10 -10
- package/components/input/input.spec.js +18 -18
- package/components/label/_label.scss +24 -24
- package/components/label/_macro.spec.js +173 -170
- package/components/language-selector/_macro.spec.js +97 -97
- package/components/language-selector/language.scss +7 -7
- package/components/list/_list.scss +84 -84
- package/components/list/_macro.njk +2 -2
- package/components/list/_macro.spec.js +583 -583
- package/components/message/_macro.njk +5 -5
- package/components/message/_macro.spec.js +74 -74
- package/components/message/_message.scss +39 -39
- package/components/message-list/_macro.spec.js +86 -86
- package/components/message-list/_message-list.scss +16 -16
- package/components/modal/_macro.spec.js +69 -69
- package/components/modal/_modal.scss +36 -36
- package/components/modal/modal.dom.js +6 -6
- package/components/modal/modal.js +89 -89
- package/components/modal/modal.spec.js +50 -50
- package/components/mutually-exclusive/_macro.spec.js +140 -140
- package/components/mutually-exclusive/mutually-exclusive.checkboxes.spec.js +188 -188
- package/components/mutually-exclusive/mutually-exclusive.date.spec.js +211 -211
- package/components/mutually-exclusive/mutually-exclusive.dom.js +5 -5
- package/components/mutually-exclusive/mutually-exclusive.duration.spec.js +210 -210
- package/components/mutually-exclusive/mutually-exclusive.email.spec.js +90 -90
- package/components/mutually-exclusive/mutually-exclusive.js +137 -137
- package/components/mutually-exclusive/mutually-exclusive.multiple-options.checkboxes.spec.js +197 -197
- package/components/mutually-exclusive/mutually-exclusive.number.spec.js +96 -96
- package/components/mutually-exclusive/mutually-exclusive.textarea.spec.js +102 -102
- package/components/navigation/_macro.spec.js +360 -354
- package/components/navigation/_navigation.scss +122 -123
- package/components/navigation/navigation.dom.js +35 -35
- package/components/navigation/navigation.js +49 -49
- package/components/navigation/navigation.spec.js +249 -249
- package/components/pagination/_macro.spec.js +342 -335
- package/components/pagination/_pagination.scss +58 -58
- package/components/panel/_macro.spec.js +372 -372
- package/components/panel/_panel.scss +200 -199
- package/components/password/_macro.spec.js +95 -95
- package/components/password/password.dom.js +5 -5
- package/components/password/password.js +10 -10
- package/components/password/password.spec.js +26 -26
- package/components/phase-banner/_macro.spec.js +86 -86
- package/components/phase-banner/_phase-banner.scss +16 -16
- package/components/question/_macro.spec.js +235 -235
- package/components/question/_question.scss +24 -24
- package/components/quote/_macro.spec.js +52 -52
- package/components/quote/_quote.scss +24 -24
- package/components/radios/_macro.spec.js +524 -524
- package/components/radios/_radio.scss +49 -48
- package/components/radios/_radios.scss +14 -20
- package/components/radios/check-radios.js +21 -21
- package/components/radios/clear-radios.js +45 -45
- package/components/radios/radio-with-fieldset.js +22 -22
- package/components/radios/radios.dom.js +32 -32
- package/components/radios/radios.spec.js +251 -251
- package/components/related-content/_macro.spec.js +109 -109
- package/components/related-content/_related-content.scss +12 -12
- package/components/related-content/_section-macro.spec.js +20 -20
- package/components/relationships/_macro.spec.js +94 -94
- package/components/relationships/_relationships.scss +9 -9
- package/components/relationships/relationships.dom.js +5 -5
- package/components/relationships/relationships.js +18 -18
- package/components/relationships/relationships.spec.js +71 -71
- package/components/reply/_macro.spec.js +47 -47
- package/components/reply/reply-input.js +15 -15
- package/components/reply/reply.dom.js +5 -5
- package/components/reply/reply.spec.js +57 -57
- package/components/section-navigation/_macro.spec.js +210 -210
- package/components/section-navigation/_section-navigation.scss +76 -76
- package/components/select/_macro.spec.js +166 -166
- package/components/share-page/_macro.spec.js +68 -68
- package/components/skip-to-content/_macro.spec.js +54 -54
- package/components/skip-to-content/_skip.scss +30 -30
- package/components/skip-to-content/skip-to-content.dom.js +6 -6
- package/components/skip-to-content/skip-to-content.js +7 -7
- package/components/skip-to-content/skip-to-content.spec.js +21 -21
- package/components/status/_macro.spec.js +53 -53
- package/components/status/_status.scss +32 -32
- package/components/summary/_macro.spec.js +551 -535
- package/components/summary/_summary.scss +191 -195
- package/components/table/_macro.spec.js +499 -499
- package/components/table/_table.scss +204 -201
- package/components/table/scrollable-table.dom.js +5 -5
- package/components/table/scrollable-table.js +60 -60
- package/components/table/sortable-table.dom.js +5 -5
- package/components/table/sortable-table.js +135 -135
- package/components/table/table.spec.js +144 -140
- package/components/table-of-contents/_macro.spec.js +125 -125
- package/components/table-of-contents/_toc.scss +9 -9
- package/components/table-of-contents/toc.dom.js +5 -5
- package/components/table-of-contents/toc.js +30 -30
- package/components/table-of-contents/toc.spec.js +88 -88
- package/components/tabs/_macro.spec.js +92 -92
- package/components/tabs/_tabs.scss +120 -115
- package/components/tabs/tabs.dom.js +5 -5
- package/components/tabs/tabs.js +266 -266
- package/components/tabs/tabs.spec.js +268 -268
- package/components/text-indent/_macro.spec.js +33 -33
- package/components/text-indent/_text-indent.scss +3 -3
- package/components/textarea/_macro.spec.js +238 -238
- package/components/textarea/textarea.dom.js +5 -5
- package/components/textarea/textarea.spec.js +78 -74
- package/components/timeline/_macro.spec.js +83 -83
- package/components/timeline/_timeline.scss +26 -26
- package/components/timeout-modal/_macro.spec.js +47 -47
- package/components/timeout-modal/timeout-modal.dom.js +9 -9
- package/components/timeout-modal/timeout-modal.js +66 -66
- package/components/timeout-modal/timeout-modal.spec.js +157 -157
- package/components/timeout-panel/_macro.spec.js +41 -41
- package/components/timeout-panel/timeout-panel.dom.js +8 -8
- package/components/timeout-panel/timeout-panel.spec.js +118 -118
- package/components/upload/_macro.spec.js +52 -52
- package/components/upload/_upload.scss +28 -28
- package/components/video/_macro.spec.js +42 -42
- package/components/video/_video.scss +16 -16
- package/components/video/video.dom.js +5 -5
- package/components/video/video.js +32 -32
- package/components/video/video.spec.js +103 -97
- package/css/main.css +1 -1
- package/favicons/android-chrome-192x192.png +0 -0
- package/favicons/android-chrome-512x512.png +0 -0
- package/favicons/apple-touch-icon.png +0 -0
- package/favicons/favicon-16x16.png +0 -0
- package/favicons/favicon-32x32.png +0 -0
- package/favicons/favicon.ico +0 -0
- package/favicons/manifest.json +25 -25
- package/favicons/maskable_icon.png +0 -0
- package/favicons/opengraph.png +0 -0
- package/favicons/twitter.png +0 -0
- package/img/large/alison-pritchard-featured.jpg +0 -0
- package/img/large/alison-pritchard.jpg +0 -0
- package/img/large/census-monuments-lights-featured.jpg +0 -0
- package/img/large/census-monuments-lights.jpg +0 -0
- package/img/large/mother-and-daughter-in-ireland.jpg +0 -0
- package/img/large/mum-and-child-healthcare-belfast.jpg +0 -0
- package/img/large/ons-award-winners.jpg +0 -0
- package/img/large/placeholder-card.png +0 -0
- package/img/large/placeholder-news-medium.png +0 -0
- package/img/large/placeholder-news.png +0 -0
- package/img/large/placeholder-portrait.png +0 -0
- package/img/large/students.jpg +0 -0
- package/img/large/woman-in-purple-dress-shirt.jpg +0 -0
- package/img/small/alison-pritchard-featured.jpg +0 -0
- package/img/small/alison-pritchard.jpg +0 -0
- package/img/small/census-monuments-lights-featured.jpg +0 -0
- package/img/small/census-monuments-lights.jpg +0 -0
- package/img/small/mother-and-daughter-in-ireland.jpg +0 -0
- package/img/small/mum-and-child-healthcare-belfast.jpg +0 -0
- package/img/small/ons-award-winners.jpg +0 -0
- package/img/small/placeholder-card.png +0 -0
- package/img/small/placeholder-news-medium.png +0 -0
- package/img/small/placeholder-news.png +0 -0
- package/img/small/placeholder-portrait.png +0 -0
- package/img/small/students.jpg +0 -0
- package/img/small/woman-in-purple-dress-shirt.jpg +0 -0
- package/js/abortable-fetch.js +23 -23
- package/js/analytics.js +53 -53
- package/js/cookies-functions.js +135 -135
- package/js/cookies-settings.dom.js +7 -7
- package/js/cookies-settings.js +77 -77
- package/js/cookies-settings.spec.js +106 -106
- package/js/domready.js +8 -8
- package/js/fetch.js +14 -14
- package/js/inpagelink.dom.js +5 -5
- package/js/inpagelink.js +19 -19
- package/js/polyfills.js +0 -1
- package/js/print-button.js +6 -6
- package/js/timeout.js +211 -211
- package/layout/_template.njk +5 -7
- package/package.json +131 -127
- package/scripts/main.es5.js +1 -1
- package/scripts/main.js +1 -1
- package/scss/base/_forms.scss +10 -10
- package/scss/base/_global.scss +45 -44
- package/scss/base/_typography.scss +20 -20
- package/scss/helpers/_functions.scss +18 -15
- package/scss/helpers/_mixins.scss +59 -53
- package/scss/helpers/_mq.scss +62 -65
- package/scss/objects/_container.scss +20 -20
- package/scss/objects/_page.scss +33 -33
- package/scss/objects/_spacing.scss +10 -10
- package/scss/overrides/hcm.scss +237 -237
- package/scss/overrides/rtl.scss +95 -95
- package/scss/print.scss +47 -47
- package/scss/utilities/_border.scss +7 -7
- package/scss/utilities/_colors.scss +6 -6
- package/scss/utilities/_display.scss +8 -8
- package/scss/utilities/_float.scss +7 -7
- package/scss/utilities/_grid.scss +144 -144
- package/scss/utilities/_highlight.scss +4 -4
- package/scss/utilities/_margin.scss +17 -17
- package/scss/utilities/_pad.scss +15 -15
- package/scss/utilities/_typography.scss +35 -33
- package/scss/utilities/_utilities.scss +8 -8
- package/scss/utilities/_visibility.scss +25 -25
- package/scss/vars/_colors.scss +116 -116
- package/scss/vars/_forms.scss +22 -22
- package/scss/vars/_grid.scss +11 -9
- package/scss/vars/_typography.scss +54 -54
|
@@ -2,86 +2,86 @@ import Modal from '../modal/modal';
|
|
|
2
2
|
import Timeout from '../../js/timeout';
|
|
3
3
|
|
|
4
4
|
export default class TimeoutModal {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
5
|
+
constructor(context, sessionExpiryEndpoint, initialExpiryTime) {
|
|
6
|
+
this.context = context;
|
|
7
|
+
this.sessionExpiryEndpoint = sessionExpiryEndpoint;
|
|
8
|
+
this.initialExpiryTime = initialExpiryTime;
|
|
9
|
+
this.continueButton = context.querySelector('.ons-js-modal-btn');
|
|
10
|
+
this.modalVisibleInMilliseconds = context.getAttribute('data-show-modal-time') * 1000;
|
|
11
|
+
this.expiryTime = '';
|
|
12
|
+
this.expiryTimeInMilliseconds = 0;
|
|
13
|
+
this.shouldRestartCheck = false;
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
// Create modal instance
|
|
16
|
+
this.modal = new Modal(this.context);
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
// Create timeout instance
|
|
19
|
+
this.timeout = new Timeout(this.context, this.sessionExpiryEndpoint, this.initialExpiryTime, true);
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
this.bindEventListeners();
|
|
22
|
+
}
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
24
|
+
bindEventListeners() {
|
|
25
|
+
window.onload = this.startTimeout();
|
|
26
|
+
window.addEventListener('keydown', this.escToClose.bind(this));
|
|
27
|
+
this.continueButton.addEventListener('click', this.closeModalAndRestartTimeout.bind(this));
|
|
28
|
+
}
|
|
29
29
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
30
|
+
startTimeout() {
|
|
31
|
+
clearTimeout(this.showModalTimeout);
|
|
32
|
+
if (this.initialExpiryTime) {
|
|
33
|
+
this.expiryTime = this.timeout.expiryTime;
|
|
34
|
+
this.expiryTimeInMilliseconds = this.timeout.convertTimeToMilliSeconds(this.expiryTime);
|
|
35
|
+
} else {
|
|
36
|
+
// For demo purposes
|
|
37
|
+
this.expiryTimeInMilliseconds = 60000;
|
|
38
|
+
}
|
|
39
|
+
this.showModalTimeout = setTimeout(
|
|
40
|
+
this.openModalAndStartCountdown.bind(this),
|
|
41
|
+
this.expiryTimeInMilliseconds - this.modalVisibleInMilliseconds,
|
|
42
|
+
);
|
|
38
43
|
}
|
|
39
|
-
this.showModalTimeout = setTimeout(
|
|
40
|
-
this.openModalAndStartCountdown.bind(this),
|
|
41
|
-
this.expiryTimeInMilliseconds - this.modalVisibleInMilliseconds,
|
|
42
|
-
);
|
|
43
|
-
}
|
|
44
44
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
45
|
+
async openModalAndStartCountdown() {
|
|
46
|
+
const modalWillOpen = await this.hasExpiryTimeResetInAnotherTab();
|
|
47
|
+
if (modalWillOpen && !this.modal.isDialogOpen()) {
|
|
48
|
+
this.modal.openDialog();
|
|
49
|
+
this.timeout.startUiCountdown();
|
|
50
50
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
51
|
+
this.shouldRestartCheck = setInterval(async () => {
|
|
52
|
+
await this.hasExpiryTimeResetInAnotherTab();
|
|
53
|
+
}, 20000);
|
|
54
|
+
}
|
|
54
55
|
}
|
|
55
|
-
}
|
|
56
56
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
57
|
+
async hasExpiryTimeResetInAnotherTab() {
|
|
58
|
+
const checkExpiryTime = await this.timeout.getExpiryTime();
|
|
59
|
+
if (checkExpiryTime.substring(0, 19) != this.timeout.expiryTime.substring(0, 19)) {
|
|
60
|
+
// Substring is required as endpoint can at random return milliseconds with expiry time
|
|
61
|
+
this.expiryTime = checkExpiryTime;
|
|
62
|
+
this.expiryTimeInMilliseconds = this.timeout.convertTimeToMilliSeconds(checkExpiryTime);
|
|
63
|
+
this.closeModalAndRestartTimeout(this.expiryTimeInMilliseconds);
|
|
64
|
+
} else {
|
|
65
|
+
return true;
|
|
66
|
+
}
|
|
66
67
|
}
|
|
67
|
-
}
|
|
68
68
|
|
|
69
|
-
|
|
70
|
-
|
|
69
|
+
async closeModalAndRestartTimeout(time) {
|
|
70
|
+
clearInterval(this.shouldRestartCheck);
|
|
71
71
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
72
|
+
if (typeof timeInMilliSeconds !== 'string') {
|
|
73
|
+
time = false;
|
|
74
|
+
}
|
|
75
|
+
if (this.modal.isDialogOpen()) {
|
|
76
|
+
this.modal.closeDialog(event);
|
|
77
|
+
}
|
|
78
|
+
await this.timeout.restartTimeout(time);
|
|
79
|
+
this.startTimeout();
|
|
77
80
|
}
|
|
78
|
-
await this.timeout.restartTimeout(time);
|
|
79
|
-
this.startTimeout();
|
|
80
|
-
}
|
|
81
81
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
82
|
+
escToClose(event) {
|
|
83
|
+
if (this.modal.isDialogOpen() && event.keyCode === 27) {
|
|
84
|
+
this.closeModalAndRestartTimeout();
|
|
85
|
+
}
|
|
85
86
|
}
|
|
86
|
-
}
|
|
87
87
|
}
|
|
@@ -1,226 +1,226 @@
|
|
|
1
1
|
import { renderComponent, setTestPage } from '../../tests/helpers/rendering';
|
|
2
2
|
|
|
3
3
|
const EXAMPLE_TIMEOUT_MODAL_BASIC = {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
4
|
+
redirectUrl: '#!',
|
|
5
|
+
title: 'You will be signed out soon',
|
|
6
|
+
textFirstLine: 'It appears you have been inactive for a while.',
|
|
7
|
+
countdownText: 'To protect your information, your progress will be saved and you will be signed out in',
|
|
8
|
+
countdownExpiredText: 'You are being signed out.',
|
|
9
|
+
btnText: 'Continue survey',
|
|
10
|
+
minutesTextSingular: 'minute',
|
|
11
|
+
minutesTextPlural: 'minutes',
|
|
12
|
+
secondsTextSingular: 'second',
|
|
13
|
+
secondsTextPlural: 'seconds',
|
|
14
|
+
endWithFullStop: true,
|
|
15
15
|
};
|
|
16
16
|
|
|
17
17
|
describe('script: timeout modal', () => {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
18
|
+
describe('when the page loads', () => {
|
|
19
|
+
beforeEach(async () => {
|
|
20
|
+
const component = renderComponent('timeout-modal', { ...EXAMPLE_TIMEOUT_MODAL_BASIC, showModalTimeInSeconds: 58 });
|
|
21
|
+
const template = `
|
|
22
22
|
<div class="ons-page">
|
|
23
23
|
${component}
|
|
24
24
|
</div>
|
|
25
25
|
`;
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
await setTestPage('/test', template);
|
|
27
|
+
});
|
|
28
28
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
});
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
describe('when the modal first opens', () => {
|
|
37
|
-
describe('when the countdown starts', () => {
|
|
38
|
-
beforeEach(async () => {
|
|
39
|
-
const component = renderComponent('timeout-modal', {
|
|
40
|
-
...EXAMPLE_TIMEOUT_MODAL_BASIC,
|
|
41
|
-
showModalTimeInSeconds: 60,
|
|
29
|
+
it('displays the modal after the correct number of seconds', async () => {
|
|
30
|
+
await page.waitForTimeout(2000);
|
|
31
|
+
const modalIsVisible = await page.$eval('.ons-modal', (node) => node.classList.contains('ons-u-db'));
|
|
32
|
+
expect(modalIsVisible).toBe(true);
|
|
42
33
|
});
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
describe('when the modal first opens', () => {
|
|
37
|
+
describe('when the countdown starts', () => {
|
|
38
|
+
beforeEach(async () => {
|
|
39
|
+
const component = renderComponent('timeout-modal', {
|
|
40
|
+
...EXAMPLE_TIMEOUT_MODAL_BASIC,
|
|
41
|
+
showModalTimeInSeconds: 60,
|
|
42
|
+
});
|
|
43
43
|
|
|
44
|
-
|
|
44
|
+
const template = `
|
|
45
45
|
<div class="ons-page">
|
|
46
46
|
${component}
|
|
47
47
|
</div>
|
|
48
48
|
`;
|
|
49
49
|
|
|
50
|
-
|
|
51
|
-
|
|
50
|
+
await setTestPage('/test', template);
|
|
51
|
+
});
|
|
52
52
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
53
|
+
it('shows the time counting down', async () => {
|
|
54
|
+
const timeAtStart = await page.$eval('.ons-js-timeout-timer span', (element) => element.innerHTML);
|
|
55
|
+
await page.waitForTimeout(1000);
|
|
56
|
+
const timeAfterOneSecond = await page.$eval('.ons-js-timeout-timer span', (element) => element.innerHTML);
|
|
57
|
+
expect(timeAfterOneSecond).not.toEqual(timeAtStart);
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
60
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
61
|
+
describe('when there are two minutes or more remaining', () => {
|
|
62
|
+
beforeEach(async () => {
|
|
63
|
+
const expiryTime = new Date(Date.now() + 60 * 3000);
|
|
64
|
+
const expiryTimeInISOFormat = new Date(expiryTime).toISOString();
|
|
65
65
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
66
|
+
const component = renderComponent('timeout-modal', {
|
|
67
|
+
...EXAMPLE_TIMEOUT_MODAL_BASIC,
|
|
68
|
+
showModalTimeInSeconds: 180,
|
|
69
|
+
sessionExpiresAt: expiryTimeInISOFormat,
|
|
70
|
+
});
|
|
71
71
|
|
|
72
|
-
|
|
72
|
+
const template = `
|
|
73
73
|
<div class="ons-page">
|
|
74
74
|
${component}
|
|
75
75
|
</div>
|
|
76
76
|
`;
|
|
77
|
-
|
|
78
|
-
|
|
77
|
+
await setTestPage('/test', template);
|
|
78
|
+
});
|
|
79
79
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
80
|
+
it('displays the `minutes` (plural) string', async () => {
|
|
81
|
+
const timeString = await page.$eval('.ons-js-timeout-timer span', (element) => element.innerHTML);
|
|
82
|
+
expect(timeString).toEqual(expect.stringContaining('minutes'));
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
85
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
86
|
+
describe('when there are two seconds or more remaining', () => {
|
|
87
|
+
beforeEach(async () => {
|
|
88
|
+
const expiryTime = new Date(Date.now() + 60 * 1000);
|
|
89
|
+
const expiryTimeInISOFormat = new Date(expiryTime).toISOString();
|
|
90
90
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
91
|
+
const component = renderComponent('timeout-modal', {
|
|
92
|
+
...EXAMPLE_TIMEOUT_MODAL_BASIC,
|
|
93
|
+
showModalTimeInSeconds: 60,
|
|
94
|
+
sessionExpiresAt: expiryTimeInISOFormat,
|
|
95
|
+
});
|
|
96
96
|
|
|
97
|
-
|
|
97
|
+
const template = `
|
|
98
98
|
<div class="ons-page">
|
|
99
99
|
${component}
|
|
100
100
|
</div>
|
|
101
101
|
`;
|
|
102
|
-
|
|
103
|
-
|
|
102
|
+
await setTestPage('/test', template);
|
|
103
|
+
});
|
|
104
104
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
105
|
+
it('displays the `seconds` (plural) string', async () => {
|
|
106
|
+
const timeString = await page.$eval('.ons-js-timeout-timer span', (element) => element.innerHTML);
|
|
107
|
+
expect(timeString).toEqual(expect.stringContaining('seconds'));
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
110
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
111
|
+
describe('when there is one minute remaining', () => {
|
|
112
|
+
beforeEach(async () => {
|
|
113
|
+
const expiryTime = new Date(Date.now() + 60 * 1500);
|
|
114
|
+
const expiryTimeInISOFormat = new Date(expiryTime).toISOString();
|
|
115
115
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
116
|
+
const component = renderComponent('timeout-modal', {
|
|
117
|
+
...EXAMPLE_TIMEOUT_MODAL_BASIC,
|
|
118
|
+
showModalTimeInSeconds: 90,
|
|
119
|
+
sessionExpiresAt: expiryTimeInISOFormat,
|
|
120
|
+
});
|
|
121
121
|
|
|
122
|
-
|
|
122
|
+
const template = `
|
|
123
123
|
<div class="ons-page">
|
|
124
124
|
${component}
|
|
125
125
|
</div>
|
|
126
126
|
`;
|
|
127
|
-
|
|
128
|
-
|
|
127
|
+
await setTestPage('/test', template);
|
|
128
|
+
});
|
|
129
129
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
130
|
+
it('displays the `minute` (singular) string', async () => {
|
|
131
|
+
const timeString = await page.$eval('.ons-js-timeout-timer span', (element) => element.innerHTML);
|
|
132
|
+
expect(timeString).toEqual(expect.stringContaining('minute'));
|
|
133
|
+
});
|
|
134
|
+
});
|
|
135
135
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
136
|
+
describe('when there is one second remaining', () => {
|
|
137
|
+
beforeEach(async () => {
|
|
138
|
+
const expiryTime = new Date(Date.now() + 3 * 1000);
|
|
139
|
+
const expiryTimeInISOFormat = new Date(expiryTime).toISOString();
|
|
140
140
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
141
|
+
const component = renderComponent('timeout-modal', {
|
|
142
|
+
...EXAMPLE_TIMEOUT_MODAL_BASIC,
|
|
143
|
+
showModalTimeInSeconds: 3,
|
|
144
|
+
sessionExpiresAt: expiryTimeInISOFormat,
|
|
145
|
+
});
|
|
146
146
|
|
|
147
|
-
|
|
147
|
+
const template = `
|
|
148
148
|
<div class="ons-page">
|
|
149
149
|
${component}
|
|
150
150
|
</div>
|
|
151
151
|
`;
|
|
152
|
-
|
|
153
|
-
|
|
152
|
+
await setTestPage('/test', template);
|
|
153
|
+
});
|
|
154
154
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
155
|
+
it('displays the `second` (singular) string', async () => {
|
|
156
|
+
const timeString = await page.$eval('.ons-js-timeout-timer span', (element) => element.innerHTML);
|
|
157
|
+
expect(timeString).toEqual(expect.stringContaining('second'));
|
|
158
|
+
});
|
|
159
|
+
});
|
|
160
160
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
161
|
+
describe('when the timer runs to zero', () => {
|
|
162
|
+
beforeEach(async () => {
|
|
163
|
+
const expiryTime = new Date(Date.now() + 1 * 1000);
|
|
164
|
+
const expiryTimeInISOFormat = new Date(expiryTime).toISOString();
|
|
165
165
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
166
|
+
const component = renderComponent('timeout-modal', {
|
|
167
|
+
...EXAMPLE_TIMEOUT_MODAL_BASIC,
|
|
168
|
+
showModalTimeInSeconds: 1,
|
|
169
|
+
sessionExpiresAt: expiryTimeInISOFormat,
|
|
170
|
+
});
|
|
171
171
|
|
|
172
|
-
|
|
172
|
+
const template = `
|
|
173
173
|
<div class="ons-page">
|
|
174
174
|
${component}
|
|
175
175
|
</div>
|
|
176
176
|
`;
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
177
|
+
await setTestPage('/test', template);
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
it('displays the `countdownExpiredText` text', async () => {
|
|
181
|
+
const timeString = await page.$eval('.ons-js-timeout-timer span', (element) => element.innerHTML);
|
|
182
|
+
expect(timeString).toEqual(expect.stringContaining('You are being signed out'));
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
it('then redirects to the provided `redirectUrl`', async () => {
|
|
186
|
+
await page.waitForTimeout(2000);
|
|
187
|
+
expect(page.url()).toContain('#!');
|
|
188
|
+
});
|
|
189
|
+
});
|
|
189
190
|
});
|
|
190
|
-
});
|
|
191
191
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
192
|
+
describe('when the modal is open', () => {
|
|
193
|
+
beforeEach(async () => {
|
|
194
|
+
const component = renderComponent('timeout-modal', {
|
|
195
|
+
...EXAMPLE_TIMEOUT_MODAL_BASIC,
|
|
196
|
+
showModalTimeInSeconds: 59,
|
|
197
|
+
});
|
|
198
198
|
|
|
199
|
-
|
|
199
|
+
const template = `
|
|
200
200
|
<div class="ons-page">
|
|
201
201
|
${component}
|
|
202
202
|
</div>
|
|
203
203
|
`;
|
|
204
204
|
|
|
205
|
-
|
|
206
|
-
|
|
205
|
+
await setTestPage('/test', template);
|
|
206
|
+
});
|
|
207
207
|
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
208
|
+
describe('when the `esc` key is pressed', () => {
|
|
209
|
+
beforeEach(async () => {
|
|
210
|
+
await page.waitForSelector('.ons-modal');
|
|
211
|
+
await page.keyboard.press('Escape');
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
it('closes the modal', async () => {
|
|
215
|
+
const modalIsVisible = await page.$eval('.ons-modal', (node) => node.classList.contains('ons-u-db'));
|
|
216
|
+
expect(modalIsVisible).toBe(false);
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
it('restarts the timer and displays the modal after the correct number of seconds', async () => {
|
|
220
|
+
await page.waitForTimeout(2000);
|
|
221
|
+
const modalIsVisible = await page.$eval('.ons-modal', (node) => node.classList.contains('ons-u-db'));
|
|
222
|
+
expect(modalIsVisible).toBe(true);
|
|
223
|
+
});
|
|
224
|
+
});
|
|
224
225
|
});
|
|
225
|
-
});
|
|
226
226
|
});
|
|
@@ -6,49 +6,49 @@ import axe from '../../tests/helpers/axe';
|
|
|
6
6
|
import { renderComponent, templateFaker } from '../../tests/helpers/rendering';
|
|
7
7
|
|
|
8
8
|
const EXAMPLE_TIMEOUT_PANEL_BASIC = {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
9
|
+
id: 'countdown',
|
|
10
|
+
sessionExpiresAt: '000-000-000',
|
|
11
|
+
redirectUrl: '#!',
|
|
12
|
+
minutesTextSingular: 'minute',
|
|
13
|
+
minutesTextPlural: 'minutes',
|
|
14
|
+
secondsTextSingular: 'second',
|
|
15
|
+
secondsTextPlural: 'seconds',
|
|
16
|
+
countdownText: 'For security, your answers will only be available to view for another',
|
|
17
|
+
nojsText: 'For security, your answers will only be available to view for another 1 minute',
|
|
18
|
+
countdownExpiredText: 'You are being signed out',
|
|
19
|
+
endWithFullStop: true,
|
|
20
20
|
};
|
|
21
21
|
|
|
22
22
|
describe('macro: timeout panel', () => {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
23
|
+
it('passes jest-axe checks with', async () => {
|
|
24
|
+
const $ = cheerio.load(renderComponent('timeout-panel', EXAMPLE_TIMEOUT_PANEL_BASIC));
|
|
25
|
+
|
|
26
|
+
const results = await axe($.html());
|
|
27
|
+
expect(results).toHaveNoViolations();
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
it('provides expected parameters to the inner `panel` component', () => {
|
|
31
|
+
const faker = templateFaker();
|
|
32
|
+
const panelSpy = faker.spy('panel');
|
|
33
|
+
|
|
34
|
+
cheerio.load(faker.renderComponent('timeout-panel', EXAMPLE_TIMEOUT_PANEL_BASIC));
|
|
35
|
+
|
|
36
|
+
expect(panelSpy.occurrences[0]).toEqual({
|
|
37
|
+
id: 'countdown',
|
|
38
|
+
classes: 'ons-js-panel-with-countdown',
|
|
39
|
+
variant: 'warn',
|
|
40
|
+
attributes: {
|
|
41
|
+
'data-redirect-url': '#!',
|
|
42
|
+
'data-server-session-expires-at': '000-000-000',
|
|
43
|
+
'data-countdown-text': 'For security, your answers will only be available to view for another',
|
|
44
|
+
'data-countdown-expired-text': 'You are being signed out',
|
|
45
|
+
'data-minutes-text-singular': 'minute',
|
|
46
|
+
'data-minutes-text-plural': 'minutes',
|
|
47
|
+
'data-seconds-text-singular': 'second',
|
|
48
|
+
'data-seconds-text-plural': 'seconds',
|
|
49
|
+
'aria-describedby': 'timeout-time-remaining',
|
|
50
|
+
'data-full-stop': true,
|
|
51
|
+
},
|
|
52
|
+
});
|
|
52
53
|
});
|
|
53
|
-
});
|
|
54
54
|
});
|