From 7e06ccd8c54298018f0ce0deeb38e91a3934418b Mon Sep 17 00:00:00 2001 From: Martin Man Date: Wed, 4 Sep 2024 16:16:57 +0200 Subject: [PATCH 1/9] fix(tests): make tests pass again by modifying serve and config --- .github/workflows/ci.yml | 4 ++-- .gitignore | 1 + cypress.config.ts | 2 +- cypress/screenshots/.gitkeep | 0 package-lock.json | 24 ++++++++++++++---------- package.json | 4 ++-- serve.json | 8 ++++++++ 7 files changed, 28 insertions(+), 15 deletions(-) delete mode 100644 cypress/screenshots/.gitkeep create mode 100644 serve.json diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2b0c199f7..60c1fe68e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -30,7 +30,7 @@ jobs: --name venus-docker victronenergy/venus-docker:latest /root/run_with_simulation.sh z - name: Run unit and E2E tests - run: npm run test:ci || exit 0 + run: npm run test:ci - name: Generate E2E Report run: npm run generate-e2e-report if: always() @@ -91,4 +91,4 @@ jobs: upload_url: ${{ steps.create_release.outputs.upload_url }} asset_path: ./venus-html5-app.tar.gz asset_name: venus-html5-app.tar.gz - asset_content_type: application/zip \ No newline at end of file + asset_content_type: application/zip diff --git a/.gitignore b/.gitignore index c8fbe1c44..d0cb486f7 100644 --- a/.gitignore +++ b/.gitignore @@ -26,6 +26,7 @@ yarn-debug.log* yarn-error.log* cypress/results +cypress/screenshots cypress/videos cypress/report diff --git a/cypress.config.ts b/cypress.config.ts index b91210244..4e43f8b6a 100644 --- a/cypress.config.ts +++ b/cypress.config.ts @@ -15,7 +15,7 @@ export default defineConfig({ json: true, }, e2e: { - baseUrl: "http://localhost:8000/", + baseUrl: "http://localhost:8000/?host=localhost&port=9001&path=%02%03", specPattern: "cypress/e2e/**/*.{js,jsx,ts,tsx}", }, }) diff --git a/cypress/screenshots/.gitkeep b/cypress/screenshots/.gitkeep deleted file mode 100644 index e69de29bb..000000000 diff --git a/package-lock.json b/package-lock.json index b7ab68ed3..518e53a29 100644 --- a/package-lock.json +++ b/package-lock.json @@ -81,7 +81,7 @@ "sass": "^1.49.8", "sass-loader": "^10.0.5", "semver": "^7.5.2", - "serve": "^14.1.2", + "serve": "^14.2.3", "stream-browserify": "^3.0.0", "terser-webpack-plugin": "^4.2.3", "ts-pnp": "^1.2.0", @@ -5052,8 +5052,9 @@ "license": "Apache-2.0" }, "node_modules/@zeit/schemas": { - "version": "2.29.0", - "license": "MIT" + "version": "2.36.0", + "resolved": "https://registry.npmjs.org/@zeit/schemas/-/schemas-2.36.0.tgz", + "integrity": "sha512-7kjMwcChYEzMKjeex9ZFXkt1AyNov9R5HZtjBKVsmVpw7pa7ZtlCGvCBC2vnnXctaYN+aRI61HjIqeetZW5ROg==" }, "node_modules/abab": { "version": "2.0.6", @@ -20000,11 +20001,12 @@ } }, "node_modules/serve": { - "version": "14.2.0", - "license": "MIT", + "version": "14.2.3", + "resolved": "https://registry.npmjs.org/serve/-/serve-14.2.3.tgz", + "integrity": "sha512-VqUFMC7K3LDGeGnJM9h56D3XGKb6KGgOw0cVNtA26yYXHCcpxf3xwCTUaQoWlVS7i8Jdh3GjQkOB23qsXyjoyQ==", "dependencies": { - "@zeit/schemas": "2.29.0", - "ajv": "8.11.0", + "@zeit/schemas": "2.36.0", + "ajv": "8.12.0", "arg": "5.0.2", "boxen": "7.0.0", "chalk": "5.0.1", @@ -20129,8 +20131,9 @@ } }, "node_modules/serve/node_modules/ajv": { - "version": "8.11.0", - "license": "MIT", + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", "dependencies": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", @@ -20154,7 +20157,8 @@ }, "node_modules/serve/node_modules/json-schema-traverse": { "version": "1.0.0", - "license": "MIT" + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" }, "node_modules/set-blocking": { "version": "2.0.0", diff --git a/package.json b/package.json index eb1bf6371..9544f90ba 100644 --- a/package.json +++ b/package.json @@ -77,7 +77,7 @@ "sass": "^1.49.8", "sass-loader": "^10.0.5", "semver": "^7.5.2", - "serve": "^14.1.2", + "serve": "^14.2.3", "stream-browserify": "^3.0.0", "terser-webpack-plugin": "^4.2.3", "ts-pnp": "^1.2.0", @@ -145,7 +145,7 @@ "start": "node scripts/start.js", "build": "node scripts/build.js", "test": "node scripts/test.js --config ./jest.config.js", - "serve": "./node_modules/.bin/serve -C -s -l 8000 dist", + "serve": "./node_modules/.bin/serve -C -l 8000 ./", "test:dev": "npm test -- --watchAll=false && npm run cy:run", "test:unit": "npm test", "test:e2e": "npm run cy:run", diff --git a/serve.json b/serve.json new file mode 100644 index 000000000..f100b7fb6 --- /dev/null +++ b/serve.json @@ -0,0 +1,8 @@ +{ + "public": "./dist", + "rewrites": [ + { "source": "app/:a", "destination": ":a" }, + { "source": "app/:a/:b", "destination": ":a/:b" }, + { "source": "app/:a/:b/:c", "destination": ":a/:b/:c" } + ] +} From e89070cfabff826f97ec7ee60ce83183778bed8f Mon Sep 17 00:00:00 2001 From: Martin Man Date: Wed, 4 Sep 2024 16:24:31 +0200 Subject: [PATCH 2/9] clarify --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 37b76d9fc..f590a80ca 100644 --- a/README.md +++ b/README.md @@ -185,7 +185,7 @@ display sizes. To run cypress you need to run the live server and an instance of (in venus docker repo): `./run.sh -s z` -Then you can run the cypress ui with `npm run cypress`. +Then you can run the cypress UI interactively with `npm run cy:open`. To run the ui tests in CI-style use `npm run test:e2e` From 72ab184e1841a011d35b2f9959e8875a21399dcc Mon Sep 17 00:00:00 2001 From: Martin Man Date: Wed, 4 Sep 2024 16:30:33 +0200 Subject: [PATCH 3/9] clarify --- README.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index f590a80ca..04be70230 100644 --- a/README.md +++ b/README.md @@ -71,11 +71,13 @@ And then open the app in the browser at `http://localhost:8000`. This will start the webpack dev server, which will recompile the app on code changes and hot reload the UI. -You can change the `host`, `port`, and `path` (defaults to `websocket-mqtt`) query parameters to connect to a different Venus websocket MQTT host. +Note that the app will attempt to by default connect to MQTT broker served via the same port as the app and path `websocket-mqtt`, and that will eventually fail. + +You will need to change the `host`, `port`, and `path` (defaults to `websocket-mqtt`) query parameters to connect to a different Venus websocket MQTT host. To connect to a Venus device with `VENUS_DEVICE_IP` running firmware >= 3.50 use the following URL: -`http://localhost:8000?host=` +`http://localhost:8000?host=&port=80` To connect to Venus device with `VENUS_DEVICE_IP` running firmware < 3.50, or to a `venus-docker` simulation, use the following URL: @@ -181,7 +183,7 @@ Most components have Enzyme unit tests. Run all of these tests with `npm run tes Cypress is used to run integration tests on the compiled ui to make sure it opens and operated correctly in different display sizes. To run cypress you need to run the live server and an instance of venus docker in the Venus GX demo mode (z): -(in html5 app repo): `npm run dev` +(in html5 app repo): `npm run start` (in venus docker repo): `./run.sh -s z` From c944f9e5c3879eb51c16a673a9cd1e6bb912bdaa Mon Sep 17 00:00:00 2001 From: Martin Man Date: Wed, 4 Sep 2024 16:39:25 +0200 Subject: [PATCH 4/9] fix(gh): bump actions/upload-artifact to v4 --- .github/workflows/ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 60c1fe68e..7101aab54 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -35,25 +35,25 @@ jobs: run: npm run generate-e2e-report if: always() - name: Upload E2E Results - uses: actions/upload-artifact@v1 + uses: actions/upload-artifact@v4 if: always() with: name: e2e-tests-results path: cypress/results/results.json - name: Upload E2E Report - uses: actions/upload-artifact@v1 + uses: actions/upload-artifact@v4 if: always() with: name: e2e-tests-report path: cypress/report - name: Upload Cypress Screenshots - uses: actions/upload-artifact@v1 + uses: actions/upload-artifact@v4 if: always() with: name: cypress-screenshots path: cypress/screenshots - name: Upload Cypress Videos - uses: actions/upload-artifact@v1 + uses: actions/upload-artifact@v4 if: always() with: name: cypress-videos From 7ab65622f08042efc5411e10333b780262ee2fb2 Mon Sep 17 00:00:00 2001 From: Martin Man Date: Wed, 4 Sep 2024 16:45:31 +0200 Subject: [PATCH 5/9] fix copy-e2e-assets step --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 9544f90ba..b6980664a 100644 --- a/package.json +++ b/package.json @@ -151,7 +151,7 @@ "test:e2e": "npm run cy:run", "test:ci": "npm test -- --watchAll=false && npm run cy:run", "generate-e2e-report": "npm run copy-e2e-assets && npm run merge-e2e-results && npm run create-e2e-html-report", - "copy-e2e-assets": "rm -rf ./cypress/report && mkdir ./cypress/report && cp -r ./cypress/screenshots ./cypress/videos ./cypress/report/", + "copy-e2e-assets": "rm -rf ./cypress/report && mkdir -p ./cypress/screenshots && mkdir -p ./cypress/videos && mkdir ./cypress/report && cp -r ./cypress/screenshots ./cypress/videos ./cypress/report/", "merge-e2e-results": "./node_modules/.bin/mochawesome-merge ./cypress/results/*.json -o ./cypress/results/results.json", "create-e2e-html-report": "./node_modules/.bin/marge ./cypress/results/results.json -f index.html -o ./cypress/report --cdn", "cy:version": "./node_modules/.bin/cypress version", From bd63a770a5e5d38876ba26e831f26daf27d4c51b Mon Sep 17 00:00:00 2001 From: Martin Man Date: Wed, 4 Sep 2024 17:04:54 +0200 Subject: [PATCH 6/9] update gh actions and node --- .github/workflows/ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7101aab54..31371a317 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -5,13 +5,13 @@ jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - name: Setup Node.js 18.x + - uses: actions/checkout@v4 + - name: Setup Node.js 20.x uses: actions/setup-node@master with: - node-version: 18.x + node-version: 20.x - name: Node modules cache - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: ~/.npm key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} From 2fdf4814d90b998ef54033281f6f682ee18d92be Mon Sep 17 00:00:00 2001 From: Martin Man Date: Thu, 5 Sep 2024 14:53:15 +0200 Subject: [PATCH 7/9] fix(visibleWidgets): track visibleWidgets changes properly in React-compatible way --- src/app/Marine2/components/views/RootView.tsx | 2 +- .../MetricsWidgets/VisibleWidgets.store.ts | 17 ++++++++++++++--- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/app/Marine2/components/views/RootView.tsx b/src/app/Marine2/components/views/RootView.tsx index b6373d381..4dd7e3334 100644 --- a/src/app/Marine2/components/views/RootView.tsx +++ b/src/app/Marine2/components/views/RootView.tsx @@ -33,7 +33,7 @@ const RootView = () => { setBoxes(visibleBoxes) setInitialBoxes(hiddenBoxes) - }, [visibleWidgetsStore.visibleElements, visibleWidgetsStore.visibleElements.size]) + }, [visibleWidgetsStore.visibleElements]) const getBoxByType = (type: BOX_TYPES) => { switch (type) { diff --git a/src/app/Marine2/modules/MetricsWidgets/VisibleWidgets.store.ts b/src/app/Marine2/modules/MetricsWidgets/VisibleWidgets.store.ts index e10523a69..6c3c9bb3d 100644 --- a/src/app/Marine2/modules/MetricsWidgets/VisibleWidgets.store.ts +++ b/src/app/Marine2/modules/MetricsWidgets/VisibleWidgets.store.ts @@ -16,15 +16,26 @@ export class VisibleWidgets { } notifyVisibility(element: notifyParams) { - if (element.visible) { + let isDirty = false + if (element.visible && !this.visibleElements.has(element.widgetName)) { this.visibleElements.add(element.widgetName) - } else { + isDirty = true + } else if (this.visibleElements.has(element.widgetName)) { this.visibleElements.delete(element.widgetName) + isDirty = true + } + + // React compares complex types like Set or Array by reference + // when computing dependency changes. + // Duplicate the Set when its contents changes + // to correctly report upwards that we should re-render. + if (isDirty) { + this.visibleElements = new Set(this.visibleElements) } } get noVisibleElements() { - return !this.visibleElements.size + return this.visibleElements.size === 0 } clearVisibleElements() { From 58e5eee2373fbb76cdd4fa671cb7eb90c27ff6fb Mon Sep 17 00:00:00 2001 From: Martin Man Date: Thu, 5 Sep 2024 15:32:47 +0200 Subject: [PATCH 8/9] you must be kidding me, autoprefixer bailing on mentioning the word in JS comment --- src/app/Marine2/modules/MetricsWidgets/VisibleWidgets.store.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/Marine2/modules/MetricsWidgets/VisibleWidgets.store.ts b/src/app/Marine2/modules/MetricsWidgets/VisibleWidgets.store.ts index 6c3c9bb3d..c20d3987c 100644 --- a/src/app/Marine2/modules/MetricsWidgets/VisibleWidgets.store.ts +++ b/src/app/Marine2/modules/MetricsWidgets/VisibleWidgets.store.ts @@ -27,7 +27,7 @@ export class VisibleWidgets { // React compares complex types like Set or Array by reference // when computing dependency changes. - // Duplicate the Set when its contents changes + // Duplicate the Set when its elements changes // to correctly report upwards that we should re-render. if (isDirty) { this.visibleElements = new Set(this.visibleElements) From c5f31ad6b2891fc74e130db494cd81db359c7bcc Mon Sep 17 00:00:00 2001 From: Martin Man Date: Thu, 5 Sep 2024 15:36:58 +0200 Subject: [PATCH 9/9] typo --- src/app/Marine2/modules/MetricsWidgets/VisibleWidgets.store.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/app/Marine2/modules/MetricsWidgets/VisibleWidgets.store.ts b/src/app/Marine2/modules/MetricsWidgets/VisibleWidgets.store.ts index c20d3987c..256cdbb42 100644 --- a/src/app/Marine2/modules/MetricsWidgets/VisibleWidgets.store.ts +++ b/src/app/Marine2/modules/MetricsWidgets/VisibleWidgets.store.ts @@ -27,8 +27,7 @@ export class VisibleWidgets { // React compares complex types like Set or Array by reference // when computing dependency changes. - // Duplicate the Set when its elements changes - // to correctly report upwards that we should re-render. + // Duplicate the Set when its elements change to indicate we should re-render. if (isDirty) { this.visibleElements = new Set(this.visibleElements) }