@json-editor/json-editor 2.5.4 → 2.6.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.
- package/CHANGELOG.md +21 -14
- package/README.md +1 -2
- package/dist/jsoneditor.js +2 -2
- package/dist/nonmin/jsoneditor.js +3041 -3198
- package/dist/nonmin/jsoneditor.js.map +1 -1
- package/docs/meta_schema.json +0 -1
- package/package.json +27 -26
- package/release-notes.md +3 -3
- package/src/editor.js +5 -1
- package/src/editors/multiple.js +2 -0
- package/src/editors/object.js +7 -2
- package/src/editors/radio.js +6 -1
- package/src/editors/string.js +3 -1
- package/src/editors/table.js +1 -0
- package/src/schemaloader.js +1 -1
- package/src/theme.js +5 -2
- package/src/themes/bootstrap3.js +2 -2
- package/src/themes/bootstrap4.js +7 -0
- package/src/validator.js +29 -13
- package/tests/codeceptjs/editors/button_test.js +1 -1
- package/tests/codeceptjs/editors/object_test.js +55 -4
- package/tests/codeceptjs/editors/stepper_test.js +12 -0
- package/tests/codeceptjs/editors/validation_test.js +1 -1
- package/tests/fixtures/validation.json +207 -0
- package/tests/pages/meta_schema.json +0 -1
- package/tests/pages/object-required-properties.html +30 -7
- package/tests/pages/object-show-opt-in.html +110 -0
- package/tests/pages/stepper-manual.html +57 -0
- package/tests/unit/validator.spec.js +10 -0
package/docs/meta_schema.json
CHANGED
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@json-editor/json-editor",
|
|
3
3
|
"title": "JSONEditor",
|
|
4
4
|
"description": "JSON Schema based editor",
|
|
5
|
-
"version": "2.
|
|
5
|
+
"version": "2.6.0",
|
|
6
6
|
"main": "dist/jsoneditor.js",
|
|
7
7
|
"author": {
|
|
8
8
|
"name": "Jeremy Dorn",
|
|
@@ -53,48 +53,49 @@
|
|
|
53
53
|
"node": ">= 0.8.0"
|
|
54
54
|
},
|
|
55
55
|
"devDependencies": {
|
|
56
|
-
"@babel/core": "^7.
|
|
57
|
-
"@babel/plugin-transform-runtime": "^7.
|
|
58
|
-
"@babel/preset-env": "^7.
|
|
59
|
-
"@babel/runtime": "^7.
|
|
60
|
-
"ace-builds": "^1.4.
|
|
61
|
-
"babel-loader": "^8.
|
|
56
|
+
"@babel/core": "^7.14.0",
|
|
57
|
+
"@babel/plugin-transform-runtime": "^7.13.15",
|
|
58
|
+
"@babel/preset-env": "^7.14.1",
|
|
59
|
+
"@babel/runtime": "^7.14.0",
|
|
60
|
+
"ace-builds": "^1.4.12",
|
|
61
|
+
"babel-loader": "^8.2.2",
|
|
62
62
|
"clean-webpack-plugin": "^3.0.0",
|
|
63
|
-
"cleave.js": "^1.
|
|
64
|
-
"codeceptjs": "^2.6.
|
|
65
|
-
"css-loader": "^3.
|
|
63
|
+
"cleave.js": "^1.6.0",
|
|
64
|
+
"codeceptjs": "^2.6.11",
|
|
65
|
+
"css-loader": "^3.6.0",
|
|
66
66
|
"css2json": "^1.1.1",
|
|
67
|
-
"cssnano": "^4.1.
|
|
67
|
+
"cssnano": "^4.1.11",
|
|
68
68
|
"eslint": "^6.8.0",
|
|
69
69
|
"eslint-loader": "^2.2.1",
|
|
70
|
+
"fast-deep-equal": "^3.1.3",
|
|
70
71
|
"http-server": "^0.12.3",
|
|
71
|
-
"jasmine": "^3.
|
|
72
|
-
"jasmine-core": "^3.
|
|
73
|
-
"jodit": "
|
|
74
|
-
"jquery": "^3.
|
|
75
|
-
"karma": "^5.
|
|
72
|
+
"jasmine": "^3.7.0",
|
|
73
|
+
"jasmine-core": "^3.7.1",
|
|
74
|
+
"jodit": "~3.3.24",
|
|
75
|
+
"jquery": "^3.6.0",
|
|
76
|
+
"karma": "^5.2.3",
|
|
76
77
|
"karma-chrome-launcher": "^3.1.0",
|
|
77
78
|
"karma-jasmine": "^2.0.1",
|
|
78
|
-
"karma-jasmine-html-reporter": "^1.
|
|
79
|
-
"karma-sourcemap-loader": "^0.3.
|
|
79
|
+
"karma-jasmine-html-reporter": "^1.6.0",
|
|
80
|
+
"karma-sourcemap-loader": "^0.3.8",
|
|
80
81
|
"karma-webpack": "^4.0.2",
|
|
81
|
-
"mathjs": "^
|
|
82
|
+
"mathjs": "^7.5.1",
|
|
82
83
|
"mini-css-extract-plugin": "^0.8.2",
|
|
83
84
|
"mocha": "^6.2.2",
|
|
84
85
|
"mochawesome": "^4.1.0",
|
|
85
|
-
"postcss-loader": "^
|
|
86
|
+
"postcss-loader": "^5.2.0",
|
|
86
87
|
"puppeteer": "^1.20.0",
|
|
87
88
|
"remove-strict-webpack-plugin": "^0.1.2",
|
|
88
89
|
"sceditor": "^2.1.3",
|
|
89
90
|
"sinon": "^8.1.1",
|
|
90
|
-
"standard": "^14.3.
|
|
91
|
-
"style-loader": "^1.
|
|
92
|
-
"webpack": "^4.
|
|
93
|
-
"webpack-cli": "^3.3.
|
|
94
|
-
"webpack-dev-server": "^3.11.
|
|
91
|
+
"standard": "^14.3.4",
|
|
92
|
+
"style-loader": "^1.3.0",
|
|
93
|
+
"webpack": "^4.46.0",
|
|
94
|
+
"webpack-cli": "^3.3.12",
|
|
95
|
+
"webpack-dev-server": "^3.11.2",
|
|
95
96
|
"webpack-merge": "^4.2.2"
|
|
96
97
|
},
|
|
97
98
|
"dependencies": {
|
|
98
|
-
"core-js": "^3.
|
|
99
|
+
"core-js": "^3.12.1"
|
|
99
100
|
}
|
|
100
101
|
}
|
package/release-notes.md
CHANGED
|
@@ -79,10 +79,10 @@ For now I have passed in `JSONEditor.defaults` as `defaults`.
|
|
|
79
79
|
|
|
80
80
|
### NPM Release
|
|
81
81
|
|
|
82
|
-
1.
|
|
83
|
-
2.
|
|
82
|
+
1. Update `CHANGELOG.md`
|
|
83
|
+
2. Switch to `release` branch and `merge master into release`
|
|
84
84
|
3. NPM login: `npm login`
|
|
85
|
-
4. Build new version: `npm version
|
|
85
|
+
4. Build new version: `npm version 2.x.x`
|
|
86
86
|
|
|
87
87
|
The `npm version` command will automatically build the source files & test the new generated script files.
|
|
88
88
|
On success the `postversion` script will push the source to GitHub and publish the version on NPM.
|
package/src/editor.js
CHANGED
|
@@ -206,7 +206,11 @@ export class AbstractEditor {
|
|
|
206
206
|
})
|
|
207
207
|
|
|
208
208
|
/* append active/deactive checkbox if show_opt_in is true */
|
|
209
|
-
|
|
209
|
+
const globalOptIn = this.jsoneditor.options.show_opt_in
|
|
210
|
+
const parentOptInDefined = (typeof this.parent.options.show_opt_in !== 'undefined')
|
|
211
|
+
const parentOptInEnabled = (parentOptInDefined && this.parent.options.show_opt_in === true)
|
|
212
|
+
const parentOptInDisabled = (parentOptInDefined && this.parent.options.show_opt_in === false)
|
|
213
|
+
if (parentOptInEnabled || (!parentOptInDisabled && globalOptIn) || (!parentOptInDefined && globalOptIn)) {
|
|
210
214
|
/* and control to type object editors if they are not required */
|
|
211
215
|
if (this.parent && this.parent.schema.type === 'object' && !this.isRequired() && this.header) {
|
|
212
216
|
this.header.appendChild(this.optInCheckbox)
|
package/src/editors/multiple.js
CHANGED
package/src/editors/object.js
CHANGED
|
@@ -793,7 +793,11 @@ export class ObjectEditor extends AbstractEditor {
|
|
|
793
793
|
|
|
794
794
|
deactivateNonRequiredProperties () {
|
|
795
795
|
/* the show_opt_in editor option is for backward compatibility */
|
|
796
|
-
|
|
796
|
+
const globalOptIn = this.jsoneditor.options.show_opt_in
|
|
797
|
+
const editorOptInDefined = (typeof this.options.show_opt_in !== 'undefined')
|
|
798
|
+
const editorOptInEnabled = (editorOptInDefined && this.options.show_opt_in === true)
|
|
799
|
+
const editorOptInDisabled = (editorOptInDefined && this.options.show_opt_in === false)
|
|
800
|
+
if (editorOptInEnabled || (!editorOptInDisabled && globalOptIn) || (!editorOptInDefined && globalOptIn)) {
|
|
797
801
|
Object.entries(this.editors).forEach(([key, editor]) => {
|
|
798
802
|
if (!this.isRequiredObject(editor)) {
|
|
799
803
|
this.editors[key].deactivate()
|
|
@@ -993,7 +997,8 @@ export class ObjectEditor extends AbstractEditor {
|
|
|
993
997
|
this.editors[name].register()
|
|
994
998
|
/* New property */
|
|
995
999
|
} else {
|
|
996
|
-
if (!this.canHaveAdditionalProperties() && (!this.schema.properties || !this.schema.properties[name])
|
|
1000
|
+
if (!this.canHaveAdditionalProperties() && (!this.schema.properties || !this.schema.properties[name]) &&
|
|
1001
|
+
(!this.schema.patternProperties || !(Object.keys(this.schema.patternProperties).find(i => new RegExp(i).test(name))))) {
|
|
997
1002
|
return
|
|
998
1003
|
}
|
|
999
1004
|
|
package/src/editors/radio.js
CHANGED
|
@@ -2,7 +2,6 @@ import { SelectEditor } from './select.js'
|
|
|
2
2
|
|
|
3
3
|
export class RadioEditor extends SelectEditor {
|
|
4
4
|
preBuild () {
|
|
5
|
-
this.schema.required = true /* force editor into required mode to prevent creation of empty radio button */
|
|
6
5
|
super.preBuild()
|
|
7
6
|
}
|
|
8
7
|
|
|
@@ -22,6 +21,12 @@ export class RadioEditor extends SelectEditor {
|
|
|
22
21
|
this.onChange(true)
|
|
23
22
|
}
|
|
24
23
|
|
|
24
|
+
if (!this.isRequired()) {
|
|
25
|
+
this.enum_display.shift()
|
|
26
|
+
this.enum_options.shift()
|
|
27
|
+
this.enum_values.shift()
|
|
28
|
+
}
|
|
29
|
+
|
|
25
30
|
for (let i = 0; i < this.enum_values.length; i++) {
|
|
26
31
|
/* form radio elements */
|
|
27
32
|
this.input = this.theme.getFormRadio({
|
package/src/editors/string.js
CHANGED
|
@@ -6,12 +6,14 @@ export class StringEditor extends AbstractEditor {
|
|
|
6
6
|
super.register()
|
|
7
7
|
if (!this.input) return
|
|
8
8
|
this.input.setAttribute('name', this.formname)
|
|
9
|
+
this.input.setAttribute('aria-label', this.formname)
|
|
9
10
|
}
|
|
10
11
|
|
|
11
12
|
unregister () {
|
|
12
13
|
super.unregister()
|
|
13
14
|
if (!this.input) return
|
|
14
15
|
this.input.removeAttribute('name')
|
|
16
|
+
this.input.removeAttribute('aria-label')
|
|
15
17
|
}
|
|
16
18
|
|
|
17
19
|
setValue (value, initial, fromTemplate) {
|
|
@@ -201,7 +203,7 @@ export class StringEditor extends AbstractEditor {
|
|
|
201
203
|
input = this.theme.getRangeControl(this.input, this.theme.getRangeOutput(this.input, this.schema.default || Math.max(this.schema.minimum || 0, 0)))
|
|
202
204
|
}
|
|
203
205
|
|
|
204
|
-
this.control = this.theme.getFormControl(this.label, input, this.description, this.infoButton)
|
|
206
|
+
this.control = this.theme.getFormControl(this.label, input, this.description, this.infoButton, this.formname)
|
|
205
207
|
this.container.appendChild(this.control)
|
|
206
208
|
|
|
207
209
|
/* Any special formatting that needs to happen after the input is added to the dom */
|
package/src/editors/table.js
CHANGED
|
@@ -99,6 +99,7 @@ export class TableEditor extends ArrayEditor {
|
|
|
99
99
|
|
|
100
100
|
/* Row Controls column */
|
|
101
101
|
this.controls_header_cell = this.theme.getTableHeaderCell(' ')
|
|
102
|
+
this.controls_header_cell.setAttribute('aria-hidden', 'true')
|
|
102
103
|
this.header_row.appendChild(this.controls_header_cell)
|
|
103
104
|
|
|
104
105
|
/* Add controls */
|
package/src/schemaloader.js
CHANGED
|
@@ -136,7 +136,7 @@ export class SchemaLoader {
|
|
|
136
136
|
|
|
137
137
|
_expandSubSchema (subschema) {
|
|
138
138
|
/* Array of types */
|
|
139
|
-
if (Array.isArray(subschema)) return subschema.map(m => typeof
|
|
139
|
+
if (Array.isArray(subschema)) return subschema.map(m => typeof m === 'object' ? this.expandSchema(m) : m)
|
|
140
140
|
|
|
141
141
|
/* Schema */
|
|
142
142
|
return this.expandSchema(subschema)
|
package/src/theme.js
CHANGED
|
@@ -325,10 +325,13 @@ export class AbstractTheme {
|
|
|
325
325
|
|
|
326
326
|
}
|
|
327
327
|
|
|
328
|
-
getFormControl (label, input, description, infoText) {
|
|
328
|
+
getFormControl (label, input, description, infoText, formName) {
|
|
329
329
|
const el = document.createElement('div')
|
|
330
330
|
el.classList.add('form-control')
|
|
331
|
-
if (label)
|
|
331
|
+
if (label) {
|
|
332
|
+
el.appendChild(label)
|
|
333
|
+
if (formName) label.setAttribute('for', formName)
|
|
334
|
+
}
|
|
332
335
|
if ((input.type === 'checkbox' || input.type === 'radio') && label) {
|
|
333
336
|
input.style.width = 'auto'
|
|
334
337
|
label.insertBefore(input, label.firstChild)
|
package/src/themes/bootstrap3.js
CHANGED
|
@@ -172,14 +172,14 @@ export class bootstrap3Theme extends AbstractTheme {
|
|
|
172
172
|
getTabHolder (propertyName) {
|
|
173
173
|
const pName = (typeof propertyName === 'undefined') ? '' : propertyName
|
|
174
174
|
const el = document.createElement('div')
|
|
175
|
-
el.innerHTML = `<ul class='col-md-2 nav nav-pills nav-stacked' id='${pName}' role='tablist'></ul><div class='col-md-10 tab-content well well-small' id='${pName}'></div>`
|
|
175
|
+
el.innerHTML = `<ul class='col-md-2 nav nav-pills nav-stacked' id='${pName}' role='tablist'></ul><div class='col-md-10 tab-content active well well-small' id='${pName}'></div>`
|
|
176
176
|
return el
|
|
177
177
|
}
|
|
178
178
|
|
|
179
179
|
getTopTabHolder (propertyName) {
|
|
180
180
|
const pName = (typeof propertyName === 'undefined') ? '' : propertyName
|
|
181
181
|
const el = document.createElement('div')
|
|
182
|
-
el.innerHTML = `<ul class='nav nav-tabs' id='${pName}' role='tablist'></ul><div class='tab-content well well-small' id='${pName}'></div>`
|
|
182
|
+
el.innerHTML = `<ul class='nav nav-tabs' id='${pName}' role='tablist'></ul><div class='tab-content active well well-small' id='${pName}'></div>`
|
|
183
183
|
return el
|
|
184
184
|
}
|
|
185
185
|
|
package/src/themes/bootstrap4.js
CHANGED
|
@@ -135,6 +135,12 @@ export class bootstrap4Theme extends AbstractTheme {
|
|
|
135
135
|
const min = input.getAttribute('min')
|
|
136
136
|
const max = input.getAttribute('max')
|
|
137
137
|
|
|
138
|
+
input.addEventListener('change', () => {
|
|
139
|
+
if (!input.getAttribute('initialized')) {
|
|
140
|
+
input.setAttribute('initialized', '1')
|
|
141
|
+
}
|
|
142
|
+
})
|
|
143
|
+
|
|
138
144
|
minusBtn.addEventListener('click', () => {
|
|
139
145
|
if (!input.getAttribute('initialized')) {
|
|
140
146
|
initialize(input, min)
|
|
@@ -405,6 +411,7 @@ export class bootstrap4Theme extends AbstractTheme {
|
|
|
405
411
|
|
|
406
412
|
const el = document.createElement('h3')
|
|
407
413
|
el.classList.add('card-title')
|
|
414
|
+
el.classList.add('level-' + pathDepth)
|
|
408
415
|
|
|
409
416
|
if (typeof text === 'string') {
|
|
410
417
|
el.textContent = text
|
package/src/validator.js
CHANGED
|
@@ -350,6 +350,7 @@ export class Validator {
|
|
|
350
350
|
schema.required.forEach(e => {
|
|
351
351
|
if (typeof value[e] !== 'undefined') return
|
|
352
352
|
const editor = this.jsoneditor.getEditor(`${path}.${e}`)
|
|
353
|
+
if (editor && editor.dependenciesFulfilled === false) return
|
|
353
354
|
/* Ignore required error if editor is of type "button" or "info" */
|
|
354
355
|
if (editor && ['button', 'info'].includes(editor.schema.format || editor.schema.type)) return
|
|
355
356
|
errors.push({
|
|
@@ -527,20 +528,35 @@ export class Validator {
|
|
|
527
528
|
const fit = { match: 0, extra: 0 }
|
|
528
529
|
if (typeof value === 'object' && value !== null) {
|
|
529
530
|
/* Work on a copy of the schema */
|
|
530
|
-
const
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
531
|
+
const schema = this._getSchema(givenSchema)
|
|
532
|
+
/* If the schema is an anyOf declaration, do use the properties of the allowed sub schemata instead.
|
|
533
|
+
Of these sub schemata, the best fit is selected */
|
|
534
|
+
if (schema.anyOf) {
|
|
535
|
+
let bestFit = { ...fit }
|
|
536
|
+
for (const subSchema of schema.anyOf) {
|
|
537
|
+
const subFit = this.fitTest(value, subSchema, weight)
|
|
538
|
+
/* The best fit is the one with the best value for match. If there are multiple results
|
|
539
|
+
with the same match value, use the one with the least number of extra properties */
|
|
540
|
+
if ((subFit.match > bestFit.match) || (subFit.match === bestFit.match && subFit.extra < bestFit.extra)) {
|
|
541
|
+
bestFit = subFit
|
|
542
|
+
}
|
|
541
543
|
}
|
|
542
|
-
|
|
543
|
-
|
|
544
|
+
return bestFit
|
|
545
|
+
} else {
|
|
546
|
+
const properties = this._getSchema(givenSchema).properties
|
|
547
|
+
for (const i in properties) {
|
|
548
|
+
if (!hasOwnProperty(properties, i)) {
|
|
549
|
+
fit.extra += weight
|
|
550
|
+
continue
|
|
551
|
+
}
|
|
552
|
+
if (typeof value[i] === 'object' && typeof properties[i] === 'object' && typeof properties[i].properties === 'object') {
|
|
553
|
+
const result = this.fitTest(value[i], properties[i], weight / 100)
|
|
554
|
+
fit.match += result.match
|
|
555
|
+
fit.extra += result.extra
|
|
556
|
+
}
|
|
557
|
+
if (typeof value[i] !== 'undefined') {
|
|
558
|
+
fit.match += weight
|
|
559
|
+
}
|
|
544
560
|
}
|
|
545
561
|
}
|
|
546
562
|
}
|
|
@@ -12,7 +12,7 @@ Scenario('should work with button editor callbacks', async (I) => {
|
|
|
12
12
|
Scenario('should work with option "validated"', async (I) => {
|
|
13
13
|
I.amOnPage('button-callbacks.html');
|
|
14
14
|
I.seeElement('[data-schemapath="root.button1"] button');
|
|
15
|
-
I.seeDisabledAttribute('[data-schemapath="root.button2"] button');
|
|
15
|
+
I.retry({ retries: 3, minTimeout: 500 }).seeDisabledAttribute('[data-schemapath="root.button2"] button');
|
|
16
16
|
|
|
17
17
|
await I.fillField('[name="root[textinput]"]', 'Hello World');
|
|
18
18
|
|
|
@@ -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) => {
|
|
@@ -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
|
+
})
|
|
@@ -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 =
|
|
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')
|