@json-editor/json-editor 2.5.2 → 2.6.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 (99) hide show
  1. package/.eslintrc +5 -2
  2. package/.github/PULL_REQUEST_TEMPLATE.md +6 -6
  3. package/.github/workflows/build.yml +58 -0
  4. package/CHANGELOG.md +41 -1
  5. package/CONTRIBUTING.md +1 -1
  6. package/README.md +39 -4
  7. package/README_ADDON.md +65 -0
  8. package/config/codeceptjs_helpers.js +4 -0
  9. package/dist/jsoneditor.js +2 -2
  10. package/dist/nonmin/jsoneditor.js +3711 -3324
  11. package/dist/nonmin/jsoneditor.js.map +1 -1
  12. package/docs/cleave.html +1 -1
  13. package/docs/datetime.html +1 -1
  14. package/docs/describedby.html +1 -1
  15. package/docs/index.html +4 -2
  16. package/docs/materialize_css.html +1 -1
  17. package/docs/meta_schema.json +0 -1
  18. package/docs/radio.html +1 -1
  19. package/docs/select2.html +1 -1
  20. package/docs/selectize.html +1 -1
  21. package/docs/starrating.html +1 -1
  22. package/docs/wysiwyg.html +1 -1
  23. package/package.json +27 -26
  24. package/release-notes.md +9 -9
  25. package/src/core.js +1 -0
  26. package/src/defaults.js +182 -94
  27. package/src/editor.js +28 -9
  28. package/src/editors/array.js +20 -16
  29. package/src/editors/autocomplete.js +1 -0
  30. package/src/editors/base64.js +5 -4
  31. package/src/editors/button.js +2 -2
  32. package/src/editors/checkbox.js +3 -3
  33. package/src/editors/datetime.js +2 -2
  34. package/src/editors/info.js +1 -1
  35. package/src/editors/multiple.js +8 -2
  36. package/src/editors/multiselect.js +5 -3
  37. package/src/editors/object.js +35 -21
  38. package/src/editors/radio.js +9 -4
  39. package/src/editors/select.js +6 -6
  40. package/src/editors/signature.js +3 -2
  41. package/src/editors/starrating.js +5 -5
  42. package/src/editors/string.js +6 -4
  43. package/src/editors/table.js +24 -14
  44. package/src/editors/upload.js +4 -3
  45. package/src/editors/uuid.js +1 -1
  46. package/src/iconlibs/index.js +2 -0
  47. package/src/iconlibs/openiconic.js +28 -0
  48. package/src/schemaloader.js +112 -28
  49. package/src/theme.js +6 -3
  50. package/src/themes/bootstrap3.js +4 -4
  51. package/src/themes/bootstrap4.js +11 -3
  52. package/src/themes/html.js +1 -2
  53. package/src/themes/materialize.js +1 -1
  54. package/src/themes/spectre.js +11 -8
  55. package/src/themes/tailwind.js +1 -1
  56. package/src/validator.js +128 -16
  57. package/tests/codeceptjs/core_test.js +125 -1
  58. package/tests/codeceptjs/editors/array_test.js +13 -11
  59. package/tests/codeceptjs/editors/button_test.js +6 -1
  60. package/tests/codeceptjs/editors/issues/issue-gh-812_test.js +32 -0
  61. package/tests/codeceptjs/editors/number_test.js +1 -1
  62. package/tests/codeceptjs/editors/object_test.js +216 -100
  63. package/tests/codeceptjs/editors/programmatic-changes_test.js +3 -1
  64. package/tests/codeceptjs/editors/radio_test.js +10 -0
  65. package/tests/codeceptjs/editors/rating_test.js +10 -11
  66. package/tests/codeceptjs/editors/select_test.js +17 -15
  67. package/tests/codeceptjs/editors/stepper_test.js +13 -1
  68. package/tests/codeceptjs/editors/string_test.js +81 -80
  69. package/tests/codeceptjs/editors/table-confirm-delete_test.js +58 -56
  70. package/tests/codeceptjs/editors/tabs_test.js +12 -10
  71. package/tests/codeceptjs/editors/validation_test.js +10 -8
  72. package/tests/codeceptjs/meta-schema_test.js +13 -14
  73. package/tests/codeceptjs/schemaloader_test.js +13 -0
  74. package/tests/codeceptjs/steps_file.js +4 -3
  75. package/tests/codeceptjs/themes_test.js +31 -0
  76. package/tests/docker-compose.yml +4 -3
  77. package/tests/fixtures/validation.json +382 -1
  78. package/tests/pages/_demo.html +2 -0
  79. package/tests/pages/anyof.html +80 -0
  80. package/tests/pages/issues/issue-gh-812.html +110 -0
  81. package/tests/pages/issues/issue-gh-848.html +81 -0
  82. package/tests/pages/meta_schema.json +0 -1
  83. package/tests/pages/object-no-additional-properties.html +27 -12
  84. package/tests/pages/object-required-properties.html +43 -9
  85. package/tests/pages/object-show-opt-in.html +110 -0
  86. package/tests/pages/object-with-dependencies-array.html +56 -0
  87. package/tests/pages/oneof.html +103 -0
  88. package/tests/pages/read-only.html +19 -4
  89. package/tests/pages/stepper-manual.html +57 -0
  90. package/tests/pages/themes.html +2 -0
  91. package/tests/pages/translate-property.html +247 -0
  92. package/tests/pages/urn.html +93 -0
  93. package/tests/unit/core.spec.js +2 -0
  94. package/tests/unit/defaults.spec.js +4 -2
  95. package/tests/unit/editor.spec.js +2 -0
  96. package/tests/unit/editors/array.spec.js +86 -0
  97. package/tests/unit/editors/table.spec.js +91 -0
  98. package/tests/unit/schemaloader.spec.js +362 -3
  99. package/tests/unit/validator.spec.js +14 -2
@@ -1,140 +1,225 @@
1
- const assert = require('assert');
1
+ /* global Feature Scenario */
2
2
 
3
- Feature('object');
3
+ const assert = require('assert')
4
+
5
+ Feature('object')
4
6
 
5
7
  Scenario('should respect property orders', async (I) => {
6
- I.amOnPage('object.html');
7
- assert.equal(await I.grabAttributeFrom('[data-schemapath^="root"] .row:nth-of-type(1) [data-schemapath^="root."]', 'data-schemapath'), 'root.age');
8
- assert.equal(await I.grabAttributeFrom('[data-schemapath^="root"] .row:nth-of-type(2) [data-schemapath^="root."]', 'data-schemapath'), 'root.name');
9
- assert.equal(await I.grabAttributeFrom('[data-schemapath^="root"] .row:nth-of-type(3) [data-schemapath^="root."]', 'data-schemapath'), 'root.single');
10
- assert.equal(await I.grabAttributeFrom('[data-schemapath^="root"] .row:nth-of-type(4) [data-schemapath^="root."]', 'data-schemapath'), 'root.values');
11
- assert.equal(await I.grabAttributeFrom('[data-schemapath^="root"] .row:nth-of-type(5) [data-schemapath^="root."]', 'data-schemapath'), 'root.zodiac');
12
- });
8
+ I.amOnPage('object.html')
9
+ assert.equal(await I.grabAttributeFrom('[data-schemapath^="root"] .row:nth-of-type(1) [data-schemapath^="root."]', 'data-schemapath'), 'root.age')
10
+ assert.equal(await I.grabAttributeFrom('[data-schemapath^="root"] .row:nth-of-type(2) [data-schemapath^="root."]', 'data-schemapath'), 'root.name')
11
+ assert.equal(await I.grabAttributeFrom('[data-schemapath^="root"] .row:nth-of-type(3) [data-schemapath^="root."]', 'data-schemapath'), 'root.single')
12
+ assert.equal(await I.grabAttributeFrom('[data-schemapath^="root"] .row:nth-of-type(4) [data-schemapath^="root."]', 'data-schemapath'), 'root.values')
13
+ assert.equal(await I.grabAttributeFrom('[data-schemapath^="root"] .row:nth-of-type(5) [data-schemapath^="root."]', 'data-schemapath'), 'root.zodiac')
14
+ })
13
15
 
14
16
  Scenario('should validate required properties', async (I) => {
15
- I.amOnPage('object.html');
16
- I.see('Value must be at least 18.');
17
- });
17
+ I.amOnPage('object.html')
18
+ I.see('Value must be at least 18.')
19
+ })
18
20
 
19
21
  Scenario('should validate also not required properties', async (I) => {
20
- I.amOnPage('object.html');
21
- I.see('Value must be at least 3 characters long.');
22
- });
22
+ I.amOnPage('object.html')
23
+ I.see('Value must be at least 3 characters long.')
24
+ })
23
25
 
24
26
  Scenario('grid-strict rows and columns', (I) => {
25
- I.amOnPage('grid-strict.html');
26
- I.seeNumberOfVisibleElements('.row', 13);
27
- I.seeElement('.col-md-1');
28
- I.seeElement('.col-md-2');
29
- I.seeElement('.col-md-3');
30
- I.seeElement('.col-md-4');
31
- I.seeElement('.col-md-5');
32
- I.seeElement('.col-md-6');
33
- I.seeElement('.col-md-7');
34
- I.seeElement('.col-md-8');
35
- I.seeElement('.col-md-9');
36
- I.seeElement('.col-md-10');
37
- I.seeElement('.col-md-11');
38
- I.seeElement('.col-md-12');
39
- I.seeElement('.col-md-1.offset-md-1');
40
- I.seeElement('.col-md-1.offset-md-2');
41
- I.seeElement('.col-md-1.offset-md-3');
42
- I.seeElement('.col-md-1.offset-md-4');
43
- I.seeElement('.col-md-1.offset-md-5');
44
- I.seeElement('.col-md-1.offset-md-6');
45
- I.seeElement('.col-md-1.offset-md-7');
46
- I.seeElement('.col-md-1.offset-md-8');
47
- I.seeElement('.col-md-1.offset-md-9');
48
- I.seeElement('.col-md-1.offset-md-10');
49
- I.seeElement('.col-md-1.offset-md-11');
50
- });
27
+ I.amOnPage('grid-strict.html')
28
+ I.seeNumberOfVisibleElements('.row', 13)
29
+ I.seeElement('.col-md-1')
30
+ I.seeElement('.col-md-2')
31
+ I.seeElement('.col-md-3')
32
+ I.seeElement('.col-md-4')
33
+ I.seeElement('.col-md-5')
34
+ I.seeElement('.col-md-6')
35
+ I.seeElement('.col-md-7')
36
+ I.seeElement('.col-md-8')
37
+ I.seeElement('.col-md-9')
38
+ I.seeElement('.col-md-10')
39
+ I.seeElement('.col-md-11')
40
+ I.seeElement('.col-md-12')
41
+ I.seeElement('.col-md-1.offset-md-1')
42
+ I.seeElement('.col-md-1.offset-md-2')
43
+ I.seeElement('.col-md-1.offset-md-3')
44
+ I.seeElement('.col-md-1.offset-md-4')
45
+ I.seeElement('.col-md-1.offset-md-5')
46
+ I.seeElement('.col-md-1.offset-md-6')
47
+ I.seeElement('.col-md-1.offset-md-7')
48
+ I.seeElement('.col-md-1.offset-md-8')
49
+ I.seeElement('.col-md-1.offset-md-9')
50
+ I.seeElement('.col-md-1.offset-md-10')
51
+ I.seeElement('.col-md-1.offset-md-11')
52
+ })
51
53
 
52
54
  Scenario('grid rows and columns', (I) => {
53
- I.amOnPage('grid.html');
54
- I.seeNumberOfVisibleElements('.row', 6);
55
- I.seeNumberOfVisibleElements('.col-md-12', 1);
56
- I.seeNumberOfVisibleElements('.col-md-6', 3);
57
- I.seeNumberOfVisibleElements('.col-md-4', 3);
58
- I.seeNumberOfVisibleElements('.col-md-3', 4);
59
- I.seeNumberOfVisibleElements('.col-md-2', 6);
60
- I.seeNumberOfVisibleElements('.col-md-1', 6);
61
- });
62
-
63
- Scenario('opt in optional properties', async (I) => {
64
- I.amOnPage('object-required-properties.html');
55
+ I.amOnPage('grid.html')
56
+ I.seeNumberOfVisibleElements('.row', 6)
57
+ I.seeNumberOfVisibleElements('.col-md-12', 1)
58
+ I.seeNumberOfVisibleElements('.col-md-6', 3)
59
+ I.seeNumberOfVisibleElements('.col-md-4', 3)
60
+ I.seeNumberOfVisibleElements('.col-md-3', 4)
61
+ I.seeNumberOfVisibleElements('.col-md-2', 6)
62
+ I.seeNumberOfVisibleElements('.col-md-1', 6)
63
+ })
64
+
65
+ Scenario('opt in optional properties @show_opt_in', async (I) => {
66
+ I.amOnPage('object-required-properties.html')
65
67
 
66
68
  // if an editor type "object" is disabled, also the child editors opt-in controls will be disabled.
67
- I.seeDisabledAttribute('[data-schemapath="root.object.number"] .json-editor-opt-in');
68
- I.seeDisabledAttribute('[data-schemapath="root.object.boolean"] .json-editor-opt-in');
69
+ I.seeDisabledAttribute('[data-schemapath="root.object.number"] .json-editor-opt-in')
70
+ I.seeDisabledAttribute('[data-schemapath="root.object.boolean"] .json-editor-opt-in')
71
+ I.seeDisabledAttribute('[data-schemapath="root.object.radio"] .json-editor-opt-in')
69
72
 
70
73
  // tests merged from master 17.9.2019
71
74
  I.dontSeeCheckedAttribute('[data-schemapath="root.string"] .json-editor-opt-in')
72
75
  I.dontSeeDisabledAttribute('[data-schemapath="root.string"] .json-editor-opt-in')
73
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]"]')
74
81
  I.dontSeeCheckedAttribute('[data-schemapath="root.object.number"] .json-editor-opt-in')
75
82
  I.seeDisabledAttribute('[data-schemapath="root.object.number"] .json-editor-opt-in')
76
83
  I.seeDisabledAttribute('[name="root[object][number]"]')
77
84
  I.dontSeeCheckedAttribute('[data-schemapath="root.object.boolean"] .json-editor-opt-in')
78
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')
79
88
 
80
- I.click('.get-value');
81
- assert.equal(await I.grabValueFrom('.value'), '{"number":0,"boolean":false}');
89
+ I.click('.get-value')
90
+ assert.equal(await I.grabValueFrom('.value'), '{"number":0,"boolean":false}')
82
91
 
83
92
  // Opening and Closing "Edit JSON" should keep opt-in state.
84
93
 
85
- I.click('[data-schemapath="root"] .json-editor-btn-edit');
86
- I.click('[data-schemapath="root"] .json-editor-btn-edit');
87
-
94
+ I.click('[data-schemapath="root"] .json-editor-btn-edit')
95
+ I.click('[data-schemapath="root"] .json-editor-btn-edit')
88
96
  I.dontSeeCheckedAttribute('[data-schemapath="root.string"] .json-editor-opt-in')
89
97
  I.dontSeeDisabledAttribute('[data-schemapath="root.string"] .json-editor-opt-in')
90
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]"]')
91
103
  I.dontSeeCheckedAttribute('[data-schemapath="root.object.number"] .json-editor-opt-in')
92
104
  I.seeDisabledAttribute('[data-schemapath="root.object.number"] .json-editor-opt-in')
93
105
  I.seeDisabledAttribute('[name="root[object][number]"]')
94
106
  I.dontSeeCheckedAttribute('[data-schemapath="root.object.boolean"] .json-editor-opt-in')
95
107
  I.seeDisabledAttribute('[data-schemapath="root.object.boolean"] .json-editor-opt-in')
96
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')
97
112
 
98
- I.click('.get-value');
99
- assert.equal(await I.grabValueFrom('.value'), '{"number":0,"boolean":false}');
113
+ I.click('.get-value')
114
+ assert.equal(await I.grabValueFrom('.value'), '{"number":0,"boolean":false}')
100
115
 
101
116
  // opt-in string property
102
117
 
103
- I.click('[data-schemapath="root.string"] .json-editor-opt-in');
104
- I.click('.get-value');
105
- assert.equal(await I.grabValueFrom('.value'), '{"string":"","number":0,"boolean":false}');
118
+ I.click('[data-schemapath="root.string"] .json-editor-opt-in')
119
+ I.click('[data-schemapath="root.radio"] .json-editor-opt-in')
120
+ I.click('.get-value')
121
+ assert.equal(await I.grabValueFrom('.value'), '{"string":"","number":0,"boolean":false,"radio":"Home"}')
106
122
 
107
123
  // opt-in array property
108
124
 
109
- I.click('[data-schemapath="root.array"] .json-editor-opt-in');
110
- I.click('.get-value');
111
- assert.equal(await I.grabValueFrom('.value'), '{"string":"","number":0,"boolean":false,"array":[]}');
125
+ I.click('[data-schemapath="root.array"] .json-editor-opt-in')
126
+ I.click('.get-value')
127
+ assert.equal(await I.grabValueFrom('.value'), '{"string":"","number":0,"boolean":false,"radio":"Home","array":[]}')
112
128
 
113
129
  // opt-in object property
114
130
 
115
- I.click('[data-schemapath="root.object"] .json-editor-opt-in');
116
- I.click('.get-value');
117
- assert.equal(await I.grabValueFrom('.value'), '{"string":"","number":0,"boolean":false,"array":[],"object":{"string":"","array":[]}}');
131
+ I.click('[data-schemapath="root.object"] .json-editor-opt-in')
132
+ I.click('.get-value')
133
+ assert.equal(await I.grabValueFrom('.value'), '{"string":"","number":0,"boolean":false,"radio":"Home","array":[],"object":{"string":"","array":[]}}')
118
134
 
119
135
  // if an editor type "object" is enabled, also the child editors opt-in controls will be enabled.
120
- I.dontSeeDisabledAttribute('[data-schemapath="root.object.number"] .json-editor-opt-in');
121
- I.dontSeeDisabledAttribute('[data-schemapath="root.object.boolean"] .json-editor-opt-in');
122
-
123
- });
124
-
125
- Scenario('should hide but not delete additional properties, when no_additional_properties is true @optional', async (I) => {
126
- I.amOnPage('object-no-additional-properties.html');
127
- I.seeElement('[data-schemapath="root.name"] input');
128
- I.dontSeeElement('[data-schemapath="root.age"] input');
129
- I.click('.get-value');
130
- let json = await I.grabValueFrom('.value');
131
- let value = JSON.parse(json);
132
- assert.equal(value.name, "Jeremy Dorn");
133
- assert.equal(value.age, 34); // This will currently fail
134
- });
136
+ I.dontSeeDisabledAttribute('[data-schemapath="root.object.number"] .json-editor-opt-in')
137
+ I.dontSeeDisabledAttribute('[data-schemapath="root.object.boolean"] .json-editor-opt-in')
138
+ I.dontSeeDisabledAttribute('[data-schemapath="root.object.radio"] .json-editor-opt-in')
139
+ })
140
+
141
+ Scenario('set value opt in optional properties @show_opt_in', async (I) => {
142
+ I.amOnPage('object-required-properties.html')
143
+
144
+ // all editors visible
145
+ I.waitForElement('[data-schemapath="root.string"]', 5)
146
+ I.waitForElement('[data-schemapath="root.number"]', 5)
147
+ I.waitForElement('[data-schemapath="root.boolean"]', 5)
148
+ I.waitForElement('[data-schemapath="root.radio"]', 5)
149
+ I.waitForElement('[data-schemapath="root.array"]', 5)
150
+ I.waitForElement('[data-schemapath="root.object"]', 5)
151
+ I.waitForElement('[data-schemapath="root.object.string"]', 5)
152
+ I.waitForElement('[data-schemapath="root.object.number"]', 5)
153
+ I.waitForElement('[data-schemapath="root.object.boolean"]', 5)
154
+ I.waitForElement('[data-schemapath="root.object.radio"]', 5)
155
+
156
+ // set values
157
+ I.click('.set-value')
158
+ I.click('.get-value')
159
+ assert.equal(await I.grabValueFrom('.value'), '{"string":"test","number":0,"boolean":false,"array":["test"],"object":{"string":"","number":10,"boolean":true,"array":[]}}')
160
+
161
+ // set empty values
162
+ I.click('.set-empty-value')
163
+ I.click('.get-value')
164
+ assert.equal(await I.grabValueFrom('.value'), '{"number":0,"boolean":false}')
165
+
166
+ // all editorsstill visible
167
+ I.waitForElement('[data-schemapath="root.string"]', 5)
168
+ I.waitForElement('[data-schemapath="root.number"]', 5)
169
+ I.waitForElement('[data-schemapath="root.boolean"]', 5)
170
+ I.waitForElement('[data-schemapath="root.radio"]', 5)
171
+ I.waitForElement('[data-schemapath="root.array"]', 5)
172
+ I.waitForElement('[data-schemapath="root.object"]', 5)
173
+ I.waitForElement('[data-schemapath="root.object.string"]', 5)
174
+ I.waitForElement('[data-schemapath="root.object.number"]', 5)
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
209
+ })
210
+
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) => {
212
+ I.amOnPage('object-no-additional-properties.html')
213
+ I.seeElement('[data-schemapath="root.aptrue.name"] input')
214
+ I.seeElement('[data-schemapath="root.aptrue.age"] input')
215
+ I.seeElement('[data-schemapath="root.apfalse.name"] input')
216
+ I.dontSeeElement('[data-schemapath="root.apfalse.age"] input')
217
+ I.click('.get-value')
218
+ assert.equal(await I.grabValueFrom('.value'), '{"aptrue":{"name":"Albert","age":0},"apfalse":{"name":"Albert"}}')
219
+ })
135
220
 
136
221
  Scenario('should have unique ids', (I) => {
137
- I.amOnPage('object-no-duplicated-id.html');
222
+ I.amOnPage('object-no-duplicated-id.html')
138
223
  I.donSeeDuplicatedIds()
139
224
  I.waitForText('i am actually a cat')
140
225
  I.waitForText('i am actually a dog')
@@ -144,16 +229,47 @@ Scenario('should have unique ids', (I) => {
144
229
  I.click('.form-group:nth-child(1) .form-check-input')
145
230
  I.click('.form-group:nth-child(2) .form-check-input')
146
231
  I.waitForText('i am actually a cat')
147
- });
148
-
149
- Scenario('should hide properties with unfulfilled dependencies', (I) => {
150
- I.amOnPage('object-with-dependencies.html');
151
- I.seeElement('[data-schemapath="root.enable_option"] input');
152
- I.dontSeeElement('[data-schemapath="root.make_new"] input');
153
- I.dontSeeElement('[data-schemapath="root.existing_name"] input');
154
-
155
- I.click('[data-schemapath="root.enable_option"] input');
156
- I.seeElement('[data-schemapath="root.enable_option"] input');
157
- I.seeElement('[data-schemapath="root.make_new"] input');
158
- I.dontSeeElement('[data-schemapath="root.existing_name"] input');
159
- });
232
+ })
233
+
234
+ Scenario('should hide properties with unfulfilled dependencies @dependencies', (I) => {
235
+ I.amOnPage('object-with-dependencies.html')
236
+ I.seeElement('[data-schemapath="root.enable_option"] input')
237
+ I.dontSeeElement('[data-schemapath="root.make_new"] input')
238
+ I.dontSeeElement('[data-schemapath="root.existing_name"] input')
239
+
240
+ I.click('[data-schemapath="root.enable_option"] input')
241
+ I.seeElement('[data-schemapath="root.enable_option"] input')
242
+ I.seeElement('[data-schemapath="root.make_new"] input')
243
+ I.dontSeeElement('[data-schemapath="root.existing_name"] input')
244
+ })
245
+
246
+ Scenario('should respect multiple dependency values @dependencies', (I) => {
247
+ I.amOnPage('object-with-dependencies-array.html')
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')
275
+ })
@@ -1,3 +1,5 @@
1
+ /* global Feature Scenario */
2
+
1
3
  var assert = require('assert')
2
4
 
3
5
  Feature('Programmatic changes')
@@ -9,7 +11,7 @@ Scenario('should have correct initial value', async (I) => {
9
11
  assert.equal(await I.grabValueFrom('.value'), '{"boolean":false,"boolean_checkbox":false,"string":"","integer":0,"number":0,"array":[],"array_checkbox":[],"array_select":[]}')
10
12
  })
11
13
 
12
- Scenario('should have correct values after setting them programmatically @optional', async (I) => {
14
+ Scenario('should have correct values after setting them programmatically', async (I) => {
13
15
  I.amOnPage('programmatic-changes.html')
14
16
  I.waitForText('READY', 5, '.state')
15
17
  I.click('.set-values')
@@ -0,0 +1,10 @@
1
+ /* global Feature Scenario */
2
+
3
+ Feature('radio')
4
+
5
+ Scenario('should be disabled if "readonly" is specified', async (I) => {
6
+ I.amOnPage('read-only.html')
7
+
8
+ I.seeDisabledAttribute('[id="root[radio][0]"]')
9
+ I.seeDisabledAttribute('[id="root[radio][1]"]')
10
+ })
@@ -1,14 +1,13 @@
1
- var assert = require('assert');
1
+ /* global Feature Scenario */
2
2
 
3
- Feature('rating');
3
+ Feature('rating')
4
4
 
5
5
  Scenario('should be disabled if "readonly" is specified', async (I) => {
6
- I.amOnPage('read-only.html');
7
-
8
- I.seeDisabledAttribute('[id="root[rating]5"]');
9
- I.seeDisabledAttribute('[id="root[rating]4"]');
10
- I.seeDisabledAttribute('[id="root[rating]3"]');
11
- I.seeDisabledAttribute('[id="root[rating]2"]');
12
- I.seeDisabledAttribute('[id="root[rating]1"]');
13
-
14
- });
6
+ I.amOnPage('read-only.html')
7
+
8
+ I.seeDisabledAttribute('[id="root[rating]5"]')
9
+ I.seeDisabledAttribute('[id="root[rating]4"]')
10
+ I.seeDisabledAttribute('[id="root[rating]3"]')
11
+ I.seeDisabledAttribute('[id="root[rating]2"]')
12
+ I.seeDisabledAttribute('[id="root[rating]1"]')
13
+ })
@@ -1,20 +1,22 @@
1
- var assert = require('assert');
1
+ /* global Feature Scenario */
2
2
 
3
- Feature('select');
3
+ var assert = require('assert')
4
+
5
+ Feature('select')
4
6
 
5
7
  Scenario('should return correct booleans values when selected', async (I) => {
6
- I.amOnPage('select.html');
7
- I.click('.get-value');
8
- assert.equal(await I.grabValueFrom('.value'), '{"boolean":true}');
9
- I.selectOption('[name="root[boolean]"]', 'false');
10
- I.click('.get-value');
11
- assert.equal(await I.grabValueFrom('.value'), '{"boolean":false}');
12
- I.selectOption('[name="root[boolean]"]', 'true');
13
- I.click('.get-value');
14
- assert.equal(await I.grabValueFrom('.value'), '{"boolean":true}');
15
- });
8
+ I.amOnPage('select.html')
9
+ I.click('.get-value')
10
+ assert.equal(await I.grabValueFrom('.value'), '{"boolean":true}')
11
+ I.selectOption('[name="root[boolean]"]', 'false')
12
+ I.click('.get-value')
13
+ assert.equal(await I.grabValueFrom('.value'), '{"boolean":false}')
14
+ I.selectOption('[name="root[boolean]"]', 'true')
15
+ I.click('.get-value')
16
+ assert.equal(await I.grabValueFrom('.value'), '{"boolean":true}')
17
+ })
16
18
 
17
19
  Scenario('should be disabled if "readonly" is specified', async (I) => {
18
- I.amOnPage('read-only.html');
19
- I.seeDisabledAttribute('[name="root[select]"]');
20
- });
20
+ I.amOnPage('read-only.html')
21
+ I.seeDisabledAttribute('[name="root[select]"]')
22
+ })
@@ -1,4 +1,4 @@
1
- /* global Feature Scenario Event */
1
+ /* global Feature Scenario */
2
2
 
3
3
  var assert = require('assert')
4
4
 
@@ -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
+ })