@muonic/muon 0.0.2-beta.0
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/.nycrc +17 -0
- package/.versionrc +3 -0
- package/CHANGELOG.md +389 -0
- package/components/card/index.js +1 -0
- package/components/card/src/card-component.js +43 -0
- package/components/card/src/card-styles.css +25 -0
- package/components/card/src/config-tokens.json +11 -0
- package/components/card/src/design-tokens.json +34 -0
- package/components/card/story.js +52 -0
- package/components/cta/index.js +1 -0
- package/components/cta/src/config-tokens.json +11 -0
- package/components/cta/src/cta-component.js +174 -0
- package/components/cta/src/cta-styles.css +105 -0
- package/components/cta/src/design-tokens.json +132 -0
- package/components/cta/story.js +99 -0
- package/components/detail/index.js +1 -0
- package/components/detail/src/config-tokens.json +11 -0
- package/components/detail/src/design-tokens.json +102 -0
- package/components/detail/src/detail-component.js +27 -0
- package/components/detail/src/detail-styles.css +83 -0
- package/components/detail/story.js +33 -0
- package/components/form/index.js +1 -0
- package/components/form/src/config-tokens.json +11 -0
- package/components/form/src/design-tokens.json +9 -0
- package/components/form/src/form-component.js +197 -0
- package/components/form/src/form-styles.css +10 -0
- package/components/form/story.js +71 -0
- package/components/icon/index.js +1 -0
- package/components/icon/src/config-tokens.json +31 -0
- package/components/icon/src/design-tokens.json +8 -0
- package/components/icon/src/icon-component.js +91 -0
- package/components/icon/src/icon-styles.css +26 -0
- package/components/icon/story.js +26 -0
- package/components/image/index.js +1 -0
- package/components/image/src/config-tokens.json +26 -0
- package/components/image/src/image-component.js +96 -0
- package/components/image/src/image-styles.css +71 -0
- package/components/image/story.js +31 -0
- package/components/inputter/index.js +1 -0
- package/components/inputter/src/config-tokens.json +14 -0
- package/components/inputter/src/design-tokens.json +308 -0
- package/components/inputter/src/inputter-component.js +227 -0
- package/components/inputter/src/inputter-styles-detail.css +59 -0
- package/components/inputter/src/inputter-styles.css +305 -0
- package/components/inputter/src/inputter-styles.slotted.css +64 -0
- package/components/inputter/story.js +243 -0
- package/css/accessibility.css +3 -0
- package/css/default.css +9 -0
- package/css/global.css +8 -0
- package/directives/image-loader-directive.js +116 -0
- package/directives/svg-loader-directive.js +94 -0
- package/index.js +52 -0
- package/mixins/card-mixin.js +27 -0
- package/mixins/detail-mixin.js +128 -0
- package/mixins/form-associate-mixin.js +36 -0
- package/mixins/form-element-mixin.js +378 -0
- package/mixins/image-holder-mixin.js +20 -0
- package/mixins/mask-mixin.js +159 -0
- package/mixins/validation-mixin.js +272 -0
- package/muon-element/index.js +97 -0
- package/package.json +72 -0
- package/rollup.config.mjs +30 -0
- package/scripts/build/storybook/index.mjs +11 -0
- package/scripts/build/storybook/run.mjs +47 -0
- package/scripts/rollup-plugins.mjs +116 -0
- package/scripts/serve/index.mjs +11 -0
- package/scripts/serve/run.mjs +27 -0
- package/scripts/style-dictionary.mjs +64 -0
- package/scripts/utils/config.mjs +30 -0
- package/scripts/utils/index.mjs +283 -0
- package/storybook/find-stories.js +36 -0
- package/storybook/server.config.mjs +19 -0
- package/storybook/stories.js +86 -0
- package/storybook/tokens/color.js +87 -0
- package/storybook/tokens/font.js +52 -0
- package/storybook/tokens/spacer.js +48 -0
- package/tests/README.md +3 -0
- package/tests/components/card/__snapshots__/card.test.snap.js +70 -0
- package/tests/components/card/card.test.js +81 -0
- package/tests/components/cta/__snapshots__/cta.test.snap.js +246 -0
- package/tests/components/cta/cta.test.js +212 -0
- package/tests/components/form/__snapshots__/form.test.snap.js +115 -0
- package/tests/components/form/form.test.js +336 -0
- package/tests/components/icon/__snapshots__/icon.test.snap.js +95 -0
- package/tests/components/icon/icon.test.js +197 -0
- package/tests/components/image/__snapshots__/image.test.snap.js +205 -0
- package/tests/components/image/image.test.js +314 -0
- package/tests/components/image/images/15.png +0 -0
- package/tests/components/image/images/150.png +0 -0
- package/tests/components/inputter/__snapshots__/inputter.test.snap.js +357 -0
- package/tests/components/inputter/inputter.test.js +427 -0
- package/tests/helpers/index.js +30 -0
- package/tests/mixins/__snapshots__/card.test.snap.js +35 -0
- package/tests/mixins/__snapshots__/detail.test.snap.js +237 -0
- package/tests/mixins/__snapshots__/form-element.test.snap.js +137 -0
- package/tests/mixins/__snapshots__/mask.test.snap.js +53 -0
- package/tests/mixins/__snapshots__/validation.test.snap.js +297 -0
- package/tests/mixins/card.test.js +63 -0
- package/tests/mixins/detail.test.js +223 -0
- package/tests/mixins/form-element.test.js +473 -0
- package/tests/mixins/mask.test.js +261 -0
- package/tests/mixins/muon-element.test.js +52 -0
- package/tests/mixins/validation.test.js +423 -0
- package/tests/runner/commands.mjs +19 -0
- package/tests/scripts/utils/card-component.js +26 -0
- package/tests/scripts/utils/muon.config.test.json +13 -0
- package/tests/scripts/utils/single.component.config.json +5 -0
- package/tests/scripts/utils/test-runner.mjs +1 -0
- package/tests/scripts/utils/utils-test.mjs +284 -0
- package/tests/utils/validation.functions.test.js +199 -0
- package/tokens/theme/color.json +482 -0
- package/tokens/theme/font.json +61 -0
- package/tokens/theme/size.json +27 -0
- package/tokens/theme/spacer.json +73 -0
- package/tokens/utils/formats/reference.js +17 -0
- package/tokens/utils/modular-scale.js +33 -0
- package/tokens/utils/templates/font-face.css.template +30 -0
- package/tokens/utils/transforms/color.js +27 -0
- package/tokens/utils/transforms/string.js +6 -0
- package/tokens/utils/validation.json +76 -0
- package/utils/scroll/index.js +31 -0
- package/utils/validation/index.js +205 -0
- package/web-test-runner.browserstack.config.mjs +123 -0
- package/web-test-runner.config.mjs +44 -0
|
@@ -0,0 +1,423 @@
|
|
|
1
|
+
/* eslint-disable no-undef */
|
|
2
|
+
import { expect, fixture, html, defineCE, unsafeStatic } from '@open-wc/testing';
|
|
3
|
+
import { MuonElement } from '@muonic/muon';
|
|
4
|
+
import sinon from 'sinon';
|
|
5
|
+
import { defaultChecks, fillIn, selectEvent } from '../helpers';
|
|
6
|
+
import { ValidationMixin } from '@muonic/muon/mixins/validation-mixin';
|
|
7
|
+
|
|
8
|
+
const MuonValidationElement = class extends ValidationMixin(MuonElement) {
|
|
9
|
+
|
|
10
|
+
get standardTemplate() {
|
|
11
|
+
return html `
|
|
12
|
+
<div class="slotted-content">
|
|
13
|
+
${this._isMultiple ? this._addHeading : this._addLabel}
|
|
14
|
+
<div class="input-holder">
|
|
15
|
+
${super.standardTemplate}
|
|
16
|
+
</div>
|
|
17
|
+
${this.isPristine ? html`` : this._addValidationMessage}
|
|
18
|
+
</div>
|
|
19
|
+
`;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
get customTemplate() {
|
|
23
|
+
return html `
|
|
24
|
+
<div class="slotted-content">
|
|
25
|
+
${this._isMultiple ? this._addHeading : this._addLabel}
|
|
26
|
+
<div class="input-holder">
|
|
27
|
+
${super.standardTemplate}
|
|
28
|
+
</div>
|
|
29
|
+
${this._addValidationListMessage}
|
|
30
|
+
</div>
|
|
31
|
+
`;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
_onChange(changeEvent) {
|
|
35
|
+
this._pristine = false;
|
|
36
|
+
super._onChange(changeEvent);
|
|
37
|
+
this.validate();
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
_onBlur(blurEvent) {
|
|
41
|
+
this._pristine = false;
|
|
42
|
+
super._onBlur(blurEvent);
|
|
43
|
+
this.validate();
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
_onInput(inputEvent) {
|
|
47
|
+
this._pristine = false;
|
|
48
|
+
super._onInput(inputEvent);
|
|
49
|
+
if (this.validation?.length > 0 && this._isSingle) {
|
|
50
|
+
if (this.value !== this._slottedValue) {
|
|
51
|
+
this.value = this._slottedValue;
|
|
52
|
+
this._fireChangeEvent();
|
|
53
|
+
}
|
|
54
|
+
this.validate();
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
const tagName = defineCE(MuonValidationElement);
|
|
60
|
+
const tag = unsafeStatic(tagName);
|
|
61
|
+
|
|
62
|
+
describe('form-element-validation', () => {
|
|
63
|
+
it('standard', async () => {
|
|
64
|
+
const validationElement = await fixture(html`<${tag}></${tag}>`);
|
|
65
|
+
|
|
66
|
+
await defaultChecks(validationElement);
|
|
67
|
+
|
|
68
|
+
const shadowRoot = validationElement.shadowRoot;
|
|
69
|
+
const holder = shadowRoot.querySelector('.input-holder');
|
|
70
|
+
|
|
71
|
+
expect(holder).to.not.be.null; // eslint-disable-line no-unused-expressions
|
|
72
|
+
expect(validationElement.type).to.equal('standard', '`type` property has default value `standard`');
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
it('text validation', async () => {
|
|
76
|
+
const formElement = await fixture(html`
|
|
77
|
+
<${tag} validation=["isRequired","isBetween(5,10)"] disableNative="true">
|
|
78
|
+
<label slot="label">input label</label>
|
|
79
|
+
<input type="text" value=""/>
|
|
80
|
+
</${tag}>`);
|
|
81
|
+
|
|
82
|
+
await defaultChecks(formElement);
|
|
83
|
+
|
|
84
|
+
const shadowRoot = formElement.shadowRoot;
|
|
85
|
+
const inputElement = formElement.querySelector('input');
|
|
86
|
+
|
|
87
|
+
// eslint-disable-next-line no-unused-expressions
|
|
88
|
+
expect(inputElement).to.not.be.null;
|
|
89
|
+
|
|
90
|
+
const changeEventSpy = sinon.spy();
|
|
91
|
+
formElement.addEventListener('change', changeEventSpy);
|
|
92
|
+
|
|
93
|
+
await fillIn(inputElement, 'hello');
|
|
94
|
+
expect(formElement.value).to.equal('hello', '`value` property has value `hello`');
|
|
95
|
+
expect(changeEventSpy.callCount).to.equal(1, '`change` event fired');
|
|
96
|
+
expect(changeEventSpy.lastCall.args[0].detail.value).to.equal('hello', '`change` event has value `hello`');
|
|
97
|
+
|
|
98
|
+
await fillIn(inputElement, '');
|
|
99
|
+
expect(formElement.value).to.equal('', '`value` property has value ``');
|
|
100
|
+
expect(changeEventSpy.callCount).to.equal(2, '`change` event fired');
|
|
101
|
+
expect(changeEventSpy.lastCall.args[0].detail.value).to.equal('', '`change` event has value ``');
|
|
102
|
+
|
|
103
|
+
await formElement.updateComplete;
|
|
104
|
+
let validationMessage = shadowRoot.querySelector('.validation');
|
|
105
|
+
expect(validationMessage).to.not.be.null; // eslint-disable-line no-unused-expressions
|
|
106
|
+
expect(validationMessage.textContent.trim()).to.equal('This field is required.', 'validation message has correct value');
|
|
107
|
+
|
|
108
|
+
await fillIn(inputElement, 'hello world');
|
|
109
|
+
expect(formElement.value).to.equal('hello world', '`value` property has value `hello world`');
|
|
110
|
+
expect(changeEventSpy.callCount).to.equal(3, '`change` event fired');
|
|
111
|
+
expect(changeEventSpy.lastCall.args[0].detail.value).to.equal('hello world', '`change` event has value `hello world`');
|
|
112
|
+
|
|
113
|
+
await formElement.updateComplete;
|
|
114
|
+
validationMessage = shadowRoot.querySelector('.validation');
|
|
115
|
+
expect(validationMessage).to.not.be.null; // eslint-disable-line no-unused-expressions
|
|
116
|
+
expect(validationMessage.textContent.trim()).to.equal('Length must be between 5 and 10 characters.', 'validation message has correct value');
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
it('text validation on input', async () => {
|
|
120
|
+
const formElement = await fixture(html`
|
|
121
|
+
<${tag} validation=["isRequired","isBetween(5,10)"] disableNative="true">
|
|
122
|
+
<label slot="label">input label</label>
|
|
123
|
+
<input type="text" value=""/>
|
|
124
|
+
</${tag}>`);
|
|
125
|
+
|
|
126
|
+
await defaultChecks(formElement);
|
|
127
|
+
|
|
128
|
+
const shadowRoot = formElement.shadowRoot;
|
|
129
|
+
const inputElement = formElement.querySelector('input');
|
|
130
|
+
|
|
131
|
+
// eslint-disable-next-line no-unused-expressions
|
|
132
|
+
expect(inputElement).to.not.be.null;
|
|
133
|
+
|
|
134
|
+
const changeEventSpy = sinon.spy();
|
|
135
|
+
formElement.addEventListener('change', changeEventSpy);
|
|
136
|
+
|
|
137
|
+
await fillIn(inputElement, 'hello', 'input');
|
|
138
|
+
expect(formElement.value).to.equal('hello', '`value` property has value `hello`');
|
|
139
|
+
expect(changeEventSpy.callCount).to.equal(1, '`change` event fired');
|
|
140
|
+
expect(changeEventSpy.lastCall.args[0].detail.value).to.equal('hello', '`change` event has value `hello`');
|
|
141
|
+
|
|
142
|
+
await fillIn(inputElement, '', 'input');
|
|
143
|
+
expect(formElement.value).to.equal('', '`value` property has value ``');
|
|
144
|
+
expect(changeEventSpy.callCount).to.equal(2, '`change` event fired');
|
|
145
|
+
expect(changeEventSpy.lastCall.args[0].detail.value).to.equal('', '`change` event has value ``');
|
|
146
|
+
|
|
147
|
+
await formElement.updateComplete;
|
|
148
|
+
let validationMessage = shadowRoot.querySelector('.validation');
|
|
149
|
+
expect(validationMessage).to.not.be.null; // eslint-disable-line no-unused-expressions
|
|
150
|
+
expect(validationMessage.textContent.trim()).to.equal('This field is required.', 'validation message has correct value');
|
|
151
|
+
|
|
152
|
+
await fillIn(inputElement, 'hello world', 'input');
|
|
153
|
+
expect(formElement.value).to.equal('hello world', '`value` property has value `hello world`');
|
|
154
|
+
expect(changeEventSpy.callCount).to.equal(3, '`change` event fired');
|
|
155
|
+
expect(changeEventSpy.lastCall.args[0].detail.value).to.equal('hello world', '`change` event has value `hello world`');
|
|
156
|
+
|
|
157
|
+
await formElement.updateComplete;
|
|
158
|
+
validationMessage = shadowRoot.querySelector('.validation');
|
|
159
|
+
expect(validationMessage).to.not.be.null; // eslint-disable-line no-unused-expressions
|
|
160
|
+
expect(validationMessage.textContent.trim()).to.equal('Length must be between 5 and 10 characters.', 'validation message has correct value');
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
it('text native validation', async () => {
|
|
164
|
+
const formElement = await fixture(html`
|
|
165
|
+
<${tag} validation=["isRequired"]>
|
|
166
|
+
<label slot="label">input label</label>
|
|
167
|
+
<input type="text" value="" required/>
|
|
168
|
+
</${tag}>`);
|
|
169
|
+
|
|
170
|
+
await defaultChecks(formElement);
|
|
171
|
+
|
|
172
|
+
const shadowRoot = formElement.shadowRoot;
|
|
173
|
+
const inputElement = formElement.querySelector('input');
|
|
174
|
+
|
|
175
|
+
// eslint-disable-next-line no-unused-expressions
|
|
176
|
+
expect(inputElement).to.not.be.null;
|
|
177
|
+
|
|
178
|
+
const changeEventSpy = sinon.spy();
|
|
179
|
+
formElement.addEventListener('change', changeEventSpy);
|
|
180
|
+
|
|
181
|
+
await fillIn(inputElement, 'hello');
|
|
182
|
+
expect(formElement.value).to.equal('hello', '`value` property has value `hello`');
|
|
183
|
+
expect(changeEventSpy.callCount).to.equal(1, '`change` event fired');
|
|
184
|
+
expect(changeEventSpy.lastCall.args[0].detail.value).to.equal('hello', '`change` event has value `hello`');
|
|
185
|
+
|
|
186
|
+
await fillIn(inputElement, '');
|
|
187
|
+
expect(formElement.value).to.equal('', '`value` property has value ``');
|
|
188
|
+
expect(changeEventSpy.callCount).to.equal(2, '`change` event fired');
|
|
189
|
+
expect(changeEventSpy.lastCall.args[0].detail.value).to.equal('', '`change` event has value ``');
|
|
190
|
+
|
|
191
|
+
await formElement.updateComplete;
|
|
192
|
+
let validationMessage = shadowRoot.querySelector('.validation');
|
|
193
|
+
expect(validationMessage).to.not.be.null; // eslint-disable-line no-unused-expressions
|
|
194
|
+
expect(validationMessage.textContent.trim().toLowerCase()).contains('this field is required', 'validation message has correct value');
|
|
195
|
+
|
|
196
|
+
await fillIn(inputElement, 'test validation');
|
|
197
|
+
expect(formElement.value).to.equal('test validation', '`value` property has value `test validation`');
|
|
198
|
+
expect(changeEventSpy.callCount).to.equal(3, '`change` event fired');
|
|
199
|
+
expect(changeEventSpy.lastCall.args[0].detail.value).to.equal('test validation', '`change` event has value `test validation`');
|
|
200
|
+
|
|
201
|
+
await formElement.updateComplete;
|
|
202
|
+
validationMessage = shadowRoot.querySelector('.validation');
|
|
203
|
+
expect(validationMessage).to.be.null; // eslint-disable-line no-unused-expressions
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
it('tel native validation', async () => {
|
|
207
|
+
const formElement = await fixture(html`
|
|
208
|
+
<${tag} validation=["isRequired"]>
|
|
209
|
+
<label slot="label">input label</label>
|
|
210
|
+
<input type="tel" value="" pattern="[0-9]{3}" title="match the pattern"/>
|
|
211
|
+
</${tag}>`);
|
|
212
|
+
|
|
213
|
+
await defaultChecks(formElement);
|
|
214
|
+
|
|
215
|
+
const shadowRoot = formElement.shadowRoot;
|
|
216
|
+
const inputElement = formElement.querySelector('input');
|
|
217
|
+
|
|
218
|
+
// eslint-disable-next-line no-unused-expressions
|
|
219
|
+
expect(inputElement).to.not.be.null;
|
|
220
|
+
|
|
221
|
+
const changeEventSpy = sinon.spy();
|
|
222
|
+
formElement.addEventListener('change', changeEventSpy);
|
|
223
|
+
|
|
224
|
+
await fillIn(inputElement, '124');
|
|
225
|
+
expect(formElement.value).to.equal('124', '`value` property has value `124`');
|
|
226
|
+
expect(changeEventSpy.callCount).to.equal(1, '`change` event fired');
|
|
227
|
+
expect(changeEventSpy.lastCall.args[0].detail.value).to.equal('124', '`change` event has value `124`');
|
|
228
|
+
|
|
229
|
+
await fillIn(inputElement, '');
|
|
230
|
+
expect(formElement.value).to.equal('', '`value` property has value ``');
|
|
231
|
+
expect(changeEventSpy.callCount).to.equal(2, '`change` event fired');
|
|
232
|
+
expect(changeEventSpy.lastCall.args[0].detail.value).to.equal('', '`change` event has value ``');
|
|
233
|
+
|
|
234
|
+
await formElement.updateComplete;
|
|
235
|
+
let validationMessage = shadowRoot.querySelector('.validation');
|
|
236
|
+
expect(validationMessage).to.not.be.null; // eslint-disable-line no-unused-expressions
|
|
237
|
+
expect(validationMessage.textContent.trim()).to.equal('This field is required.', 'validation message has correct value');
|
|
238
|
+
|
|
239
|
+
await fillIn(inputElement, '56');
|
|
240
|
+
expect(formElement.value).to.equal('56', '`value` property has value `56`');
|
|
241
|
+
expect(changeEventSpy.callCount).to.equal(3, '`change` event fired');
|
|
242
|
+
expect(changeEventSpy.lastCall.args[0].detail.value).to.equal('56', '`change` event has value `56`');
|
|
243
|
+
|
|
244
|
+
await formElement.updateComplete;
|
|
245
|
+
validationMessage = shadowRoot.querySelector('.validation');
|
|
246
|
+
expect(validationMessage).to.not.be.null; // eslint-disable-line no-unused-expressions
|
|
247
|
+
expect(validationMessage.textContent.trim()).to.equal('match the pattern.', 'validation message has correct value');
|
|
248
|
+
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
it('text custom type validation', async () => {
|
|
252
|
+
const formElement = await fixture(html`
|
|
253
|
+
<${tag} type="custom" validation=["isRequired"]>
|
|
254
|
+
<label slot="label">input label</label>
|
|
255
|
+
<input type="text" value=""/>
|
|
256
|
+
</${tag}>`);
|
|
257
|
+
|
|
258
|
+
await defaultChecks(formElement);
|
|
259
|
+
|
|
260
|
+
const shadowRoot = formElement.shadowRoot;
|
|
261
|
+
const inputElement = formElement.querySelector('input');
|
|
262
|
+
|
|
263
|
+
// eslint-disable-next-line no-unused-expressions
|
|
264
|
+
expect(inputElement).to.not.be.null;
|
|
265
|
+
|
|
266
|
+
const changeEventSpy = sinon.spy();
|
|
267
|
+
formElement.addEventListener('change', changeEventSpy);
|
|
268
|
+
|
|
269
|
+
await fillIn(inputElement, 'hello');
|
|
270
|
+
expect(formElement.value).to.equal('hello', '`value` property has value `hello`');
|
|
271
|
+
expect(changeEventSpy.callCount).to.equal(1, '`change` event fired');
|
|
272
|
+
expect(changeEventSpy.lastCall.args[0].detail.value).to.equal('hello', '`change` event has value `hello`');
|
|
273
|
+
|
|
274
|
+
await fillIn(inputElement, '');
|
|
275
|
+
expect(formElement.value).to.equal('', '`value` property has value ``');
|
|
276
|
+
expect(changeEventSpy.callCount).to.equal(2, '`change` event fired');
|
|
277
|
+
expect(changeEventSpy.lastCall.args[0].detail.value).to.equal('', '`change` event has value ``');
|
|
278
|
+
|
|
279
|
+
await formElement.updateComplete;
|
|
280
|
+
const validationMessage = shadowRoot.querySelector('.validation');
|
|
281
|
+
expect(validationMessage).to.not.be.null; // eslint-disable-line no-unused-expressions
|
|
282
|
+
const listMessage = validationMessage.querySelectorAll('ul > li > p');
|
|
283
|
+
expect(listMessage[0].textContent.trim()).to.equal('This field is required.', 'validation message has correct value');
|
|
284
|
+
});
|
|
285
|
+
|
|
286
|
+
it('radio validation', async () => {
|
|
287
|
+
const formElement = await fixture(html`
|
|
288
|
+
<${tag} heading="What is your heating source?" validation=["isRequired"]>
|
|
289
|
+
<input type="radio" id="question-gas" name="question" value="gas"></input>
|
|
290
|
+
<label for="question-gas">Gas</label>
|
|
291
|
+
<input type="radio" id="question-electricity" name="question" value="electricity"></input>
|
|
292
|
+
<label for="question-electricity">Electricity</label>
|
|
293
|
+
</${tag}>`);
|
|
294
|
+
|
|
295
|
+
await defaultChecks(formElement);
|
|
296
|
+
|
|
297
|
+
const shadowRoot = formElement.shadowRoot;
|
|
298
|
+
const inputElement = formElement.querySelector('input');
|
|
299
|
+
|
|
300
|
+
// eslint-disable-next-line no-unused-expressions
|
|
301
|
+
expect(inputElement).to.not.be.null;
|
|
302
|
+
|
|
303
|
+
// eslint-disable-next-line no-unused-expressions
|
|
304
|
+
expect(inputElement.checked).to.false;
|
|
305
|
+
|
|
306
|
+
await inputElement.focus();
|
|
307
|
+
await inputElement.blur();
|
|
308
|
+
|
|
309
|
+
await formElement.updateComplete;
|
|
310
|
+
const validationMessage = shadowRoot.querySelector('.validation');
|
|
311
|
+
expect(validationMessage).to.not.be.null; // eslint-disable-line no-unused-expressions
|
|
312
|
+
expect(validationMessage.textContent.trim()).to.equal('This field is required.', 'validation message has correct value');
|
|
313
|
+
});
|
|
314
|
+
|
|
315
|
+
it('checkbox validation', async () => {
|
|
316
|
+
const formElement = await fixture(html`
|
|
317
|
+
<${tag} heading="What is your heating source?" validation=["isRequired"]>
|
|
318
|
+
<input type="checkbox" id="question-gas" name="question" value="gas" checked></input>
|
|
319
|
+
<label for="question-gas">Gas</label>
|
|
320
|
+
<input type="checkbox" id="question-electricity" name="question" value="electricity"></input>
|
|
321
|
+
<label for="question-electricity">Electricity</label>
|
|
322
|
+
</${tag}>`);
|
|
323
|
+
|
|
324
|
+
await defaultChecks(formElement);
|
|
325
|
+
|
|
326
|
+
const shadowRoot = formElement.shadowRoot;
|
|
327
|
+
const inputElement = formElement.querySelectorAll('input');
|
|
328
|
+
|
|
329
|
+
// eslint-disable-next-line no-unused-expressions
|
|
330
|
+
expect(inputElement).to.not.be.null;
|
|
331
|
+
|
|
332
|
+
const changeEventSpy = sinon.spy();
|
|
333
|
+
formElement.addEventListener('change', changeEventSpy);
|
|
334
|
+
|
|
335
|
+
// eslint-disable-next-line no-unused-expressions
|
|
336
|
+
expect(inputElement[0].checked).to.true;
|
|
337
|
+
|
|
338
|
+
await inputElement[0].click();
|
|
339
|
+
await formElement.updateComplete;
|
|
340
|
+
|
|
341
|
+
expect(changeEventSpy.callCount).to.equal(1, '`change` event fired');
|
|
342
|
+
const validationMessage = shadowRoot.querySelector('.validation');
|
|
343
|
+
expect(validationMessage).to.not.be.null; // eslint-disable-line no-unused-expressions
|
|
344
|
+
expect(validationMessage.textContent.trim()).to.equal('This field is required.', 'validation message has correct value');
|
|
345
|
+
});
|
|
346
|
+
|
|
347
|
+
it('select validation', async () => {
|
|
348
|
+
const formElement = await fixture(html`
|
|
349
|
+
<${tag} validation=["isRequired"]>
|
|
350
|
+
<label slot="label" for="select-input">What is your heating source?</label>
|
|
351
|
+
<select name="select" id="select-input">
|
|
352
|
+
<option value="">Please Select</option>
|
|
353
|
+
<option value="value1">One</option>
|
|
354
|
+
<option value="value2">Two</option>
|
|
355
|
+
<option value="value3">Three</option>
|
|
356
|
+
<option value="value4">Four</option>
|
|
357
|
+
</select>
|
|
358
|
+
</${tag}>`);
|
|
359
|
+
|
|
360
|
+
await defaultChecks(formElement);
|
|
361
|
+
|
|
362
|
+
const shadowRoot = formElement.shadowRoot;
|
|
363
|
+
const selectElement = formElement.querySelector('select');
|
|
364
|
+
// eslint-disable-next-line no-unused-expressions
|
|
365
|
+
expect(selectElement).to.not.be.null;
|
|
366
|
+
|
|
367
|
+
const changeEventSpy = sinon.spy();
|
|
368
|
+
formElement.addEventListener('change', changeEventSpy);
|
|
369
|
+
|
|
370
|
+
await selectEvent(selectElement, '');
|
|
371
|
+
await formElement.updateComplete;
|
|
372
|
+
|
|
373
|
+
expect(changeEventSpy.callCount).to.equal(1, '`change` event fired');
|
|
374
|
+
const validationMessage = shadowRoot.querySelector('.validation');
|
|
375
|
+
expect(validationMessage).to.not.be.null; // eslint-disable-line no-unused-expressions
|
|
376
|
+
expect(validationMessage.textContent.trim()).to.equal('This field is required.', 'validation message has correct value');
|
|
377
|
+
});
|
|
378
|
+
|
|
379
|
+
it('date validation', async () => {
|
|
380
|
+
const formElement = await fixture(html`
|
|
381
|
+
<${tag} validation=["isRequired","minDate('11/11/2021')"]>
|
|
382
|
+
<label slot="label">input label</label>
|
|
383
|
+
<input type="text" value="" />
|
|
384
|
+
</${tag}>`);
|
|
385
|
+
|
|
386
|
+
await defaultChecks(formElement);
|
|
387
|
+
|
|
388
|
+
const shadowRoot = formElement.shadowRoot;
|
|
389
|
+
const inputElement = formElement.querySelector('input');
|
|
390
|
+
|
|
391
|
+
// eslint-disable-next-line no-unused-expressions
|
|
392
|
+
expect(inputElement).to.not.be.null;
|
|
393
|
+
|
|
394
|
+
const changeEventSpy = sinon.spy();
|
|
395
|
+
formElement.addEventListener('change', changeEventSpy);
|
|
396
|
+
|
|
397
|
+
await fillIn(inputElement, '12/11/2021');
|
|
398
|
+
await formElement.updateComplete;
|
|
399
|
+
expect(formElement.value).to.equal('12/11/2021', '`value` property has value `12/11/2021`');
|
|
400
|
+
expect(changeEventSpy.callCount).to.equal(1, '`change` event fired');
|
|
401
|
+
expect(changeEventSpy.lastCall.args[0].detail.value).to.equal('12/11/2021', '`change` event has value `12/11/2021`');
|
|
402
|
+
|
|
403
|
+
await fillIn(inputElement, '');
|
|
404
|
+
await formElement.updateComplete;
|
|
405
|
+
expect(formElement.value).to.equal('', '`value` property has value ``');
|
|
406
|
+
expect(changeEventSpy.callCount).to.equal(2, '`change` event fired');
|
|
407
|
+
expect(changeEventSpy.lastCall.args[0].detail.value).to.equal('', '`change` event has value ``');
|
|
408
|
+
|
|
409
|
+
let validationMessage = shadowRoot.querySelector('.validation');
|
|
410
|
+
expect(validationMessage).to.not.be.null; // eslint-disable-line no-unused-expressions
|
|
411
|
+
expect(validationMessage.textContent.trim()).to.equal('This field is required.', 'validation message has correct value');
|
|
412
|
+
|
|
413
|
+
await fillIn(inputElement, '10/11/2021');
|
|
414
|
+
await formElement.updateComplete;
|
|
415
|
+
expect(formElement.value).to.equal('10/11/2021', '`value` property has value `10/11/2021`');
|
|
416
|
+
expect(changeEventSpy.callCount).to.equal(3, '`change` event fired');
|
|
417
|
+
expect(changeEventSpy.lastCall.args[0].detail.value).to.equal('10/11/2021', '`change` event has value `10/11/2021`');
|
|
418
|
+
|
|
419
|
+
validationMessage = shadowRoot.querySelector('.validation');
|
|
420
|
+
expect(validationMessage).to.not.be.null; // eslint-disable-line no-unused-expressions
|
|
421
|
+
expect(validationMessage.textContent.trim()).to.equal('Date must be on or after 11/11/2021.', 'validation message has correct value');
|
|
422
|
+
});
|
|
423
|
+
});
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export function checkRunSnapshots(run) {
|
|
2
|
+
return {
|
|
3
|
+
name: 'check-run-snapshots',
|
|
4
|
+
|
|
5
|
+
executeCommand({ command, session }) {
|
|
6
|
+
if (command === 'run-snapshots') {
|
|
7
|
+
if (typeof run === 'boolean') {
|
|
8
|
+
return { run, browser: session.browser.type};
|
|
9
|
+
} else if (session.browser.type === 'selenium') {
|
|
10
|
+
return { run: false, browser: session.browser.type };
|
|
11
|
+
} else if (session.browser.type === 'playwright') {
|
|
12
|
+
return { run: true, browser: session.browser.type };
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
return { run: false, browser: session.browser.type };
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Card } from '@muonic/muon/components/card';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* A fancier version of the card.
|
|
5
|
+
*
|
|
6
|
+
* @element card
|
|
7
|
+
*
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
export class FancyCard extends Card {
|
|
11
|
+
|
|
12
|
+
static get properties() {
|
|
13
|
+
return {
|
|
14
|
+
fancy: { type: Boolean }
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
get coolBean() {
|
|
19
|
+
return 'cool beans';
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
something() {
|
|
23
|
+
return 'doing something';
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"components": {
|
|
3
|
+
"included": ["inputter" ,"card","image"],
|
|
4
|
+
"dir": "tests/scripts/utils/*-component.js"
|
|
5
|
+
},
|
|
6
|
+
"tokens": {
|
|
7
|
+
"dir": ["tokens/*.json"],
|
|
8
|
+
"theme": "default"
|
|
9
|
+
},
|
|
10
|
+
"alias": {
|
|
11
|
+
"@muon/utils/validation": "./utils/validation"
|
|
12
|
+
}
|
|
13
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
console.log('test runner function');
|