@json-editor/json-editor 2.5.4 → 2.7.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.
Files changed (91) hide show
  1. package/.github/workflows/build.yml +12 -3
  2. package/CHANGELOG.md +51 -14
  3. package/README.md +159 -20
  4. package/dist/jsoneditor.js +2 -2
  5. package/dist/nonmin/jsoneditor.js +5483 -3610
  6. package/dist/nonmin/jsoneditor.js.map +1 -1
  7. package/docs/cleave.html +1 -1
  8. package/docs/datetime.html +1 -1
  9. package/docs/describedby.html +1 -1
  10. package/docs/form-submission.html +76 -0
  11. package/docs/index.html +2 -2
  12. package/docs/materialize_css.html +1 -1
  13. package/docs/meta_schema.json +0 -1
  14. package/docs/radio.html +1 -1
  15. package/docs/select2.html +1 -1
  16. package/docs/selectize.html +1 -1
  17. package/docs/starrating.html +1 -1
  18. package/docs/wysiwyg.html +1 -1
  19. package/package.json +28 -26
  20. package/release-notes.md +5 -3
  21. package/src/core.js +36 -37
  22. package/src/defaults.js +9 -2
  23. package/src/editor.js +6 -2
  24. package/src/editors/array.js +12 -1
  25. package/src/editors/autocomplete.js +4 -3
  26. package/src/editors/button.js +1 -1
  27. package/src/editors/multiple.js +2 -0
  28. package/src/editors/multiselect.js +14 -5
  29. package/src/editors/object.js +10 -6
  30. package/src/editors/radio.js +6 -1
  31. package/src/editors/string.js +7 -1
  32. package/src/editors/table.js +21 -2
  33. package/src/editors/upload.js +1 -1
  34. package/src/editors/uuid.js +2 -12
  35. package/src/iconlib.js +1 -1
  36. package/src/schemaloader.js +232 -109
  37. package/src/style.css +3 -0
  38. package/src/style.css.js +1 -1
  39. package/src/theme.js +5 -4
  40. package/src/themes/bootstrap3.js +3 -2
  41. package/src/themes/bootstrap4.js +7 -0
  42. package/src/themes/spectre.js +2 -1
  43. package/src/utilities.js +18 -0
  44. package/src/validator.js +65 -47
  45. package/tests/codeceptjs/codecept.json +1 -1
  46. package/tests/codeceptjs/core_test.js +98 -0
  47. package/tests/codeceptjs/editors/advanced_test.js +1 -1
  48. package/tests/codeceptjs/editors/array_test.js +74 -0
  49. package/tests/codeceptjs/editors/autocomplete_test.js +16 -0
  50. package/tests/codeceptjs/editors/button_test.js +11 -4
  51. package/tests/codeceptjs/editors/integer_test.js +7 -2
  52. package/tests/codeceptjs/editors/jodit_test.js +3 -3
  53. package/tests/codeceptjs/editors/object_test.js +84 -13
  54. package/tests/codeceptjs/editors/range_test.js +12 -0
  55. package/tests/codeceptjs/editors/stepper_test.js +12 -0
  56. package/tests/codeceptjs/editors/uuid_test.js +31 -4
  57. package/tests/codeceptjs/editors/validation_test.js +1 -1
  58. package/tests/docker-compose.yml +1 -1
  59. package/tests/fixtures/definitions.json +22 -0
  60. package/tests/fixtures/properties.json +20 -0
  61. package/tests/fixtures/validation.json +207 -0
  62. package/tests/pages/array-checkboxes-infotext.html +52 -0
  63. package/tests/pages/array-move-events.html +4 -2
  64. package/tests/pages/array-unique-items-sort.html +78 -0
  65. package/tests/pages/autocomplete.html +69 -0
  66. package/tests/pages/button-icons.html +38 -0
  67. package/tests/pages/core.html +4 -2
  68. package/tests/pages/error-messages.html +47 -0
  69. package/tests/pages/grid-strict.html +6 -10
  70. package/tests/pages/grid.html +0 -4
  71. package/tests/pages/issues/issue-gh-812.html +4 -2
  72. package/tests/pages/meta_schema.json +14 -1
  73. package/tests/pages/object-required-properties.html +37 -14
  74. package/tests/pages/object-show-opt-in.html +110 -0
  75. package/tests/pages/object-with-dependencies-array.html +29 -19
  76. package/tests/pages/range.html +60 -0
  77. package/tests/pages/ready.html +43 -0
  78. package/tests/pages/references.html +162 -0
  79. package/tests/pages/stepper-manual.html +57 -0
  80. package/tests/pages/string-simplemde-editor.html +81 -0
  81. package/tests/pages/table-move-events.html +4 -1
  82. package/tests/pages/urn.html +11 -8
  83. package/tests/pages/uuid.html +89 -50
  84. package/tests/pages/validation-messages.json +705 -0
  85. package/tests/unit/core.spec.js +79 -66
  86. package/tests/unit/editor.spec.js +20 -8
  87. package/tests/unit/editors/array.spec.js +3 -2
  88. package/tests/unit/editors/object.spec.js +3 -1
  89. package/tests/unit/editors/table.spec.js +4 -2
  90. package/tests/unit/schemaloader.spec.js +77 -105
  91. package/tests/unit/validator.spec.js +10 -0
@@ -0,0 +1,16 @@
1
+ /* global Feature Scenario */
2
+
3
+ var assert = require('assert')
4
+
5
+ Feature('autocomplete')
6
+
7
+ Scenario('autocomplete should work @autocomplete', async (I) => {
8
+ I.amOnPage('autocomplete.html')
9
+ I.waitForElement('.je-ready', 10)
10
+ I.fillField('root', 'ir')
11
+ I.waitForText('iran', 10, '.autocomplete-result-list')
12
+ I.waitForText('iraq', 10, '.autocomplete-result-list')
13
+ I.click('iraq', '.autocomplete-result:nth-child(2)')
14
+ I.wait(1)
15
+ assert.equal(await I.grabValueFrom('.value'), '"iraq"')
16
+ })
@@ -4,6 +4,7 @@ Feature('button');
4
4
 
5
5
  Scenario('should work with button editor callbacks', async (I) => {
6
6
  I.amOnPage('button-callbacks.html');
7
+ I.waitForElement('.je-ready', 10)
7
8
  I.seeElement('[data-schemapath="root.button1"] button');
8
9
  I.click('[data-schemapath="root.button1"] button');
9
10
  assert.equal(await I.grabValueFrom('.value'), 'button1CB');
@@ -11,11 +12,10 @@ Scenario('should work with button editor callbacks', async (I) => {
11
12
 
12
13
  Scenario('should work with option "validated"', async (I) => {
13
14
  I.amOnPage('button-callbacks.html');
15
+ I.waitForElement('.je-ready', 10)
14
16
  I.seeElement('[data-schemapath="root.button1"] button');
15
- I.seeDisabledAttribute('[data-schemapath="root.button2"] button');
16
-
17
+ I.retry({ retries: 3, minTimeout: 500 }).seeDisabledAttribute('[data-schemapath="root.button2"] button');
17
18
  await I.fillField('[name="root[textinput]"]', 'Hello World');
18
-
19
19
  I.pressKey('Tab');
20
20
  I.dontSeeDisabledAttribute('[data-schemapath="root.button2"] button');
21
21
  I.click('[data-schemapath="root.button2"] button');
@@ -24,12 +24,19 @@ Scenario('should work with option "validated"', async (I) => {
24
24
 
25
25
  Scenario('should not leave any footprints in result', async (I) => {
26
26
  I.amOnPage('button-callbacks.html');
27
+ I.waitForElement('.je-ready', 10)
27
28
  I.click('.get-value');
28
29
  assert.equal(await I.grabValueFrom('.value'), JSON.stringify({"textinput":""}));
29
30
  });
30
31
 
31
32
  Scenario('should be disabled if "readonly" is specified', async (I) => {
32
33
  I.amOnPage('read-only.html');
33
-
34
+ I.waitForElement('.je-ready', 10)
34
35
  I.seeDisabledAttribute('[data-schemapath="root.button"] button');
35
36
  });
37
+
38
+ Scenario('should set icon @button @button-icon', async (I) => {
39
+ I.amOnPage('button-icons.html')
40
+ I.waitForElement('.je-ready', 10)
41
+ I.waitForElement('i.fas.fa-search', 10)
42
+ });
@@ -67,10 +67,15 @@ Scenario('should be readonly if specified and not disabled', async (I) => {
67
67
  I.seeReadOnlyAttribute('[name="root[integer]"]');
68
68
  });
69
69
 
70
- Scenario('should update output when setValue is called', async (I) => {
70
+ Scenario('should update output when (method) setValue is called', async (I) => {
71
71
  I.amOnPage('integer.html');
72
+ I.saveScreenshot('integer-setvalue-1.png')
73
+ I.waitForText('5', 20, '[data-schemapath="root.integer_range"] output');
74
+ I.saveScreenshot('integer-setvalue-2.png')
72
75
  I.click('.set-value');
73
- I.see('2', '[data-schemapath="root.integer_range"] output');
76
+ I.saveScreenshot('integer-setvalue-3.png')
77
+ I.waitForText('2', 20, '[data-schemapath="root.integer_range"] output');
78
+ I.saveScreenshot('integer-setvalue-4.png')
74
79
  });
75
80
 
76
81
  Scenario('should validate value', async (I) => {
@@ -12,13 +12,13 @@ Scenario('should have coerent values', async (I) => {
12
12
  I.amOnPage('string-jodit-editor.html');
13
13
  I.click('Add item');
14
14
  I.see('item 1');
15
- I.seeElement('.jodit_wysiwyg');
15
+ I.seeElement('.jodit-wysiwyg_mode');
16
16
 
17
- I.click('.jodit_toolbar_btn-bold a');
17
+ I.click('.jodit-toolbar-button_bold button');
18
18
  I.pressKeys('__JODIT__');
19
19
  I.see('__JODIT__');
20
20
 
21
21
  I.click('.get-value');
22
- assert.equal(await I.grabValueFrom('.debug'), JSON.stringify([{"editor":"<strong>__JODIT__</strong>"}]));
22
+ assert.equal(await I.grabValueFrom('.debug'), JSON.stringify([{"editor":"<p><strong>__JODIT__</strong><br></p>"}]));
23
23
 
24
24
  });
@@ -68,16 +68,23 @@ Scenario('opt in optional properties @show_opt_in', async (I) => {
68
68
  // if an editor type "object" is disabled, also the child editors opt-in controls will be disabled.
69
69
  I.seeDisabledAttribute('[data-schemapath="root.object.number"] .json-editor-opt-in')
70
70
  I.seeDisabledAttribute('[data-schemapath="root.object.boolean"] .json-editor-opt-in')
71
+ I.seeDisabledAttribute('[data-schemapath="root.object.radio"] .json-editor-opt-in')
71
72
 
72
73
  // tests merged from master 17.9.2019
73
74
  I.dontSeeCheckedAttribute('[data-schemapath="root.string"] .json-editor-opt-in')
74
75
  I.dontSeeDisabledAttribute('[data-schemapath="root.string"] .json-editor-opt-in')
75
76
  I.seeDisabledAttribute('[name="root[string]"]')
77
+ I.dontSeeCheckedAttribute('[data-schemapath="root.radio"] .json-editor-opt-in')
78
+ I.dontSeeDisabledAttribute('[data-schemapath="root.radio"] .json-editor-opt-in')
79
+ I.seeDisabledAttribute('[id="root[radio][0]"]')
80
+ I.seeDisabledAttribute('[id="root[radio][1]"]')
76
81
  I.dontSeeCheckedAttribute('[data-schemapath="root.object.number"] .json-editor-opt-in')
77
82
  I.seeDisabledAttribute('[data-schemapath="root.object.number"] .json-editor-opt-in')
78
83
  I.seeDisabledAttribute('[name="root[object][number]"]')
79
84
  I.dontSeeCheckedAttribute('[data-schemapath="root.object.boolean"] .json-editor-opt-in')
80
85
  I.seeDisabledAttribute('[data-schemapath="root.object.boolean"] .json-editor-opt-in')
86
+ I.dontSeeCheckedAttribute('[data-schemapath="root.object.radio"] .json-editor-opt-in')
87
+ I.seeDisabledAttribute('[data-schemapath="root.object.radio"] .json-editor-opt-in')
81
88
 
82
89
  I.click('.get-value')
83
90
  assert.equal(await I.grabValueFrom('.value'), '{"number":0,"boolean":false}')
@@ -86,16 +93,22 @@ Scenario('opt in optional properties @show_opt_in', async (I) => {
86
93
 
87
94
  I.click('[data-schemapath="root"] .json-editor-btn-edit')
88
95
  I.click('[data-schemapath="root"] .json-editor-btn-edit')
89
-
90
96
  I.dontSeeCheckedAttribute('[data-schemapath="root.string"] .json-editor-opt-in')
91
97
  I.dontSeeDisabledAttribute('[data-schemapath="root.string"] .json-editor-opt-in')
92
98
  I.seeDisabledAttribute('[name="root[string]"]')
99
+ I.dontSeeCheckedAttribute('[data-schemapath="root.radio"] .json-editor-opt-in')
100
+ I.dontSeeDisabledAttribute('[data-schemapath="root.radio"] .json-editor-opt-in')
101
+ I.seeDisabledAttribute('[id="root[radio][0]"]')
102
+ I.seeDisabledAttribute('[id="root[radio][1]"]')
93
103
  I.dontSeeCheckedAttribute('[data-schemapath="root.object.number"] .json-editor-opt-in')
94
104
  I.seeDisabledAttribute('[data-schemapath="root.object.number"] .json-editor-opt-in')
95
105
  I.seeDisabledAttribute('[name="root[object][number]"]')
96
106
  I.dontSeeCheckedAttribute('[data-schemapath="root.object.boolean"] .json-editor-opt-in')
97
107
  I.seeDisabledAttribute('[data-schemapath="root.object.boolean"] .json-editor-opt-in')
98
108
  I.seeDisabledAttribute('[name="root[object][boolean]"]')
109
+ I.seeDisabledAttribute('[data-schemapath="root.object.boolean"] .json-editor-opt-in')
110
+ I.dontSeeCheckedAttribute('[data-schemapath="root.object.radio"] .json-editor-opt-in')
111
+ I.seeDisabledAttribute('[data-schemapath="root.object.radio"] .json-editor-opt-in')
99
112
 
100
113
  I.click('.get-value')
101
114
  assert.equal(await I.grabValueFrom('.value'), '{"number":0,"boolean":false}')
@@ -103,24 +116,26 @@ Scenario('opt in optional properties @show_opt_in', async (I) => {
103
116
  // opt-in string property
104
117
 
105
118
  I.click('[data-schemapath="root.string"] .json-editor-opt-in')
119
+ I.click('[data-schemapath="root.radio"] .json-editor-opt-in')
106
120
  I.click('.get-value')
107
- assert.equal(await I.grabValueFrom('.value'), '{"string":"","number":0,"boolean":false}')
121
+ assert.equal(await I.grabValueFrom('.value'), '{"string":"","number":0,"boolean":false,"radio":"Home"}')
108
122
 
109
123
  // opt-in array property
110
124
 
111
125
  I.click('[data-schemapath="root.array"] .json-editor-opt-in')
112
126
  I.click('.get-value')
113
- assert.equal(await I.grabValueFrom('.value'), '{"string":"","number":0,"boolean":false,"array":[]}')
127
+ assert.equal(await I.grabValueFrom('.value'), '{"string":"","number":0,"boolean":false,"radio":"Home","array":[]}')
114
128
 
115
129
  // opt-in object property
116
130
 
117
131
  I.click('[data-schemapath="root.object"] .json-editor-opt-in')
118
132
  I.click('.get-value')
119
- assert.equal(await I.grabValueFrom('.value'), '{"string":"","number":0,"boolean":false,"array":[],"object":{"string":"","array":[]}}')
133
+ assert.equal(await I.grabValueFrom('.value'), '{"string":"","number":0,"boolean":false,"radio":"Home","array":[],"object":{"string":"","array":[]}}')
120
134
 
121
135
  // if an editor type "object" is enabled, also the child editors opt-in controls will be enabled.
122
136
  I.dontSeeDisabledAttribute('[data-schemapath="root.object.number"] .json-editor-opt-in')
123
137
  I.dontSeeDisabledAttribute('[data-schemapath="root.object.boolean"] .json-editor-opt-in')
138
+ I.dontSeeDisabledAttribute('[data-schemapath="root.object.radio"] .json-editor-opt-in')
124
139
  })
125
140
 
126
141
  Scenario('set value opt in optional properties @show_opt_in', async (I) => {
@@ -130,11 +145,13 @@ Scenario('set value opt in optional properties @show_opt_in', async (I) => {
130
145
  I.waitForElement('[data-schemapath="root.string"]', 5)
131
146
  I.waitForElement('[data-schemapath="root.number"]', 5)
132
147
  I.waitForElement('[data-schemapath="root.boolean"]', 5)
148
+ I.waitForElement('[data-schemapath="root.radio"]', 5)
133
149
  I.waitForElement('[data-schemapath="root.array"]', 5)
134
150
  I.waitForElement('[data-schemapath="root.object"]', 5)
135
151
  I.waitForElement('[data-schemapath="root.object.string"]', 5)
136
152
  I.waitForElement('[data-schemapath="root.object.number"]', 5)
137
153
  I.waitForElement('[data-schemapath="root.object.boolean"]', 5)
154
+ I.waitForElement('[data-schemapath="root.object.radio"]', 5)
138
155
 
139
156
  // set values
140
157
  I.click('.set-value')
@@ -150,11 +167,45 @@ Scenario('set value opt in optional properties @show_opt_in', async (I) => {
150
167
  I.waitForElement('[data-schemapath="root.string"]', 5)
151
168
  I.waitForElement('[data-schemapath="root.number"]', 5)
152
169
  I.waitForElement('[data-schemapath="root.boolean"]', 5)
170
+ I.waitForElement('[data-schemapath="root.radio"]', 5)
153
171
  I.waitForElement('[data-schemapath="root.array"]', 5)
154
172
  I.waitForElement('[data-schemapath="root.object"]', 5)
155
173
  I.waitForElement('[data-schemapath="root.object.string"]', 5)
156
174
  I.waitForElement('[data-schemapath="root.object.number"]', 5)
157
175
  I.waitForElement('[data-schemapath="root.object.boolean"]', 5)
176
+ I.waitForElement('[data-schemapath="root.object.radio"]', 5)
177
+ })
178
+
179
+ Scenario('set value opt in optional properties @show_opt_in_schema', async (I) => {
180
+ I.amOnPage('object-show-opt-in.html')
181
+
182
+ // all editors visible
183
+ I.waitForElement('[data-schemapath="root"]', 5)
184
+ I.waitForElement('[data-schemapath="root.option_show_opt_in_undefined"]', 5)
185
+ I.waitForElement('[data-schemapath="root.option_show_opt_in_undefined.string"]', 5)
186
+ I.waitForElement('[data-schemapath="root.option_show_opt_in_true"]', 5)
187
+ I.waitForElement('[data-schemapath="root.option_show_opt_in_true.string"]', 5)
188
+ I.waitForElement('[data-schemapath="root.option_show_opt_in_false"]', 5)
189
+ I.waitForElement('[data-schemapath="root.option_show_opt_in_false.string"]', 5)
190
+
191
+ // checkboxes for optional properties should appear only when
192
+ // case 1) the parent option show_opt_in is enabled
193
+ // OR
194
+ // case 2) the parent option show_opt_in is disabled and the global option show_opt_in is enabled
195
+ // OR
196
+ // case 3) the parent option show_opt_in is not defined and the global option show_opt_in is enabled
197
+
198
+ // global show_opt_in true
199
+ I.dontSeeCheckedAttribute('#show-opt-in')
200
+ I.dontSeeElement('[data-schemapath="root.option_show_opt_in_undefined.string"] .json-editor-opt-in') // global show_opt_in: false && parent editor show_opt_in: 'undefined'
201
+ I.waitForElement('[data-schemapath="root.option_show_opt_in_true.string"] .json-editor-opt-in', 5) // global show_opt_in: false && parent editor show_opt_in: true
202
+ I.dontSeeElement('[data-schemapath="root.option_show_opt_in_false.string"] .json-editor-opt-in') // global show_opt_in: false && parent editor show_opt_in: false
203
+
204
+ // global show_opt_in false
205
+ I.click('#show-opt-in')
206
+ I.waitForElement('[data-schemapath="root.option_show_opt_in_undefined.string"] .json-editor-opt-in') // global show_opt_in: true && parent editor show_opt_in: 'undefined'
207
+ I.waitForElement('[data-schemapath="root.option_show_opt_in_true.string"] .json-editor-opt-in', 5) // global show_opt_in: true && parent editor show_opt_in: true
208
+ I.dontSeeElement('[data-schemapath="root.option_show_opt_in_false.string"] .json-editor-opt-in') // global show_opt_in: true && parent editor show_opt_in: false
158
209
  })
159
210
 
160
211
  Scenario('objects should contain properties defined with the properties keyword unless the property "additionalProperties: true" is specified in the object schema @additional-properties', async (I) => {
@@ -180,7 +231,7 @@ Scenario('should have unique ids', (I) => {
180
231
  I.waitForText('i am actually a cat')
181
232
  })
182
233
 
183
- Scenario('should hide properties with unfulfilled dependencies', (I) => {
234
+ Scenario('should hide properties with unfulfilled dependencies @dependencies', (I) => {
184
235
  I.amOnPage('object-with-dependencies.html')
185
236
  I.seeElement('[data-schemapath="root.enable_option"] input')
186
237
  I.dontSeeElement('[data-schemapath="root.make_new"] input')
@@ -192,13 +243,33 @@ Scenario('should hide properties with unfulfilled dependencies', (I) => {
192
243
  I.dontSeeElement('[data-schemapath="root.existing_name"] input')
193
244
  })
194
245
 
195
- Scenario('should respect multiple dependency values', (I) => {
246
+ Scenario('should respect multiple dependency values @dependencies', (I) => {
196
247
  I.amOnPage('object-with-dependencies-array.html')
197
- I.waitForVisible('[data-schemapath="root.answerB"] input', 5)
198
- I.selectOption('[name="root[answerA]"]', 'C')
199
- I.waitForInvisible('[data-schemapath="root.answerB"] input', 5)
200
- I.selectOption('[name="root[answerA]"]', 'B')
201
- I.waitForVisible('[data-schemapath="root.answerB"] input', 5)
202
- I.selectOption('[name="root[answerA]"]', 'A')
203
- I.waitForVisible('[data-schemapath="root.answerB"] input', 5)
248
+ I.waitForVisible('[data-schemapath="root.question_1"] select', 5)
249
+ I.selectOption('[name="root[question_1]"]', 'a')
250
+ I.waitForInvisible('[data-schemapath="root.question_1_feedback"]', 5)
251
+ I.selectOption('[name="root[question_1]"]', 'b')
252
+ I.waitForVisible('[data-schemapath="root.question_1_feedback"]', 5)
253
+ I.selectOption('[name="root[question_1]"]', 'c')
254
+ I.waitForInvisible('[data-schemapath="root.question_1_feedback"]', 5)
255
+ I.selectOption('[name="root[question_1]"]', 'd')
256
+ I.waitForVisible('[data-schemapath="root.question_1_feedback"]', 5)
257
+
258
+ I.waitForVisible('[data-schemapath="root.question_2"]', 5)
259
+ I.waitForInvisible('[data-schemapath="root.question_2_feedback"]', 5)
260
+ I.click('label[for="root[question_2]1"]')
261
+ I.click('label[for="root[question_2]2"]')
262
+ I.waitForVisible('[data-schemapath="root.question_2_feedback"]', 5)
263
+ I.click('label[for="root[question_2]0"]')
264
+ I.click('label[for="root[question_2]3"]')
265
+ I.waitForInvisible('[data-schemapath="root.question_2_feedback"]', 5)
266
+ })
267
+
268
+ Scenario('should open and close the properties modal', (I) => {
269
+ I.amOnPage('object.html')
270
+ I.seeElement('.json-editor-btn-edit_properties')
271
+ I.click('.json-editor-btn-edit_properties')
272
+ I.seeElement('.je-modal .property-selector')
273
+ I.click('textarea')
274
+ I.dontSeeElement('.je-modal .property-selector')
204
275
  })
@@ -0,0 +1,12 @@
1
+ /* global Feature Scenario */
2
+
3
+ var assert = require('assert')
4
+
5
+ Feature('range')
6
+
7
+ Scenario('should have and display initial value @range', async (I) => {
8
+ I.amOnPage('range.html')
9
+ I.click('.get-value')
10
+ assert.equal(await I.grabValueFrom('.value'), '{"speed":1}')
11
+ I.waitForText('1', 5, 'output')
12
+ })
@@ -25,3 +25,15 @@ Scenario('should be constrained to maximun and minimun values when stepped @step
25
25
  I.click('.get-value')
26
26
  assert.equal(await I.grabValueFrom('.value'), '{"stepper":5}')
27
27
  })
28
+
29
+ Scenario('should be correct initialized when manually set @stepper', async (I) => {
30
+ I.amOnPage('stepper-manual.html')
31
+ I.fillField('[name="root[stepper]"]', 10)
32
+ I.click('.stepper-up')
33
+ I.click('.get-value')
34
+ assert.equal(await I.grabValueFrom('.value'), '{"stepper":11}')
35
+ I.click('.stepper-down')
36
+ I.click('.stepper-down')
37
+ I.click('.get-value')
38
+ assert.equal(await I.grabValueFrom('.value'), '{"stepper":9}')
39
+ })
@@ -12,10 +12,37 @@ Scenario('should have initial value matching uuid @uuid', async (I) => {
12
12
  })
13
13
 
14
14
  Scenario('should have initial value matching uuid in arrays @uuid', async (I) => {
15
- I.click('Add item')
16
- I.click('Add item')
17
- const value0 = await I.grabValueFrom('[name="root[uuidArray][0][uuid]"]')
15
+ I.click('Add uuid string array item')
16
+ I.click('Add uuid string array item')
17
+ const value0 = await I.grabValueFrom('[name="root[uuidStringArray][0]"]')
18
18
  assert.equal((/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(value0)), true)
19
- const value1 = await I.grabValueFrom('[name="root[uuidArray][1][uuid]"]')
19
+ const value1 = await I.grabValueFrom('[name="root[uuidStringArray][1]"]')
20
20
  assert.equal((/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(value1)), true)
21
21
  })
22
+
23
+ Scenario('should have initial value matching uuid in arrays of objects with @uuid', async (I) => {
24
+ I.click('Add uuid object array item')
25
+ I.click('Add uuid object array item')
26
+ const value0 = await I.grabValueFrom('[name="root[uuidObjectArray][0][uuid]"]')
27
+ assert.equal((/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(value0)), true)
28
+ const value1 = await I.grabValueFrom('[name="root[uuidObjectArray][1][uuid]"]')
29
+ assert.equal((/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(value1)), true)
30
+ })
31
+
32
+ Scenario('should have initial value matching uuid in arrays (table) of strings with @uuid', async (I) => {
33
+ I.click('Add uuid string table item')
34
+ I.click('Add uuid string table item')
35
+ const value0 = await I.grabValueFrom('[name="root[uuidStringTable][0]')
36
+ assert.equal((/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(value0)), true)
37
+ const value1 = await I.grabValueFrom('[name="root[uuidStringTable][1]')
38
+ assert.equal((/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(value1)), true)
39
+ })
40
+
41
+ Scenario('should have initial value matching uuid in arrays (table) of objects with @uuid', async (I) => {
42
+ I.click('Add uuid object table item')
43
+ I.click('Add uuid object table item')
44
+ const value0 = await I.grabValueFrom('[name="root[uuidObjectTable][0][uuid]"]')
45
+ assert.equal((/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(value0)), true)
46
+ const value1 = await I.grabValueFrom('[name="root[uuidObjectTable][1][uuid]"]')
47
+ assert.equal((/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(value1)), true)
48
+ })
@@ -6,7 +6,7 @@ Feature('Validations')
6
6
 
7
7
  Scenario('test validations in validation.html', (I) => {
8
8
  I.amOnPage('validation.html')
9
- var numberOfTestItemsExpected = 152
9
+ var numberOfTestItemsExpected = 158
10
10
  I.waitForElement('#output div:nth-child(' + numberOfTestItemsExpected + ')', 10)
11
11
  I.seeNumberOfElements('#output div', numberOfTestItemsExpected)
12
12
  I.see('success')
@@ -11,7 +11,7 @@ services:
11
11
  expose:
12
12
  - '9001'
13
13
  firefox:
14
- image: selenium/standalone-firefox-debug:3.141.59-20200525
14
+ image: selenium/standalone-firefox-debug:3.141.59-20210929
15
15
  depends_on:
16
16
  - node
17
17
  environment:
@@ -0,0 +1,22 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft-04/schema",
3
+ "title": "Reusable Definitions",
4
+ "type": "object",
5
+ "id": "https://raw.githubusercontent.com/json-editor/json-editor/master/tests/fixtures/definitions.json",
6
+ "definitions": {
7
+ "address": {
8
+ "title": "Address",
9
+ "type": "object",
10
+ "properties": {
11
+ "street_address": { "type": "string" },
12
+ "city": { "type": "string" },
13
+ "state": { "type": "string" }
14
+ },
15
+ "required": ["street_address"]
16
+ },
17
+ "link" : {"$refs": "./properties.json#/properties/title"}
18
+ },
19
+ "properties": {
20
+ "address" : {"$refs": "#/definitions/address"}
21
+ }
22
+ }
@@ -0,0 +1,20 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-04/schema#",
3
+ "category": "atom",
4
+ "title": "Link",
5
+ "entity": "link",
6
+ "type": "object",
7
+ "format": "grid",
8
+ "properties": {
9
+ "href": {
10
+ "title": "URL",
11
+ "type": "string",
12
+ "format": "url"
13
+ },
14
+ "title": {
15
+ "title": "Title attribute",
16
+ "description": "Shown on mouseover.",
17
+ "type": "string"
18
+ }
19
+ }
20
+ }
@@ -1136,5 +1136,212 @@
1136
1136
  "charlie": { "type": "string" }
1137
1137
  }
1138
1138
  ]
1139
+ },
1140
+ "nested_anyOf": {
1141
+ "schema": {
1142
+ "type": "object",
1143
+ "properties": {
1144
+ "prop": {
1145
+ "anyOf": [
1146
+ {
1147
+ "$ref": "#/definitions/A"
1148
+ },
1149
+ {
1150
+ "$ref": "#/definitions/B"
1151
+ }
1152
+ ]
1153
+ }
1154
+ },
1155
+ "definitions": {
1156
+ "A": {
1157
+ "title": "A",
1158
+ "type": "object",
1159
+ "properties": {
1160
+ "fooA": {
1161
+ "type": "string"
1162
+ },
1163
+ "barA": {
1164
+ "type": "string"
1165
+ },
1166
+ "common": {
1167
+ "type": "string"
1168
+ }
1169
+ },
1170
+ "required": [
1171
+ "fooA",
1172
+ "barA"
1173
+ ]
1174
+ },
1175
+ "B": {
1176
+ "title": "B",
1177
+ "anyOf": [
1178
+ {
1179
+ "$ref": "#/definitions/C"
1180
+ },
1181
+ {
1182
+ "$ref": "#/definitions/D"
1183
+ }
1184
+ ]
1185
+ },
1186
+ "C": {
1187
+ "title": "C",
1188
+ "type": "object",
1189
+ "properties": {
1190
+ "fooC": {
1191
+ "type": "string"
1192
+ },
1193
+ "barC": {
1194
+ "type": "string"
1195
+ },
1196
+ "common": {
1197
+ "type": "string"
1198
+ }
1199
+ },
1200
+ "required": [
1201
+ "fooC",
1202
+ "barC"
1203
+ ]
1204
+ },
1205
+ "D": {
1206
+ "title": "D",
1207
+ "type": "object",
1208
+ "properties": {
1209
+ "fooD": {
1210
+ "type": "string"
1211
+ },
1212
+ "barD": {
1213
+ "type": "string"
1214
+ }
1215
+ },
1216
+ "required": [
1217
+ "fooD",
1218
+ "barD"
1219
+ ]
1220
+ }
1221
+ }
1222
+ },
1223
+ "valid": [
1224
+ {
1225
+ "prop": {
1226
+ "fooC": "foo",
1227
+ "barC": "bar",
1228
+ "common": "common"
1229
+ }
1230
+ },
1231
+ {
1232
+ "prop": {
1233
+ "fooD": "foo",
1234
+ "barD": "bar",
1235
+ "common": "common"
1236
+ }
1237
+ },
1238
+ {
1239
+ "prop": {
1240
+ "fooA": "foo",
1241
+ "barA": "bar",
1242
+ "common": "common"
1243
+ }
1244
+ }
1245
+ ],
1246
+ "invalid": [
1247
+ {
1248
+ "prop": {
1249
+ "common": "common"
1250
+ }
1251
+ }
1252
+ ]
1253
+ },
1254
+ "anyOf_invalid_better_fit_test": {
1255
+ "schema": {
1256
+ "type": "object",
1257
+ "properties": {
1258
+ "foo": {
1259
+ "anyOf": [
1260
+ {
1261
+ "$ref": "#/definitions/A"
1262
+ },
1263
+ {
1264
+ "$ref": "#/definitions/B"
1265
+ }
1266
+ ]
1267
+ }
1268
+ },
1269
+ "definitions": {
1270
+ "A": {
1271
+ "type": "object",
1272
+ "properties": {
1273
+ "type": {
1274
+ "enum": [
1275
+ "A"
1276
+ ],
1277
+ "type": "string"
1278
+ },
1279
+ "referenced": {
1280
+ "$ref": "#/definitions/ReferencedObject"
1281
+ }
1282
+ },
1283
+ "required": [
1284
+ "type"
1285
+ ]
1286
+ },
1287
+ "B": {
1288
+ "type": "object",
1289
+ "properties": {
1290
+ "type": {
1291
+ "enum": [
1292
+ "B"
1293
+ ],
1294
+ "type": "string"
1295
+ },
1296
+ "referenced": {
1297
+ "properties": {
1298
+ "foo": {
1299
+ "type": "string"
1300
+ },
1301
+ "bar": {
1302
+ "type": "string"
1303
+ }
1304
+ },
1305
+ "type": "object"
1306
+ }
1307
+ },
1308
+ "required": [
1309
+ "type"
1310
+ ]
1311
+ },
1312
+ "ReferencedObject": {
1313
+ "properties": {
1314
+ "foo": {
1315
+ "type": "string"
1316
+ },
1317
+ "bar": {
1318
+ "type": "string"
1319
+ }
1320
+ },
1321
+ "type": "object"
1322
+ }
1323
+ }
1324
+ },
1325
+ "valid": [
1326
+ {
1327
+ "foo": {
1328
+ "type": "A",
1329
+ "referenced": {
1330
+ "foo": "",
1331
+ "bar": ""
1332
+ }
1333
+ }
1334
+ },
1335
+ {
1336
+ "foo": {
1337
+ "type": "B",
1338
+ "referenced": {
1339
+ "foo": "",
1340
+ "bar": ""
1341
+ }
1342
+ }
1343
+ }
1344
+ ],
1345
+ "invalid": []
1139
1346
  }
1140
1347
  }