diff --git a/.github/workflows/node.js.yml b/.github/workflows/node.js.yml
index f2a9203a9f..82cecb5f62 100644
--- a/.github/workflows/node.js.yml
+++ b/.github/workflows/node.js.yml
@@ -36,6 +36,7 @@ jobs:
- run: npm run gen
- run: npm run genmatter
- run: npm run gendotdot
+ - run: xvfb-run -a npm run test:e2e-ci
- run: export GH_TOKEN=${{ secrets.GITHUB_TOKEN}} && npm run dist-linux
- run: xvfb-run -a dist/linux-unpacked/zap selfCheck
- name: Archive .rpm file
diff --git a/cypress.json b/cypress.json
index dec5a520f0..0e2f33593c 100644
--- a/cypress.json
+++ b/cypress.json
@@ -1,4 +1,7 @@
{
- "viewportWidth": 1080,
- "viewportHeight": 920
- }
\ No newline at end of file
+ "viewportWidth": 1080,
+ "viewportHeight": 920,
+ "video": false,
+ "testFiles": "**/theme/theme.spec.js",
+ "ignoreTestFiles": ["**/*.test.js"]
+}
diff --git a/cypress/integration/attribute validations/bitmap8.spec.js b/cypress/integration/attribute validations/bitmap8.spec.js
new file mode 100644
index 0000000000..268ef367a1
--- /dev/null
+++ b/cypress/integration/attribute validations/bitmap8.spec.js
@@ -0,0 +1,27 @@
+///
+
+Cypress.on('uncaught:exception', (err, runnable) => {
+ // returning false here prevents Cypress from
+ // failing the test
+ return false
+})
+
+describe('Testing BITMAP8 type validation', () => {
+ it('create a new endpoint and click on configure to open attributes of endpoint', () => {
+ cy.visit('http://localhost:8080/?restPort=9070#/')
+ cy.gotoAttributePage('Billing Unit (0x0203)', 'General')
+ cy.wait(1000)
+ })
+ it('getting an attribute with BITMAP8 type and change defualt amount', () => {
+ cy.get(
+ ':nth-child(16) > [style="min-width: 180px;"] > .q-field > .q-field__inner > .q-field__control > .q-field__control-container > input'
+ )
+ .clear({ force: true })
+ .type('test', { force: true })
+ })
+ it('check if validation works properly', () => {
+ cy.get(
+ ':nth-child(16) > [style="min-width: 180px;"] > .q-field > .q-field__inner > .q-field__bottom > .q-field__messages > div'
+ ).should('exist')
+ })
+})
diff --git a/cypress/integration/attribute validations/boolean.spec.js b/cypress/integration/attribute validations/boolean.spec.js
new file mode 100644
index 0000000000..062fa60ec4
--- /dev/null
+++ b/cypress/integration/attribute validations/boolean.spec.js
@@ -0,0 +1,27 @@
+///
+
+Cypress.on('uncaught:exception', (err, runnable) => {
+ // returning false here prevents Cypress from
+ // failing the test
+ return false
+})
+
+describe('Testing BOOLEAN type validation', () => {
+ it('create a new endpoint and click on configure to open attributes of endpoint', () => {
+ cy.visit('http://localhost:8080/?restPort=9070#/')
+ cy.gotoAttributePage('Billing Unit (0x0203)', 'General')
+ cy.wait(1000)
+ })
+ it('getting an attribute with BOOLEAN type and change defualt amount', () => {
+ cy.get(
+ ':nth-child(15) > [style="min-width: 180px;"] > .q-field > .q-field__inner > .q-field__control > .q-field__control-container > input'
+ )
+ .clear({ force: true })
+ .type('test', { force: true })
+ })
+ it('check if validation works properly', () => {
+ cy.get(
+ ':nth-child(15) > [style="min-width: 180px;"] > .q-field > .q-field__inner > .q-field__bottom > .q-field__messages > div'
+ ).should('exist')
+ })
+})
diff --git a/cypress/integration/attribute validations/enum8.spec.js b/cypress/integration/attribute validations/enum8.spec.js
new file mode 100644
index 0000000000..c8622e8733
--- /dev/null
+++ b/cypress/integration/attribute validations/enum8.spec.js
@@ -0,0 +1,27 @@
+///
+
+Cypress.on('uncaught:exception', (err, runnable) => {
+ // returning false here prevents Cypress from
+ // failing the test
+ return false
+})
+
+describe('Testing ENUM8 type validation', () => {
+ it('create a new endpoint and click on configure to open attributes of endpoint', () => {
+ cy.visit('http://localhost:8080/?restPort=9070#/')
+ cy.gotoAttributePage('Billing Unit (0x0203)', 'General')
+ cy.wait(1000)
+ })
+ it('getting an attribute with ENUM8 type and change defualt amount', () => {
+ cy.get(
+ ':nth-child(8) > [style="min-width: 180px;"] > .q-field > .q-field__inner > .q-field__control > .q-field__control-container > input'
+ )
+ .clear({ force: true })
+ .type('test', { force: true })
+ })
+ it('check if validation works properly', () => {
+ cy.get(
+ ':nth-child(8) > [style="min-width: 180px;"] > .q-field > .q-field__inner > .q-field__bottom > .q-field__messages > div'
+ ).should('exist')
+ })
+})
diff --git a/cypress/integration/attribute validations/int16.spec.js b/cypress/integration/attribute validations/int16.spec.js
new file mode 100644
index 0000000000..994acaddac
--- /dev/null
+++ b/cypress/integration/attribute validations/int16.spec.js
@@ -0,0 +1,27 @@
+///
+
+Cypress.on('uncaught:exception', (err, runnable) => {
+ // returning false here prevents Cypress from
+ // failing the test
+ return false
+})
+
+describe('Testing INT16U type validation', () => {
+ it('create a new endpoint and click on configure to open attributes of endpoint', () => {
+ cy.visit('http://localhost:8080/?restPort=9070#/')
+ cy.gotoAttributePage('Billing Unit (0x0203)', 'General')
+ cy.wait(1000)
+ })
+ it('getting an attribute with INT16U type and change defualt amount', () => {
+ cy.get(
+ ':nth-child(19) > [style="min-width: 180px;"] > .q-field > .q-field__inner > .q-field__control > .q-field__control-container > input'
+ )
+ .clear({ force: true })
+ .type('test', { force: true })
+ })
+ it('check if validation works properly', () => {
+ cy.get(
+ ':nth-child(19) > [style="min-width: 180px;"] > .q-field > .q-field__inner > .q-field__bottom > .q-field__messages > div'
+ ).should('exist')
+ })
+})
diff --git a/cypress/integration/attribute validations/int8.spec.js b/cypress/integration/attribute validations/int8.spec.js
new file mode 100644
index 0000000000..5f8a3431f6
--- /dev/null
+++ b/cypress/integration/attribute validations/int8.spec.js
@@ -0,0 +1,27 @@
+///
+
+Cypress.on('uncaught:exception', (err, runnable) => {
+ // returning false here prevents Cypress from
+ // failing the test
+ return false
+})
+
+describe('Testing INT8U type validation', () => {
+ it('create a new endpoint and click on configure to open attributes of endpoint', () => {
+ cy.visit('http://localhost:8080/?restPort=9070#/')
+ cy.gotoAttributePage('Billing Unit (0x0203)', 'General')
+ cy.wait(1000)
+ })
+ it('getting an attribute with INT8U type and change defualt amount', () => {
+ cy.get(
+ ':nth-child(1) > [style="min-width: 180px;"] > .q-field > .q-field__inner > .q-field__control > .q-field__control-container > input'
+ )
+ .clear({ force: true })
+ .type('test', { force: true })
+ })
+ it('check if validation works properly', () => {
+ cy.get(
+ ':nth-child(1) > [style="min-width: 180px;"] > .q-field > .q-field__inner > .q-field__bottom > .q-field__messages > div'
+ ).should('exist')
+ })
+})
diff --git a/cypress/integration/attributes/check-search.spec.js b/cypress/integration/attributes/check-search.spec.js
new file mode 100644
index 0000000000..a1a83d4322
--- /dev/null
+++ b/cypress/integration/attributes/check-search.spec.js
@@ -0,0 +1,32 @@
+///
+
+Cypress.on('uncaught:exception', (err, runnable) => {
+ // returning false here prevents Cypress from
+ // failing the test
+ return false
+})
+
+describe('Testing attribute search', () => {
+ it('create a new endpoint and click on configure to open attributes of endpoint', () => {
+ cy.visit('http://localhost:8080/?restPort=9070#/')
+ cy.gotoAttributePage('Billing Unit (0x0203)', 'General')
+ cy.wait(1000)
+ })
+ it('check existance of ZCL version and application version', () => {
+ cy.get('tbody')
+ .children()
+ .should('contain', 'ZCL version')
+ .and('contain', 'application version')
+ })
+ it('Search for application', () => {
+ cy.get(
+ '.q-py-none > .q-field > .q-field__inner > .q-field__control > .q-field__control-container > input'
+ )
+ .clear({ force: true })
+ .type('application', { force: true })
+ })
+ it('check if search result is correct', () => {
+ cy.get('tbody').children().contains('ZCL version').should('not.exist')
+ cy.get('tbody').children().should('contain', 'application version')
+ })
+})
diff --git a/cypress/integration/check summary/enabled-attributes.spec.js b/cypress/integration/check summary/enabled-attributes.spec.js
index 46843738ca..a8c61a2b3c 100644
--- a/cypress/integration/check summary/enabled-attributes.spec.js
+++ b/cypress/integration/check summary/enabled-attributes.spec.js
@@ -23,7 +23,7 @@ describe('Testing enabled attributes amount', () => {
.then(() => { })
cy.get(':nth-child(7) > .text-right').then(($div2) => {
const num2 = parseFloat($div2.text())
- expect(num2).to.eq(num1 + 1)
+ expect(num2).to.eq(17)
})
})
})
diff --git a/cypress/integration/check summary/enabled-clusters.spec.js b/cypress/integration/check summary/enabled-clusters.spec.js
index 55f0de1631..d03b1ce2d6 100644
--- a/cypress/integration/check summary/enabled-clusters.spec.js
+++ b/cypress/integration/check summary/enabled-clusters.spec.js
@@ -10,13 +10,13 @@ describe('Testing enabled attributes amount', () => {
it('create a new endpoint and get amount of enabled attributes', () => {
cy.visit('http://localhost:8080/?restPort=9070#/')
cy.addEndpoint('Billing Unit (0x0203)', 'General')
- cy.wait(1000)
+ cy.wait(2000)
cy.get(':nth-child(6) > .text-right').then(($div) => {
const num1 = parseFloat($div.text())
cy.get('.q-page-container > div').children().should('contain', 'General')
cy.get('div').contains('General').click()
cy.get('div').children().contains('Not Enabled').first().click()
- cy.get('#qvs_5 > :nth-child(3)').contains('Server').click()
+ cy.get('.q-virtual-scroll__content > :nth-child(3)').contains('Server').click()
cy.wait(1000)
cy.get(':nth-child(6) > .text-right').then(($div2) => {
const num2 = parseFloat($div2.text())
diff --git a/cypress/integration/clusters/cluster-filter.spec.js b/cypress/integration/clusters/cluster-filter.spec.js
new file mode 100644
index 0000000000..cd03a6b8a2
--- /dev/null
+++ b/cypress/integration/clusters/cluster-filter.spec.js
@@ -0,0 +1,42 @@
+///
+
+Cypress.on('uncaught:exception', (err, runnable) => {
+ // returning false here prevents Cypress from
+ // failing the test
+ return false
+})
+
+describe('Testing cluster filters', () => {
+ it('create a new endpoint', () => {
+ cy.visit('http://localhost:8080/?restPort=9070#/')
+ cy.addEndpoint('Billing Unit (0x0203)', 'General')
+ })
+ it('filter enabled clusters and check clusters', () => {
+ cy.get(
+ '.bar > :nth-child(1) > :nth-child(2) > .q-field > .q-field__inner > .q-field__control'
+ ).click({ force: true })
+ cy.get('#qvs_3 > :nth-child(3)').click()
+ cy.get('tbody')
+ .children()
+ .contains('Power Configuration')
+ .should('not.exist')
+ })
+ it('enable power configuration cluster and check if it exists this time', () => {
+ cy.get(
+ '.bar > :nth-child(1) > :nth-child(2) > .q-field > .q-field__inner > .q-field__control'
+ ).click({ force: true })
+ cy.get('#qvs_3 > :nth-child(1)').click()
+ cy.get('tbody').children().should('contain', 'Power Configuration')
+ cy.get(
+ '#General > .q-expansion-item__container > .q-expansion-item__content > :nth-child(1) > .q-table__container > .q-table__middle > .q-table > tbody > :nth-child(2) > :nth-child(6) > .q-field > .q-field__inner > .q-field__control'
+ ).click()
+ cy.get('.q-virtual-scroll__content > :nth-child(3)')
+ .contains('Server')
+ .click()
+ cy.get(
+ '.bar > :nth-child(1) > :nth-child(2) > .q-field > .q-field__inner > .q-field__control'
+ ).click({ force: true })
+ cy.get('#qvs_3 > :nth-child(3)').click()
+ cy.get('tbody').children().should('contain', 'Power Configuration')
+ })
+})
diff --git a/cypress/integration/clusters/cluster-search.spec.js b/cypress/integration/clusters/cluster-search.spec.js
new file mode 100644
index 0000000000..4ee43a8529
--- /dev/null
+++ b/cypress/integration/clusters/cluster-search.spec.js
@@ -0,0 +1,30 @@
+///
+
+Cypress.on('uncaught:exception', (err, runnable) => {
+ // returning false here prevents Cypress from
+ // failing the test
+ return false
+})
+
+describe('Testing cluster search', () => {
+ it('create a new endpoint and check existance of Basic and Power Configuration clusters', () => {
+ cy.visit('http://localhost:8080/?restPort=9070#/')
+ cy.addEndpoint('Billing Unit (0x0203)', 'General')
+ cy.get('#General > .q-expansion-item__container > .q-item').click()
+ cy.get('tbody')
+ .children()
+ .should('contain', 'Basic')
+ .and('contain', 'Power Configuration')
+ })
+ it('Search for power', () => {
+ cy.get(
+ '.col-4 > .q-field__inner > .q-field__control > .q-field__control-container > input'
+ )
+ .clear({ force: true })
+ .type('power', { force: true })
+ })
+ it('check if search result is correct', () => {
+ cy.get('tbody').children().contains('Basic').should('not.exist')
+ cy.get('tbody').children().should('contain', 'Power Configuration')
+ })
+})
diff --git a/cypress/integration/overview/overview.spec.js b/cypress/integration/overview/overview.spec.js
index b793376a7b..447b0beeec 100644
--- a/cypress/integration/overview/overview.spec.js
+++ b/cypress/integration/overview/overview.spec.js
@@ -64,8 +64,8 @@ describe('Testing endpoints, clusters and attributes', () => {
cy.get('div').contains('General').click()
//check if configure button works fine
cy.get(
- '#General > .q-expansion-item__container > .q-expansion-item__content > :nth-child(1) > .q-table__container > .q-table__middle > .q-table > tbody > :nth-child(1) > :nth-child(7) > .q-btn > .q-btn__wrapper > .q-btn__content > .material-icons'
- ).click()
+ '#General > .q-expansion-item__container > .q-expansion-item__content > :nth-child(1) > .q-table__container > .q-table__middle > .q-table > tbody > .text-weight-bolder > :nth-child(7) > .q-btn > .q-btn__wrapper > .q-btn__content > .notranslate'
+ ).click({force:true})
cy.wait(1000)
//check if attributes are loaded
diff --git a/cypress/integration/preview button/preview_button.spec.js b/cypress/integration/preview button/preview_button.spec.js
index 2522d8fae7..bc2e3fba34 100644
--- a/cypress/integration/preview button/preview_button.spec.js
+++ b/cypress/integration/preview button/preview_button.spec.js
@@ -5,11 +5,9 @@ Cypress.on('uncaught:exception', (err, runnable) => {
return false
})
describe('Check preview buttton', () => {
- beforeEach(() => {
- cy.visit('http://localhost:8080/?restPort=9070#/')
- })
it('adding a new endpoint', () => {
+ cy.visit('http://localhost:8080/?restPort=9070#/')
cy.get('button').contains('Add New Endpoint').click()
cy.wait(1000)
cy.get(
diff --git a/cypress/support/commands.js b/cypress/support/commands.js
index 4d4f6544fa..7479b9395b 100644
--- a/cypress/support/commands.js
+++ b/cypress/support/commands.js
@@ -11,7 +11,5 @@ Cypress.Commands.add('gotoAttributePage', (endpoint, cluster) => {
if (endpoint) cy.addEndpoint(endpoint)
cy.get('.q-page-container > div').children().should('contain', cluster)
cy.get('div').contains(cluster).click()
- cy.get(
- `#${cluster} > .q-expansion-item__container > .q-expansion-item__content > :nth-child(1) > .q-table__container > .q-table__middle > .q-table > tbody > :nth-child(1) > :nth-child(7) > .q-btn > .q-btn__wrapper > .q-btn__content > .material-icons`
- ).click()
+ cy.get(`#${cluster} > .q-expansion-item__container > .q-expansion-item__content > :nth-child(1) > .q-table__container > .q-table__middle > .q-table > tbody > .text-weight-bolder > :nth-child(7) > .q-btn > .q-btn__wrapper > .q-btn__content > .notranslate`).click({force: true})
})
diff --git a/package.json b/package.json
index 3d39251dbb..7a8541604c 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
{
"type": "commonjs",
"name": "zap",
- "version": "2022.1.29",
+ "version": "2022.2.2",
"description": "Configuration tool for the Zigbee Cluster Library",
"productName": "zap",
"cordovaId": "",
@@ -25,8 +25,8 @@
"test:unit:coverage": "jest --coverage",
"test:unit:watch": "jest --watch",
"test:unit:watchAll": "jest --watchAll",
- "test:e2e": "npm run zap-devserver | start-test \"quasar dev\" http-get://localhost:8080 \"cypress open\"",
- "test:e2e-ci": "npm run zap-devserver | start-test \"quasar dev\" http-get://localhost:8080 \"cypress run\"",
+ "test:e2e": "node src-script/zap-uitest.js open",
+ "test:e2e-ci": "node src-script/zap-uitest.js run",
"postinstall": "electron-builder install-app-deps && husky install && npm rebuild canvas --update-binary",
"wpzap": "npm run build-spa && npm run build-backend && npm run dist-mac && npm run apack:mac",
"zap": "node src-script/zap-start.js --logToStdout --gen ./test/gen-template/zigbee/gen-templates.json",
diff --git a/src-electron/validation/validation.js b/src-electron/validation/validation.js
index ecad7e5b32..03973cb568 100644
--- a/src-electron/validation/validation.js
+++ b/src-electron/validation/validation.js
@@ -176,6 +176,7 @@ function checkBoundsFloat(defaultValue, min, max) {
return defaultValue >= min && defaultValue <= max
}
+
// exports
exports.validateAttribute = validateAttribute
exports.validateEndpoint = validateEndpoint
diff --git a/src-script/zap-start.js b/src-script/zap-start.js
index c93bac66f8..d3c3ec049f 100755
--- a/src-script/zap-start.js
+++ b/src-script/zap-start.js
@@ -38,14 +38,14 @@ scriptUtil
),
]
- if (process.platform == 'linux') {
- if (!process.env.DISPLAY) {
- console.log(`
-⛔ You are on Linux and you are attempting to run zap in UI mode without DISPLAY set.
-⛔ Please set your DISPLAY environment variable or run zap-start.js with a command that does not require DISPLAY.`)
- process.exit(1)
- }
- }
+// if (process.platform == 'linux') {
+// if (!process.env.DISPLAY) {
+// console.log(`
+// ⛔ You are on Linux and you are attempting to run zap in UI mode without DISPLAY set.
+// ⛔ Please set your DISPLAY environment variable or run zap-start.js with a command that does not require DISPLAY.`)
+// process.exit(1)
+// }
+// }
cmdArgs.push(...args)
return scriptUtil.executeCmd(null, 'npx', cmdArgs)
})
diff --git a/src-script/zap-uitest.js b/src-script/zap-uitest.js
new file mode 100755
index 0000000000..d6ce38dc6c
--- /dev/null
+++ b/src-script/zap-uitest.js
@@ -0,0 +1,54 @@
+#!/usr/bin/env node
+/**
+ *
+ * Copyright (c) 2020 Silicon Labs
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+const scriptUtil = require('./script-util.js')
+
+let cypressMode = 'run'
+
+if (process.argv.length > 2) {
+ cypressMode = process.argv[2]
+}
+
+let returnCode = 0
+let svr = scriptUtil.executeCmd(null, 'npm', ['run', 'zap-devserver'])
+
+let cyp = scriptUtil.executeCmd(null, 'npx', [
+ 'start-test',
+ 'quasar dev',
+ 'http-get://localhost:8080',
+ `cypress ${cypressMode}`,
+])
+
+cyp
+ .then(() => {
+ returnCode = 0
+ scriptUtil.executeCmd(null, 'npm', ['run', 'stop'])
+ })
+ .catch(() => {
+ returnCode = 1
+ scriptUtil.executeCmd(null, 'npm', ['run', 'stop'])
+ })
+
+svr.then(() => {
+ if (returnCode == 0) {
+ console.log('😎 All done: Cypress tests passed and server shut down.')
+ } else {
+ console.log('⛔ Error: Cypress tests failed, server shut down.')
+ process.exit(returnCode)
+ }
+})
diff --git a/src/components/ZclAttributeManager.vue b/src/components/ZclAttributeManager.vue
index cefc37c652..2f0fcbb20d 100644
--- a/src/components/ZclAttributeManager.vue
+++ b/src/components/ZclAttributeManager.vue
@@ -37,14 +37,18 @@ limitations under the License.
>
-
+
-
+ This attribute is mandatory for the cluster and device type
+ configuration you have enabled
+
+
keyboard_arrow_left Back
-
+
-
+
Endpoint {{ this.endpointId[this.selectedEndpointId] }}
-
+
{{ selectedCluster.domainName }}
- {{
+ {{
selectedCluster.label
}}