@json-editor/json-editor 2.6.1 → 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 (68) hide show
  1. package/.github/workflows/build.yml +12 -3
  2. package/CHANGELOG.md +24 -0
  3. package/README.md +131 -18
  4. package/dist/jsoneditor.js +2 -2
  5. package/dist/nonmin/jsoneditor.js +2607 -582
  6. package/dist/nonmin/jsoneditor.js.map +1 -1
  7. package/docs/form-submission.html +76 -0
  8. package/package.json +4 -3
  9. package/release-notes.md +2 -0
  10. package/src/core.js +36 -37
  11. package/src/defaults.js +9 -2
  12. package/src/editors/array.js +12 -1
  13. package/src/editors/autocomplete.js +4 -3
  14. package/src/editors/button.js +1 -1
  15. package/src/editors/multiselect.js +14 -5
  16. package/src/editors/string.js +4 -0
  17. package/src/editors/table.js +20 -2
  18. package/src/editors/upload.js +1 -1
  19. package/src/editors/uuid.js +2 -12
  20. package/src/iconlib.js +1 -1
  21. package/src/schemaloader.js +231 -108
  22. package/src/style.css +3 -0
  23. package/src/style.css.js +1 -1
  24. package/src/theme.js +0 -2
  25. package/src/themes/bootstrap3.js +1 -0
  26. package/src/themes/spectre.js +2 -1
  27. package/src/utilities.js +18 -0
  28. package/src/validator.js +36 -34
  29. package/tests/codeceptjs/codecept.json +1 -1
  30. package/tests/codeceptjs/core_test.js +98 -0
  31. package/tests/codeceptjs/editors/advanced_test.js +1 -1
  32. package/tests/codeceptjs/editors/array_test.js +74 -0
  33. package/tests/codeceptjs/editors/autocomplete_test.js +16 -0
  34. package/tests/codeceptjs/editors/button_test.js +10 -3
  35. package/tests/codeceptjs/editors/integer_test.js +7 -2
  36. package/tests/codeceptjs/editors/jodit_test.js +3 -3
  37. package/tests/codeceptjs/editors/range_test.js +12 -0
  38. package/tests/codeceptjs/editors/uuid_test.js +31 -4
  39. package/tests/docker-compose.yml +1 -1
  40. package/tests/fixtures/definitions.json +22 -0
  41. package/tests/fixtures/properties.json +20 -0
  42. package/tests/pages/array-checkboxes-infotext.html +52 -0
  43. package/tests/pages/array-move-events.html +4 -2
  44. package/tests/pages/array-unique-items-sort.html +78 -0
  45. package/tests/pages/autocomplete.html +69 -0
  46. package/tests/pages/button-icons.html +38 -0
  47. package/tests/pages/core.html +4 -2
  48. package/tests/pages/error-messages.html +47 -0
  49. package/tests/pages/grid-strict.html +6 -10
  50. package/tests/pages/grid.html +0 -4
  51. package/tests/pages/issues/issue-gh-812.html +4 -2
  52. package/tests/pages/meta_schema.json +14 -0
  53. package/tests/pages/object-required-properties.html +7 -7
  54. package/tests/pages/range.html +60 -0
  55. package/tests/pages/ready.html +43 -0
  56. package/tests/pages/references.html +162 -0
  57. package/tests/pages/string-simplemde-editor.html +81 -0
  58. package/tests/pages/table-move-events.html +4 -1
  59. package/tests/pages/urn.html +11 -8
  60. package/tests/pages/uuid.html +89 -50
  61. package/tests/pages/validation-messages.json +705 -0
  62. package/tests/unit/core.spec.js +79 -66
  63. package/tests/unit/editor.spec.js +20 -8
  64. package/tests/unit/editors/array.spec.js +3 -2
  65. package/tests/unit/editors/object.spec.js +3 -1
  66. package/tests/unit/editors/table.spec.js +4 -2
  67. package/tests/unit/schemaloader.spec.js +77 -105
  68. package/tests/unit/validator.spec.js +2 -2
package/src/validator.js CHANGED
@@ -17,7 +17,7 @@ export class Validator {
17
17
  return [{
18
18
  path,
19
19
  property: 'const',
20
- message: this.translate('error_const')
20
+ message: this.translate('error_const', null, schema)
21
21
  }]
22
22
  }
23
23
  return []
@@ -29,7 +29,7 @@ export class Validator {
29
29
  return [{
30
30
  path,
31
31
  property: 'enum',
32
- message: this.translate('error_enum')
32
+ message: this.translate('error_enum', null, schema)
33
33
  }]
34
34
  }
35
35
  return []
@@ -54,7 +54,7 @@ export class Validator {
54
54
  return [{
55
55
  path,
56
56
  property: 'anyOf',
57
- message: this.translate('error_anyOf')
57
+ message: this.translate('error_anyOf', null, schema)
58
58
  }]
59
59
  }
60
60
  return []
@@ -79,7 +79,7 @@ export class Validator {
79
79
  errors.push({
80
80
  path,
81
81
  property: 'oneOf',
82
- message: this.translate('error_oneOf', [valid])
82
+ message: this.translate('error_oneOf', [valid], schema)
83
83
  })
84
84
  errors.push(...oneofErrors)
85
85
  }
@@ -90,7 +90,7 @@ export class Validator {
90
90
  return [{
91
91
  path,
92
92
  property: 'not',
93
- message: this.translate('error_not')
93
+ message: this.translate('error_not', null, schema)
94
94
  }]
95
95
  }
96
96
  return []
@@ -103,7 +103,7 @@ export class Validator {
103
103
  return [{
104
104
  path,
105
105
  property: 'type',
106
- message: this.translate('error_type_union')
106
+ message: this.translate('error_type_union', null, schema)
107
107
  }]
108
108
  }
109
109
  } else {
@@ -115,14 +115,14 @@ export class Validator {
115
115
  return [{
116
116
  path,
117
117
  property: 'type',
118
- message: this.translate('error_type', [schema.format])
118
+ message: this.translate('error_type', [schema.format], schema)
119
119
  }]
120
120
  }
121
121
  } else if (!this._checkType(schema.type, value)) {
122
122
  return [{
123
123
  path,
124
124
  property: 'type',
125
- message: this.translate('error_type', [schema.type])
125
+ message: this.translate('error_type', [schema.type], schema)
126
126
  }]
127
127
  }
128
128
  }
@@ -136,7 +136,7 @@ export class Validator {
136
136
  return [{
137
137
  path,
138
138
  property: 'disallow',
139
- message: this.translate('error_disallow_union')
139
+ message: this.translate('error_disallow_union', null, schema)
140
140
  }]
141
141
  }
142
142
  } else {
@@ -145,7 +145,7 @@ export class Validator {
145
145
  return [{
146
146
  path,
147
147
  property: 'disallow',
148
- message: this.translate('error_disallow', [schema.disallow])
148
+ message: this.translate('error_disallow', [schema.disallow], schema)
149
149
  }]
150
150
  }
151
151
  }
@@ -177,7 +177,8 @@ export class Validator {
177
177
  property: 'maximum',
178
178
  message: this.translate(
179
179
  (schema.exclusiveMaximum ? 'error_maximum_excl' : 'error_maximum_incl'),
180
- [schema.maximum]
180
+ [schema.maximum],
181
+ schema
181
182
  )
182
183
  }]
183
184
  }
@@ -204,7 +205,8 @@ export class Validator {
204
205
  property: 'minimum',
205
206
  message: this.translate(
206
207
  (schema.exclusiveMinimum ? 'error_minimum_excl' : 'error_minimum_incl'),
207
- [schema.minimum]
208
+ [schema.minimum],
209
+ schema
208
210
  )
209
211
  }]
210
212
  }
@@ -219,7 +221,7 @@ export class Validator {
219
221
  errors.push({
220
222
  path,
221
223
  property: 'maxLength',
222
- message: this.translate('error_maxLength', [schema.maxLength])
224
+ message: this.translate('error_maxLength', [schema.maxLength], schema)
223
225
  })
224
226
  }
225
227
  return errors
@@ -230,7 +232,7 @@ export class Validator {
230
232
  return [{
231
233
  path,
232
234
  property: 'minLength',
233
- message: this.translate((schema.minLength === 1 ? 'error_notempty' : 'error_minLength'), [schema.minLength])
235
+ message: this.translate((schema.minLength === 1 ? 'error_notempty' : 'error_minLength'), [schema.minLength], schema)
234
236
  }]
235
237
  }
236
238
  return []
@@ -241,7 +243,7 @@ export class Validator {
241
243
  return [{
242
244
  path,
243
245
  property: 'pattern',
244
- message: (schema.options && schema.options.patternmessage) ? schema.options.patternmessage : this.translate('error_pattern', [schema.pattern])
246
+ message: (schema.options && schema.options.patternmessage) ? schema.options.patternmessage : this.translate('error_pattern', [schema.pattern], schema)
245
247
  }]
246
248
  }
247
249
  return []
@@ -269,7 +271,7 @@ export class Validator {
269
271
  errors.push({
270
272
  path,
271
273
  property: 'additionalItems',
272
- message: this.translate('error_additionalItems')
274
+ message: this.translate('error_additionalItems', null, schema)
273
275
  })
274
276
  break
275
277
  /* Default for `additionalItems` is an empty schema */
@@ -291,7 +293,7 @@ export class Validator {
291
293
  return [{
292
294
  path,
293
295
  property: 'maxItems',
294
- message: this.translate('error_maxItems', [schema.maxItems])
296
+ message: this.translate('error_maxItems', [schema.maxItems], schema)
295
297
  }]
296
298
  }
297
299
  return []
@@ -301,7 +303,7 @@ export class Validator {
301
303
  return [{
302
304
  path,
303
305
  property: 'minItems',
304
- message: this.translate('error_minItems', [schema.minItems])
306
+ message: this.translate('error_minItems', [schema.minItems], schema)
305
307
  }]
306
308
  }
307
309
  return []
@@ -314,7 +316,7 @@ export class Validator {
314
316
  return [{
315
317
  path,
316
318
  property: 'uniqueItems',
317
- message: this.translate('error_uniqueItems')
319
+ message: this.translate('error_uniqueItems', null, schema)
318
320
  }]
319
321
  }
320
322
  seen[valid] = true
@@ -329,7 +331,7 @@ export class Validator {
329
331
  return [{
330
332
  path,
331
333
  property: 'maxProperties',
332
- message: this.translate('error_maxProperties', [schema.maxProperties])
334
+ message: this.translate('error_maxProperties', [schema.maxProperties], schema)
333
335
  }]
334
336
  }
335
337
  return []
@@ -339,7 +341,7 @@ export class Validator {
339
341
  return [{
340
342
  path,
341
343
  property: 'minProperties',
342
- message: this.translate('error_minProperties', [schema.minProperties])
344
+ message: this.translate('error_minProperties', [schema.minProperties], schema)
343
345
  }]
344
346
  }
345
347
  return []
@@ -356,7 +358,7 @@ export class Validator {
356
358
  errors.push({
357
359
  path,
358
360
  property: 'required',
359
- message: this.translate('error_required', [schema && schema.properties && schema.properties[e] && schema.properties[e].title ? schema.properties[e].title : e])
361
+ message: this.translate('error_required', [schema && schema.properties && schema.properties[e] && schema.properties[e].title ? schema.properties[e].title : e], schema)
360
362
  })
361
363
  })
362
364
  }
@@ -403,7 +405,7 @@ export class Validator {
403
405
  errors.push({
404
406
  path,
405
407
  property: 'propertyNames',
406
- message: this.translate('error_property_names_false', [k])
408
+ message: this.translate('error_property_names_false', [k], schema)
407
409
  })
408
410
  break
409
411
  }
@@ -457,14 +459,14 @@ export class Validator {
457
459
  errors.push({
458
460
  path,
459
461
  property: 'propertyNames',
460
- message: this.translate('error_property_names_unsupported', [j])
462
+ message: this.translate('error_property_names_unsupported', [j], schema)
461
463
  })
462
464
  return false
463
465
  }
464
466
  errors.push({
465
467
  path,
466
468
  property: 'propertyNames',
467
- message: this.translate(msg, [k])
469
+ message: this.translate(msg, [k], schema)
468
470
  })
469
471
  return false
470
472
  })
@@ -483,7 +485,7 @@ export class Validator {
483
485
  errors.push({
484
486
  path,
485
487
  property: 'additionalProperties',
486
- message: this.translate('error_additional_properties', [k])
488
+ message: this.translate('error_additional_properties', [k], schema)
487
489
  })
488
490
  break
489
491
  /* Allowed */
@@ -510,7 +512,7 @@ export class Validator {
510
512
  errors.push({
511
513
  path,
512
514
  property: 'dependencies',
513
- message: this.translate('error_dependency', [d])
515
+ message: this.translate('error_dependency', [d], schema)
514
516
  })
515
517
  }
516
518
  })
@@ -638,7 +640,7 @@ export class Validator {
638
640
  return [{
639
641
  path,
640
642
  property: 'required',
641
- message: this.translate('error_notset')
643
+ message: this.translate('error_notset', null, schema)
642
644
  }]
643
645
  }
644
646
  return []
@@ -713,7 +715,7 @@ export class Validator {
713
715
  return [{
714
716
  path,
715
717
  property: 'format',
716
- message: this.translate('error_pattern', ['^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-5][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$'])
718
+ message: this.translate('error_pattern', ['^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-5][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$'], schema)
717
719
  }]
718
720
  }
719
721
  return []
@@ -736,7 +738,7 @@ export class Validator {
736
738
  return [{
737
739
  path,
738
740
  property: schema.multipleOf ? 'multipleOf' : 'divisibleBy',
739
- message: this.translate('error_multipleOf', [divisor])
741
+ message: this.translate('error_multipleOf', [divisor], schema)
740
742
  }]
741
743
  }
742
744
  return []
@@ -750,14 +752,14 @@ export class Validator {
750
752
  return [{
751
753
  path,
752
754
  property: 'format',
753
- message: this.translate('error_invalid_epoch')
755
+ message: this.translate('error_invalid_epoch', null, schema)
754
756
  }]
755
757
  } else if (value !== Math.abs(parseInt(value))) {
756
758
  /* not much to check for, so we assume value is ok if it's a positive number */
757
759
  return [{
758
760
  path,
759
761
  property: 'format',
760
- message: this.translate(`error_${schema.format.replace(/-/g, '_')}`, [dateFormat])
762
+ message: this.translate(`error_${schema.format.replace(/-/g, '_')}`, [dateFormat], schema)
761
763
  }]
762
764
  }
763
765
  return []
@@ -786,7 +788,7 @@ export class Validator {
786
788
  return [{
787
789
  path,
788
790
  property: 'format',
789
- message: this.translate(`error_${editor.format.replace(/-/g, '_')}`, [errorDateFormat])
791
+ message: this.translate(`error_${editor.format.replace(/-/g, '_')}`, [errorDateFormat], schema)
790
792
  }]
791
793
  }
792
794
  }
@@ -815,7 +817,7 @@ export class Validator {
815
817
  return [{
816
818
  path,
817
819
  property: 'format',
818
- message: this.translate(`error_${schema.format.replace(/-/g, '_')}`, [dateFormat])
820
+ message: this.translate(`error_${schema.format.replace(/-/g, '_')}`, [dateFormat], schema)
819
821
  }]
820
822
  }
821
823
  } else if (editor) {
@@ -11,7 +11,7 @@
11
11
  "browser": "firefox",
12
12
  "restart": false,
13
13
  "host": "firefox",
14
- "smartWait": 5000
14
+ "smartWait": 10000
15
15
  },
16
16
  "customHelpers": {
17
17
  "require": "./../../config/codeceptjs_helpers.js"
@@ -4,6 +4,11 @@ var assert = require('assert')
4
4
 
5
5
  Feature('core')
6
6
 
7
+ Scenario('should have class je-ready when ready @core @ready', async (I) => {
8
+ I.amOnPage('ready.html')
9
+ I.waitForElement('.je-ready')
10
+ })
11
+
7
12
  Scenario('should Disable and enable entire form', async (I) => {
8
13
  I.amOnPage('core.html')
9
14
  I.seeElement('[data-schemapath="root.name"] input')
@@ -215,3 +220,96 @@ Scenario('should validate against oneOf schemas and display single oneOf and edi
215
220
  I.waitForText('Rating Description (but in german)')
216
221
  I.seeInSource('Rating Info Text (but in german)')
217
222
  })
223
+
224
+ Scenario('should load internal schema definitions, external schema definitions and external schema properties @core @references', async (I) => {
225
+ I.amOnPage('references.html')
226
+ I.waitForText('References JSON Editor Example')
227
+
228
+ // internal schema definitions
229
+ I.waitForElement('[data-schemapath="root.external"]')
230
+ I.waitForElement('[data-schemapath="root.orgid"]')
231
+
232
+ // external schema definitions
233
+ I.click('Add Person')
234
+ I.waitForElement('[data-schemapath="root.people.0.name"]')
235
+ I.waitForElement('[data-schemapath="root.people.0.age"]')
236
+ I.waitForElement('[data-schemapath="root.people.0.gender"]')
237
+ I.selectOption('.je-switcher', 'Complex Person')
238
+ I.waitForElement('[data-schemapath="root.people.0.location.city"]')
239
+ I.waitForElement('[data-schemapath="root.people.0.location.state"]')
240
+ I.waitForElement('[data-schemapath="root.people.0.location.citystate"]')
241
+
242
+ // external schema properties
243
+ I.waitForElement('[data-schemapath="root.link.street_address"]')
244
+ })
245
+
246
+ Scenario('should override error messages if specified in schema options @core @errors-messages', async (I) => {
247
+ I.amOnPage('error-messages.html')
248
+ I.waitForText('Error Messages')
249
+
250
+ I.waitForText('CUSTOM EN: Value required')
251
+ I.waitForText('CUSTOM EN: Value must be the constant value')
252
+ I.waitForText('CUSTOM EN: Value must be at least 6 characters long')
253
+ I.waitForText('CUSTOM EN: Value must be at most 6 characters long')
254
+ I.waitForText('CUSTOM EN: Value must validate against at least one of the provided schemas')
255
+ I.waitForText('CUSTOM EN: Value must validate against exactly one of the provided schemas. It currently validates against 0 of the schemas')
256
+ I.waitForText('CUSTOM EN: Value must be one of the provided types')
257
+ I.waitForText('CUSTOM EN: Value must not be one of the provided disallowed types')
258
+ I.waitForText('CUSTOM EN: Value must not be of type string')
259
+ I.waitForText('CUSTOM EN: Value must be of type integer')
260
+ I.waitForText('CUSTOM EN: Value must not validate against the provided schema')
261
+ I.waitForText('CUSTOM EN: Date must be greater than 1 January 1970')
262
+ I.waitForText('CUSTOM EN: Value must match the pattern ^[a-zA-Z0-9_]+$')
263
+ I.waitForText('CUSTOM EN: Value must be a multiple of 5')
264
+ I.waitForText('CUSTOM EN: Value must be at least 5')
265
+ I.waitForText('CUSTOM EN: Value must be greater than 5')
266
+ I.waitForText('CUSTOM EN: Value must be less than 10')
267
+ I.waitForText('CUSTOM EN: Value must be less than 15')
268
+ I.waitForText('CUSTOM EN: Object must have at least 1 properties')
269
+ I.waitForText('CUSTOM EN: Object must have at most 1 properties')
270
+ I.waitForText('CUSTOM EN: Object is missing the required property \'name\'')
271
+ I.waitForText('CUSTOM EN: Unsupported propertyName UNSOPPORTED')
272
+ I.waitForText('CUSTOM EN: Property name fullname cannot match invalid pattern')
273
+ I.waitForText('CUSTOM EN: Property name fullname cannot match invalid enum')
274
+ I.waitForText('CUSTOM EN: Property name fullname cannot match invalid maxLength')
275
+ I.waitForText('CUSTOM EN: Property name fullname exceeds maxLength')
276
+ I.waitForText('CUSTOM EN: Property name pets does not match pattern')
277
+ I.waitForText('CUSTOM EN: Property name $pets does not match pattern')
278
+ I.waitForText('CUSTOM EN: Property name pets does not match the const value')
279
+ I.waitForText('CUSTOM EN: Property name pets does not match any enum values')
280
+ I.waitForText('CUSTOM EN: Array must have unique items')
281
+
282
+ I.click('Switch to ES')
283
+
284
+ I.waitForText('CUSTOM ES: Value required')
285
+ I.waitForText('CUSTOM ES: Value must be the constant value')
286
+ I.waitForText('CUSTOM ES: Value must be at least 6 characters long')
287
+ I.waitForText('CUSTOM ES: Value must be at most 6 characters long')
288
+ I.waitForText('CUSTOM ES: Value must validate against at least one of the provided schemas')
289
+ I.waitForText('CUSTOM ES: Value must validate against exactly one of the provided schemas. It currently validates against 0 of the schemas')
290
+ I.waitForText('CUSTOM ES: Value must be one of the provided types')
291
+ I.waitForText('CUSTOM ES: Value must not be one of the provided disallowed types')
292
+ I.waitForText('CUSTOM ES: Value must not be of type string')
293
+ I.waitForText('CUSTOM ES: Value must be of type integer')
294
+ I.waitForText('CUSTOM ES: Value must not validate against the provided schema')
295
+ I.waitForText('CUSTOM ES: Date must be greater than 1 January 1970')
296
+ I.waitForText('CUSTOM ES: Value must match the pattern ^[a-zA-Z0-9_]+$')
297
+ I.waitForText('CUSTOM ES: Value must be a multiple of 5')
298
+ I.waitForText('CUSTOM ES: Value must be at least 5')
299
+ I.waitForText('CUSTOM ES: Value must be greater than 5')
300
+ I.waitForText('CUSTOM ES: Value must be less than 10')
301
+ I.waitForText('CUSTOM ES: Value must be less than 15')
302
+ I.waitForText('CUSTOM ES: Object must have at least 1 properties')
303
+ I.waitForText('CUSTOM ES: Object must have at most 1 properties')
304
+ I.waitForText('CUSTOM ES: Object is missing the required property \'name\'')
305
+ I.waitForText('CUSTOM ES: Unsupported propertyName UNSOPPORTED')
306
+ I.waitForText('CUSTOM ES: Property name fullname cannot match invalid pattern')
307
+ I.waitForText('CUSTOM ES: Property name fullname cannot match invalid enum')
308
+ I.waitForText('CUSTOM ES: Property name fullname cannot match invalid maxLength')
309
+ I.waitForText('CUSTOM ES: Property name fullname exceeds maxLength')
310
+ I.waitForText('CUSTOM ES: Property name pets does not match pattern')
311
+ I.waitForText('CUSTOM ES: Property name $pets does not match pattern')
312
+ I.waitForText('CUSTOM ES: Property name pets does not match the const value')
313
+ I.waitForText('CUSTOM ES: Property name pets does not match any enum values')
314
+ I.waitForText('CUSTOM ES: Array must have unique items')
315
+ })
@@ -3,7 +3,7 @@ Feature('Advanced Editor');
3
3
 
4
4
  Scenario('test validation & delete', (I) => {
5
5
  I.amOnPage('advanced.html');
6
- I.seeElement('#valid_indicator');
6
+ I.retry({ retries: 5, minTimeout: 500 }).seeElement('#valid_indicator');
7
7
  I.see('valid', '#valid_indicator');
8
8
  I.fillField('root[0][location][city]', 'Stuttgart');
9
9
  I.waitForValue("[name='root[0][location][city]']", 'Stuttgart');
@@ -10,6 +10,56 @@ Scenario('should have correct initial value', async (I) => {
10
10
  assert.equal(await I.grabValueFrom('.debug'), '[]');
11
11
  });
12
12
 
13
+ Scenario('unique items arrays sorting @unique-itmes-sorting', async (I) => {
14
+ I.amOnPage('array-unique-items-sort.html')
15
+ I.waitForElement('.je-ready', 10)
16
+ I.click('[data-schemapath="root.items"] .form-control:nth-of-type(1)')
17
+ I.click('.get-value')
18
+ assert.equal(await I.grabValueFrom('.debug'), '{"items":["01"]}')
19
+ I.click('[data-schemapath="root.items"] .form-control:nth-of-type(2)')
20
+ I.click('.get-value')
21
+ assert.equal(await I.grabValueFrom('.debug'), '{"items":["01","02"]}')
22
+ I.click('[data-schemapath="root.items"] .form-control:nth-of-type(3)')
23
+ I.click('.get-value')
24
+ assert.equal(await I.grabValueFrom('.debug'), '{"items":["01","02","03"]}')
25
+ I.click('[data-schemapath="root.items"] .form-control:nth-of-type(4)')
26
+ I.click('.get-value')
27
+ assert.equal(await I.grabValueFrom('.debug'), '{"items":["01","02","03","04"]}')
28
+ I.click('[data-schemapath="root.items"] .form-control:nth-of-type(5)')
29
+ I.click('.get-value')
30
+ assert.equal(await I.grabValueFrom('.debug'), '{"items":["01","02","03","04","05"]}')
31
+ I.click('[data-schemapath="root.items"] .form-control:nth-of-type(6)')
32
+ I.click('.get-value')
33
+ assert.equal(await I.grabValueFrom('.debug'), '{"items":["01","02","03","04","05","06"]}')
34
+ I.click('[data-schemapath="root.items"] .form-control:nth-of-type(7)')
35
+ I.click('.get-value')
36
+ assert.equal(await I.grabValueFrom('.debug'), '{"items":["01","02","03","04","05","06","07"]}')
37
+ I.click('[data-schemapath="root.items"] .form-control:nth-of-type(8)')
38
+ I.click('.get-value')
39
+ assert.equal(await I.grabValueFrom('.debug'), '{"items":["01","02","03","04","05","06","07","08"]}')
40
+ I.click('[data-schemapath="root.items"] .form-control:nth-of-type(9)')
41
+ I.click('.get-value')
42
+ assert.equal(await I.grabValueFrom('.debug'), '{"items":["01","02","03","04","05","06","07","08","09"]}')
43
+ I.click('[data-schemapath="root.items"] .form-control:nth-of-type(10)')
44
+ I.click('.get-value')
45
+ assert.equal(await I.grabValueFrom('.debug'), '{"items":["01","02","03","04","05","06","07","08","09","10"]}')
46
+ I.click('[data-schemapath="root.items"] .form-control:nth-of-type(11)')
47
+ I.click('.get-value')
48
+ assert.equal(await I.grabValueFrom('.debug'), '{"items":["01","02","03","04","05","06","07","08","09","10","11"]}')
49
+ I.click('[data-schemapath="root.items"] .form-control:nth-of-type(12)')
50
+ I.click('.get-value')
51
+ assert.equal(await I.grabValueFrom('.debug'), '{"items":["01","02","03","04","05","06","07","08","09","10","11","12"]}')
52
+ I.click('[data-schemapath="root.items"] .form-control:nth-of-type(13)')
53
+ I.click('.get-value')
54
+ assert.equal(await I.grabValueFrom('.debug'), '{"items":["01","02","03","04","05","06","07","08","09","10","11","12","13"]}')
55
+ I.click('[data-schemapath="root.items"] .form-control:nth-of-type(14)')
56
+ I.click('.get-value')
57
+ assert.equal(await I.grabValueFrom('.debug'), '{"items":["01","02","03","04","05","06","07","08","09","10","11","12","13","14"]}')
58
+ I.click('[data-schemapath="root.items"] .form-control:nth-of-type(15)')
59
+ I.click('.get-value')
60
+ assert.equal(await I.grabValueFrom('.debug'), '{"items":["01","02","03","04","05","06","07","08","09","10","11","12","13","14","15"]}')
61
+ });
62
+
13
63
  Scenario('should trigger array (table) editing triggers @retry', async (I) => {
14
64
  I.amOnPage('table-move-events.html');
15
65
  I.seeElement('[data-schemapath="root.0"]');
@@ -478,6 +528,30 @@ Scenario('should work well with checkbox editors', async (I) => {
478
528
  I.dontSee('Checkbox 3');
479
529
  });
480
530
 
531
+ Scenario('should work well with checkbox editors with infoText', async (I) => {
532
+ I.amOnPage('array-checkboxes-infotext.html')
533
+
534
+ function check (checkboxId, title, infoText) {
535
+ const label = '//label[@for="' + checkboxId + '"]'
536
+ I.see(title, label)
537
+ const infoTextIcon = label + '/span[@class="je-infobutton-icon"]'
538
+
539
+ if (infoText) {
540
+ I.seeElement(infoTextIcon)
541
+ I.moveCursorTo(infoTextIcon)
542
+ I.see(infoText, label + '//span[@class="je-infobutton-tooltip"]')
543
+ } else {
544
+ I.dontSeeElement(infoTextIcon)
545
+ }
546
+ }
547
+
548
+ check('root0', 'old a')
549
+ check('root1', 'b')
550
+ check('root2', '3')
551
+ check('root3', '4', 'dd')
552
+ check('root4', 'e', 'ee')
553
+ })
554
+
481
555
  Scenario('should work well with rating editors', async (I) => {
482
556
  I.amOnPage('array-ratings.html');
483
557
  I.seeElement('[data-schemapath="root.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
17
  I.retry({ retries: 3, minTimeout: 500 }).seeDisabledAttribute('[data-schemapath="root.button2"] button');
16
-
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
  });
@@ -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
+ })