@json-editor/json-editor 2.13.2 → 2.14.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.
Files changed (159) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/README.md +2 -1
  3. package/dist/jsoneditor.js +1 -1
  4. package/dist/jsoneditor.js.LICENSE.txt +1 -1
  5. package/dist/nonmin/jsoneditor.js +436 -247
  6. package/dist/nonmin/jsoneditor.js.map +1 -1
  7. package/docs/imask.html +1 -1
  8. package/docs/meta_schema.json +3 -0
  9. package/package.json +1 -1
  10. package/src/defaults.js +5 -1
  11. package/src/editor.js +15 -2
  12. package/src/editors/array/selectize.js +13 -0
  13. package/src/editors/array.js +16 -2
  14. package/src/editors/info.js +1 -1
  15. package/src/editors/multiple.js +13 -2
  16. package/src/editors/multiselect.js +3 -2
  17. package/src/editors/object.js +20 -3
  18. package/src/editors/radio.js +4 -0
  19. package/src/editors/select.js +1 -1
  20. package/src/editors/starrating.js +5 -1
  21. package/src/editors/string.js +5 -3
  22. package/src/editors/table.js +3 -2
  23. package/src/theme.js +56 -4
  24. package/src/themes/barebones.js +1 -0
  25. package/src/themes/bootstrap3.js +49 -12
  26. package/src/themes/bootstrap4.js +38 -13
  27. package/src/themes/bootstrap5.js +37 -7
  28. package/src/themes/html.js +1 -0
  29. package/src/themes/spectre.js +15 -7
  30. package/src/validator.js +4 -3
  31. package/tests/codeceptjs/core_test.js +11 -0
  32. package/tests/codeceptjs/editors/array_test.js +7 -0
  33. package/tests/codeceptjs/editors/button_test.js +1 -1
  34. package/tests/codeceptjs/editors/checkbox_test.js +1 -1
  35. package/tests/codeceptjs/editors/integer_test.js +1 -1
  36. package/tests/codeceptjs/editors/multiselect_test.js +1 -1
  37. package/tests/codeceptjs/editors/number_test.js +1 -1
  38. package/tests/codeceptjs/editors/object_test.js +7 -0
  39. package/tests/codeceptjs/editors/radio_test.js +1 -2
  40. package/tests/codeceptjs/editors/rating_test.js +1 -2
  41. package/tests/codeceptjs/editors/select_test.js +1 -1
  42. package/tests/codeceptjs/editors/string_test.js +1 -1
  43. package/tests/codeceptjs/issues/issue-gh-1171_test.js +11 -0
  44. package/tests/codeceptjs/issues/issue-gh-1272_test.js +21 -0
  45. package/tests/codeceptjs/issues/issue-gh-1471_test.js +17 -0
  46. package/tests/codeceptjs/issues/issue-gh-1485_test.js +13 -0
  47. package/tests/codeceptjs/issues/issue-gh-1491_test.js +9 -0
  48. package/tests/codeceptjs/issues/issue-gh-812_test.js +2 -2
  49. package/tests/codeceptjs/meta-schema_test.js +1 -1
  50. package/tests/codeceptjs/schemaloader_test.js +1 -1
  51. package/tests/pages/advanced.html +1 -1
  52. package/tests/pages/anyof-2.html +1 -0
  53. package/tests/pages/anyof.html +4 -2
  54. package/tests/pages/array-anyof.html +5 -2
  55. package/tests/pages/array-checkboxes-infotext.html +5 -2
  56. package/tests/pages/array-checkboxes.html +5 -2
  57. package/tests/pages/array-choices.html +5 -2
  58. package/tests/pages/array-events-table.html +5 -2
  59. package/tests/pages/array-events.html +7 -3
  60. package/tests/pages/array-header-template.html +1 -0
  61. package/tests/pages/array-integers.html +5 -2
  62. package/tests/pages/array-multiselects.html +5 -2
  63. package/tests/pages/array-nested-arrays.html +5 -2
  64. package/tests/pages/array-numbers.html +5 -2
  65. package/tests/pages/array-objects.html +5 -2
  66. package/tests/pages/array-ratings.html +5 -2
  67. package/tests/pages/array-selectize-create.html +1 -0
  68. package/tests/pages/array-selectize.html +5 -2
  69. package/tests/pages/array-selects.html +5 -2
  70. package/tests/pages/array-strings.html +5 -2
  71. package/tests/pages/array-table-responsive.html +1 -0
  72. package/tests/pages/array-unique-items-sort.html +5 -2
  73. package/tests/pages/array.html +5 -2
  74. package/tests/pages/autocomplete.html +3 -1
  75. package/tests/pages/button-callbacks.html +4 -2
  76. package/tests/pages/button-icons.html +2 -1
  77. package/tests/pages/button_state_mode_1.html +1 -0
  78. package/tests/pages/button_state_mode_2.html +1 -0
  79. package/tests/pages/checkbox-labels.html +4 -2
  80. package/tests/pages/colorpicker-no-3rd-party.html +4 -2
  81. package/tests/pages/colorpicker-use-vanilla-picker.html +4 -2
  82. package/tests/pages/container-attributes.html +1 -0
  83. package/tests/pages/contains.html +1 -0
  84. package/tests/pages/core.html +5 -3
  85. package/tests/pages/datetime.html +2 -0
  86. package/tests/pages/dependentRequired.html +1 -0
  87. package/tests/pages/dependentSchemas.html +1 -0
  88. package/tests/pages/disable-button-in-object-editors.html +1 -0
  89. package/tests/pages/error-messages.html +1 -0
  90. package/tests/pages/form-name.html +4 -1
  91. package/tests/pages/grid-strict.html +3 -2
  92. package/tests/pages/grid.html +3 -2
  93. package/tests/pages/if-else.html +1 -0
  94. package/tests/pages/if-then-else-allOf.html +1 -0
  95. package/tests/pages/if-then-else-disable-fields.html +1 -0
  96. package/tests/pages/if-then-else.html +1 -0
  97. package/tests/pages/if-then.html +1 -0
  98. package/tests/pages/inheritance.html +6 -2
  99. package/tests/pages/integer.html +4 -2
  100. package/tests/pages/issues/_template.html +1 -1
  101. package/tests/pages/issues/issue-gh-1158-2.html +1 -1
  102. package/tests/pages/issues/issue-gh-1158.html +1 -1
  103. package/tests/pages/issues/issue-gh-1171.html +39 -0
  104. package/tests/pages/issues/issue-gh-1272.html +167 -0
  105. package/tests/pages/issues/issue-gh-1364.html +1 -1
  106. package/tests/pages/issues/issue-gh-1367.html +1 -1
  107. package/tests/pages/issues/issue-gh-1466.html +63 -0
  108. package/tests/pages/issues/issue-gh-1471.html +49 -0
  109. package/tests/pages/issues/issue-gh-1485.html +59 -0
  110. package/tests/pages/issues/issue-gh-1491.html +59 -0
  111. package/tests/pages/issues/issue-gh-812.html +3 -2
  112. package/tests/pages/issues/issue-gh-823-meta-schema.html +1 -1
  113. package/tests/pages/issues/issue-gh-848.html +1 -1
  114. package/tests/pages/keep_only_existing_values.html +1 -0
  115. package/tests/pages/load-events.html +1 -0
  116. package/tests/pages/maxContains.html +1 -0
  117. package/tests/pages/meta-schema.html +4 -0
  118. package/tests/pages/meta_schema.json +3 -0
  119. package/tests/pages/minContains.html +1 -0
  120. package/tests/pages/number.html +4 -2
  121. package/tests/pages/object-case-sensitive-property-search-false.html +2 -1
  122. package/tests/pages/object-case-sensitive-property-search-true.html +2 -1
  123. package/tests/pages/object-no-additional-properties.html +5 -2
  124. package/tests/pages/object-no-duplicated-id.html +2 -0
  125. package/tests/pages/object-required-properties.html +5 -3
  126. package/tests/pages/object-show-opt-in.html +3 -2
  127. package/tests/pages/object-with-dependencies-array.html +4 -2
  128. package/tests/pages/object-with-dependencies.html +2 -0
  129. package/tests/pages/object.html +5 -3
  130. package/tests/pages/oneof-2.html +1 -0
  131. package/tests/pages/oneof.html +4 -2
  132. package/tests/pages/option-dependencies.html +1 -0
  133. package/tests/pages/option-no_default_values.html +4 -2
  134. package/tests/pages/per-editor-options.html +1 -1
  135. package/tests/pages/programmatic-changes.html +4 -3
  136. package/tests/pages/range.html +4 -2
  137. package/tests/pages/read-only.html +36 -5
  138. package/tests/pages/ready.html +2 -1
  139. package/tests/pages/references.html +1 -1
  140. package/tests/pages/select.html +4 -3
  141. package/tests/pages/stepper-manual.html +4 -2
  142. package/tests/pages/stepper.html +4 -2
  143. package/tests/pages/string-ace-editor.html +4 -2
  144. package/tests/pages/string-cleave.html +4 -2
  145. package/tests/pages/string-custom-attributes.html +4 -2
  146. package/tests/pages/string-formats.html +4 -2
  147. package/tests/pages/string-formats2.html +4 -2
  148. package/tests/pages/string-jodit-editor.html +4 -2
  149. package/tests/pages/string-sceditor.html +4 -2
  150. package/tests/pages/string-simplemde-editor.html +4 -2
  151. package/tests/pages/table.html +4 -2
  152. package/tests/pages/tabs.html +1 -1
  153. package/tests/pages/themes.html +38 -52
  154. package/tests/pages/title-hidden.html +75 -0
  155. package/tests/pages/translate-property.html +2 -1
  156. package/tests/pages/urn.html +4 -2
  157. package/tests/pages/use-name-attributes.html +2 -1
  158. package/tests/pages/uuid.html +2 -0
  159. package/tests/pages/validation.html +2 -1
@@ -75,8 +75,8 @@ export class bootstrap4Theme extends AbstractTheme {
75
75
  return el
76
76
  }
77
77
 
78
- getRangeInput (min, max, step) {
79
- const el = super.getRangeInput(min, max, step)
78
+ getRangeInput (min, max, step, description, formName) {
79
+ const el = super.getRangeInput(min, max, step, description, formName)
80
80
 
81
81
  if (this.options.custom_forms === true) {
82
82
  el.classList.remove('form-control')
@@ -188,7 +188,29 @@ export class bootstrap4Theme extends AbstractTheme {
188
188
  return el
189
189
  }
190
190
 
191
- getFormControl (label, input, description, infoText) {
191
+ getHiddenLabel (text) {
192
+ const el = document.createElement('label')
193
+ el.textContent = text
194
+ el.classList.add('sr-only')
195
+ return el
196
+ }
197
+
198
+ visuallyHidden (element) {
199
+ if (!element) {
200
+ return
201
+ }
202
+
203
+ element.classList.add('sr-only')
204
+ }
205
+
206
+ getHiddenText (text) {
207
+ const el = document.createElement('span')
208
+ el.textContent = text
209
+ el.classList.add('sr-only')
210
+ return el
211
+ }
212
+
213
+ getFormControl (label, input, description, infoText, formName) {
192
214
  const group = document.createElement('div')
193
215
  group.classList.add('form-group')
194
216
 
@@ -211,10 +233,6 @@ export class bootstrap4Theme extends AbstractTheme {
211
233
  }
212
234
  }
213
235
 
214
- const unique = (Date.now() * Math.random()).toFixed(0)
215
- input.setAttribute('id', unique)
216
- label.setAttribute('for', unique)
217
-
218
236
  check.appendChild(input)
219
237
  check.appendChild(label)
220
238
  if (infoText) check.appendChild(infoText)
@@ -234,6 +252,16 @@ export class bootstrap4Theme extends AbstractTheme {
234
252
  group.appendChild(description)
235
253
  }
236
254
 
255
+ if (input.tagName.toLowerCase() !== 'div' && input && label && formName) {
256
+ label.setAttribute('for', formName)
257
+ input.setAttribute('id', formName)
258
+ }
259
+
260
+ if (input.tagName.toLowerCase() !== 'div' && input && description) {
261
+ description.setAttribute('id', formName + '-description')
262
+ input.setAttribute('aria-describedby', formName + '-description')
263
+ }
264
+
237
265
  return group
238
266
  }
239
267
 
@@ -406,10 +434,8 @@ export class bootstrap4Theme extends AbstractTheme {
406
434
  }
407
435
 
408
436
  getHeader (text, pathDepth) {
409
- /* var cardHeader = document.createElement('div') */
410
- /* cardHeader.classList.add('card-header') */
411
-
412
- const el = document.createElement('h3')
437
+ const el = document.createElement('span')
438
+ el.classList.add('h3')
413
439
  el.classList.add('card-title')
414
440
  el.classList.add('level-' + pathDepth)
415
441
 
@@ -421,8 +447,6 @@ export class bootstrap4Theme extends AbstractTheme {
421
447
 
422
448
  el.style.display = 'inline-block'
423
449
 
424
- /* cardHeader.appendChild(el) */
425
-
426
450
  return el
427
451
  }
428
452
 
@@ -500,6 +524,7 @@ export class bootstrap4Theme extends AbstractTheme {
500
524
 
501
525
  input.errmsg.style.display = 'block'
502
526
  input.errmsg.textContent = text
527
+ input.errmsg.setAttribute('role', 'alert')
503
528
  }
504
529
 
505
530
  removeInputError (input) {
@@ -68,8 +68,8 @@ export class bootstrap5Theme extends AbstractTheme {
68
68
  return el
69
69
  }
70
70
 
71
- getRangeInput (min, max, step) {
72
- const el = super.getRangeInput(min, max, step)
71
+ getRangeInput (min, max, step, description, formName) {
72
+ const el = super.getRangeInput(min, max, step, description, formName)
73
73
  el.classList.remove('form-control')
74
74
  el.classList.add('form-range')
75
75
  return el
@@ -163,7 +163,7 @@ export class bootstrap5Theme extends AbstractTheme {
163
163
  return el
164
164
  }
165
165
 
166
- getFormControl (label, input, description, infoText) {
166
+ getFormControl (label, input, description, infoText, formName) {
167
167
  const group = document.createElement('div')
168
168
  group.classList.add('form-group')
169
169
 
@@ -174,9 +174,15 @@ export class bootstrap5Theme extends AbstractTheme {
174
174
  input.classList.add('form-check-input')
175
175
  label.classList.add('form-check-label')
176
176
 
177
- const unique = (Date.now() * Math.random()).toFixed(0)
178
- input.setAttribute('id', unique)
179
- label.setAttribute('for', unique)
177
+ if (input.tagName.toLowerCase() !== 'div' && input && label && formName) {
178
+ label.setAttribute('for', formName)
179
+ input.setAttribute('id', formName)
180
+ }
181
+
182
+ if (input.tagName.toLowerCase() !== 'div' && input && description) {
183
+ description.setAttribute('id', formName + '-description')
184
+ input.setAttribute('aria-describedby', formName + '-description')
185
+ }
180
186
 
181
187
  check.appendChild(input)
182
188
  check.appendChild(label)
@@ -201,6 +207,28 @@ export class bootstrap5Theme extends AbstractTheme {
201
207
  return group
202
208
  }
203
209
 
210
+ getHiddenLabel (text) {
211
+ const el = document.createElement('label')
212
+ el.textContent = text
213
+ el.classList.add('visually-hidden')
214
+ return el
215
+ }
216
+
217
+ visuallyHidden (element) {
218
+ if (!element) {
219
+ return
220
+ }
221
+
222
+ element.classList.add('visually-hidden')
223
+ }
224
+
225
+ getHiddenText (text) {
226
+ const el = document.createElement('span')
227
+ el.textContent = text
228
+ el.classList.add('sr-only')
229
+ return el
230
+ }
231
+
204
232
  getInfoButton (text) {
205
233
  const button = document.createElement('button') /* shoud be a <button> but no fitting tbws style... */
206
234
  button.type = 'button'
@@ -347,7 +375,8 @@ export class bootstrap5Theme extends AbstractTheme {
347
375
  }
348
376
 
349
377
  getHeader (text, pathDepth) {
350
- const el = document.createElement('h3')
378
+ const el = document.createElement('span')
379
+ el.classList.add('h3')
351
380
  el.classList.add('card-title')
352
381
  el.classList.add('level-' + pathDepth)
353
382
 
@@ -436,6 +465,7 @@ export class bootstrap5Theme extends AbstractTheme {
436
465
 
437
466
  input.errmsg.style.display = 'block'
438
467
  input.errmsg.textContent = text
468
+ input.errmsg.setAttribute('role', 'alert')
439
469
  }
440
470
 
441
471
  removeInputError (input) {
@@ -57,6 +57,7 @@ export class htmlTheme extends AbstractTheme {
57
57
 
58
58
  input.errmsg.innerHTML = ''
59
59
  input.errmsg.appendChild(document.createTextNode(text))
60
+ input.errmsg.setAttribute('role', 'alert')
60
61
  }
61
62
 
62
63
  removeInputError (input) {
@@ -99,7 +99,7 @@ export class spectreTheme extends AbstractTheme {
99
99
  }
100
100
 
101
101
  getHeader (text, pathDepth) {
102
- const el = document.createElement('h4')
102
+ const el = document.createElement('span')
103
103
  if (typeof text === 'string') {
104
104
  el.textContent = text
105
105
  } else {
@@ -182,14 +182,11 @@ export class spectreTheme extends AbstractTheme {
182
182
  }
183
183
 
184
184
  /* Create input field for type="range" */
185
- getRangeInput (min, max, step) {
186
- const el = this.getFormInputField('range')
185
+ getRangeInput (min, max, step, description, formName) {
186
+ const el = super.getRangeInput(min, max, step, description, formName)
187
187
  el.classList.add('slider')
188
188
  el.classList.remove('form-input')
189
189
  el.setAttribute('oninput', 'this.setAttribute("value", this.value)')
190
- el.setAttribute('min', min)
191
- el.setAttribute('max', max)
192
- el.setAttribute('step', step)
193
190
  return el
194
191
  }
195
192
 
@@ -213,7 +210,7 @@ export class spectreTheme extends AbstractTheme {
213
210
  return el
214
211
  }
215
212
 
216
- getFormControl (label, input, description, infoText) {
213
+ getFormControl (label, input, description, infoText, formName) {
217
214
  const group = document.createElement('div')
218
215
  group.classList.add('form-group')
219
216
 
@@ -237,6 +234,16 @@ export class spectreTheme extends AbstractTheme {
237
234
 
238
235
  if (description) group.appendChild(description)
239
236
 
237
+ if (input.tagName.toLowerCase() !== 'div' && input && label && formName) {
238
+ label.setAttribute('for', formName)
239
+ input.setAttribute('id', formName)
240
+ }
241
+
242
+ if (input.tagName.toLowerCase() !== 'div' && input && description) {
243
+ description.setAttribute('id', formName + '-description')
244
+ input.setAttribute('aria-describedby', formName + '-description')
245
+ }
246
+
240
247
  return group
241
248
  }
242
249
 
@@ -393,6 +400,7 @@ export class spectreTheme extends AbstractTheme {
393
400
  }
394
401
  input.errmsg.classList.remove('d-hide')
395
402
  input.errmsg.textContent = text
403
+ input.errmsg.setAttribute('role', 'alert')
396
404
  }
397
405
 
398
406
  removeInputError (input) {
package/src/validator.js CHANGED
@@ -918,9 +918,9 @@ export class Validator {
918
918
  }
919
919
 
920
920
  const validatorRx = {
921
- date: /^(\d{4}\D\d{2}\D\d{2})?$/,
922
- time: /^(\d{2}:\d{2}(?::\d{2})?)?$/,
923
- 'datetime-local': /^(\d{4}\D\d{2}\D\d{2}[ T]\d{2}:\d{2}(?::\d{2})?)?$/
921
+ date: /^(\d{4}\D\d{2}\D\d{2})$/,
922
+ time: /^(\d{2}:\d{2}(?::\d{2})?)$/,
923
+ 'datetime-local': /^(\d{4}\D\d{2}\D\d{2}[ T]\d{2}:\d{2}(?::\d{2})?)$/
924
924
  }
925
925
  const format = {
926
926
  date: '"YYYY-MM-DD"',
@@ -946,6 +946,7 @@ export class Validator {
946
946
  /* Flatpickr validation */
947
947
  return _validateFlatPicker(schema, value, path, editor)
948
948
  }
949
+
949
950
  return []
950
951
  }
951
952
 
@@ -5,6 +5,17 @@ const { DEFAULT_WAIT_TIME } = require('./test-config')
5
5
 
6
6
  Feature('core')
7
7
 
8
+ Scenario('should hide titles @titleHidden', async ({ I }) => {
9
+ I.amOnPage('title-hidden.html')
10
+ I.waitForElement('.je-ready')
11
+ I.waitForText('root', DEFAULT_WAIT_TIME, '.sr-only')
12
+ I.waitForText('boolean', DEFAULT_WAIT_TIME, '.sr-only')
13
+ I.waitForText('integer', DEFAULT_WAIT_TIME, '.sr-only')
14
+ I.waitForText('number', DEFAULT_WAIT_TIME, '.sr-only')
15
+ I.waitForText('string', DEFAULT_WAIT_TIME, '.sr-only')
16
+ I.waitForText('array', DEFAULT_WAIT_TIME, '.sr-only')
17
+ })
18
+
8
19
  Scenario('should show validation errors based on "show_errors" setting @showValidationErrors', async ({ I }) => {
9
20
  I.amOnPage('show-validation-errors.html')
10
21
  I.waitForElement('.je-ready')
@@ -4,6 +4,13 @@ const { DEFAULT_WAIT_TIME } = require('../test-config')
4
4
 
5
5
  Feature('array')
6
6
 
7
+ Scenario('should be readonly if specified and not disabled @readOnly', async ({ I }) => {
8
+ I.amOnPage('read-only.html')
9
+ I.waitForElement('.je-ready', DEFAULT_WAIT_TIME)
10
+ I.seeDisabledAttribute('[name="root[array][0]"]')
11
+ I.seeDisabledAttribute('[name="root[array][1]"]')
12
+ })
13
+
7
14
  Scenario('Should display properties enum titles in items headerTemplate @headerTemplate', async ({ I }) => {
8
15
  I.amOnPage('array-header-template.html')
9
16
  I.waitForElement('.je-ready', DEFAULT_WAIT_TIME)
@@ -31,7 +31,7 @@ Scenario('should not leave any footprints in result', async ({ I }) => {
31
31
  I.waitForValue('.value', JSON.stringify({ textinput: '' }))
32
32
  })
33
33
 
34
- Scenario('should be disabled if "readonly" is specified', async ({ I }) => {
34
+ Scenario('should be disabled if "readonly" is specified @readOnly', async ({ I }) => {
35
35
  I.amOnPage('read-only.html')
36
36
  I.waitForElement('.je-ready', DEFAULT_WAIT_TIME)
37
37
  I.seeDisabledAttribute('[data-schemapath="root.button"] button')
@@ -4,7 +4,7 @@ const { DEFAULT_WAIT_TIME } = require('../test-config')
4
4
 
5
5
  Feature('checkbox')
6
6
 
7
- Scenario('should be disabled if "readonly" is specified', async ({ I }) => {
7
+ Scenario('should be disabled if "readonly" is specified @readOnly', async ({ I }) => {
8
8
  I.amOnPage('read-only.html')
9
9
  I.waitForText('READY', DEFAULT_WAIT_TIME, '.state')
10
10
  I.seeDisabledAttribute('[name="root[checkbox]"]')
@@ -64,7 +64,7 @@ Scenario('should respect step by incrementing and decrementing the value of a ra
64
64
  I.waitForValue('.value', '{"integer":5,"integer_number":5,"integer_range":5}')
65
65
  })
66
66
 
67
- Scenario('should be readonly if specified and not disabled', async ({ I }) => {
67
+ Scenario('should be readonly if specified and not disabled @readOnly', async ({ I }) => {
68
68
  I.amOnPage('read-only.html')
69
69
  I.seeReadOnlyAttribute('[name="root[integer]"]')
70
70
  })
@@ -2,7 +2,7 @@
2
2
 
3
3
  Feature('multiselect')
4
4
 
5
- Scenario('should be disabled if "readonly" is specified', async ({ I }) => {
5
+ Scenario('should be disabled if "readonly" is specified @readOnly', async ({ I }) => {
6
6
  I.amOnPage('read-only.html')
7
7
  I.seeDisabledAttribute('[name="root[multiselect]"]')
8
8
  })
@@ -72,7 +72,7 @@ Scenario('should respect step by incrementing and decrementing the value of a ra
72
72
  I.waitForValue('.value', '{"number":5.75,"number_number":5.75,"number_range":5.75,"stepper_number_default":5,"stepper_integer_default":5}')
73
73
  })
74
74
 
75
- Scenario('should be readonly if specified and not disabled @number', async ({ I }) => {
75
+ Scenario('should be readonly if specified and not disabled @number @readOnly', async ({ I }) => {
76
76
  I.amOnPage('read-only.html')
77
77
  I.seeReadOnlyAttribute('[name="root[number]"]')
78
78
  })
@@ -5,6 +5,13 @@ const { DEFAULT_WAIT_TIME } = require('../test-config')
5
5
 
6
6
  Feature('object')
7
7
 
8
+ Scenario('should be readonly if specified and not disabled @readOnly', async ({ I }) => {
9
+ I.amOnPage('read-only.html')
10
+ I.waitForElement('.je-ready', DEFAULT_WAIT_TIME)
11
+ I.seeDisabledAttribute('[name="root[object][string]"]')
12
+ I.seeDisabledAttribute('[name="root[object][number]"]')
13
+ })
14
+
8
15
  Scenario('@case-sensitive-property-search', async ({ I }) => {
9
16
  I.amOnPage('object-case-sensitive-property-search-true.html')
10
17
  I.click('.json-editor-btn-edit_properties')
@@ -2,9 +2,8 @@
2
2
 
3
3
  Feature('radio')
4
4
 
5
- Scenario('should be disabled if "readonly" is specified', async ({ I }) => {
5
+ Scenario('should be disabled if "readonly" is specified @readOnly', async ({ I }) => {
6
6
  I.amOnPage('read-only.html')
7
-
8
7
  I.seeDisabledAttribute('[id="root[radio][0]"]')
9
8
  I.seeDisabledAttribute('[id="root[radio][1]"]')
10
9
  })
@@ -2,9 +2,8 @@
2
2
 
3
3
  Feature('rating')
4
4
 
5
- Scenario('should be disabled if "readonly" is specified', async ({ I }) => {
5
+ Scenario('should be disabled if "readonly" is specified @readOnly', async ({ I }) => {
6
6
  I.amOnPage('read-only.html')
7
-
8
7
  I.seeDisabledAttribute('[id="root[rating]5"]')
9
8
  I.seeDisabledAttribute('[id="root[rating]4"]')
10
9
  I.seeDisabledAttribute('[id="root[rating]3"]')
@@ -2,7 +2,7 @@
2
2
 
3
3
  Feature('select')
4
4
 
5
- Scenario('should return correct booleans values when selected', async ({ I }) => {
5
+ Scenario('should return correct booleans values when selected @readOnly', async ({ I }) => {
6
6
  I.amOnPage('select.html')
7
7
  I.click('.get-value')
8
8
  I.waitForValue('.value', '{"boolean":true}')
@@ -98,7 +98,7 @@ Scenario('Should work correctly in arrays @optional', async ({ I }) => {
98
98
  I.switchTo()
99
99
  })
100
100
 
101
- Scenario('should be readonly if specified and not disabled', async ({ I }) => {
101
+ Scenario('should be readonly if specified and not disabled @readOnly', async ({ I }) => {
102
102
  I.amOnPage('read-only.html')
103
103
  I.seeReadOnlyAttribute('[name="root[string]"]')
104
104
  })
@@ -0,0 +1,11 @@
1
+ /* global Feature Scenario */
2
+
3
+ Feature('issues')
4
+
5
+ Scenario('GitHub issue 1171 should remain fixed @issue-1171', async ({ I }) => {
6
+ I.amOnPage('issues/issue-gh-1171.html')
7
+ I.waitForElement('.je-ready')
8
+ I.dontSeeCheckedAttribute('[id="root[1]"]')
9
+ I.checkOption('[id="root[1]"]')
10
+ I.dontSeeCheckedAttribute('[id="root[0]"]')
11
+ })
@@ -0,0 +1,21 @@
1
+ /* global Feature Scenario */
2
+
3
+ Feature('issues')
4
+
5
+ Scenario('GitHub issue 1272 should remain fixed @issue-1272', async ({ I }) => {
6
+ I.amOnPage('issues/issue-gh-1272.html')
7
+ I.waitForElement('.je-ready')
8
+ I.selectOption('[name="root[recorder][albums]"]', 'album2')
9
+ I.waitForText('song1')
10
+ I.dontSee('array editor')
11
+ I.selectOption('[data-schemapath="root.recorder.album2"] .je-switcher', 'SideB')
12
+ I.waitForText('array editor')
13
+ I.dontSee('song1')
14
+ I.selectOption('[data-schemapath="root.recorder.album2"] .je-switcher', 'SideA')
15
+ I.waitForText('song1')
16
+ I.dontSee('array editor')
17
+ I.selectOption('[name="root[recorder][albums]"]', 'album1')
18
+ I.selectOption('[name="root[recorder][albums]"]', 'album2')
19
+ I.waitForText('song1')
20
+ I.dontSee('array editor')
21
+ })
@@ -0,0 +1,17 @@
1
+ /* global Feature Scenario */
2
+
3
+ Feature('issues')
4
+
5
+ Scenario('GitHub issue 1471 should remain fixed @issue-1471', async ({ I }) => {
6
+ I.amOnPage('issues/issue-gh-1471.html')
7
+ I.waitForElement('.je-ready')
8
+ I.dontSee('Date must be in the format "YYYY-MM-DD"')
9
+ I.dontSee('Time must be in the format "HH:MM"')
10
+ I.dontSee('Datetime must be in the format "YYYY-MM-DD HH:MM"')
11
+ I.fillField('[name="root[date]"]', '')
12
+ I.fillField('[name="root[time]"]', '')
13
+ I.fillField('[name="root[datetime-local]"]', '')
14
+ I.waitForText('Date must be in the format "YYYY-MM-DD"')
15
+ I.waitForText('Time must be in the format "HH:MM"')
16
+ I.waitForText('Datetime must be in the format "YYYY-MM-DD HH:MM"')
17
+ })
@@ -0,0 +1,13 @@
1
+ /* global Feature Scenario */
2
+
3
+ Feature('issues')
4
+
5
+ Scenario('GitHub issue 1485 should remain fixed @issue-1485', async ({ I }) => {
6
+ I.amOnPage('issues/issue-gh-1485.html')
7
+ I.waitForElement('.je-ready')
8
+ I.fillField('[name="root[first_name]"]', 'John')
9
+ I.pressKey('Tab')
10
+ I.fillField('[name="root[last_name]"]', 'Doe')
11
+ I.pressKey('Tab')
12
+ I.waitForValue('[name="root[full_name]"]', 'John Doe')
13
+ })
@@ -0,0 +1,9 @@
1
+ /* global Feature Scenario */
2
+
3
+ Feature('issues')
4
+
5
+ Scenario('GitHub issue 1491 should remain fixed @issue-1491', async ({ I }) => {
6
+ I.amOnPage('issues/issue-gh-1491.html')
7
+ I.waitForElement('.je-ready')
8
+ I.dontSee('Value required')
9
+ })
@@ -8,7 +8,7 @@ Scenario('GitHub issue 812 should remain fixed @issue-812', async ({ I }) => {
8
8
  I.waitForValue('.debug', '{"students":[{"name":"AAA","sessions":[{"student_name":"AAA","minutes":15},{"student_name":"AAA","minutes":15}]},{"name":"BBB","sessions":[{"student_name":"BBB","minutes":20}]},{"name":"CCC","sessions":[{"student_name":"CCC","minutes":10}]}]}')
9
9
 
10
10
  I.amAcceptingPopups()
11
- I.click('//*[@id="root.students.0"]/span[2]/button[contains(@class, "json-editor-btn-delete") and @data-i="0"]')
11
+ I.click('//*[@id="root.students.0"]/span[3]/button[contains(@class, "json-editor-btn-delete") and @data-i="0"]')
12
12
  I.retry({ retries: 5, minTimeout: 500 }).seeInPopup('Are you sure you want to remove this item?')
13
13
  I.acceptPopup()
14
14
 
@@ -16,7 +16,7 @@ Scenario('GitHub issue 812 should remain fixed @issue-812', async ({ I }) => {
16
16
  I.waitForValue('.debug', '{"students":[{"name":"BBB","sessions":[{"student_name":"BBB","minutes":20}]},{"name":"CCC","sessions":[{"student_name":"CCC","minutes":10}]}]}')
17
17
 
18
18
  I.amAcceptingPopups()
19
- I.click('//*[@id="root.students.0"]/span[2]/button[contains(@class, "json-editor-btn-delete") and @data-i="0"]')
19
+ I.click('//*[@id="root.students.0"]/span[3]/button[contains(@class, "json-editor-btn-delete") and @data-i="0"]')
20
20
  I.retry({ retries: 5, minTimeout: 500 }).seeInPopup('Are you sure you want to remove this item?')
21
21
  I.acceptPopup()
22
22
 
@@ -58,7 +58,7 @@ Scenario('work with json-schema meta-schema @meta-schema-core', async ({ I }) =>
58
58
  // https://github.com/json-editor/json-editor/issues/823
59
59
  Scenario('work with json-schema meta-schema @meta-schema', async ({ I }) => {
60
60
  I.amOnPage('issues/issue-gh-823-meta-schema.html')
61
- I.waitForElement('[data-schemapath="root"] h3', DEFAULT_WAIT_TIME)
61
+ I.waitForElement('[data-schemapath="root"] span', DEFAULT_WAIT_TIME)
62
62
  I.click('Object Properties')
63
63
  I.click('options')
64
64
  I.see('$ref')
@@ -6,7 +6,7 @@ Feature('schemaloader')
6
6
 
7
7
  Scenario('resolving nested external URNs', async ({ I }) => {
8
8
  I.amOnPage('urn.html')
9
- I.waitForElement('[data-schemapath="root"] h3', DEFAULT_WAIT_TIME)
9
+ I.waitForElement('[data-schemapath="root"] span', DEFAULT_WAIT_TIME)
10
10
  I.seeElementInDOM('[data-schemapath="root.fname"]')
11
11
  I.seeElementInDOM('[data-schemapath="root.lname"]')
12
12
  I.click('.get-value')
@@ -1,5 +1,5 @@
1
1
  <!DOCTYPE html>
2
- <html>
2
+ <html lang="en">
3
3
  <head>
4
4
  <meta charset="utf-8" />
5
5
  <title>Advanced JSON Editor Example</title>
@@ -10,6 +10,7 @@
10
10
  <body>
11
11
 
12
12
  <div class="container">
13
+ <h1>Test</h1>
13
14
  <label for="value">Value</label>
14
15
  <textarea class="form-control" id="value" rows="12" style="font-size: 12px; font-family: monospace;"></textarea>
15
16
  <button id='set-value'>Set Value</button>
@@ -1,5 +1,5 @@
1
1
  <!DOCTYPE html>
2
- <html>
2
+ <html lang="en">
3
3
  <head>
4
4
  <meta charset="utf-8"/>
5
5
  <title>anyOf</title>
@@ -10,7 +10,9 @@
10
10
  <body>
11
11
 
12
12
  <div class="container">
13
- <textarea class="value form-control" rows="10"></textarea>
13
+ <h1>Test</h1>
14
+ <label for="value">value</label>
15
+ <textarea id="value" class="value form-control" rows="10"></textarea>
14
16
  <button class='get-value'>Get Value</button>
15
17
  <button class='set-value'>Set Value</button>
16
18
  <div class='json-editor-container'></div>
@@ -1,12 +1,15 @@
1
1
  <!DOCTYPE html>
2
- <html>
2
+ <html lang="en">
3
3
  <head>
4
+ <title>array anyof</title>
4
5
  <meta charset="utf-8"/>
5
6
  <script src="../../dist/jsoneditor.js"></script>
6
7
  </head>
7
8
  <body>
8
9
 
9
- <textarea class="debug" cols="30" rows="10"></textarea>
10
+ <h1>Test</h1>
11
+ <label for="debug">Value</label>
12
+ <textarea id="debug" class="debug" cols="30" rows="10"></textarea>
10
13
  <button class='get-value'>Get Value</button>
11
14
  <div class='container'></div>
12
15
 
@@ -1,12 +1,15 @@
1
1
  <!DOCTYPE html>
2
- <html>
2
+ <html lang="en">
3
3
  <head>
4
+ <title>array checkboxes infotext</title>
4
5
  <meta charset="utf-8"/>
5
6
  <script src="../../dist/jsoneditor.js"></script>
6
7
  </head>
7
8
  <body>
8
9
 
9
- <textarea class="debug" cols="30" rows="10"></textarea>
10
+ <h1>Test</h1>
11
+ <label for="debug">Value</label>
12
+ <textarea id="debug" class="debug" cols="30" rows="10"></textarea>
10
13
  <button class='get-value'>Get Value</button>
11
14
  <div class='container'></div>
12
15
 
@@ -1,12 +1,15 @@
1
1
  <!DOCTYPE html>
2
- <html>
2
+ <html lang="en">
3
3
  <head>
4
+ <title>array checkboxes</title>
4
5
  <meta charset="utf-8"/>
5
6
  <script src="../../dist/jsoneditor.js"></script>
6
7
  </head>
7
8
  <body>
8
9
 
9
- <textarea class="debug" cols="30" rows="10"></textarea>
10
+ <h1>Test</h1>
11
+ <label for="debug">Value</label>
12
+ <textarea id="debug" class="debug" cols="30" rows="10"></textarea>
10
13
  <button class='get-value'>Get Value</button>
11
14
  <div class='container'></div>
12
15
 
@@ -1,6 +1,7 @@
1
1
  <!DOCTYPE html>
2
- <html>
2
+ <html lang="en">
3
3
  <head>
4
+ <title>Array choices</title>
4
5
  <meta charset="utf-8"/>
5
6
  <script src="../../dist/jsoneditor.js"></script>
6
7
  <link rel="stylesheet" href="../../dist/css/jsoneditor.min.css">
@@ -9,7 +10,9 @@
9
10
  </head>
10
11
  <body>
11
12
 
12
- <textarea class="debug" cols="30" rows="10"></textarea>
13
+ <h1>Test</h1>
14
+ <label for="debug">Value</label>
15
+ <textarea id="debug" class="debug" cols="30" rows="10"></textarea>
13
16
  <button class='get-value'>Get Value</button>
14
17
  <div class='container'></div>
15
18