@epa-wg/custom-element-dist 0.0.22 → 0.0.24
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 +4 -4
- package/coverage/coverage-final.json +13 -15
- package/coverage/index.html +30 -30
- package/coverage/src/custom-element/coverage.svg +1 -1
- package/coverage/src/custom-element/custom-element.js/coverage.svg +1 -1
- package/coverage/src/custom-element/custom-element.js.html +336 -312
- package/coverage/src/custom-element/http-request.js.html +10 -10
- package/coverage/src/custom-element/index.html +19 -49
- package/coverage/src/custom-element/local-storage.js.html +5 -5
- package/coverage/src/custom-element/location-element.js.html +1 -1
- package/coverage/src/index.html +1 -1
- package/coverage/src/mocks/handlers.ts.html +1 -1
- package/coverage/src/mocks/index.html +1 -1
- package/coverage/src/stories/attributes.test.stories.ts/coverage.svg +1 -1
- package/coverage/src/stories/attributes.test.stories.ts.html +85 -91
- package/coverage/src/stories/coverage.svg +1 -1
- package/coverage/src/stories/css.test.stories.ts/coverage.svg +1 -1
- package/coverage/src/stories/css.test.stories.ts.html +75 -78
- package/coverage/src/stories/dom-merge.test.stories.ts/coverage.svg +1 -1
- package/coverage/src/stories/dom-merge.test.stories.ts.html +302 -74
- package/coverage/src/stories/external-template.test.stories.ts/coverage.svg +1 -1
- package/coverage/src/stories/external-template.test.stories.ts.html +154 -154
- package/coverage/src/stories/form.test.stories.ts/coverage.svg +1 -1
- package/coverage/src/stories/form.test.stories.ts.html +83 -86
- package/coverage/src/stories/http-request.stories.ts.html +1 -1
- package/coverage/src/stories/index.html +104 -104
- package/coverage/src/stories/local-storage.test.stories.ts/coverage.svg +1 -1
- package/coverage/src/stories/local-storage.test.stories.ts.html +444 -444
- package/coverage/src/stories/location-element.test.stories.ts/coverage.svg +1 -1
- package/coverage/src/stories/location-element.test.stories.ts.html +96 -96
- package/coverage/src/stories/slice-events.test.stories.ts/coverage.svg +1 -1
- package/coverage/src/stories/slice-events.test.stories.ts.html +141 -141
- package/coverage/src/stories/slots.test.stories.ts/coverage.svg +1 -1
- package/coverage/src/stories/slots.test.stories.ts.html +120 -123
- package/coverage/src/stories/{renderPlay.ts.html → testStoryBook.ts.html} +45 -24
- package/coverage/src/sum.ts.html +1 -1
- package/dist/{custom-element-N-sWiqGK.cjs → custom-element-BDK7dcJN.cjs} +8 -8
- package/dist/{custom-element-BISbI4SU.js → custom-element-DqtzLkTG.js} +74 -66
- package/dist/custom-element-bundle.cjs +1 -1
- package/dist/custom-element-bundle.js +23 -22
- package/package.json +3 -3
- package/src/custom-element/custom-element.js +9 -1
- package/src/custom-element/demo/form.html +92 -46
- package/src/custom-element/demo/s.xml +9 -17
- package/src/custom-element/ide/web-types-dce.json +1 -1
- package/src/custom-element/ide/web-types-xsl.json +1 -1
- package/src/stories/attributes.test.stories.ts +9 -11
- package/src/stories/css.test.stories.ts +6 -7
- package/src/stories/dom-merge.test.stories.ts +81 -5
- package/src/stories/external-template.test.stories.ts +6 -6
- package/src/stories/form.test.stories.ts +6 -7
- package/src/stories/local-storage.test.stories.ts +7 -7
- package/src/stories/location-element.test.stories.ts +6 -6
- package/src/stories/slice-events.test.stories.ts +6 -6
- package/src/stories/slots.test.stories.ts +6 -7
- package/src/stories/testStoryBook.ts +28 -0
- package/storybook-static/assets/{Color-PRSJMWNM-e4s261EJ.js → Color-PRSJMWNM-y4ZsI1hY.js} +1 -1
- package/storybook-static/assets/{Configure-DWut7txe.js → Configure-CyLVkwlf.js} +1 -1
- package/storybook-static/assets/{DocsRenderer-K4EAMTCU-CaXVGjCl.js → DocsRenderer-K4EAMTCU-VRGUwRrq.js} +2 -2
- package/storybook-static/assets/{WithTooltip-KJL26V4Q--B8vdnMi.js → WithTooltip-KJL26V4Q-xdXH9Ztt.js} +1 -1
- package/storybook-static/assets/{attributes.test.stories-IuwazrdL.js → attributes.test.stories-BckCcyrF.js} +3 -2
- package/storybook-static/assets/{css.test.stories-D9WaxrEv.js → css.test.stories-B-QcObCF.js} +1 -1
- package/storybook-static/assets/{custom-element-BV8-hRQS.js → custom-element-BIxkVg7K.js} +5 -5
- package/storybook-static/assets/dom-merge.test.stories-CjXhjTQY.js +258 -0
- package/storybook-static/assets/{external-template.test.stories-Bpr_wxBo.js → external-template.test.stories-BBqyi0az.js} +1 -1
- package/storybook-static/assets/{form.test.stories-3tURbEdv.js → form.test.stories-DsIo1B4n.js} +1 -1
- package/storybook-static/assets/{formatter-2WMMO6ZP-SJtgH3vM.js → formatter-2WMMO6ZP-CThVcQxM.js} +1 -1
- package/storybook-static/assets/{http-request.stories-8K_qSs8C.js → http-request.stories-sXA_Y-VM.js} +1 -1
- package/storybook-static/assets/{iframe-CM82WlGY.js → iframe-DcDTQOmA.js} +2 -2
- package/storybook-static/assets/{index-DNL-IEpS.js → index-CUFHd5VD.js} +1 -1
- package/storybook-static/assets/{index-CEZitmnt.js → index-DPPi9iZu.js} +5 -5
- package/storybook-static/assets/{index-D1MP-Zis.js → index-VWixWKZ7.js} +1 -1
- package/storybook-static/assets/{local-storage.test.stories-CtisAQBB.js → local-storage.test.stories-Cs2v3QTS.js} +1 -1
- package/storybook-static/assets/{location-element.test.stories-5O_t_m4Y.js → location-element.test.stories-WkrQDzJJ.js} +1 -1
- package/storybook-static/assets/{preview-5Y0XiZgz.js → preview-p-Bwze-K.js} +2 -2
- package/storybook-static/assets/{slice-events.test.stories-BSXCLIA5.js → slice-events.test.stories-BRBBc0JT.js} +1 -1
- package/storybook-static/assets/{slots.test.stories-B1vqfHmN.js → slots.test.stories-r-i91k3y.js} +1 -1
- package/storybook-static/assets/{syntaxhighlighter-BP7B2CQK-BWFH_0wQ.js → syntaxhighlighter-BP7B2CQK-OnioRcs9.js} +1 -1
- package/storybook-static/iframe.html +1 -1
- package/storybook-static/index.json +1 -1
- package/storybook-static/project.json +1 -1
- package/tsconfig.json +31 -21
- package/coverage/src/custom-element/custom-element1-1.js/coverage.svg +0 -10
- package/coverage/src/custom-element/custom-element1-1.js.html +0 -2374
- package/coverage/src/custom-element/custom-element1.js/coverage.svg +0 -10
- package/coverage/src/custom-element/custom-element1.js.html +0 -2374
- package/src/custom-element/custom-element1-1.js +0 -763
- package/src/custom-element/custom-element1.js +0 -763
- package/src/custom-element/custom-element1.js0 +0 -750
- package/src/custom-element/custom-element2.js0 +0 -759
- package/src/custom-element/custom-element3.js0 +0 -763
- package/src/stories/renderPlay.ts +0 -21
- package/storybook-static/assets/dom-merge.test.stories-BhbNeum_.js +0 -137
- /package/coverage/src/stories/{renderPlay.ts → testStoryBook.ts}/coverage.svg +0 -0
|
@@ -9,9 +9,18 @@
|
|
|
9
9
|
<script type="module" src="../custom-element.js"></script>
|
|
10
10
|
<style>
|
|
11
11
|
@import "./demo.css";
|
|
12
|
-
|
|
13
|
-
label
|
|
14
|
-
|
|
12
|
+
|
|
13
|
+
label {
|
|
14
|
+
display: flex;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
label:has(input[type="text"],input[type="password"],input:not([type]) ) {
|
|
18
|
+
flex-direction: column;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
nav {
|
|
22
|
+
max-width: 32em;
|
|
23
|
+
}
|
|
15
24
|
</style>
|
|
16
25
|
<!-- https://github.com/mdn/learning-area/blob/main/html/forms/form-validation/custom-error-message.html
|
|
17
26
|
todo: apply setCustomValidity( warningStr )
|
|
@@ -22,36 +31,74 @@
|
|
|
22
31
|
|
|
23
32
|
<nav>
|
|
24
33
|
<a href="../index.html"><h3><code>custom-element</code> demo</h3></a>
|
|
25
|
-
|
|
26
|
-
<
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
<
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
<
|
|
35
|
-
|
|
34
|
+
|
|
35
|
+
<p> <b>formData</b><br/>
|
|
36
|
+
The values of named form fields are populated into the <b>slice</b> as <b>form-data</b> on <var>change</var>
|
|
37
|
+
or <var>submit</var> event. The field values can be used in form validation via <var>custom-validity</var>
|
|
38
|
+
attribute
|
|
39
|
+
and in condition to enabling the form parts
|
|
40
|
+
<a href="https://developer.mozilla.org/en-US/docs/Web/API/FormData">formData MDN</a>
|
|
41
|
+
</p>
|
|
42
|
+
<details>
|
|
43
|
+
<summary>slice to form-data mapping</summary>
|
|
44
|
+
<html-demo-element>
|
|
45
|
+
<template>
|
|
46
|
+
<datadom hidden>
|
|
47
|
+
<slice>
|
|
48
|
+
<signin-form>
|
|
49
|
+
<form-data>
|
|
50
|
+
<username>QWE</username>
|
|
51
|
+
<password>ASD</password>
|
|
52
|
+
</form-data>
|
|
53
|
+
</signin-form>
|
|
54
|
+
</slice>
|
|
55
|
+
</datadom>
|
|
56
|
+
</template>
|
|
57
|
+
</html-demo-element>
|
|
58
|
+
</details>
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
<p> <b> custom-validity attribute </b><br/>
|
|
62
|
+
applied on the form itself or on the form field.<br/>
|
|
63
|
+
The value is an XPath over DCE <var>datadom</var>. When evaluated as <u>boolean</u>, it would enable(true) or
|
|
64
|
+
disable(false)
|
|
65
|
+
the form submission, acting as form validation mechanism.<br>
|
|
66
|
+
Alternatively, the value can be evaluated as a <u>string</u> which would be treated as an error and can be used
|
|
67
|
+
as
|
|
68
|
+
validation error message set as <var>@validation-message</var> attribute on the form slice.
|
|
69
|
+
Look for <var>email-form/@validation-message</var> example on the page.<br/>
|
|
70
|
+
</p>
|
|
71
|
+
<p> When <var>custom-validity</var> attribute is set on the field, its XPath evaluated value is propagated to
|
|
72
|
+
<a href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLObjectElement/validationMessage">
|
|
73
|
+
validationMessage property</a>. Which would be shown via browser system popup as the field validation error.
|
|
74
|
+
</p>
|
|
75
|
+
<p> <var>@validation-message</var> is set either by <var>custom-validity</var> attribute or by browser as system message.
|
|
76
|
+
By default, it is shown as popup on the field validation. But also is available for template as a string via
|
|
77
|
+
form field attribute. Like in <var>email-form/@validation-message</var>.
|
|
78
|
+
|
|
79
|
+
</p>
|
|
80
|
+
|
|
81
|
+
<a href="https://developer.mozilla.org/en-US/docs/Learn/Forms/Form_validation">Form Validation MDN</a>
|
|
36
82
|
</nav>
|
|
37
83
|
|
|
38
84
|
<html-demo-element legend="1. Simple validation"
|
|
39
85
|
description="custom-validity boolean value prevents submission, username length switches Next to 'Sign In' button ">
|
|
40
86
|
<ol>
|
|
41
|
-
<li> Click Next, observe the warning
|
|
42
|
-
<li> Fill input with 10+ characters
|
|
43
|
-
<li> Click Next, the password and "Sign In" button should appear
|
|
87
|
+
<li> Click Next, observe the warning</li>
|
|
88
|
+
<li> Fill input with 10+ characters</li>
|
|
89
|
+
<li> Click Next, the password and "Sign In" button should appear</li>
|
|
44
90
|
</ol>
|
|
45
91
|
<template>
|
|
46
92
|
<custom-element>
|
|
47
93
|
<template>
|
|
48
|
-
<form
|
|
49
|
-
|
|
94
|
+
<form slice="signin-form"
|
|
95
|
+
custom-validity="
|
|
50
96
|
string-length(/datadom/slice/signin-form/form-data/username) > 10
|
|
51
97
|
and string-length(//form-data/password) > 3 "
|
|
52
|
-
|
|
98
|
+
>
|
|
53
99
|
<label> Email
|
|
54
|
-
<input name="username" autocomplete="username" placeholder="Email, phone, or username"
|
|
100
|
+
<input name="username" autocomplete="username" placeholder="Email, phone, or username"
|
|
101
|
+
required="">
|
|
55
102
|
</label>
|
|
56
103
|
<variable name="showpassword" select="string-length(//form-data/username) > 10 "></variable>
|
|
57
104
|
<if test="not($showpassword)">
|
|
@@ -69,20 +116,20 @@
|
|
|
69
116
|
</html-demo-element>
|
|
70
117
|
|
|
71
118
|
<html-demo-element legend="2. Form life cycle demo"
|
|
72
|
-
description="form-data in the form slice is the source of truth"
|
|
119
|
+
description="form-data in the form slice is the source of truth">
|
|
73
120
|
|
|
74
121
|
<template>
|
|
75
122
|
<custom-element>
|
|
76
123
|
<template>
|
|
77
|
-
<form
|
|
78
|
-
|
|
124
|
+
<form slice="signin-form"
|
|
125
|
+
custom-validity="
|
|
79
126
|
string-length(/datadom/slice/signin-form/form-data/username) > 9
|
|
80
127
|
and ( ( //confirm-by = 'sms' )
|
|
81
128
|
or ( //confirm-by = 'email' )
|
|
82
129
|
or ( //confirm-by = 'password' and string-length(//form-data/password) > 3 )
|
|
83
130
|
)
|
|
84
131
|
"
|
|
85
|
-
|
|
132
|
+
>
|
|
86
133
|
<!-- form validity should be based on form-data -->
|
|
87
134
|
<variable name="warn">
|
|
88
135
|
<if test="string-length(//username-slice) < 9 ">
|
|
@@ -96,22 +143,22 @@
|
|
|
96
143
|
</variable>
|
|
97
144
|
<label> Enter your email, phone, or user name
|
|
98
145
|
<input name="username" autocomplete="username"
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
146
|
+
placeholder="Email, phone, or username"
|
|
147
|
+
custom-validity="( string-length(//username-slice) > 9 ) ?? 'should be 10+ symbols'"
|
|
148
|
+
slice-event="input"
|
|
149
|
+
slice="username-slice"
|
|
150
|
+
required
|
|
104
151
|
/>
|
|
105
152
|
</label>
|
|
106
153
|
<var> {$warn} </var>
|
|
107
154
|
<fieldset>
|
|
108
155
|
<legend>Confirm by</legend>
|
|
109
|
-
<label><input type="radio" name="confirm-by" value="email"
|
|
110
|
-
<label><input type="radio" name="confirm-by" value="sms"
|
|
111
|
-
<label><input type="radio" name="confirm-by" value="password"
|
|
156
|
+
<label><input type="radio" name="confirm-by" value="email"/> email </label>
|
|
157
|
+
<label><input type="radio" name="confirm-by" value="sms"/> text to phone </label>
|
|
158
|
+
<label><input type="radio" name="confirm-by" value="password"/> password </label>
|
|
112
159
|
<if test="/datadom/slice/signin-form/form-data/confirm-by = 'password'">
|
|
113
160
|
<label>Enter password: <input type="password" NAME="password"
|
|
114
|
-
|
|
161
|
+
custom-validity="( string-length(//form-data/password) > 3 ) ?? 'password is too short'"
|
|
115
162
|
/></label>
|
|
116
163
|
</if>
|
|
117
164
|
<if test="not(//confirm-by)">
|
|
@@ -136,8 +183,8 @@
|
|
|
136
183
|
<ol>
|
|
137
184
|
<li> type in input field</li>
|
|
138
185
|
<li> delete input field content</li>
|
|
139
|
-
<li> observe the warning in string
|
|
140
|
-
<li> Click Next observe the system warning in
|
|
186
|
+
<li> observe the warning in string after input</li>
|
|
187
|
+
<li> Click Next observe the system warning in dropdown over input</li>
|
|
141
188
|
</ol>
|
|
142
189
|
<template>
|
|
143
190
|
<custom-element>
|
|
@@ -150,7 +197,6 @@
|
|
|
150
197
|
<var>{//username/@validation-message}</var>
|
|
151
198
|
</if>
|
|
152
199
|
<button>Next</button>
|
|
153
|
-
<p>{//email-form/@validation-message}</p>
|
|
154
200
|
</form>
|
|
155
201
|
</template>
|
|
156
202
|
</custom-element>
|
|
@@ -160,27 +206,27 @@
|
|
|
160
206
|
<html-demo-element legend="4. form validity message"
|
|
161
207
|
description="@validation-message propagated into form slice and ">
|
|
162
208
|
<ol>
|
|
163
|
-
<li> type up to 3 chars in input field
|
|
164
|
-
<li> observe the slice value change
|
|
165
|
-
<li> click next
|
|
166
|
-
<li> observe the warning bellow the button
|
|
209
|
+
<li> type up to 3 chars in input field</li>
|
|
210
|
+
<li> observe the slice value change</li>
|
|
211
|
+
<li> click next</li>
|
|
212
|
+
<li> observe the warning bellow the button</li>
|
|
167
213
|
</ol>
|
|
168
214
|
<template>
|
|
169
215
|
<custom-element>
|
|
170
216
|
<template>
|
|
171
217
|
<form slice="email-form"
|
|
172
|
-
|
|
218
|
+
custom-validity=" string-length(//slice/username) > 3 ??
|
|
173
219
|
concat('should be more than 3 characters, now is ',string-length(//slice/username) ) "
|
|
174
|
-
|
|
220
|
+
>
|
|
175
221
|
<label> Email
|
|
176
|
-
<input name="email" slice="username" slice-event="input" placeholder="non-empty" required
|
|
222
|
+
<input name="email" slice="username" slice-event="input" placeholder="non-empty" required/>
|
|
177
223
|
</label>
|
|
178
224
|
<if test="//username/@validation-message">
|
|
179
225
|
<var>{//username/@validation-message}</var>
|
|
180
226
|
</if>
|
|
181
227
|
<button>Next</button>
|
|
182
|
-
<p>//email-form/@validation-message:
|
|
183
|
-
<p>//slice/username:
|
|
228
|
+
<p>//email-form/@validation-message: {//email-form/@validation-message} </p>
|
|
229
|
+
<p>//slice/username: {//slice/username} </p>
|
|
184
230
|
</form>
|
|
185
231
|
</template>
|
|
186
232
|
</custom-element>
|
|
@@ -1,19 +1,11 @@
|
|
|
1
1
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
-
<datadom
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
</
|
|
11
|
-
<attributes>
|
|
12
|
-
<id>dce32</id>
|
|
13
|
-
<data-dce-style>54f96d52-ce70-435d-83c4-b421357d9a17</data-dce-style>
|
|
14
|
-
</attributes>
|
|
15
|
-
<dataset>
|
|
16
|
-
<dceStyle>54f96d52-ce70-435d-83c4-b421357d9a17</dceStyle>
|
|
17
|
-
</dataset>
|
|
18
|
-
<slice/>
|
|
2
|
+
<datadom>
|
|
3
|
+
<slice>
|
|
4
|
+
<signin-form>
|
|
5
|
+
<form-data>
|
|
6
|
+
<username>QWE</username>
|
|
7
|
+
<password>ASD</password>
|
|
8
|
+
</form-data>
|
|
9
|
+
</signin-form>
|
|
10
|
+
</slice>
|
|
19
11
|
</datadom>
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
// noinspection DuplicatedCode
|
|
2
2
|
|
|
3
3
|
import type { StoryObj } from '@storybook/web-components';
|
|
4
|
-
import {expect,
|
|
4
|
+
import {expect, within} from '@storybook/test';
|
|
5
5
|
|
|
6
6
|
import '../custom-element/custom-element.js';
|
|
7
|
-
import {OverrideInPayload, StyleDoesNotLeak, StyleIn2Instances} from './css.test.stories';
|
|
8
7
|
|
|
9
8
|
type TProps = { title: string; body:string};
|
|
10
9
|
|
|
11
10
|
type Story = StoryObj<TProps>;
|
|
11
|
+
|
|
12
12
|
function sleep(ms: number) { return new Promise((resolve) => setTimeout(resolve, ms)); }
|
|
13
13
|
|
|
14
14
|
function render(args: TProps)
|
|
@@ -123,7 +123,7 @@ export const InstanceAttributes:Story =
|
|
|
123
123
|
const titleText = AttributeDefaults.args!.title as string;
|
|
124
124
|
const canvas = within(canvasElement)
|
|
125
125
|
, code = async (id) => (await canvas.findByTestId(id)).textContent.trim();
|
|
126
|
-
|
|
126
|
+
debugger;
|
|
127
127
|
await sleep(20)
|
|
128
128
|
expect( await code('p1') ).toEqual('123' );
|
|
129
129
|
expect( await code('p2') ).toEqual('always_p2' );
|
|
@@ -131,14 +131,12 @@ export const InstanceAttributes:Story =
|
|
|
131
131
|
},
|
|
132
132
|
};
|
|
133
133
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
const TestStories = { AttributeDefaults, AttributesRuntimeChange, InstanceAttributes };
|
|
137
|
-
|
|
138
134
|
/* istanbul ignore else -- @preserve */
|
|
139
|
-
if(
|
|
135
|
+
if( 'test' === import.meta.env.MODE &&
|
|
136
|
+
!import.meta.url.includes('skiptest') )
|
|
140
137
|
{
|
|
141
|
-
const
|
|
142
|
-
const {
|
|
143
|
-
|
|
138
|
+
const mod = await import('./attributes.test.stories.ts?skiptest');
|
|
139
|
+
const { testStoryBook } = await import('./testStoryBook')
|
|
140
|
+
const { describe } = await import('vitest')
|
|
141
|
+
describe(meta.title, () => testStoryBook( mod, meta ) );
|
|
144
142
|
}
|
|
@@ -112,13 +112,12 @@ export const OverrideInPayload: Story =
|
|
|
112
112
|
},
|
|
113
113
|
};
|
|
114
114
|
|
|
115
|
-
|
|
116
|
-
const TestStories = { StyleDoesNotLeak, StyleIn2Instances, OverrideInPayload };
|
|
117
|
-
|
|
118
115
|
/* istanbul ignore else -- @preserve */
|
|
119
|
-
if(
|
|
116
|
+
if( 'test' === import.meta.env.MODE &&
|
|
117
|
+
!import.meta.url.includes('skiptest') )
|
|
120
118
|
{
|
|
121
|
-
const
|
|
122
|
-
const {
|
|
123
|
-
|
|
119
|
+
const mod = await import('./css.test.stories.ts?skiptest');
|
|
120
|
+
const { testStoryBook } = await import('./testStoryBook')
|
|
121
|
+
const { describe } = await import('vitest')
|
|
122
|
+
describe(meta.title, () => testStoryBook( mod, meta ) );
|
|
124
123
|
}
|
|
@@ -118,12 +118,88 @@ export const WordCountOnType:Story =
|
|
|
118
118
|
},
|
|
119
119
|
};
|
|
120
120
|
|
|
121
|
-
const
|
|
121
|
+
export const OrderPreservingOn2ndTransform:Story =
|
|
122
|
+
{ args : {title: 'Order preserving on 2nd transform', body:`
|
|
123
|
+
<p>IF condition content should be displayed in place where it is defined (not shifted down on the parent children)</p>
|
|
124
|
+
<custom-element>
|
|
125
|
+
<form slice="f1">
|
|
126
|
+
<label>
|
|
127
|
+
<input type="checkbox" name="c1" data-testid="cb1"/>
|
|
128
|
+
click to display #1 bellow
|
|
129
|
+
</label>
|
|
130
|
+
<br data-testid="beforeC1"/>
|
|
131
|
+
<if test="//c1">
|
|
132
|
+
<p data-testid="isC1">#1</p>
|
|
133
|
+
</if>
|
|
134
|
+
<label>
|
|
135
|
+
<input type="checkbox" name="c2" data-testid="cb2"/>
|
|
136
|
+
click to display #2 bellow
|
|
137
|
+
</label>
|
|
138
|
+
<br data-testid="beforeC2"/>
|
|
139
|
+
<if test="//c2">
|
|
140
|
+
<p>#2</p>
|
|
141
|
+
</if>
|
|
142
|
+
</form>
|
|
143
|
+
</custom-element>
|
|
144
|
+
`}
|
|
145
|
+
, play: async ({canvasElement}) =>
|
|
146
|
+
{
|
|
147
|
+
const titleText = OrderPreservingOn2ndTransform.args!.title as string;
|
|
148
|
+
const canvas = within(canvasElement);
|
|
149
|
+
await canvas.findByText(titleText);
|
|
150
|
+
|
|
151
|
+
await userEvent.click(canvas.getByTestId('cb1'));
|
|
152
|
+
await expect(await canvas.findByText('#1')).toBeInTheDocument();
|
|
153
|
+
await userEvent.click(canvas.getByTestId('cb2'));
|
|
154
|
+
await expect(await canvas.findByText('#2')).toBeInTheDocument();
|
|
155
|
+
await expect(canvas.getByTestId("beforeC1").nextElementSibling).toEqual(canvas.getByTestId("isC1"))
|
|
156
|
+
},
|
|
157
|
+
};
|
|
158
|
+
export const ReadSystemValidityMessage:Story =
|
|
159
|
+
{ args : {title: 'read system validity message', body:`
|
|
160
|
+
<p>validationMessage propagated into slice as 'validation-message' attribute</p>
|
|
161
|
+
<ol>
|
|
162
|
+
<li> type in input field</li>
|
|
163
|
+
<li> delete input field content</li>
|
|
164
|
+
<li> observe the warning in string after input</li>
|
|
165
|
+
<li> Click Next observe the system warning in dropdown over input</li>
|
|
166
|
+
</ol>
|
|
167
|
+
<custom-element>
|
|
168
|
+
<template>
|
|
169
|
+
<form slice="email-form">
|
|
170
|
+
<label> Email
|
|
171
|
+
<input slice="username" slice-event="input" placeholder="non-empty" required data-testid="inp1">
|
|
172
|
+
</label>
|
|
173
|
+
<if test="//username/@validation-message">
|
|
174
|
+
<var data-testid="var1">{//username/@validation-message}</var>
|
|
175
|
+
</if>
|
|
176
|
+
<button data-testid="btn1">Next</button>
|
|
177
|
+
</form>
|
|
178
|
+
</template>
|
|
179
|
+
</custom-element>
|
|
180
|
+
`}
|
|
181
|
+
, play: async ({canvasElement}) =>
|
|
182
|
+
{
|
|
183
|
+
const titleText = ReadSystemValidityMessage.args!.title as string;
|
|
184
|
+
const canvas = within(canvasElement);
|
|
185
|
+
await canvas.findByText(titleText);
|
|
186
|
+
await userEvent.type(canvas.getByTestId('inp1'),'Hi');
|
|
187
|
+
await userEvent.clear(canvas.getByTestId('inp1'));
|
|
188
|
+
await userEvent.click(canvas.getByTestId('btn1'));
|
|
189
|
+
await expect(await canvas.findByTestId('var1')).toBeInTheDocument();
|
|
190
|
+
await expect(canvas.getByTestId("var1").textContent).toEqual(canvas.getByTestId("inp1").validationMessage);
|
|
191
|
+
await expect(canvas.getByTestId("var1").textContent.length>1).toEqual(true);
|
|
192
|
+
},
|
|
193
|
+
};
|
|
122
194
|
|
|
195
|
+
//<editor-fold desc="unit test run" collapsed>
|
|
123
196
|
/* istanbul ignore else -- @preserve */
|
|
124
|
-
if(
|
|
197
|
+
if( 'test' === import.meta.env.MODE &&
|
|
198
|
+
!import.meta.url.includes('skiptest') )
|
|
125
199
|
{
|
|
126
|
-
const
|
|
127
|
-
const {
|
|
128
|
-
|
|
200
|
+
const mod = await import('./dom-merge.test.stories.ts?skiptest');
|
|
201
|
+
const { testStoryBook } = await import('./testStoryBook')
|
|
202
|
+
const { describe } = await import('vitest')
|
|
203
|
+
describe(meta.title, () => testStoryBook( mod, meta ) );
|
|
129
204
|
}
|
|
205
|
+
//</editor-fold>
|
|
@@ -244,12 +244,12 @@ export const EmbeddingInAnotherFile:Story =
|
|
|
244
244
|
},
|
|
245
245
|
};
|
|
246
246
|
|
|
247
|
-
const TestStories = { TemplateInPage, NoTag, ExternalSvg, ExternalXsltFile, ExternalHtmlFile, ExternalHtmlFileInline, HtmlWithinHtmlFile, SvgWithinHtmlFile, MathMLWithinHtmlFile, ByIdWithinXsltFile, MissingIdWithinXsltFile, EmbeddingInAnotherFile };
|
|
248
|
-
|
|
249
247
|
/* istanbul ignore else -- @preserve */
|
|
250
|
-
if(
|
|
248
|
+
if( 'test' === import.meta.env.MODE &&
|
|
249
|
+
!import.meta.url.includes('skiptest') )
|
|
251
250
|
{
|
|
252
|
-
const
|
|
253
|
-
const {
|
|
254
|
-
|
|
251
|
+
const mod = await import('./external-template.test.stories.ts?skiptest');
|
|
252
|
+
const { testStoryBook } = await import('./testStoryBook')
|
|
253
|
+
const { describe } = await import('vitest')
|
|
254
|
+
describe(meta.title, () => testStoryBook( mod, meta ) );
|
|
255
255
|
}
|
|
@@ -179,13 +179,12 @@ export const FormCustomValidityString:Story =
|
|
|
179
179
|
};
|
|
180
180
|
// custom validity rules on form : boolean and string values
|
|
181
181
|
|
|
182
|
-
|
|
183
|
-
const TestStories = { SystemMessage, FormData, SetValidityMessage, FormCustomValidityBoolean, FormCustomValidityString};
|
|
184
|
-
|
|
185
182
|
/* istanbul ignore else -- @preserve */
|
|
186
|
-
if(
|
|
183
|
+
if( 'test' === import.meta.env.MODE &&
|
|
184
|
+
!import.meta.url.includes('skiptest') )
|
|
187
185
|
{
|
|
188
|
-
const
|
|
189
|
-
const {
|
|
190
|
-
|
|
186
|
+
const mod = await import('./form.test.stories.ts?skiptest');
|
|
187
|
+
const { testStoryBook } = await import('./testStoryBook')
|
|
188
|
+
const { describe } = await import('vitest')
|
|
189
|
+
describe(meta.title, () => testStoryBook( mod, meta ) );
|
|
191
190
|
}
|
|
@@ -389,12 +389,12 @@ export const TypeAttribute:Story =
|
|
|
389
389
|
},
|
|
390
390
|
};
|
|
391
391
|
|
|
392
|
-
const TestStories = { Demo, AlwaysOverride, FromStorageWithDefault, TypeAttribute };
|
|
393
|
-
|
|
394
392
|
/* istanbul ignore else -- @preserve */
|
|
395
|
-
if(
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
const
|
|
399
|
-
|
|
393
|
+
if( 'test' === import.meta.env.MODE &&
|
|
394
|
+
!import.meta.url.includes('skiptest') )
|
|
395
|
+
{
|
|
396
|
+
const mod = await import('./local-storage.test.stories.ts?skiptest');
|
|
397
|
+
const { testStoryBook } = await import('./testStoryBook')
|
|
398
|
+
const { describe } = await import('vitest')
|
|
399
|
+
describe(meta.title, () => testStoryBook( mod, meta ) );
|
|
400
400
|
}
|
|
@@ -134,12 +134,12 @@ export const SrcAttribute:Story =
|
|
|
134
134
|
};
|
|
135
135
|
|
|
136
136
|
|
|
137
|
-
const TestStories = { Demo, SrcAttribute };
|
|
138
|
-
|
|
139
137
|
/* istanbul ignore else -- @preserve */
|
|
140
|
-
if(
|
|
138
|
+
if( 'test' === import.meta.env.MODE &&
|
|
139
|
+
!import.meta.url.includes('skiptest') )
|
|
141
140
|
{
|
|
142
|
-
const
|
|
143
|
-
const {
|
|
144
|
-
|
|
141
|
+
const mod = await import('./location-element.test.stories.ts?skiptest');
|
|
142
|
+
const { testStoryBook } = await import('./testStoryBook')
|
|
143
|
+
const { describe } = await import('vitest')
|
|
144
|
+
describe(meta.title, () => testStoryBook( mod, meta ) );
|
|
145
145
|
}
|
|
@@ -189,12 +189,12 @@ export const SlicesInAttrAndName:Story =
|
|
|
189
189
|
},
|
|
190
190
|
};
|
|
191
191
|
|
|
192
|
-
const TestStories = { SliceInitChangeEvent, RealtimeEventInSlice, DoubleEventInSlice, MultipleSlices, SlicesInAttrAndName };
|
|
193
|
-
|
|
194
192
|
/* istanbul ignore else -- @preserve */
|
|
195
|
-
if(
|
|
193
|
+
if( 'test' === import.meta.env.MODE &&
|
|
194
|
+
!import.meta.url.includes('skiptest') )
|
|
196
195
|
{
|
|
197
|
-
const
|
|
198
|
-
const {
|
|
199
|
-
|
|
196
|
+
const mod = await import('./slice-events.test.stories.ts?skiptest');
|
|
197
|
+
const { testStoryBook } = await import('./testStoryBook')
|
|
198
|
+
const { describe } = await import('vitest')
|
|
199
|
+
describe(meta.title, () => testStoryBook( mod, meta ) );
|
|
200
200
|
}
|
|
@@ -206,13 +206,12 @@ export const TemplateWithAttributesAndCondition:Story =
|
|
|
206
206
|
}
|
|
207
207
|
};
|
|
208
208
|
|
|
209
|
-
const TestStories = {Regular, NamedSlot, DoubleSlot, NamedUnnamedDefaultSlot, NamedDefaultSlot
|
|
210
|
-
, DefaultSlot, TemplateWithAttributesAndCondition};
|
|
211
|
-
|
|
212
209
|
/* istanbul ignore else -- @preserve */
|
|
213
|
-
if(
|
|
210
|
+
if( 'test' === import.meta.env.MODE &&
|
|
211
|
+
!import.meta.url.includes('skiptest') )
|
|
214
212
|
{
|
|
215
|
-
const
|
|
216
|
-
const {
|
|
217
|
-
|
|
213
|
+
const mod = await import('./slots.test.stories.ts?skiptest');
|
|
214
|
+
const { testStoryBook } = await import('./testStoryBook')
|
|
215
|
+
const { describe } = await import('vitest')
|
|
216
|
+
describe(meta.title, () => testStoryBook( mod, meta ) );
|
|
218
217
|
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type {StoryObj, Meta} from '@storybook/web-components';
|
|
2
|
+
import {it} from 'vitest';
|
|
3
|
+
|
|
4
|
+
async function playStory( story: StoryObj, meta: Meta )
|
|
5
|
+
{
|
|
6
|
+
document.body.innerHTML = meta.render(story.args);
|
|
7
|
+
await new Promise( (resolve) => setTimeout(async ()=>
|
|
8
|
+
{
|
|
9
|
+
await story.play({canvasElement: document.body.lastElementChild});
|
|
10
|
+
resolve(0);
|
|
11
|
+
},0))
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export async function testStoryBook<TProps>( mod: Record<string, StoryObj>, meta: Meta )
|
|
15
|
+
{
|
|
16
|
+
const {describe, it } = await import('vitest');
|
|
17
|
+
function playStories( mod: Record<string, StoryObj>, meta: Meta )
|
|
18
|
+
{
|
|
19
|
+
Object.keys(mod).map(name=>
|
|
20
|
+
{
|
|
21
|
+
const story = mod[name];
|
|
22
|
+
if( !story.play )
|
|
23
|
+
return;
|
|
24
|
+
it( name, async()=>playStory(story,meta));
|
|
25
|
+
})
|
|
26
|
+
}
|
|
27
|
+
describe( meta.title, async () => playStories(mod, meta) )
|
|
28
|
+
}
|