brut-js 0.0.1
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/.projections.json +10 -0
- package/CODE_OF_CONDUCT.txt +99 -0
- package/LICENSE.txt +370 -0
- package/README.md +118 -0
- package/package.json +30 -0
- package/specs/AjaxSubmit.spec.js +241 -0
- package/specs/Autosubmit.spec.js +127 -0
- package/specs/ConfirmSubmit.spec.js +193 -0
- package/specs/ConstraintViolationMessage.spec.js +33 -0
- package/specs/ConstraintViolationMessages.spec.js +27 -0
- package/specs/Form.spec.js +136 -0
- package/specs/I18nTranslation.spec.js +19 -0
- package/specs/LocaleDetection.spec.js +22 -0
- package/specs/Message.spec.js +15 -0
- package/specs/Tabs.spec.js +41 -0
- package/specs/config/asset_metadata.json +7 -0
- package/specs/public/js/bundle.js +1284 -0
- package/specs/public/js/bundle.js.map +7 -0
- package/src/AjaxSubmit.js +364 -0
- package/src/Autosubmit.js +61 -0
- package/src/BaseCustomElement.js +261 -0
- package/src/ConfirmSubmit.js +114 -0
- package/src/ConfirmationDialog.js +141 -0
- package/src/ConstraintViolationMessage.js +101 -0
- package/src/ConstraintViolationMessages.js +90 -0
- package/src/Form.js +117 -0
- package/src/I18nTranslation.js +59 -0
- package/src/LocaleDetection.js +93 -0
- package/src/Logger.js +90 -0
- package/src/Message.js +55 -0
- package/src/RichString.js +113 -0
- package/src/Tabs.js +167 -0
- package/src/appForTestingOnly.js +15 -0
- package/src/index.js +119 -0
- package/src/testing/index.js +348 -0
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
import { withHTML, readRequestBodyIntoString, waitForSetTimeout } from "../src/testing/index.js"
|
|
2
|
+
|
|
3
|
+
describe("<brut-ajax-submit>", () => {
|
|
4
|
+
withHTML(`
|
|
5
|
+
<form action="http://example.net/foo" method="POST">
|
|
6
|
+
<input required type="text" name="some-text">
|
|
7
|
+
<input required type="number" name="some-number">
|
|
8
|
+
<brut-ajax-submit submitted-lifetime="10">
|
|
9
|
+
<button>Submit</button>
|
|
10
|
+
</brut-ajax-submit>
|
|
11
|
+
</form>
|
|
12
|
+
`).onFetch( "/foo", [
|
|
13
|
+
{ then: { status: 200 }},
|
|
14
|
+
]
|
|
15
|
+
).test("submits the form, setting various attributes during the lifecycle", ({document,assert,fetchRequests}) => {
|
|
16
|
+
const element = document.querySelector("brut-ajax-submit")
|
|
17
|
+
const button = element.querySelector("button")
|
|
18
|
+
const text = document.querySelector("input[name=some-text]")
|
|
19
|
+
const number = document.querySelector("input[name=some-number]")
|
|
20
|
+
|
|
21
|
+
let okReceived = false
|
|
22
|
+
element.addEventListener("brut:submitok", () => {
|
|
23
|
+
okReceived = true
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
text.value = "Some Text"
|
|
27
|
+
number.value = "11"
|
|
28
|
+
|
|
29
|
+
button.click()
|
|
30
|
+
assert(element.getAttribute("requesting") != null)
|
|
31
|
+
|
|
32
|
+
const promises = fetchRequests.
|
|
33
|
+
filter( (fetchRequest) => fetchRequest.promiseReturned ).
|
|
34
|
+
map( (fetchRequest) => fetchRequest.promiseReturned )
|
|
35
|
+
|
|
36
|
+
return Promise.all(promises).then( () => {
|
|
37
|
+
assert(okReceived)
|
|
38
|
+
assert(element.getAttribute("requesting") == null)
|
|
39
|
+
assert(element.getAttribute("submitted") != null)
|
|
40
|
+
waitForSetTimeout(11).then( () => {
|
|
41
|
+
assert(element.getAttribute("submitted") == null)
|
|
42
|
+
return readRequestBodyIntoString(fetchRequests[0]).then( (string) => {
|
|
43
|
+
const params = new URLSearchParams(string)
|
|
44
|
+
assert.equal(params.get("some-text"),"Some Text")
|
|
45
|
+
assert.equal(params.get("some-number"),"11")
|
|
46
|
+
})
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
})
|
|
50
|
+
}).test("does not submit the form if it's invalid", ({document,assert,fetchRequests}) => {
|
|
51
|
+
|
|
52
|
+
const form = document.querySelector("form")
|
|
53
|
+
const element = form.querySelector("brut-ajax-submit")
|
|
54
|
+
const button = element.querySelector("button")
|
|
55
|
+
const text = form.querySelector("input[name=some-text]")
|
|
56
|
+
const number = form.querySelector("input[name=some-number]")
|
|
57
|
+
|
|
58
|
+
let okReceived = false
|
|
59
|
+
element.addEventListener("brut:submitok", () => {
|
|
60
|
+
okReceived = true
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
const isValid = form.reportValidity()
|
|
64
|
+
assert(!isValid)
|
|
65
|
+
|
|
66
|
+
button.click()
|
|
67
|
+
|
|
68
|
+
assert.equal(fetchRequests.length,0)
|
|
69
|
+
assert(!okReceived)
|
|
70
|
+
})
|
|
71
|
+
withHTML(`
|
|
72
|
+
<form action="http://example.net/foo" method="POST">
|
|
73
|
+
<input required type="text" name="some-text">
|
|
74
|
+
<input required type="number" name="some-number">
|
|
75
|
+
<brut-ajax-submit submitted-lifetime="10">
|
|
76
|
+
<button>Submit</button>
|
|
77
|
+
</brut-ajax-submit>
|
|
78
|
+
</form>
|
|
79
|
+
`).onFetch( "/foo", [
|
|
80
|
+
{ then: { status: 500 }},
|
|
81
|
+
{ then: { status: 200 }},
|
|
82
|
+
]
|
|
83
|
+
).test("submits the form after a retry", ({document,assert,fetchRequests}) => {
|
|
84
|
+
const element = document.querySelector("brut-ajax-submit")
|
|
85
|
+
const button = element.querySelector("button")
|
|
86
|
+
const text = document.querySelector("input[name=some-text]")
|
|
87
|
+
const number = document.querySelector("input[name=some-number]")
|
|
88
|
+
|
|
89
|
+
let okReceived = 0
|
|
90
|
+
element.addEventListener("brut:submitok", () => {
|
|
91
|
+
okReceived++
|
|
92
|
+
})
|
|
93
|
+
|
|
94
|
+
text.value = "Some Text"
|
|
95
|
+
number.value = "11"
|
|
96
|
+
|
|
97
|
+
button.click()
|
|
98
|
+
return waitForSetTimeout(5).then( () => {
|
|
99
|
+
|
|
100
|
+
const promises = fetchRequests.
|
|
101
|
+
filter( (fetchRequest) => fetchRequest.promiseReturned ).
|
|
102
|
+
map( (fetchRequest) => fetchRequest.promiseReturned )
|
|
103
|
+
|
|
104
|
+
return Promise.all(promises).then( () => {
|
|
105
|
+
assert.equal(okReceived,1)
|
|
106
|
+
return readRequestBodyIntoString(fetchRequests[1]).then( (string) => {
|
|
107
|
+
const params = new URLSearchParams(string)
|
|
108
|
+
assert.equal(params.get("some-text"),"Some Text")
|
|
109
|
+
assert.equal(params.get("some-number"),"11")
|
|
110
|
+
})
|
|
111
|
+
})
|
|
112
|
+
})
|
|
113
|
+
})
|
|
114
|
+
withHTML(`
|
|
115
|
+
<form action="http://example.net/foo" method="POST">
|
|
116
|
+
<input required type="text" name="some-text">
|
|
117
|
+
<input required type="number" name="some-number">
|
|
118
|
+
<brut-ajax-submit submitted-lifetime="10" max-retry-attempts=2>
|
|
119
|
+
<button>Submit</button>
|
|
120
|
+
</brut-ajax-submit>
|
|
121
|
+
</form>
|
|
122
|
+
`).onFetch( "/foo", [
|
|
123
|
+
{ then: { status: 500 }},
|
|
124
|
+
{ then: { status: 500 }},
|
|
125
|
+
{ then: { status: 500 }},
|
|
126
|
+
]
|
|
127
|
+
).test("when too many failures, submits the form the old-fashioned way", ({document,assert,fetchRequests}) => {
|
|
128
|
+
const form = document.querySelector("form")
|
|
129
|
+
const element = form.querySelector("brut-ajax-submit")
|
|
130
|
+
const button = element.querySelector("button")
|
|
131
|
+
const text = form.querySelector("input[name=some-text]")
|
|
132
|
+
const number = form.querySelector("input[name=some-number]")
|
|
133
|
+
|
|
134
|
+
let okReceived = 0
|
|
135
|
+
element.addEventListener("brut:submitok", () => {
|
|
136
|
+
okReceived++
|
|
137
|
+
})
|
|
138
|
+
|
|
139
|
+
text.value = "Some Text"
|
|
140
|
+
number.value = "11"
|
|
141
|
+
|
|
142
|
+
let submitted = false
|
|
143
|
+
form.addEventListener("submit", (event) => {
|
|
144
|
+
event.preventDefault()
|
|
145
|
+
submitted = true
|
|
146
|
+
})
|
|
147
|
+
|
|
148
|
+
button.click()
|
|
149
|
+
return waitForSetTimeout(50).then( () => {
|
|
150
|
+
|
|
151
|
+
const promises = fetchRequests.
|
|
152
|
+
filter( (fetchRequest) => fetchRequest.promiseReturned ).
|
|
153
|
+
map( (fetchRequest) => fetchRequest.promiseReturned )
|
|
154
|
+
|
|
155
|
+
return Promise.all(promises).then( () => {
|
|
156
|
+
assert.equal(okReceived,0)
|
|
157
|
+
assert(submitted)
|
|
158
|
+
})
|
|
159
|
+
})
|
|
160
|
+
})
|
|
161
|
+
withHTML(`
|
|
162
|
+
<form action="http://example.net/foo" method="POST">
|
|
163
|
+
|
|
164
|
+
<input required type="text" name="some-text">
|
|
165
|
+
<brut-constraint-violation-messages server-side input-name="some-text">
|
|
166
|
+
</brut-constraint-violation-messages>
|
|
167
|
+
|
|
168
|
+
<input required type="number" name="some-number">
|
|
169
|
+
<brut-constraint-violation-messages server-side input-name="some-number">
|
|
170
|
+
</brut-constraint-violation-messages>
|
|
171
|
+
|
|
172
|
+
<brut-ajax-submit submitted-lifetime="10">
|
|
173
|
+
<button>Submit</button>
|
|
174
|
+
</brut-ajax-submit>
|
|
175
|
+
</form>
|
|
176
|
+
`).onFetch( "/foo", [
|
|
177
|
+
{
|
|
178
|
+
then: {
|
|
179
|
+
status: 422,
|
|
180
|
+
text: `
|
|
181
|
+
<brut-constraint-violation-message input-name="some-text">
|
|
182
|
+
A sever-side error
|
|
183
|
+
</brut-constraint-violation-message>
|
|
184
|
+
<brut-constraint-violation-message input-name="some-text">
|
|
185
|
+
Another sever-side error
|
|
186
|
+
</brut-constraint-violation-message>
|
|
187
|
+
<brut-constraint-violation-message input-name="some-other-text">
|
|
188
|
+
Irrelevant server-side error
|
|
189
|
+
</brut-constraint-violation-message>
|
|
190
|
+
<brut-constraint-violation-message>
|
|
191
|
+
Error that should be ignored
|
|
192
|
+
</brut-constraint-violation-message>
|
|
193
|
+
<div>element that should be ignored</div>
|
|
194
|
+
`
|
|
195
|
+
}
|
|
196
|
+
},
|
|
197
|
+
]
|
|
198
|
+
).test("when we get a 422, parses the result from the server", ({document,window,assert,fetchRequests}) => {
|
|
199
|
+
const form = document.querySelector("form")
|
|
200
|
+
const element = form.querySelector("brut-ajax-submit")
|
|
201
|
+
const button = element.querySelector("button")
|
|
202
|
+
const text = form.querySelector("input[name=some-text]")
|
|
203
|
+
const number = form.querySelector("input[name=some-number]")
|
|
204
|
+
|
|
205
|
+
let okReceived = 0
|
|
206
|
+
element.addEventListener("brut:submitok", () => {
|
|
207
|
+
okReceived++
|
|
208
|
+
})
|
|
209
|
+
|
|
210
|
+
text.value = "Some Text"
|
|
211
|
+
number.value = "11"
|
|
212
|
+
|
|
213
|
+
button.click()
|
|
214
|
+
return waitForSetTimeout(5).then( () => {
|
|
215
|
+
|
|
216
|
+
const promises = fetchRequests.
|
|
217
|
+
filter( (fetchRequest) => fetchRequest.promiseReturned ).
|
|
218
|
+
map( (fetchRequest) => fetchRequest.promiseReturned )
|
|
219
|
+
|
|
220
|
+
return Promise.all(promises).then( () => {
|
|
221
|
+
assert.equal(okReceived,0)
|
|
222
|
+
const textFieldErrors = form.querySelectorAll("brut-constraint-violation-messages[input-name='some-text'] brut-constraint-violation-message")
|
|
223
|
+
assert.equal(2,textFieldErrors.length)
|
|
224
|
+
|
|
225
|
+
let error = Array.from(textFieldErrors).find( (e) => e.textContent.trim() == "A sever-side error" )
|
|
226
|
+
assert(error)
|
|
227
|
+
error = Array.from(textFieldErrors).find( (e) => e.textContent.trim() == "Another sever-side error" )
|
|
228
|
+
assert(error)
|
|
229
|
+
|
|
230
|
+
const numberFieldErrors = form.querySelectorAll("brut-constraint-violation-messages[input-name=some-number] brut-constraint-violation-message")
|
|
231
|
+
assert.equal(0,numberFieldErrors.length)
|
|
232
|
+
|
|
233
|
+
assert(text.validity.customError)
|
|
234
|
+
assert(!number.validity.customError)
|
|
235
|
+
|
|
236
|
+
text.dispatchEvent(new window.Event("change"))
|
|
237
|
+
assert(!text.validity.customError)
|
|
238
|
+
})
|
|
239
|
+
})
|
|
240
|
+
})
|
|
241
|
+
})
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { withHTML } from "../src/testing/index.js"
|
|
2
|
+
|
|
3
|
+
describe("<brut-autosubmit>", () => {
|
|
4
|
+
withHTML(`
|
|
5
|
+
<form id="form-1">
|
|
6
|
+
<brut-autosubmit>
|
|
7
|
+
<select name="status">
|
|
8
|
+
<option value="draft">Draft</option>
|
|
9
|
+
<option value="ready">Ready</option>
|
|
10
|
+
<option value="published">Published</option>
|
|
11
|
+
</select>
|
|
12
|
+
<textarea></textarea>
|
|
13
|
+
<input type="text" id="input-1">
|
|
14
|
+
<input type="text" id="input-2" form="form-2">
|
|
15
|
+
</brut-autosubmit>
|
|
16
|
+
<button>Save</button>
|
|
17
|
+
</form>
|
|
18
|
+
<form id="form-2">
|
|
19
|
+
<button>Save</button>
|
|
20
|
+
</form>
|
|
21
|
+
`).test("<select> 'change' event submits the form", ({window,document,assert}) => {
|
|
22
|
+
|
|
23
|
+
const form = document.getElementById("form-1")
|
|
24
|
+
const select = form.querySelector("select")
|
|
25
|
+
|
|
26
|
+
let submitted = false
|
|
27
|
+
|
|
28
|
+
form.addEventListener("submit", (event) => {
|
|
29
|
+
event.preventDefault()
|
|
30
|
+
submitted = true
|
|
31
|
+
})
|
|
32
|
+
const event = new window.Event("change",{})
|
|
33
|
+
select.dispatchEvent(event)
|
|
34
|
+
assert(submitted)
|
|
35
|
+
}).test("<textarea> 'change' event submits the form", ({window,document,assert}) => {
|
|
36
|
+
|
|
37
|
+
const form = document.getElementById("form-1")
|
|
38
|
+
const textarea = form.querySelector("textarea")
|
|
39
|
+
|
|
40
|
+
let submitted = false
|
|
41
|
+
|
|
42
|
+
form.addEventListener("submit", (event) => {
|
|
43
|
+
event.preventDefault()
|
|
44
|
+
submitted = true
|
|
45
|
+
})
|
|
46
|
+
const event = new window.Event("change",{})
|
|
47
|
+
textarea.dispatchEvent(event)
|
|
48
|
+
assert(submitted)
|
|
49
|
+
}).test("<input> 'change' event submits the form", ({window,document,assert}) => {
|
|
50
|
+
|
|
51
|
+
const form = document.getElementById("form-1")
|
|
52
|
+
const input = document.getElementById("input-1")
|
|
53
|
+
|
|
54
|
+
let submitted = false
|
|
55
|
+
|
|
56
|
+
form.addEventListener("submit", (event) => {
|
|
57
|
+
event.preventDefault()
|
|
58
|
+
submitted = true
|
|
59
|
+
})
|
|
60
|
+
const event = new window.Event("change",{})
|
|
61
|
+
input.dispatchEvent(event)
|
|
62
|
+
assert(submitted)
|
|
63
|
+
}).test("<select> 'input' event does not submit the form", ({window,document,assert}) => {
|
|
64
|
+
|
|
65
|
+
const form = document.getElementById("form-1")
|
|
66
|
+
const select = form.querySelector("select")
|
|
67
|
+
|
|
68
|
+
let submitted = false
|
|
69
|
+
|
|
70
|
+
form.addEventListener("submit", (event) => {
|
|
71
|
+
event.preventDefault()
|
|
72
|
+
submitted = true
|
|
73
|
+
})
|
|
74
|
+
const event = new window.Event("input",{})
|
|
75
|
+
select.dispatchEvent(event)
|
|
76
|
+
assert(!submitted)
|
|
77
|
+
}).test("<textarea> 'input' event does not submit the form", ({window,document,assert}) => {
|
|
78
|
+
|
|
79
|
+
const form = document.getElementById("form-1")
|
|
80
|
+
const textarea = form.querySelector("textarea")
|
|
81
|
+
|
|
82
|
+
let submitted = false
|
|
83
|
+
|
|
84
|
+
form.addEventListener("submit", (event) => {
|
|
85
|
+
event.preventDefault()
|
|
86
|
+
submitted = true
|
|
87
|
+
})
|
|
88
|
+
const event = new window.Event("input",{})
|
|
89
|
+
textarea.dispatchEvent(event)
|
|
90
|
+
assert(!submitted)
|
|
91
|
+
}).test("<input> 'input' event does not submit the form", ({window,document,assert}) => {
|
|
92
|
+
|
|
93
|
+
const form = document.getElementById("form-1")
|
|
94
|
+
const input = document.getElementById("input-1")
|
|
95
|
+
|
|
96
|
+
let submitted = false
|
|
97
|
+
|
|
98
|
+
form.addEventListener("submit", (event) => {
|
|
99
|
+
event.preventDefault()
|
|
100
|
+
submitted = true
|
|
101
|
+
})
|
|
102
|
+
const event = new window.Event("input",{})
|
|
103
|
+
input.dispatchEvent(event)
|
|
104
|
+
assert(!submitted)
|
|
105
|
+
}).test("'change' event for element related to another form does nothing", ({window,document,assert}) => {
|
|
106
|
+
|
|
107
|
+
const form1 = document.getElementById("form-1")
|
|
108
|
+
const form2 = document.getElementById("form-1")
|
|
109
|
+
const input = document.getElementById("input-2")
|
|
110
|
+
|
|
111
|
+
let submitted1 = false
|
|
112
|
+
let submitted2 = false
|
|
113
|
+
|
|
114
|
+
form1.addEventListener("submit", (event) => {
|
|
115
|
+
event.preventDefault()
|
|
116
|
+
submitted1 = true
|
|
117
|
+
})
|
|
118
|
+
form2.addEventListener("submit", (event) => {
|
|
119
|
+
event.preventDefault()
|
|
120
|
+
submitted2 = true
|
|
121
|
+
})
|
|
122
|
+
const event = new window.Event("input",{})
|
|
123
|
+
input.dispatchEvent(event)
|
|
124
|
+
assert(!submitted1)
|
|
125
|
+
assert(!submitted2)
|
|
126
|
+
})
|
|
127
|
+
})
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
import { withHTML } from "../src/testing/index.js"
|
|
2
|
+
|
|
3
|
+
describe("<brut-confirm-submit>", () => {
|
|
4
|
+
describe("without an explicit dialog", () => {
|
|
5
|
+
withHTML(`
|
|
6
|
+
<form>
|
|
7
|
+
<input type="text" name="text">
|
|
8
|
+
<brut-confirm-submit message='You sure?'>
|
|
9
|
+
<button>Save</button>
|
|
10
|
+
<input type="submit" value="Submit">
|
|
11
|
+
</brut-confirm-submit>
|
|
12
|
+
</form>
|
|
13
|
+
`).test("uses window.confirm and cancels the click on Cancel", ({window,document,assert}) => {
|
|
14
|
+
const form = document.querySelector("form")
|
|
15
|
+
const button = document.querySelector("button")
|
|
16
|
+
|
|
17
|
+
let submitted = false
|
|
18
|
+
form.addEventListener("submit", (event) => {
|
|
19
|
+
event.preventDefault()
|
|
20
|
+
submitted = true
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
let shown = false
|
|
24
|
+
let messageShown = null
|
|
25
|
+
|
|
26
|
+
window.confirm = (message) => {
|
|
27
|
+
shown = true
|
|
28
|
+
messageShown = message
|
|
29
|
+
return false // "Cancel"
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
button.click()
|
|
33
|
+
assert(shown)
|
|
34
|
+
assert.equal(messageShown,"You sure?")
|
|
35
|
+
assert(!submitted)
|
|
36
|
+
}).test("uses window.confirm and allows the click on OK", ({window,document,assert}) => {
|
|
37
|
+
const form = document.querySelector("form")
|
|
38
|
+
const button = document.querySelector("button")
|
|
39
|
+
|
|
40
|
+
let submitted = false
|
|
41
|
+
form.addEventListener("submit", (event) => {
|
|
42
|
+
event.preventDefault()
|
|
43
|
+
submitted = true
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
let shown = false
|
|
47
|
+
let messageShown = null
|
|
48
|
+
|
|
49
|
+
window.confirm = (message) => {
|
|
50
|
+
shown = true
|
|
51
|
+
messageShown = message
|
|
52
|
+
return true // "OK"
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
button.click()
|
|
57
|
+
assert(shown)
|
|
58
|
+
assert.equal(messageShown,"You sure?")
|
|
59
|
+
assert(submitted)
|
|
60
|
+
}).test("uses window.confirm on submit button", ({window,document,assert}) => {
|
|
61
|
+
const form = document.querySelector("form")
|
|
62
|
+
const button = document.querySelector("input[type=submit]")
|
|
63
|
+
|
|
64
|
+
let submitted = false
|
|
65
|
+
form.addEventListener("submit", (event) => {
|
|
66
|
+
event.preventDefault()
|
|
67
|
+
submitted = true
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
let shown = false
|
|
71
|
+
let messageShown = null
|
|
72
|
+
|
|
73
|
+
window.confirm = (message) => {
|
|
74
|
+
shown = true
|
|
75
|
+
messageShown = message
|
|
76
|
+
return true // "OK"
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
button.click()
|
|
81
|
+
assert(shown)
|
|
82
|
+
assert.equal(messageShown,"You sure?")
|
|
83
|
+
assert(submitted)
|
|
84
|
+
})
|
|
85
|
+
})
|
|
86
|
+
describe("with an implicit dialog", () => {
|
|
87
|
+
withHTML(`
|
|
88
|
+
<form>
|
|
89
|
+
<input type="text" name="text">
|
|
90
|
+
<brut-confirm-submit message='You sure?' show-warnings>
|
|
91
|
+
<button>Save</button>
|
|
92
|
+
<input type="submit" value="Submit">
|
|
93
|
+
</brut-confirm-submit>
|
|
94
|
+
</form>
|
|
95
|
+
<brut-confirmation-dialog>
|
|
96
|
+
<dialog>
|
|
97
|
+
<h1></h1>
|
|
98
|
+
<button value="ok">OK</button>
|
|
99
|
+
<button value="cancel">Cancel</button>
|
|
100
|
+
</dialog>
|
|
101
|
+
</brut-confirmation-dialog>
|
|
102
|
+
`).test("uses the dialog and cancels the click on Cancel", ({window,document,assert}) => {
|
|
103
|
+
const form = document.querySelector("form")
|
|
104
|
+
const button = document.querySelector("button")
|
|
105
|
+
const dialog = document.querySelector("dialog")
|
|
106
|
+
|
|
107
|
+
let submitted = false
|
|
108
|
+
form.addEventListener("submit", (event) => {
|
|
109
|
+
event.preventDefault()
|
|
110
|
+
submitted = true
|
|
111
|
+
})
|
|
112
|
+
|
|
113
|
+
button.click()
|
|
114
|
+
|
|
115
|
+
assert(dialog.open)
|
|
116
|
+
const message = dialog.querySelector("h1").textContent
|
|
117
|
+
assert.equal(message,"You sure?")
|
|
118
|
+
|
|
119
|
+
const cancel = dialog.querySelector("button[value=cancel]")
|
|
120
|
+
cancel.click()
|
|
121
|
+
|
|
122
|
+
assert(!submitted)
|
|
123
|
+
}).test("uses the dialog and submits the click on OK", ({window,document,assert}) => {
|
|
124
|
+
const form = document.querySelector("form")
|
|
125
|
+
const button = document.querySelector("button")
|
|
126
|
+
const dialog = document.querySelector("dialog")
|
|
127
|
+
|
|
128
|
+
let submitted = false
|
|
129
|
+
form.addEventListener("submit", (event) => {
|
|
130
|
+
event.preventDefault()
|
|
131
|
+
submitted = true
|
|
132
|
+
})
|
|
133
|
+
|
|
134
|
+
button.click()
|
|
135
|
+
|
|
136
|
+
assert(dialog.open)
|
|
137
|
+
const message = dialog.querySelector("h1").textContent
|
|
138
|
+
assert.equal("You sure?",message)
|
|
139
|
+
|
|
140
|
+
const ok = dialog.querySelector("button[value=ok]")
|
|
141
|
+
assert.equal(ok.textContent,button.textContent)
|
|
142
|
+
ok.click()
|
|
143
|
+
assert(submitted)
|
|
144
|
+
})
|
|
145
|
+
})
|
|
146
|
+
describe("with multiple dialogs", () => {
|
|
147
|
+
withHTML(`
|
|
148
|
+
<form>
|
|
149
|
+
<input type="text" name="text">
|
|
150
|
+
<brut-confirm-submit message='You sure?' dialog="dialog-2" show-warnings>
|
|
151
|
+
<button>Save</button>
|
|
152
|
+
<input type="submit" value="Submit">
|
|
153
|
+
</brut-confirm-submit>
|
|
154
|
+
</form>
|
|
155
|
+
<brut-confirmation-dialog id="dialog-1">
|
|
156
|
+
<dialog>
|
|
157
|
+
<h1></h1>
|
|
158
|
+
<button value="ok">OK</button>
|
|
159
|
+
<button value="cancel">Cancel</button>
|
|
160
|
+
</dialog>
|
|
161
|
+
</brut-confirmation-dialog>
|
|
162
|
+
<brut-confirmation-dialog id="dialog-2">
|
|
163
|
+
<dialog>
|
|
164
|
+
<h1></h1>
|
|
165
|
+
<button value="ok">OK</button>
|
|
166
|
+
<button value="cancel">Cancel</button>
|
|
167
|
+
</dialog>
|
|
168
|
+
</brut-confirmation-dialog>
|
|
169
|
+
`).test("click event uses the identified dialog", ({window,document,assert}) => {
|
|
170
|
+
const form = document.querySelector("form")
|
|
171
|
+
const button = form.querySelector("button")
|
|
172
|
+
const dialog = document.getElementById("dialog-2").querySelector("dialog")
|
|
173
|
+
|
|
174
|
+
let submitted = false
|
|
175
|
+
form.addEventListener("submit", (event) => {
|
|
176
|
+
event.preventDefault()
|
|
177
|
+
submitted = true
|
|
178
|
+
})
|
|
179
|
+
|
|
180
|
+
button.click()
|
|
181
|
+
|
|
182
|
+
assert(dialog.open)
|
|
183
|
+
|
|
184
|
+
const message = dialog.querySelector("h1").textContent
|
|
185
|
+
assert.equal("You sure?",message)
|
|
186
|
+
|
|
187
|
+
const ok = dialog.querySelector("button[value=ok]")
|
|
188
|
+
assert.equal(ok.textContent,button.textContent)
|
|
189
|
+
ok.click()
|
|
190
|
+
assert(submitted)
|
|
191
|
+
})
|
|
192
|
+
})
|
|
193
|
+
})
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { withHTML } from "../src/testing/index.js"
|
|
2
|
+
|
|
3
|
+
describe("<brut-constraint-violation-message>", () => {
|
|
4
|
+
withHTML(`
|
|
5
|
+
<brut-i18n-translation key="problem" value="%{field} has a problem"></brut-i18n-translation>
|
|
6
|
+
|
|
7
|
+
<brut-constraint-violation-message input-name="some-field" key="problem"></brut-constraint-violation-message>
|
|
8
|
+
`).test("Inserts using 'this field' as the placeholder", ({document,assert}) => {
|
|
9
|
+
const element = document.querySelector("brut-constraint-violation-message")
|
|
10
|
+
assert.equal(element.textContent,"This field has a problem")
|
|
11
|
+
})
|
|
12
|
+
|
|
13
|
+
withHTML(`
|
|
14
|
+
<brut-i18n-translation key="problem" value="%{field} has a problem"></brut-i18n-translation>
|
|
15
|
+
<brut-i18n-translation key="general.cv.this_field" value="THAT FIELD"></brut-i18n-translation>
|
|
16
|
+
|
|
17
|
+
<brut-constraint-violation-message input-name="some-field" key="problem"></brut-constraint-violation-message>
|
|
18
|
+
`).test("Inserts using the this_field key as the placeholder", ({document,assert}) => {
|
|
19
|
+
const element = document.querySelector("brut-constraint-violation-message")
|
|
20
|
+
assert.equal(element.textContent,"THAT FIELD has a problem")
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
withHTML(`
|
|
24
|
+
<brut-i18n-translation key="problem" value="%{field} has a problem"></brut-i18n-translation>
|
|
25
|
+
<brut-i18n-translation key="general.cv.this_field" value="THAT FIELD"></brut-i18n-translation>
|
|
26
|
+
<brut-i18n-translation key="general.cv.fe.fieldNames.some-field" value="Some Field"></brut-i18n-translation>
|
|
27
|
+
|
|
28
|
+
<brut-constraint-violation-message input-name="some-field" key="problem"></brut-constraint-violation-message>
|
|
29
|
+
`).test("Inserts using the this_field key as the placeholder", ({document,assert}) => {
|
|
30
|
+
const element = document.querySelector("brut-constraint-violation-message")
|
|
31
|
+
assert.equal(element.textContent,"Some Field has a problem")
|
|
32
|
+
})
|
|
33
|
+
})
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { withHTML } from "../src/testing/index.js"
|
|
2
|
+
|
|
3
|
+
describe("<brut-constraint-violation-messages>", () => {
|
|
4
|
+
withHTML(`
|
|
5
|
+
<brut-i18n-translation key="general.cv.fe.patternMismatch" value="%{field} does not match the pattern"></brut-i18n-translation>
|
|
6
|
+
<brut-i18n-translation key="general.cv.fe.rangeOverflow" value="%{field} is above the range"></brut-i18n-translation>
|
|
7
|
+
|
|
8
|
+
<brut-constraint-violation-messages input-name="some-field"></brut-constraint-violation-messages>
|
|
9
|
+
`).test("Inserts constraint violation messages based on validity state", ({document,assert}) => {
|
|
10
|
+
const element = document.querySelector("brut-constraint-violation-messages")
|
|
11
|
+
|
|
12
|
+
const validityState = {
|
|
13
|
+
patternMismatch: true,
|
|
14
|
+
rangeOverflow: true,
|
|
15
|
+
}
|
|
16
|
+
const inputName = "some-field"
|
|
17
|
+
|
|
18
|
+
element.createMessages({validityState,inputName})
|
|
19
|
+
|
|
20
|
+
assert.match(element.textContent,new RegExp("This field does not match the pattern","m"))
|
|
21
|
+
assert.match(element.textContent,new RegExp("This field is above the range","m"))
|
|
22
|
+
|
|
23
|
+
element.clearMessages()
|
|
24
|
+
assert.equal(element.textContent,"")
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
})
|