@madgex/design-system 3.0.2 → 3.0.3

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.
Files changed (109) hide show
  1. package/.eslintignore +2 -0
  2. package/.eslintrc.js +3 -3
  3. package/__tests__/.eslintrc.js +3 -3
  4. package/__tests__/unit/src/components/combobox.spec.js +4 -28
  5. package/__tests__/unit/src/components/notification.spec.js +14 -12
  6. package/__tests__/unit/src/components/popover.spec.js +4 -0
  7. package/__tests__/unit/tasks/css.spec.js +3 -2
  8. package/__tests__/unit/tasks/jsbundle.spec.js +3 -2
  9. package/__tests__/unit/tasks/svgsprite.spec.js +3 -2
  10. package/__tests__/unit/tasks/tokens.spec.js +3 -2
  11. package/coverage/cobertura-coverage.xml +389 -389
  12. package/coverage/components/accordion/accordion.js.html +164 -127
  13. package/coverage/components/accordion/index.html +23 -22
  14. package/coverage/components/button/button.js.html +3 -2
  15. package/coverage/components/button/index.html +3 -2
  16. package/coverage/components/inputs/combobox/combobox.js.html +3 -2
  17. package/coverage/components/inputs/combobox/index.html +3 -2
  18. package/coverage/components/inputs/combobox/vue-components/Combobox.vue.html +55 -54
  19. package/coverage/components/inputs/combobox/vue-components/ListBoxOption.vue.html +9 -8
  20. package/coverage/components/inputs/combobox/vue-components/index.html +21 -20
  21. package/coverage/components/inputs/file-upload/file-upload.js.html +7 -3
  22. package/coverage/components/inputs/file-upload/index.html +3 -2
  23. package/coverage/components/inputs/textarea/character-count.js.html +13 -3
  24. package/coverage/components/inputs/textarea/index.html +3 -2
  25. package/coverage/components/modal/index.html +23 -22
  26. package/coverage/components/modal/modal.js.html +118 -111
  27. package/coverage/components/notification/index.html +3 -2
  28. package/coverage/components/notification/notification.js.html +13 -3
  29. package/coverage/components/popover/index.html +3 -2
  30. package/coverage/components/popover/popover.js.html +3 -2
  31. package/coverage/components/switch-state/index.html +19 -18
  32. package/coverage/components/switch-state/switch-state.js.html +22 -21
  33. package/coverage/components/tabs/index.html +3 -2
  34. package/coverage/components/tabs/tabs.js.html +37 -3
  35. package/coverage/favicon.png +0 -0
  36. package/coverage/index.html +52 -51
  37. package/coverage/js/common.js.html +3 -2
  38. package/coverage/js/fractal-scripts/combobox.js.html +22 -3
  39. package/coverage/js/fractal-scripts/index.html +3 -2
  40. package/coverage/js/fractal-scripts/notification.js.html +13 -3
  41. package/coverage/js/fractal-scripts/switch-state.js.html +13 -3
  42. package/coverage/js/index-fractal.js.html +3 -2
  43. package/coverage/js/index-polyfills.js.html +3 -2
  44. package/coverage/js/index-vue.js.html +3 -2
  45. package/coverage/js/index.html +3 -2
  46. package/coverage/js/index.js.html +3 -2
  47. package/coverage/js/polyfills/arrayPrototypeFind.js.html +20 -10
  48. package/coverage/js/polyfills/closest.js.html +8 -4
  49. package/coverage/js/polyfills/index.html +3 -2
  50. package/coverage/js/polyfills/objectAssign.js.html +19 -9
  51. package/coverage/js/polyfills/remove.js.html +3 -2
  52. package/coverage/tokens/_config.js.html +3 -2
  53. package/coverage/tokens/index.html +3 -2
  54. package/cypress/.eslintrc.js +6 -6
  55. package/cypress/fixtures/testuploadfile.txt +1 -0
  56. package/cypress/integration/components/accordion.spec.js +40 -3
  57. package/cypress/integration/components/button.spec.js +2 -3
  58. package/cypress/integration/components/card.spec.js +2 -3
  59. package/cypress/integration/components/icons.spec.js +10 -0
  60. package/cypress/integration/components/{combobox.spec.js → inputs/combobox.spec.js} +6 -0
  61. package/cypress/integration/components/inputs/file-upload.spec.js +45 -0
  62. package/cypress/integration/components/{input.spec.js → inputs/input.spec.js} +1 -1
  63. package/cypress/integration/components/inputs/label.spec.js +15 -0
  64. package/cypress/integration/components/inputs/radio.spec.js +20 -0
  65. package/cypress/integration/components/inputs/select.spec.js +31 -0
  66. package/cypress/integration/components/inputs/textarea.spec.js +23 -0
  67. package/cypress/integration/components/modal.spec.js +65 -0
  68. package/cypress/integration/components/notifications.spec.js +35 -0
  69. package/cypress/integration/components/popover.spec.js +36 -0
  70. package/cypress/integration/components/skip-link.spec.js +9 -0
  71. package/cypress/plugins/index.js +1 -1
  72. package/cypress/support/commands.js +14 -0
  73. package/cypress/support/index.js +2 -0
  74. package/dist/_tokens/css/_tokens.css +1 -1
  75. package/dist/_tokens/js/_tokens-module.js +455 -1
  76. package/dist/_tokens/scss/_tokens.scss +4 -4
  77. package/dist/assets/icons.json +1 -1
  78. package/dist/assets/icons.svg +6 -1
  79. package/dist/js/index.js +1 -1
  80. package/fractal.js +2 -0
  81. package/package.json +59 -54
  82. package/server.js +1 -1
  83. package/src/components/accordion/accordion.config.js +9 -12
  84. package/src/components/accordion/accordion.js +12 -0
  85. package/src/components/inputs/file-upload/file-upload.js +1 -0
  86. package/src/components/inputs/textarea/character-count.js +3 -0
  87. package/src/components/modal/modal.js +3 -1
  88. package/src/components/notification/notification.js +3 -0
  89. package/src/components/skip-link/skip-link.njk +11 -1
  90. package/src/components/tabs/tabs.js +11 -0
  91. package/src/js/fractal-scripts/combobox.js +6 -0
  92. package/src/js/fractal-scripts/notification.js +3 -0
  93. package/src/js/fractal-scripts/switch-state.js +3 -0
  94. package/src/js/polyfills/arrayPrototypeFind.js +9 -6
  95. package/src/js/polyfills/closest.js +2 -1
  96. package/src/js/polyfills/objectAssign.js +9 -6
  97. package/tasks/colorTransforms.js +4 -0
  98. package/tasks/createMacroIndex.js +1 -0
  99. package/tasks/css.js +3 -0
  100. package/tasks/fractal.js +2 -0
  101. package/tasks/js-bundle.js +6 -2
  102. package/tasks/svgsprite.js +31 -21
  103. package/tasks/tokens.js +2 -0
  104. package/__tests__/unit/src/components/accordion.spec.js +0 -88
  105. package/__tests__/unit/src/components/modal.spec.js +0 -87
  106. package/__tests__/unit/src/components/switch-state.spec.js +0 -21
  107. package/cypress/integration/components/textarea.spec.js +0 -9
  108. /package/cypress/integration/components/{checkbox-list.spec.js → inputs/checkbox-list.spec.js} +0 -0
  109. /package/cypress/integration/components/{single-checkbox.spec.js → inputs/single-checkbox.spec.js} +0 -0
@@ -7,7 +7,8 @@
7
7
  <meta charset="utf-8" />
8
8
  <link rel="stylesheet" href="../../prettify.css" />
9
9
  <link rel="stylesheet" href="../../base.css" />
10
- <meta name="viewport" content="width=device-width, initial-scale=1">
10
+ <link rel="shortcut icon" type="image/x-icon" href="../../favicon.png" />
11
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
11
12
  <style type='text/css'>
12
13
  .coverage-summary .sorter {
13
14
  background-image: url(../../sort-arrow-sprite.png);
@@ -84,7 +85,7 @@
84
85
  <div class='footer quiet pad2 space-top1 center small'>
85
86
  Code coverage generated by
86
87
  <a href="https://istanbul.js.org/" target="_blank">istanbul</a>
87
- at Wed Jul 07 2021 12:25:30 GMT+0100 (British Summer Time)
88
+ at Thu Jul 08 2021 15:47:09 GMT+0100 (British Summer Time)
88
89
  </div>
89
90
  </div>
90
91
  <script src="../../prettify.js"></script>
@@ -7,7 +7,8 @@
7
7
  <meta charset="utf-8" />
8
8
  <link rel="stylesheet" href="../prettify.css" />
9
9
  <link rel="stylesheet" href="../base.css" />
10
- <meta name="viewport" content="width=device-width, initial-scale=1">
10
+ <link rel="shortcut icon" type="image/x-icon" href="../favicon.png" />
11
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
11
12
  <style type='text/css'>
12
13
  .coverage-summary .sorter {
13
14
  background-image: url(../sort-arrow-sprite.png);
@@ -552,7 +553,7 @@ const config = <span class="cstat-no" title="statement not covered" >{</span>
552
553
  <div class='footer quiet pad2 space-top1 center small'>
553
554
  Code coverage generated by
554
555
  <a href="https://istanbul.js.org/" target="_blank">istanbul</a>
555
- at Wed Jul 07 2021 12:25:30 GMT+0100 (British Summer Time)
556
+ at Thu Jul 08 2021 15:47:09 GMT+0100 (British Summer Time)
556
557
  </div>
557
558
  </div>
558
559
  <script src="../prettify.js"></script>
@@ -7,7 +7,8 @@
7
7
  <meta charset="utf-8" />
8
8
  <link rel="stylesheet" href="../prettify.css" />
9
9
  <link rel="stylesheet" href="../base.css" />
10
- <meta name="viewport" content="width=device-width, initial-scale=1">
10
+ <link rel="shortcut icon" type="image/x-icon" href="../favicon.png" />
11
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
11
12
  <style type='text/css'>
12
13
  .coverage-summary .sorter {
13
14
  background-image: url(../sort-arrow-sprite.png);
@@ -94,7 +95,7 @@
94
95
  <div class='footer quiet pad2 space-top1 center small'>
95
96
  Code coverage generated by
96
97
  <a href="https://istanbul.js.org/" target="_blank">istanbul</a>
97
- at Wed Jul 07 2021 12:25:30 GMT+0100 (British Summer Time)
98
+ at Thu Jul 08 2021 15:47:09 GMT+0100 (British Summer Time)
98
99
  </div>
99
100
  </div>
100
101
  <script src="../prettify.js"></script>
@@ -1,12 +1,12 @@
1
1
  module.exports = {
2
2
  plugins: ['cypress'],
3
3
  env: {
4
- "cypress/globals": true
4
+ 'cypress/globals': true,
5
5
  },
6
6
  rules: {
7
- "import/no-extraneous-dependencies": 0,
7
+ 'import/no-extraneous-dependencies': 0,
8
8
  // Cypress uses a .then mechanism to unwrap information, which is not really a promise
9
- "promise/always-return": 0,
10
- "promise/catch-or-return": 0
11
- }
12
- }
9
+ 'promise/always-return': 0,
10
+ 'promise/catch-or-return': 0,
11
+ },
12
+ };
@@ -0,0 +1 @@
1
+ I am a file to upload
@@ -58,7 +58,7 @@ context('Accordion', () => {
58
58
  if (triggerId) {
59
59
  cy.get(`#${triggerId}`).should('exist');
60
60
  }
61
- });;
61
+ });
62
62
  // Alt Icons
63
63
  cy.get('[data-test="accordion-trigger-altIcons"] button').not('.mds-display-none').click({ multiple: true });
64
64
  cy.get('[data-test="accordion-content-altIcons"]').each((content) => {
@@ -67,7 +67,7 @@ context('Accordion', () => {
67
67
  if (triggerId) {
68
68
  cy.get(`#${triggerId}`).should('exist');
69
69
  }
70
- });;
70
+ });
71
71
  // Collapsed
72
72
  cy.get('[data-test="accordion-trigger-collapsed"] button').not('.mds-display-none').click({ multiple: true });
73
73
  cy.get('[data-test="accordion-content-collapsed"]').each((content) => {
@@ -76,7 +76,7 @@ context('Accordion', () => {
76
76
  if (triggerId) {
77
77
  cy.get(`#${triggerId}`).should('exist');
78
78
  }
79
- });;
79
+ });
80
80
  // non-closing
81
81
  cy.get('[data-test="accordion-trigger-non-closing"] button').not('.mds-display-none').click({ multiple: true });
82
82
  cy.get('[data-test="accordion-content-non-closing"]').each((content) => {
@@ -87,4 +87,41 @@ context('Accordion', () => {
87
87
  }
88
88
  });
89
89
  });
90
+
91
+ it('shows accordion when no bp is set', () => {
92
+ cy.get('[data-test="accordion-trigger-taxonomy"] button').not('.mds-display-none').click();
93
+ cy.get('[data-test="accordion-content-taxonomy"]').should('be.visible');
94
+ });
95
+
96
+ it('shows accordion when screen is < than bp', () => {
97
+ cy.get('[data-test="accordion-trigger-mobile"]').should('be.hidden');
98
+ cy.get('[data-test="accordion-trigger-mobile"]')
99
+ .should('have.attr', 'data-bp')
100
+ .then((bp) => {
101
+ const bpInt = Number.parseInt(bp, 10);
102
+
103
+ cy.viewport(bpInt - 10, bpInt - 10);
104
+ cy.reload();
105
+ cy.get('[data-test="accordion-trigger-mobile"]').should('be.visible');
106
+ });
107
+ });
108
+
109
+ it('hide accordion when screen is > than bp', () => {
110
+ cy.get('[data-test="accordion-trigger-mobile"]')
111
+ .should('have.attr', 'data-bp')
112
+ .then((bp) => {
113
+ const bpInt = Number.parseInt(bp, 10);
114
+
115
+ cy.viewport(bpInt + 10, bpInt + 10);
116
+ cy.reload();
117
+ cy.get('[data-test="accordion-trigger-mobile"]').should('be.hidden');
118
+ });
119
+ });
120
+
121
+ it('switches labels when clicked', async () => {
122
+ cy.get('[data-test="accordion-trigger-taxonomy"] button').as('trigger');
123
+ cy.get('@trigger').contains('View more categories');
124
+ cy.get('@trigger').click({ multiple: true });
125
+ cy.get('@trigger').contains('View less categories');
126
+ });
90
127
  });
@@ -4,7 +4,6 @@ context('Button', () => {
4
4
  });
5
5
 
6
6
  it('has no detectable a11y violations on load', () => {
7
- // Need to skip others due to contrast issues currently
8
- cy.checkA11y('[data-test="button-plain"]');
7
+ cy.checkA11y('[data-test^="button-"]');
9
8
  });
10
- });
9
+ });
@@ -4,8 +4,7 @@ context('Card', () => {
4
4
  });
5
5
 
6
6
  it('has no detectable a11y violations on load', () => {
7
- cy.checkA11y('[data-test="card-default"]');
8
- cy.checkA11y('[data-test="card-in-list"]');
9
- cy.checkA11y('[data-test="card-with-background"]');
7
+ cy.excludeA11yTests(['heading-order']);
8
+ cy.checkA11y('[data-test^="card-"]');
10
9
  });
11
10
  });
@@ -6,4 +6,14 @@ context('Icon', () => {
6
6
  it('has no detectable a11y violations on load', () => {
7
7
  cy.checkA11y('p');
8
8
  });
9
+
10
+ it('renders icons', () => {
11
+ cy.document().then((doc) => {
12
+ const allTestables = doc.querySelectorAll('svg.mds-icon');
13
+
14
+ allTestables.forEach((element) => {
15
+ cy.get(element).should('be.visible');
16
+ });
17
+ });
18
+ });
9
19
  });
@@ -17,6 +17,12 @@ context('Combobox', () => {
17
17
  cy.checkA11y('[data-test="combobox-distance-selection"]');
18
18
  });
19
19
 
20
+ it('has attrs set as expected', () => {
21
+ cy.get('#distance-selection').as('comboboxInput');
22
+ cy.get('@comboboxInput').attribute('autocomplete').should('equal', 'off');
23
+ cy.get('@comboboxInput').attribute('aria-autocomplete').should('equal', 'list');
24
+ });
25
+
20
26
  it('can be navigated with up and down arrows', () => {
21
27
  cy.get('[data-test="combobox-distance-selection"] input').first().focus().type('Within');
22
28
  cy.get('[data-test="combobox-distance-selection"] input').first().focus().type('{downArrow}');
@@ -0,0 +1,45 @@
1
+ context('File Upload', () => {
2
+ beforeEach(() => {
3
+ cy.visitComponent('file-upload');
4
+ });
5
+
6
+ it('has no detectable a11y violations on load', () => {
7
+ cy.checkA11y('[data-test="input-file"]');
8
+ cy.checkA11y('[data-test="input-selected-file"]');
9
+ });
10
+
11
+ it('changes to show the remove option when a file is uploaded', () => {
12
+ cy.get('[data-test="input-file"]').as('fileInput');
13
+ cy.get('@fileInput')
14
+ .find('.mds-file-upload__input-controls > .mds-file-upload__selection-state')
15
+ .should('be.visible');
16
+ cy.get('@fileInput')
17
+ .find('.mds-file-upload__input-controls > .mds-file-upload__selected-state')
18
+ .should('be.hidden');
19
+ cy.get('@fileInput').find('.mds-form-control').attachFile('testuploadfile.txt');
20
+ cy.wait(500);
21
+ cy.get('@fileInput')
22
+ .find('.mds-file-upload__input-controls > .mds-file-upload__selected-state')
23
+ .should('be.visible');
24
+ cy.get('@fileInput')
25
+ .find('.mds-file-upload__input-controls > .mds-file-upload__selection-state')
26
+ .should('be.hidden');
27
+ });
28
+
29
+ it('removes a file when button clicked', () => {
30
+ cy.get('[data-test="input-selected-file"]').as('fileInput');
31
+ cy.get('@fileInput')
32
+ .find('.mds-file-upload__input-controls > .mds-file-upload__selection-state')
33
+ .should('be.hidden');
34
+ cy.get('@fileInput')
35
+ .find('.mds-file-upload__input-controls > .mds-file-upload__selected-state')
36
+ .should('be.visible');
37
+ cy.get('@fileInput').find('.mds-file-upload__remove-button').click();
38
+ cy.get('@fileInput')
39
+ .find('.mds-file-upload__input-controls > .mds-file-upload__selected-state')
40
+ .should('be.hidden');
41
+ cy.get('@fileInput')
42
+ .find('.mds-file-upload__input-controls > .mds-file-upload__selection-state')
43
+ .should('be.visible');
44
+ });
45
+ });
@@ -15,4 +15,4 @@ context('Input', () => {
15
15
  cy.checkA11y('[data-test="input-input-with-placeholder"]');
16
16
  cy.checkA11y('[data-test="input-input-with-hidden-label"]');
17
17
  });
18
- });
18
+ });
@@ -0,0 +1,15 @@
1
+ context('Label', () => {
2
+ beforeEach(() => {
3
+ cy.visitComponent('label');
4
+ });
5
+
6
+ it('has no detectable a11y violations on load', () => {
7
+ cy.document().then((doc) => {
8
+ const allTestables = doc.querySelectorAll('.mds-form-label');
9
+
10
+ allTestables.forEach((element) => {
11
+ cy.checkA11y(element);
12
+ });
13
+ });
14
+ });
15
+ });
@@ -0,0 +1,20 @@
1
+ context('Radio', () => {
2
+ beforeEach(() => {
3
+ cy.visitComponent('radio');
4
+ });
5
+
6
+ it('has no detectable a11y violations on load', () => {
7
+ cy.checkA11y('[data-test="radio-radio-input"]');
8
+ cy.checkA11y('[data-test="radio-inline-radio-input"]');
9
+ cy.checkA11y('[data-test="radio-stacked-radio-input-disabled"]');
10
+ });
11
+
12
+ it('checks the radio when label clicked', () => {
13
+ cy.get('[data-test="radio-radio-input"]').as('radioGroup');
14
+ cy.get('@radioGroup').find('label').first().click();
15
+ cy.get('@radioGroup').find('input').first().should('be.checked');
16
+ cy.get('@radioGroup').find('label').last().click();
17
+ cy.get('@radioGroup').find('input').first().should('not.be.checked');
18
+ cy.get('@radioGroup').find('input').last().should('be.checked');
19
+ });
20
+ });
@@ -0,0 +1,31 @@
1
+ context('Select', () => {
2
+ beforeEach(() => {
3
+ cy.visitComponent('select');
4
+ });
5
+
6
+ it('has no detectable a11y violations on load', () => {
7
+ cy.checkA11y('[data-test="select-select-input"]');
8
+ cy.document().then((doc) => {
9
+ const allTestables = doc.querySelectorAll("[data-test^='select-']");
10
+
11
+ allTestables.forEach((element) => {
12
+ cy.checkA11y(element);
13
+ });
14
+ });
15
+ });
16
+
17
+ it('can hide the default option', () => {
18
+ cy.get('[data-test="select-default-option-hidden"]').as('select');
19
+ cy.get('@select').find('option').first().should('be.selected').and('have.value', 'option-1');
20
+ });
21
+
22
+ it('can have a custom default option', () => {
23
+ cy.get('[data-test="select-default-option-custom"]').as('select');
24
+ cy.get('@select').find('option').first().should('be.selected').and('contain.text', 'All');
25
+ });
26
+
27
+ it('can preselct an option', () => {
28
+ cy.get('[data-test="select-preselected-input"]').as('select');
29
+ cy.get('@select').find('option:selected').should('have.value', 'option-2');
30
+ });
31
+ });
@@ -0,0 +1,23 @@
1
+ context('Textarea', () => {
2
+ beforeEach(() => {
3
+ cy.visitComponent('textarea');
4
+ });
5
+
6
+ it('has no detectable a11y violations on load', () => {
7
+ cy.checkA11y('[data-test="textarea-example-textarea"]');
8
+ });
9
+
10
+ it('shows characters remaining', () => {
11
+ cy.get('[data-test="textarea-example-textarea"]').as('textarea');
12
+ cy.get('@textarea')
13
+ .find('.js-character-count-number')
14
+ .invoke('text')
15
+ .then((charsRemaining) => {
16
+ cy.get('@textarea').type('123');
17
+ cy.get('@textarea')
18
+ .find('.js-character-count-number')
19
+ .invoke('text')
20
+ .should('equal', String(Number.parseInt(charsRemaining, 10) - 3));
21
+ });
22
+ });
23
+ });
@@ -0,0 +1,65 @@
1
+ context('Modal', () => {
2
+ beforeEach(() => {
3
+ cy.visitComponent('modal');
4
+ });
5
+
6
+ it('has no detectable a11y violations on load', () => {
7
+ cy.checkA11y("[data-modal-id='test-modal']");
8
+ });
9
+
10
+ it('opens a modal when trigger clicked', () => {
11
+ cy.get("button[data-modal-id='test-modal']").as('trigger');
12
+ cy.get('#test-modal').as('modalWindow');
13
+
14
+ cy.get('@modalWindow').should('be.hidden');
15
+ cy.get('@trigger').click();
16
+ cy.get('@modalWindow').should('be.visible');
17
+ });
18
+
19
+ it('has no a11y violations when open', () => {
20
+ cy.get("button[data-modal-id='test-modal']").as('trigger');
21
+ cy.get('#test-modal').as('modalWindow');
22
+ cy.get('@trigger').click();
23
+ cy.checkA11y('#test-modal');
24
+ });
25
+
26
+ it('close modal if clicking outside of "modal__inner"', () => {
27
+ cy.get("button[data-modal-id='test-modal']").as('trigger');
28
+ cy.get('#test-modal').as('modalWindow');
29
+ cy.get('@trigger').click();
30
+ cy.get('@modalWindow').should('be.visible');
31
+ cy.get('@modalWindow').click({ force: true });
32
+ cy.get('@modalWindow').should('be.hidden');
33
+ });
34
+
35
+ it('close modal if using escape key', () => {
36
+ cy.get("button[data-modal-id='test-modal']").as('trigger');
37
+ cy.get('#test-modal').as('modalWindow');
38
+ cy.get('@trigger').click();
39
+ cy.get('body').type('{esc}');
40
+ });
41
+
42
+ it('close modal if using close button', () => {
43
+ // First close button
44
+ cy.get("button[data-modal-id='test-modal']").as('trigger');
45
+ cy.get('#test-modal').as('modalWindow');
46
+ cy.get('@trigger').click();
47
+ cy.get('@modalWindow').should('be.visible');
48
+ cy.get('@modalWindow').find('.js-mds-modal-close').first().click();
49
+ cy.get('@modalWindow').should('be.hidden');
50
+
51
+ // Second close button
52
+ cy.get('@trigger').click();
53
+ cy.get('@modalWindow').should('be.visible');
54
+ cy.get('@modalWindow').find('.js-mds-modal-close').last().click();
55
+ cy.get('@modalWindow').should('be.hidden');
56
+ });
57
+
58
+ it('tab or shift tab keeps you focused on the close button inside the modal', () => {
59
+ cy.get("button[data-modal-id='test-modal']").as('trigger');
60
+ cy.get('#test-modal').as('modalWindow');
61
+ cy.get('@trigger').click();
62
+ cy.focused().tab().tab().should('have.class', 'js-mds-modal-close');
63
+ cy.focused().tab({ shift: true }).tab({ shift: true }).should('have.class', 'js-mds-modal-close');
64
+ });
65
+ });
@@ -0,0 +1,35 @@
1
+ context('Notification', () => {
2
+ beforeEach(() => {
3
+ cy.visitComponent('notification');
4
+ });
5
+
6
+ it('has no detectable a11y violations on load', () => {
7
+ cy.document().then((doc) => {
8
+ const allTestables = doc.querySelectorAll('.js-notification-example');
9
+
10
+ allTestables.forEach((element) => {
11
+ cy.checkA11y(element);
12
+ });
13
+ });
14
+ });
15
+
16
+ it('has no detectable a11y violations when clicked', () => {
17
+ cy.document().then((doc) => {
18
+ const allTestables = doc.querySelectorAll('.js-notification-example');
19
+
20
+ allTestables.forEach((element) => {
21
+ cy.get(element).click();
22
+ cy.checkA11y(element);
23
+ });
24
+ });
25
+ });
26
+
27
+ it('shows the correct notifications when clicked', () => {
28
+ cy.get('[data-message-type="success"]').click();
29
+ cy.get('.mds-message--success').should('be.visible');
30
+ cy.get('[data-message-type="error"]').click();
31
+ cy.get('.mds-message--error').should('be.visible');
32
+ cy.get('[data-message-type="info"]').click();
33
+ cy.get('.mds-message--info').should('be.visible');
34
+ });
35
+ });
@@ -0,0 +1,36 @@
1
+ context('Popover', () => {
2
+ beforeEach(() => {
3
+ cy.visitComponent('popover');
4
+ });
5
+
6
+ it('has no detectable a11y violations on load', () => {
7
+ cy.document().then((doc) => {
8
+ const allTestables = doc.querySelectorAll('.js-mds-popover-trigger');
9
+
10
+ allTestables.forEach((element) => {
11
+ cy.checkA11y(element);
12
+ });
13
+ });
14
+ });
15
+
16
+ it('has no detectable a11y violations when clicked', () => {
17
+ cy.excludeA11yTests(['color-contrast']);
18
+ cy.document().then((doc) => {
19
+ const allTestables = doc.querySelectorAll('.js-mds-popover-trigger');
20
+
21
+ allTestables.forEach((element) => {
22
+ cy.get(element).click({ force: true });
23
+ cy.checkA11y(element);
24
+ });
25
+ });
26
+ });
27
+
28
+ it('shows the correct notifications when clicked', () => {
29
+ cy.get('[data-test="button-simple-popover-popover-trigger"]').click();
30
+ cy.get('#simple-popover-content').should('be.visible');
31
+ cy.get('[data-test="button-popover-link-popover-trigger"]').click();
32
+ cy.get('#popover-link-content').should('be.visible');
33
+ cy.get('[data-test="button-popover-left-popover-trigger"]').click({ force: true });
34
+ cy.get('#popover-left-content').should('be.visible');
35
+ });
36
+ });
@@ -0,0 +1,9 @@
1
+ context('Skip Link', () => {
2
+ beforeEach(() => {
3
+ cy.visitComponent('skip-link');
4
+ });
5
+
6
+ it('has no detectable a11y violations on load', () => {
7
+ cy.checkA11y('.mds-skip-to-content');
8
+ });
9
+ });
@@ -11,7 +11,7 @@
11
11
  // This function is called when a project is opened or re-opened (e.g. due to
12
12
  // the project's config changing)
13
13
 
14
- module.exports = (on, config) => {
14
+ module.exports = (/* on, config */) => {
15
15
  // `on` is used to hook into various events Cypress emits
16
16
  // `config` is the resolved Cypress config
17
17
  };
@@ -14,6 +14,20 @@ Cypress.Commands.add('visitComponent', (componentName) => {
14
14
  cy.visit(`http://localhost:4000/components/preview/${componentName}`);
15
15
  cy.injectAxe();
16
16
  });
17
+
18
+ Cypress.Commands.add('excludeA11yTests', (testNames) => {
19
+ const checks = [];
20
+
21
+ testNames.forEach((test) => {
22
+ checks.push({
23
+ id: test,
24
+ enabled: false,
25
+ });
26
+ });
27
+ cy.configureAxe({
28
+ checks,
29
+ });
30
+ });
17
31
  //
18
32
  //
19
33
  // -- This is a child command --
@@ -20,3 +20,5 @@ import './commands';
20
20
  // Alternatively you can use CommonJS syntax:
21
21
  // require('./commands')
22
22
  require('cypress-commands');
23
+ require('cypress-plugin-tab');
24
+ require('cypress-file-upload');
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Do not edit directly
3
- * Generated on Wed, 07 Jul 2021 11:25:59 GMT
3
+ * Generated on Thu, 08 Jul 2021 14:47:40 GMT
4
4
  */
5
5
 
6
6
  :root {