diff --git a/STD-COMP.md b/STD-COMP.md index ed6a351..75a6e69 100755 --- a/STD-COMP.md +++ b/STD-COMP.md @@ -38,9 +38,9 @@ If you don't like the cold text description, click on the [interactive version]( autocomplete: { // Automatic completion itemValueField: 'value', // Item data represents the field of value - itemTemplate: '{{item.value}}', // Display item template + itemTemplate: '{{item.value}} {{item.desc}}', // Display item template immediateShow: false, // Whether to display immediately, if it is false, it will be displayed when input the keyword. - enumSource: [{value: [String | Number | Boolean], label: ''}], // Provided when the prompt data is local rather than remote + enumSource: [{value: [String | Number | Boolean], desc: ''}], // Provided when the prompt data is local rather than remote enumSourceRemote: { remoteUrl: '', // If it is remote call, fill in the url paramName: 'keyword', // Request parameter name, default is keyword diff --git a/STD-COMP_CN.md b/STD-COMP_CN.md index c15eb2f..40c2b03 100644 --- a/STD-COMP_CN.md +++ b/STD-COMP_CN.md @@ -38,9 +38,9 @@ autocomplete: { // 自动补全 itemValueField: 'value', // 项数据表示value的字段 - itemTemplate: '{{item.value}}', // 显示项的模板 + itemTemplate: '{{item.value}} {{item.desc}}', // 显示项的模板 immediateShow: false, // 是否立即显示,如果为false则当输入关键字才显示 - enumSource: [{value: [String | Number | Boolean], label: ''}], // 当提示数据是本地而非远程时提供 + enumSource: [{value: [String | Number | Boolean], desc: ''}], // 当提示数据是本地而非远程时提供 enumSourceRemote: { remoteUrl: '', // 如果是远程访问,则填写该url paramName: 'keyword', // 请求参数名,默认是keyword diff --git a/packages/ncform-e2e/ncform-theme-elementui/cypress.json b/packages/ncform-e2e/ncform-theme-elementui/cypress.json index 724cb75..f90bc8e 100644 --- a/packages/ncform-e2e/ncform-theme-elementui/cypress.json +++ b/packages/ncform-e2e/ncform-theme-elementui/cypress.json @@ -1,4 +1,4 @@ { "projectId": "5y86ie", - "ignoreTestFiles": "__template.spec.js" + "ignoreTestFiles": ["__template.spec.js", "common.js"] } diff --git a/packages/ncform-e2e/ncform-theme-elementui/cypress/fixtures/assets/img/demo1.jpg b/packages/ncform-e2e/ncform-theme-elementui/cypress/fixtures/assets/img/demo1.jpg new file mode 100644 index 0000000..9077bef Binary files /dev/null and b/packages/ncform-e2e/ncform-theme-elementui/cypress/fixtures/assets/img/demo1.jpg differ diff --git a/packages/ncform-e2e/ncform-theme-elementui/cypress/fixtures/assets/img/dx.png b/packages/ncform-e2e/ncform-theme-elementui/cypress/fixtures/assets/img/dx.png new file mode 100644 index 0000000..5d7d691 Binary files /dev/null and b/packages/ncform-e2e/ncform-theme-elementui/cypress/fixtures/assets/img/dx.png differ diff --git a/packages/ncform-e2e/ncform-theme-elementui/cypress/integration/examples/__template.spec.js b/packages/ncform-e2e/ncform-theme-elementui/cypress/integration/examples/__template.spec.js index ac17d72..61cdf85 100644 --- a/packages/ncform-e2e/ncform-theme-elementui/cypress/integration/examples/__template.spec.js +++ b/packages/ncform-e2e/ncform-theme-elementui/cypress/integration/examples/__template.spec.js @@ -1,18 +1,31 @@ /// -const md5 = require('blueimp-md5'); - context('', () => { before(() => { - cy.visit('http://localhost:3000/examples/components/vue-ncform/.html') + cy.visit('http://localhost:3004/examples/components/playground/index.html') }) it('', () => { - let id = md5(''); - cy.get(`[data-cy=${id}]`).within(() => { - cy.get('label').contains('name').next().find('input').should('have.value', 'daniel'); + let formSchema = { + type: 'object', + properties: { + name: { + type: 'string', + } + } + }; + cy.window() + .its('editor') + .invoke('setValue', JSON.stringify(formSchema, null, 2)); + common.startRun(); + + cy.get('.previewArea').within(() => { + // Declare action elements + + // common.submitForm(); }) - }) + + }); }) diff --git a/packages/ncform-e2e/ncform-theme-elementui/cypress/integration/examples/common.js b/packages/ncform-e2e/ncform-theme-elementui/cypress/integration/examples/common.js new file mode 100644 index 0000000..d65c0c6 --- /dev/null +++ b/packages/ncform-e2e/ncform-theme-elementui/cypress/integration/examples/common.js @@ -0,0 +1,31 @@ +export function fillInSchema(formSchema) { + return cy.window() + .its('editor') + .invoke('setValue', JSON.stringify(formSchema, null, 2)); +} + +export function startRun() { + return cy.get('button').contains('Run').click(); +} + +export function submitForm() { + return cy.get('button').contains('Get Data').click() +} + +export function uploadFile(fileUrl) { + return cy.fixture(fileUrl).as('logo') + .get('input[type=file]').then(function (el) { + return Cypress.Blob.base64StringToBlob(this.logo, 'image/png') + .then(blob => { + el[0].files[0] = blob + el[0].dispatchEvent(new Event('change', { bubbles: true })) + }) + }) +} + +export default { + startRun, + submitForm, + fillInSchema, + uploadFile +} diff --git a/packages/ncform-e2e/ncform-theme-elementui/cypress/integration/examples/input.spec.js b/packages/ncform-e2e/ncform-theme-elementui/cypress/integration/examples/input.spec.js index dbb7328..da13ddf 100644 --- a/packages/ncform-e2e/ncform-theme-elementui/cypress/integration/examples/input.spec.js +++ b/packages/ncform-e2e/ncform-theme-elementui/cypress/integration/examples/input.spec.js @@ -1,27 +1,407 @@ /// +import common from './common'; + context('input', () => { before(() => { cy.visit('http://localhost:3004/examples/components/playground/index.html'); }); - it('', () => { + it('Basic', () => { + let formSchema = { + type: 'object', + properties: { + // has init value + name0: { + type: 'string', + value: 'daniel' + }, + name1: { + type: 'string', + ui: { + disabled: true + } + }, + name2: { + type: 'string', + ui: { + readonly: true + } + }, + name3: { + type: 'string', + ui: { + hidden: true + } + }, + name4: { + type: 'string', + ui: { + placeholder: 'your name' + } + } + } + }; + common.fillInSchema(formSchema); + common.startRun(); + // common.submitForm(); + + cy.get('.previewArea').within(() => { + + cy.get('label').contains('name0').as('nameLabel0'); + cy.get('@nameLabel0').next().find('input').as('nameInput0'); + cy.get('@nameInput0').should('have.value', 'daniel'); + + cy.get('label').contains('name1').as('nameLabel1'); + cy.get('@nameLabel1').next().find('input').as('nameInput1'); + cy.get('@nameInput1').should('be.disabled'); + + cy.get('label').contains('name2').as('nameLabel2'); + cy.get('@nameLabel2').next().find('input').as('nameInput2'); + cy.get('@nameInput2').should('have.prop', 'readonly'); + + cy.get('label').contains('name3').as('nameLabel3'); + cy.get('@nameLabel3').next().find('input').as('nameInput3'); + cy.get('@nameInput3').should('not.be.visible'); + + cy.get('label').contains('name4').as('nameLabel4'); + cy.get('@nameLabel4').next().find('input').as('nameInput4'); + cy.get('@nameInput4').should('have.prop', 'placeholder', 'your name'); + + }) + + }); + + it('Simple Props', () => { + + let formSchema = { + type: 'object', + properties: { + // has init value + name1: { + type: 'string', + ui: { + widgetConfig: { + prefixIcon: 'el-icon-search', + trim: false + } + } + }, + name2: { + type: 'string', + ui: { + widgetConfig: { + suffixIcon: 'el-icon-date', + clearable: true + } + } + }, + name3: { + type: 'string', + ui: { + widgetConfig: { + prefixIcon: 'el-icon-search', + suffixIcon: 'el-icon-date', + } + } + } + } + }; + common.fillInSchema(formSchema); + common.startRun(); + // common.submitForm(); + + cy.get('.previewArea').within(() => { + + cy.get('label').contains('name1').as('nameLabel1'); + cy.get('@nameLabel1').next().find('input').as('nameInput1'); + cy.get('@nameInput1').type(' daniel ').should('have.value', ' daniel '); + cy.get('@nameInput1').parent().find('.el-icon-search').should('exist'); + cy.get('@nameInput1').parent().find('.el-input__clear').should('not.be.visible'); + + cy.get('label').contains('name2').as('nameLabel2'); + cy.get('@nameLabel2').next().find('input').as('nameInput2'); + cy.get('@nameInput2').parent().find('.el-input__clear').should('not.be.visible'); + cy.get('@nameInput2').type(' daniel ').should('have.value', 'daniel'); + cy.get('@nameInput2').parent().find('.el-input__clear').should('be.visible'); + cy.get('@nameInput2').parent().find('.el-input__clear').click(); + cy.get('@nameInput2').should('have.value', ''); + cy.get('@nameInput2').parent().find('.el-input__clear').should('not.be.visible'); + cy.get('@nameInput2').parent().find('.el-icon-date').should('exist'); + + cy.get('label').contains('name3').parent().as('item'); + cy.get('@item').find('.el-icon-search').should('exist'); + cy.get('@item').find('.el-icon-date').should('exist'); + }) + + }); + + it('type', () => { + + cy.server() + cy.route({ + method: 'POST', + url: '/upload', + response: { data: 'https://avatars1.githubusercontent.com/u/22042268?s=40&v=4' } + }).as('upload'); + + let formSchema = { + type: 'object', + properties: { + name2: { + type: 'string', + ui: { + widgetConfig: { + type: 'number' + } + } + }, + name3: { + type: 'string', + ui: { + widgetConfig: { + type: 'password' + } + } + }, + name4: { + type: 'string', + ui: { + widgetConfig: { + type: 'file', + upload: { + uploadUrl: '/upload', + resField: 'data.data', + data: { + name: 'daniel' + }, + fileField: 'photo', + accept: '.png', + uploadText: 'Upload Now', + } + }, + preview: { + type: 'image' + } + } + }, + name5: { + type: 'string', + ui: { + widgetConfig: { + type: 'file', + upload: { + uploadUrl: '/upload', + resField: 'data.data', + data: { + name: 'daniel' + }, + constraint: { + maxSize: 30, + minSize: 10 + }, + } + }, + preview: { + type: 'image' + } + } + }, + name6: { + type: 'string', + ui: { + widgetConfig: { + type: 'file', + upload: { + uploadUrl: '/upload', + resField: 'data.data', + data: { + name: 'daniel' + }, + constraint: { + width: 320, + height: 320, + sizeFixed: true + }, + } + }, + preview: { + type: 'image' + } + } + }, + name7: { + type: 'string', + ui: { + widgetConfig: { + type: 'file', + upload: { + uploadUrl: '/upload', + resField: 'data.data', + data: { + name: 'daniel' + }, + constraint: { + width: 320, + height: 320, + sizeFixed: false + }, + } + }, + preview: { + type: 'image' + } + } + } + } + }; + common.fillInSchema(formSchema); + common.startRun(); + + cy.get('.previewArea').within(() => { + + cy.get('label').contains('name2').as('nameLabel2'); + cy.get('@nameLabel2').next().find('input').as('nameInput2'); + cy.get('@nameInput2').type('daniel').should('have.value', ''); + cy.get('@nameInput2').type('123').should('have.value', '123'); + + cy.get('label').contains('name3').as('nameLabel3'); + cy.get('@nameLabel3').next().find('input').as('nameInput3'); + cy.get('@nameInput3').type('daniel123').should('have.value', 'daniel123').and('have.prop', 'type', 'password'); + + cy.get('label').contains('name4').parent().within(() => { + cy.get('button').contains('Upload Now').should('exist') + common.uploadFile('assets/img/dx.png'); + cy.wait('@upload').then(xhr => { + let uploadParams = {}; + xhr.request.body.forEach((item, key) => uploadParams[key] = item); + cy.wrap(uploadParams).its('name').should('equal', 'daniel'); + cy.wrap(uploadParams).should('have.property', 'photo'); + }); + cy.get('input').should('have.value', 'https://avatars1.githubusercontent.com/u/22042268?s=40&v=4') + }); + + cy.get('label').contains('name5').parent().within(() => { + common.uploadFile('assets/img/dx.png'); + cy.wait(1000); + cy.get('input').should('have.value', '') + + common.uploadFile('assets/img/demo1.jpg'); + cy.wait(1000); + cy.get('input').should('have.value', '') + }); + + cy.get('label').contains('name6').parent().within(() => { + common.uploadFile('assets/img/demo1.jpg'); + cy.wait(1000); + cy.get('input').should('have.value', '') + + common.uploadFile('assets/img/dx.png'); + cy.wait(1000); + cy.get('input').should('have.value', '') + }); + + cy.get('label').contains('name7').parent().within(() => { + common.uploadFile('assets/img/demo1.jpg'); + cy.wait(1000); + cy.get('input').should('have.value', '') + + common.uploadFile('assets/img/dx.png'); + cy.wait(1000); + cy.get('input').should('have.value', 'https://avatars1.githubusercontent.com/u/22042268?s=40&v=4') + }); + + }) + + }); + + it('autocomplete', () => { + + cy.server() + cy.route({ + method: 'GET', + url: '/autocomplete?**', + response: { + data: [ + { + name: 'daniel', + desc: 'boy' + }, + { + name: 'sarah', + desc: 'girl' + } + ] + } + }).as('autocomplete'); + + let formSchema = { + type: 'object', + properties: { + name1: { + type: 'string', + ui: { + widgetConfig: { + autocomplete: { + itemValueField: 'name', + immediateShow: false, + enumSource: [{ name: 'daniel' }, { name: 'sarah' }], + }, + } + } + }, + name2: { + type: 'string', + ui: { + widgetConfig: { + autocomplete: { + itemValueField: 'name', + itemTemplate: '{{item.name}} [{{item.desc}}]', + immediateShow: true, + enumSourceRemote: { + remoteUrl: '/autocomplete', + paramName: 'keyword', + otherParams: { + name: 'daniel' + }, + resField: 'data', + } + }, + } + } + } + } + }; cy.window() .its('editor') - .invoke( - 'setValue', - JSON.stringify( - { - type: 'object', - properties: { - name: { - type: 'string' - } - } - }, - null, - 2 - ) - ); + .invoke('setValue', JSON.stringify(formSchema, null, 2)); + common.startRun(); + + cy.get('body').as('body'); + + cy.get('.previewArea').within(() => { + // Declare action elements + cy.get('label').contains('name1').parent().within(() => { + cy.get('input').type('da'); + cy.get('@body').find('li:contains("daniel")').click(); + cy.get('input').should('have.value', 'daniel'); + }) + + cy.get('label').contains('name2').parent().within(() => { + cy.get('input').focus(); + cy.wait('@autocomplete').then(xhr => { + expect(xhr.url).to.be.contains('name=daniel&keyword=') + }); + cy.get('input').type('sa'); + cy.wait('@autocomplete').then(xhr => { + expect(xhr.url).to.be.contains('name=daniel&keyword=sa') + }); + }) + + }) + + + }); + }); diff --git a/packages/ncform-theme-elementui/examples/control-comps/input.html b/packages/ncform-theme-elementui/examples/control-comps/input.html index 2ae66b8..b02d659 100755 --- a/packages/ncform-theme-elementui/examples/control-comps/input.html +++ b/packages/ncform-theme-elementui/examples/control-comps/input.html @@ -106,44 +106,6 @@ } } }, - { - title: { - cn: '[属性] trim: 前后去空格。默认值是true', - en: '[ATTR] trim: remove the spaces before and after. Default is true' - }, - schema: { - type: 'object', - properties: { - name: { - type: 'string', - ui: { - widgetConfig: { - trim: false - } - } - } - } - } - }, - { - title: { - cn: '[属性] clearable: 当有内容时显示清空按钮。默认值是false', - en: '[ATTR] clearable: With clear button. Default is false' - }, - schema: { - type: 'object', - properties: { - name: { - type: 'string', - ui: { - widgetConfig: { - clearable: true - } - } - } - } - } - }, { title: { cn: '[属性] readonly: 只读状态', @@ -214,6 +176,44 @@ } } }, + { + title: { + cn: '[属性] trim: 前后去空格。默认值是true', + en: '[ATTR] trim: remove the spaces before and after. Default is true' + }, + schema: { + type: 'object', + properties: { + name: { + type: 'string', + ui: { + widgetConfig: { + trim: false + } + } + } + } + } + }, + { + title: { + cn: '[属性] clearable: 当有内容时显示清空按钮。默认值是false', + en: '[ATTR] clearable: With clear button. Default is false' + }, + schema: { + type: 'object', + properties: { + name: { + type: 'string', + ui: { + widgetConfig: { + clearable: true + } + } + } + } + } + }, { title: { cn: '[属性] prefixIcon: 前图标样式名', diff --git a/packages/ncform-theme-elementui/src/components/control-comps/input.vue b/packages/ncform-theme-elementui/src/components/control-comps/input.vue index f23f3c3..d046e8d 100755 --- a/packages/ncform-theme-elementui/src/components/control-comps/input.vue +++ b/packages/ncform-theme-elementui/src/components/control-comps/input.vue @@ -1,53 +1,157 @@