diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 787069e..ed4604e 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -1,5 +1,61 @@ # GitHub Copilot Agent Instructions for MQTT Explorer +## Test Suites + +MQTT Explorer has several test suites to ensure code quality and reliability: + +### Unit Tests + +**App tests** - Frontend component and logic tests: +```bash +yarn test:app +# Or: cd app && yarn test +``` + +**Backend tests** - Data model and business logic tests: +```bash +yarn test:backend +# Or: cd backend && yarn test +``` + +**Run all unit tests**: +```bash +yarn test +``` + +### Integration Tests + +**UI test suite** - Independent, deterministic browser tests: +```bash +yarn test:ui +# Requires: yarn build +``` + +**Demo video generation** - UI test recording with video capture: +```bash +yarn test:demo-video +# Requires: Xvfb, mosquitto broker, tmux, ffmpeg +# For development: Use ./scripts/uiTests.sh for full video recording setup +``` + +**MCP introspection tests** - Model Context Protocol tests: +```bash +yarn test:mcp +``` + +**Run all tests** (unit + demo-video): +```bash +yarn test:all +``` + +### CI/CD Test Execution + +In CI environments, tests run in isolated containers with all dependencies pre-installed: +- `test` job: Runs unit tests (app + backend) +- `ui-tests` job: Runs UI test suite with screenshots +- `demo-video` job: Generates demo video with full recording setup +- `test-browser` job: Runs browser mode smoke tests + ## Debugging Browser Mode ### Prerequisites diff --git a/Readme.md b/Readme.md index 6923282..6c9fc27 100644 --- a/Readme.md +++ b/Readme.md @@ -80,12 +80,51 @@ The `app` directory contains all the rendering logic, the `backend` directory cu ## Automated Tests -To achieve a reliable product automated tests run regularly on CI. +MQTT Explorer uses multiple test suites to ensure reliability and quality: -- **Data model tests**: `yarn test:backend` -- **App tests**: `yarn test:app` -- **UI test suite**: `yarn test:ui` (independent, deterministic tests) -- **Demo video**: `yarn ui-test` (UI test recording for documentation) +### Unit Tests + +**App tests** - Frontend component and logic tests: +```bash +yarn test:app +``` + +**Backend tests** - Data model and business logic tests: +```bash +yarn test:backend +``` + +**Run all unit tests**: +```bash +yarn test +``` + +### Integration & UI Tests + +**UI test suite** - Independent, deterministic browser tests: +```bash +yarn build +yarn test:ui +``` + +**Demo video generation** - UI test recording for documentation: +```bash +yarn build +yarn test:demo-video +``` +Note: Requires Xvfb, mosquitto broker, tmux, and ffmpeg. For full video recording setup, use `./scripts/uiTests.sh`. + +**MCP introspection tests** - Model Context Protocol validation: +```bash +yarn build +yarn test:mcp +``` + +**Run all tests** (unit tests + demo video): +```bash +yarn build +yarn test:all +``` ### Run UI Test Suite @@ -104,13 +143,27 @@ See [docs/UI-TEST-SUITE.md](docs/UI-TEST-SUITE.md) for more details. ### Run Demo Video Generation -A [mosquitto](https://mosquitto.org/) MQTT broker is required to generate the demo video. +The demo video is used for documentation and showcases key features. It requires additional dependencies: ```bash yarn build -yarn ui-test +yarn test:demo-video ``` +**Requirements:** +- mosquitto MQTT broker +- Xvfb (virtual framebuffer) +- tmux (terminal multiplexer) +- ffmpeg (video encoding) + +**For full video recording with post-processing:** +```bash +yarn build +./scripts/uiTests.sh +``` + +This script handles Xvfb setup, mosquitto startup, video recording, and cleanup. + ## Create a release Create a PR to `release` branch. diff --git a/app/package.json b/app/package.json index 83cde45..400ae9f 100644 --- a/app/package.json +++ b/app/package.json @@ -16,10 +16,10 @@ "license": "CC-BY-ND-4.0", "dependencies": { "@emotion/react": "^11.14.0", - "@emotion/styled": "^11.14.0", - "@mui/icons-material": "^5.18.0", - "@mui/lab": "^5.0.0-alpha.177", - "@mui/material": "^5.18.0", + "@emotion/styled": "^11.14.1", + "@mui/icons-material": "^7.3.6", + "@mui/lab": "^7.0.1-beta.20", + "@mui/material": "^7.3.6", "@mui/styles": "^6.4.8", "@types/react-transition-group": "^4.4.11", "ace-builds": "^1.4.11", @@ -44,9 +44,9 @@ "parse-duration": "^0.1.1", "path-browserify": "^1.0.1", "prismjs": "^1.29.0", - "react": "^18.3.1", - "react-ace": "^12.0.0", - "react-dom": "^18.3.1", + "react": "^19.2.3", + "react-ace": "^14.0.1", + "react-dom": "^19.2.3", "react-redux": "^9.2.0", "react-resize-detector": "^11.0.1", "react-split-pane": "^0.1.92", @@ -68,8 +68,8 @@ "@types/lodash.debounce": "^4.0.9", "@types/node": "^25.0.3", "@types/prismjs": "^1.26.5", - "@types/react": "^18.3.18", - "@types/react-dom": "^18.3.5", + "@types/react": "^19.2.7", + "@types/react-dom": "^19.2.3", "@types/react-redux": "^7.1.34", "@types/react-resize-detector": "^4.0.3", "@types/sha1": "^1.1.1", diff --git a/app/src/components/Chart/Chart.tsx b/app/src/components/Chart/Chart.tsx index 6079151..49e5528 100644 --- a/app/src/components/Chart/Chart.tsx +++ b/app/src/components/Chart/Chart.tsx @@ -1,3 +1,4 @@ +import '../../react-vis-compat' // React 19 compatibility shim for react-vis import DateFormatter from '../helper/DateFormatter' import NoData from './NoData' import NumberFormatter from '../helper/NumberFormatter' diff --git a/app/src/components/Sidebar/CodeDiff/ChartPreview.tsx b/app/src/components/Sidebar/CodeDiff/ChartPreview.tsx index 0095ce8..ec56f0c 100644 --- a/app/src/components/Sidebar/CodeDiff/ChartPreview.tsx +++ b/app/src/components/Sidebar/CodeDiff/ChartPreview.tsx @@ -41,31 +41,29 @@ function ChartPreview(props: Props) { const addChartToPanelButton = hasEnoughDataToDisplayDiagrams ? ( - + style={{ cursor: 'pointer', display: 'inline-flex' }} + > + + ) : ( - + + + ) return ( - - {addChartToPanelButton} +
+ + {addChartToPanelButton} + @@ -77,7 +75,7 @@ function ChartPreview(props: Props) { - +
) } diff --git a/app/src/components/Sidebar/ValueRenderer/ActionButtons.tsx b/app/src/components/Sidebar/ValueRenderer/ActionButtons.tsx index 663d63b..b81372a 100644 --- a/app/src/components/Sidebar/ValueRenderer/ActionButtons.tsx +++ b/app/src/components/Sidebar/ValueRenderer/ActionButtons.tsx @@ -1,8 +1,8 @@ import React, { useCallback } from 'react' import Code from '@mui/icons-material/Code' import Reorder from '@mui/icons-material/Reorder' -import ToggleButton from '@mui/lab/ToggleButton' -import ToggleButtonGroup from '@mui/lab/ToggleButtonGroup' +import ToggleButton from '@mui/material/ToggleButton' +import ToggleButtonGroup from '@mui/material/ToggleButtonGroup' import { settingsActions } from '../../../actions' import { Tooltip } from '@mui/material' import { withStyles } from '@mui/styles' diff --git a/app/src/react-vis-compat.ts b/app/src/react-vis-compat.ts new file mode 100644 index 0000000..0062f92 --- /dev/null +++ b/app/src/react-vis-compat.ts @@ -0,0 +1,28 @@ +/** + * React 19 compatibility shim for react-vis + * + * react-vis uses React internals that were removed in React 19. + * This shim adds back the missing internals to maintain compatibility. + */ +import * as React from 'react' + +// Add missing React internals that react-vis expects +if (typeof React !== 'undefined') { + const internals = (React as any).__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED + + if (internals) { + // ReactCurrentOwner was removed in React 19 but react-vis expects it + if (!internals.ReactCurrentOwner) { + internals.ReactCurrentOwner = { + current: null, + } + } + + // ReactCurrentDispatcher compatibility + if (!internals.ReactCurrentDispatcher) { + internals.ReactCurrentDispatcher = { + current: null, + } + } + } +} diff --git a/app/tsconfig.json b/app/tsconfig.json index 03b2979..f5a5e67 100644 --- a/app/tsconfig.json +++ b/app/tsconfig.json @@ -10,7 +10,7 @@ "sourceMap": true, "module": "esnext", "target": "ES2020", - "jsx": "react", + "jsx": "react-jsx", "paths": { "react": ["./node_modules/@types/react"] }, diff --git a/app/yarn.lock b/app/yarn.lock index e5b877d..e8dcce2 100644 --- a/app/yarn.lock +++ b/app/yarn.lock @@ -52,7 +52,7 @@ dependencies: "@babel/types" "^7.28.5" -"@babel/runtime@^7.12.5", "@babel/runtime@^7.18.3", "@babel/runtime@^7.23.9", "@babel/runtime@^7.26.0", "@babel/runtime@^7.28.4", "@babel/runtime@^7.3.1", "@babel/runtime@^7.5.5", "@babel/runtime@^7.8.3", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2": +"@babel/runtime@^7.12.5", "@babel/runtime@^7.18.3", "@babel/runtime@^7.26.0", "@babel/runtime@^7.28.4", "@babel/runtime@^7.3.1", "@babel/runtime@^7.5.5", "@babel/runtime@^7.8.3", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2": version "7.28.4" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.28.4.tgz#a70226016fabe25c5783b2f22d3e1c9bc5ca3326" integrity sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ== @@ -114,7 +114,7 @@ source-map "^0.5.7" stylis "4.2.0" -"@emotion/cache@^11.13.5", "@emotion/cache@^11.14.0": +"@emotion/cache@^11.14.0": version "11.14.0" resolved "https://registry.yarnpkg.com/@emotion/cache/-/cache-11.14.0.tgz#ee44b26986eeb93c8be82bb92f1f7a9b21b2ed76" integrity sha512-L/B1lc/TViYk4DcpGxtAVbx0ZyiKM5ktoIyafGkH6zg/tj+mA+NE//aPYKG0k8kCHSHVJrpLpcAlOBEXQ3SavA== @@ -172,7 +172,7 @@ resolved "https://registry.yarnpkg.com/@emotion/sheet/-/sheet-1.4.0.tgz#c9299c34d248bc26e82563735f78953d2efca83c" integrity sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg== -"@emotion/styled@^11.14.0": +"@emotion/styled@^11.14.1": version "11.14.1" resolved "https://registry.yarnpkg.com/@emotion/styled/-/styled-11.14.1.tgz#8c34bed2948e83e1980370305614c20955aacd1c" integrity sha512-qEEJt42DuToa3gurlH4Qqc1kVpNq8wO8cJtDzU46TjlzWjDlsVyevtYCRijVq3SrHsROS+gVQ8Fnea108GnKzw== @@ -204,33 +204,6 @@ resolved "https://registry.yarnpkg.com/@emotion/weak-memoize/-/weak-memoize-0.4.0.tgz#5e13fac887f08c44f76b0ccaf3370eb00fec9bb6" integrity sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg== -"@floating-ui/core@^1.7.3": - version "1.7.3" - resolved "https://registry.yarnpkg.com/@floating-ui/core/-/core-1.7.3.tgz#462d722f001e23e46d86fd2bd0d21b7693ccb8b7" - integrity sha512-sGnvb5dmrJaKEZ+LDIpguvdX3bDlEllmv4/ClQ9awcmCZrlx5jQyyMWFM5kBI+EyNOCDDiKk8il0zeuX3Zlg/w== - dependencies: - "@floating-ui/utils" "^0.2.10" - -"@floating-ui/dom@^1.7.4": - version "1.7.4" - resolved "https://registry.yarnpkg.com/@floating-ui/dom/-/dom-1.7.4.tgz#ee667549998745c9c3e3e84683b909c31d6c9a77" - integrity sha512-OOchDgh4F2CchOX94cRVqhvy7b3AFb+/rQXyswmzmGakRfkMgoWVjfnLWkRirfLEfuD4ysVW16eXzwt3jHIzKA== - dependencies: - "@floating-ui/core" "^1.7.3" - "@floating-ui/utils" "^0.2.10" - -"@floating-ui/react-dom@^2.0.8": - version "2.1.6" - resolved "https://registry.yarnpkg.com/@floating-ui/react-dom/-/react-dom-2.1.6.tgz#189f681043c1400561f62972f461b93f01bf2231" - integrity sha512-4JX6rEatQEvlmgU80wZyq9RT96HZJa88q8hp0pBd+LrczeDI4o6uA2M+uvxngVHo4Ihr8uibXxH6+70zhAFrVw== - dependencies: - "@floating-ui/dom" "^1.7.4" - -"@floating-ui/utils@^0.2.10": - version "0.2.10" - resolved "https://registry.yarnpkg.com/@floating-ui/utils/-/utils-0.2.10.tgz#a2a1e3812d14525f725d011a73eceb41fef5bc1c" - integrity sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ== - "@jridgewell/gen-mapping@^0.3.0": version "0.3.5" resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz#dcce6aff74bdf6dad1a95802b69b04a2fcb1fb36" @@ -342,71 +315,48 @@ resolved "https://registry.yarnpkg.com/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz#b2ac626d6cb9c8718ab459166d4bb405b8ffa78b" integrity sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A== -"@mui/base@5.0.0-beta.40-1": - version "5.0.0-beta.40-1" - resolved "https://registry.yarnpkg.com/@mui/base/-/base-5.0.0-beta.40-1.tgz#6da6229e5e675e811f319149f6e29d7a77522851" - integrity sha512-agKXuNNy0bHUmeU7pNmoZwNFr7Hiyhojkb9+2PVyDG5+6RafYuyMgbrav8CndsB7KUc/U51JAw9vKNDLYBzaUA== +"@mui/core-downloads-tracker@^7.3.6": + version "7.3.6" + resolved "https://registry.yarnpkg.com/@mui/core-downloads-tracker/-/core-downloads-tracker-7.3.6.tgz#e7e3a4dc161a377be8224aa988410e89571ab40a" + integrity sha512-QaYtTHlr8kDFN5mE1wbvVARRKH7Fdw1ZuOjBJcFdVpfNfRYKF3QLT4rt+WaB6CKJvpqxRsmEo0kpYinhH5GeHg== + +"@mui/icons-material@^7.3.6": + version "7.3.6" + resolved "https://registry.yarnpkg.com/@mui/icons-material/-/icons-material-7.3.6.tgz#c0092afd04a661603d9751c851e0099a27c1d556" + integrity sha512-0FfkXEj22ysIq5pa41A2NbcAhJSvmcZQ/vcTIbjDsd6hlslG82k5BEBqqS0ZJprxwIL3B45qpJ+bPHwJPlF7uQ== dependencies: - "@babel/runtime" "^7.23.9" - "@floating-ui/react-dom" "^2.0.8" - "@mui/types" "~7.2.15" - "@mui/utils" "^5.17.1" - "@popperjs/core" "^2.11.8" - clsx "^2.1.0" + "@babel/runtime" "^7.28.4" + +"@mui/lab@^7.0.1-beta.20": + version "7.0.1-beta.20" + resolved "https://registry.yarnpkg.com/@mui/lab/-/lab-7.0.1-beta.20.tgz#e63282cf686c46c44b36066c99dc7e3cf3acdf86" + integrity sha512-xZW+gLO0htUjL02lZRhrziyOuz/azdwqgyiyjKvn52W2wbbcXtFhDVp3ns7YYiQAF9I+Sgu1g1a2HZutOlqeWw== + dependencies: + "@babel/runtime" "^7.28.4" + "@mui/system" "^7.3.6" + "@mui/types" "^7.4.9" + "@mui/utils" "^7.3.6" + clsx "^2.1.1" prop-types "^15.8.1" -"@mui/core-downloads-tracker@^5.18.0": - version "5.18.0" - resolved "https://registry.yarnpkg.com/@mui/core-downloads-tracker/-/core-downloads-tracker-5.18.0.tgz#85019a8704b0f63305fc5600635ee663810f2b66" - integrity sha512-jbhwoQ1AY200PSSOrNXmrFCaSDSJWP7qk6urkTmIirvRXDROkqe+QwcLlUiw/PrREwsIF/vm3/dAXvjlMHF0RA== - -"@mui/icons-material@^5.18.0": - version "5.18.0" - resolved "https://registry.yarnpkg.com/@mui/icons-material/-/icons-material-5.18.0.tgz#97d87f1b7bee5fa7b9ba844518631de3112c1e57" - integrity sha512-1s0vEZj5XFXDMmz3Arl/R7IncFqJ+WQ95LDp1roHWGDE2oCO3IS4/hmiOv1/8SD9r6B7tv9GLiqVZYHo+6PkTg== +"@mui/material@^7.3.6": + version "7.3.6" + resolved "https://registry.yarnpkg.com/@mui/material/-/material-7.3.6.tgz#6bd4705ca97d80fd5ae1b6b2b7c56ba0cfab0d6a" + integrity sha512-R4DaYF3dgCQCUAkr4wW1w26GHXcf5rCmBRHVBuuvJvaGLmZdD8EjatP80Nz5JCw0KxORAzwftnHzXVnjR8HnFw== dependencies: - "@babel/runtime" "^7.23.9" - -"@mui/lab@^5.0.0-alpha.177": - version "5.0.0-alpha.177" - resolved "https://registry.yarnpkg.com/@mui/lab/-/lab-5.0.0-alpha.177.tgz#a02f43b36d7e204166706f2c27640f378e3d7c88" - integrity sha512-bdCxxtNjlWAgN9rtrwlmFydJ1qxA3IIbb6OlomGFsIXw0zGoHomLyjvh72q/R3yUAC0kvSef18cHY1UalLylyQ== - dependencies: - "@babel/runtime" "^7.23.9" - "@mui/base" "5.0.0-beta.40-1" - "@mui/system" "^5.18.0" - "@mui/types" "~7.2.15" - "@mui/utils" "^5.17.1" - clsx "^2.1.0" - prop-types "^15.8.1" - -"@mui/material@^5.18.0": - version "5.18.0" - resolved "https://registry.yarnpkg.com/@mui/material/-/material-5.18.0.tgz#71e72d52338252edc6f8d9461e04fdf0d61905cd" - integrity sha512-bbH/HaJZpFtXGvWg3TsBWG4eyt3gah3E7nCNU8GLyRjVoWcA91Vm/T+sjHfUcwgJSw9iLtucfHBoq+qW/T30aA== - dependencies: - "@babel/runtime" "^7.23.9" - "@mui/core-downloads-tracker" "^5.18.0" - "@mui/system" "^5.18.0" - "@mui/types" "~7.2.15" - "@mui/utils" "^5.17.1" + "@babel/runtime" "^7.28.4" + "@mui/core-downloads-tracker" "^7.3.6" + "@mui/system" "^7.3.6" + "@mui/types" "^7.4.9" + "@mui/utils" "^7.3.6" "@popperjs/core" "^2.11.8" - "@types/react-transition-group" "^4.4.10" - clsx "^2.1.0" + "@types/react-transition-group" "^4.4.12" + clsx "^2.1.1" csstype "^3.1.3" prop-types "^15.8.1" - react-is "^19.0.0" + react-is "^19.2.0" react-transition-group "^4.4.5" -"@mui/private-theming@^5.17.1": - version "5.17.1" - resolved "https://registry.yarnpkg.com/@mui/private-theming/-/private-theming-5.17.1.tgz#b4b6fbece27830754ef78186e3f1307dca42f295" - integrity sha512-XMxU0NTYcKqdsG8LRmSoxERPXwMbp16sIXPcLVgLGII/bVNagX0xaheWAwFv8+zDK7tI3ajllkuD3GZZE++ICQ== - dependencies: - "@babel/runtime" "^7.23.9" - "@mui/utils" "^5.17.1" - prop-types "^15.8.1" - "@mui/private-theming@^6.4.8": version "6.4.9" resolved "https://registry.yarnpkg.com/@mui/private-theming/-/private-theming-6.4.9.tgz#0c1d65a638a1740aad0eb715d79e76471abe8175" @@ -416,14 +366,24 @@ "@mui/utils" "^6.4.9" prop-types "^15.8.1" -"@mui/styled-engine@^5.18.0": - version "5.18.0" - resolved "https://registry.yarnpkg.com/@mui/styled-engine/-/styled-engine-5.18.0.tgz#914cca1385bb33ce0cde31721f529c8bd7fa301c" - integrity sha512-BN/vKV/O6uaQh2z5rXV+MBlVrEkwoS/TK75rFQ2mjxA7+NBo8qtTAOA4UaM0XeJfn7kh2wZ+xQw2HAx0u+TiBg== +"@mui/private-theming@^7.3.6": + version "7.3.6" + resolved "https://registry.yarnpkg.com/@mui/private-theming/-/private-theming-7.3.6.tgz#1ca65a08e8f7f538d9a10ba974f1f4db5231a969" + integrity sha512-Ws9wZpqM+FlnbZXaY/7yvyvWQo1+02Tbx50mVdNmzWEi51C51y56KAbaDCYyulOOBL6BJxuaqG8rNNuj7ivVyw== dependencies: - "@babel/runtime" "^7.23.9" - "@emotion/cache" "^11.13.5" + "@babel/runtime" "^7.28.4" + "@mui/utils" "^7.3.6" + prop-types "^15.8.1" + +"@mui/styled-engine@^7.3.6": + version "7.3.6" + resolved "https://registry.yarnpkg.com/@mui/styled-engine/-/styled-engine-7.3.6.tgz#dde8e6ae32c9b5b400dcd37afd9514a5344f7d91" + integrity sha512-+wiYbtvj+zyUkmDB+ysH6zRjuQIJ+CM56w0fEXV+VDNdvOuSywG+/8kpjddvvlfMLsaWdQe5oTuYGBcodmqGzQ== + dependencies: + "@babel/runtime" "^7.28.4" + "@emotion/cache" "^11.14.0" "@emotion/serialize" "^1.3.3" + "@emotion/sheet" "^1.4.0" csstype "^3.1.3" prop-types "^15.8.1" @@ -450,37 +410,32 @@ jss-plugin-vendor-prefixer "^10.10.0" prop-types "^15.8.1" -"@mui/system@^5.18.0": - version "5.18.0" - resolved "https://registry.yarnpkg.com/@mui/system/-/system-5.18.0.tgz#e55331203a40584b26c5a855a07949ac8973bfb6" - integrity sha512-ojZGVcRWqWhu557cdO3pWHloIGJdzVtxs3rk0F9L+x55LsUjcMUVkEhiF7E4TMxZoF9MmIHGGs0ZX3FDLAf0Xw== +"@mui/system@^7.3.6": + version "7.3.6" + resolved "https://registry.yarnpkg.com/@mui/system/-/system-7.3.6.tgz#460f82fc6fe1b79b8c04dc97694f6b162ffc3d25" + integrity sha512-8fehAazkHNP1imMrdD2m2hbA9sl7Ur6jfuNweh5o4l9YPty4iaZzRXqYvBCWQNwFaSHmMEj2KPbyXGp7Bt73Rg== dependencies: - "@babel/runtime" "^7.23.9" - "@mui/private-theming" "^5.17.1" - "@mui/styled-engine" "^5.18.0" - "@mui/types" "~7.2.15" - "@mui/utils" "^5.17.1" - clsx "^2.1.0" + "@babel/runtime" "^7.28.4" + "@mui/private-theming" "^7.3.6" + "@mui/styled-engine" "^7.3.6" + "@mui/types" "^7.4.9" + "@mui/utils" "^7.3.6" + clsx "^2.1.1" csstype "^3.1.3" prop-types "^15.8.1" -"@mui/types@~7.2.15", "@mui/types@~7.2.24": +"@mui/types@^7.4.9": + version "7.4.9" + resolved "https://registry.yarnpkg.com/@mui/types/-/types-7.4.9.tgz#99accc87920b4c8c4ce33c5076a58f7f81b528fa" + integrity sha512-dNO8Z9T2cujkSIaCnWwprfeKmTWh97cnjkgmpFJ2sbfXLx8SMZijCYHOtP/y5nnUb/Rm2omxbDMmtUoSaUtKaw== + dependencies: + "@babel/runtime" "^7.28.4" + +"@mui/types@~7.2.24": version "7.2.24" resolved "https://registry.yarnpkg.com/@mui/types/-/types-7.2.24.tgz#5eff63129d9c29d80bbf2d2e561bd0690314dec2" integrity sha512-3c8tRt/CbWZ+pEg7QpSwbdxOk36EfmhbKf6AGZsD1EcLDLTSZoxxJ86FVtcjxvjuhdyBiWKSTGZFaXCnidO2kw== -"@mui/utils@^5.17.1": - version "5.17.1" - resolved "https://registry.yarnpkg.com/@mui/utils/-/utils-5.17.1.tgz#72ba4ffa79f7bdf69d67458139390f18484b6e6b" - integrity sha512-jEZ8FTqInt2WzxDV8bhImWBqeQRD99c/id/fq83H0ER9tFl+sfZlaAoCdznGvbSQQ9ividMxqSV2c7cC1vBcQg== - dependencies: - "@babel/runtime" "^7.23.9" - "@mui/types" "~7.2.15" - "@types/prop-types" "^15.7.12" - clsx "^2.1.1" - prop-types "^15.8.1" - react-is "^19.0.0" - "@mui/utils@^6.4.8", "@mui/utils@^6.4.9": version "6.4.9" resolved "https://registry.yarnpkg.com/@mui/utils/-/utils-6.4.9.tgz#b0df01daa254c7c32a1a30b30a5179e19ef071a7" @@ -493,6 +448,18 @@ prop-types "^15.8.1" react-is "^19.0.0" +"@mui/utils@^7.3.6": + version "7.3.6" + resolved "https://registry.yarnpkg.com/@mui/utils/-/utils-7.3.6.tgz#508fbe864832f99b215d134eb89e1198cdc66b34" + integrity sha512-jn+Ba02O6PiFs7nKva8R2aJJ9kJC+3kQ2R0BbKNY3KQQ36Qng98GnPRFTlbwYTdMD6hLEBKaMLUktyg/rTfd2w== + dependencies: + "@babel/runtime" "^7.28.4" + "@mui/types" "^7.4.9" + "@types/prop-types" "^15.7.15" + clsx "^2.1.1" + prop-types "^15.8.1" + react-is "^19.2.0" + "@polka/url@^1.0.0-next.24": version "1.0.0-next.25" resolved "https://registry.yarnpkg.com/@polka/url/-/url-1.0.0-next.25.tgz#f077fdc0b5d0078d30893396ff4827a13f99e817" @@ -907,7 +874,7 @@ resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.11.tgz#2596fb352ee96a1379c657734d4b913a613ad563" integrity sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng== -"@types/prop-types@^15.7.12", "@types/prop-types@^15.7.14": +"@types/prop-types@^15.7.14", "@types/prop-types@^15.7.15": version "15.7.15" resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.15.tgz#e6e5a86d602beaca71ce5163fadf5f95d70931c7" integrity sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw== @@ -922,10 +889,10 @@ resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.7.tgz#50ae4353eaaddc04044279812f52c8c65857dbcb" integrity sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ== -"@types/react-dom@^18.3.5": - version "18.3.7" - resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.3.7.tgz#b89ddf2cd83b4feafcc4e2ea41afdfb95a0d194f" - integrity sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ== +"@types/react-dom@^19.2.3": + version "19.2.3" + resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-19.2.3.tgz#c1e305d15a52a3e508d54dca770d202cb63abf2c" + integrity sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ== "@types/react-redux@^7.1.34": version "7.1.34" @@ -944,7 +911,7 @@ dependencies: "@types/react" "*" -"@types/react-transition-group@^4.4.10", "@types/react-transition-group@^4.4.11": +"@types/react-transition-group@^4.4.11", "@types/react-transition-group@^4.4.12": version "4.4.12" resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-4.4.12.tgz#b5d76568485b02a307238270bfe96cb51ee2a044" integrity sha512-8TV6R3h2j7a91c+1DXdJi3Syo69zzIZbz7Lg5tORM5LEJG7X/E6a1V3drRyBRZq7/utz7A+c4OgYLiLcYGHG6w== @@ -958,12 +925,11 @@ "@types/scheduler" "*" csstype "^3.0.2" -"@types/react@^18.3.18": - version "18.3.27" - resolved "https://registry.yarnpkg.com/@types/react/-/react-18.3.27.tgz#74a3b590ea183983dc65a474dc17553ae1415c34" - integrity sha512-cisd7gxkzjBKU2GgdYrTdtQx1SORymWyaAFhaxQPK9bYO9ot3Y5OikQRvY0VYQtvwjeQnizCINJAenh/V7MK2w== +"@types/react@^19.2.7": + version "19.2.7" + resolved "https://registry.yarnpkg.com/@types/react/-/react-19.2.7.tgz#84e62c0f23e8e4e5ac2cadcea1ffeacccae7f62f" + integrity sha512-MWtvHrGZLFttgeEj28VXHxpmwYbor/ATPYbBfSFZEIRK0ecCFLl2Qo55z52Hss+UV9CRN7trSeq1zbgx7YDWWg== dependencies: - "@types/prop-types" "*" csstype "^3.2.2" "@types/retry@0.12.2": @@ -1210,7 +1176,7 @@ accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.8: mime-types "~2.1.34" negotiator "0.6.3" -ace-builds@^1.32.8: +ace-builds@^1.36.3: version "1.43.5" resolved "https://registry.yarnpkg.com/ace-builds/-/ace-builds-1.43.5.tgz#2099eee8caade0cd1ee4ce3e0d2c6fb2cd7e8619" integrity sha512-iH5FLBKdB7SVn9GR37UgA/tpQS8OTWIxWAuq3Ofaw+Qbc69FfPXsXd9jeW7KRG2xKpKMqBDnu0tHBrCWY5QI7A== @@ -1583,7 +1549,7 @@ clone-deep@^4.0.1: kind-of "^6.0.2" shallow-clone "^3.0.0" -clsx@^2.1.0, clsx@^2.1.1: +clsx@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/clsx/-/clsx-2.1.1.tgz#eed397c9fd8bd882bfb18deab7102049a2f32999" integrity sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA== @@ -3375,7 +3341,7 @@ log-symbols@^4.1.0: chalk "^4.1.0" is-unicode-supported "^0.1.0" -loose-envify@^1.1.0, loose-envify@^1.4.0: +loose-envify@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== @@ -3977,31 +3943,30 @@ raw-body@~2.5.3: iconv-lite "~0.4.24" unpipe "~1.0.0" -react-ace@^12.0.0: - version "12.0.0" - resolved "https://registry.yarnpkg.com/react-ace/-/react-ace-12.0.0.tgz#d40afc7382092109eead7227d9426f55dcc2209d" - integrity sha512-PstU6CSMfYIJknb4su2Fa0WgLXzq2ufQgR6fjcSWuGT1hGTHkBzuKw+SncV8PuLCdSJBJc1VehPhyeXlWByG/g== +react-ace@^14.0.1: + version "14.0.1" + resolved "https://registry.yarnpkg.com/react-ace/-/react-ace-14.0.1.tgz#dba5761cee92a1e522be7e7dab7584df7e1aa1c7" + integrity sha512-z6YAZ20PNf/FqmYEic//G/UK6uw0rn21g58ASgHJHl9rfE4nITQLqthr9rHMVQK4ezwohJbp2dGrZpkq979PYQ== dependencies: - ace-builds "^1.32.8" + ace-builds "^1.36.3" diff-match-patch "^1.0.5" lodash.get "^4.4.2" lodash.isequal "^4.5.0" prop-types "^15.8.1" -react-dom@^18.3.1: - version "18.3.1" - resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.3.1.tgz#c2265d79511b57d479b3dd3fdfa51536494c5cb4" - integrity sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw== +react-dom@^19.2.3: + version "19.2.3" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-19.2.3.tgz#f0b61d7e5c4a86773889fcc1853af3ed5f215b17" + integrity sha512-yELu4WmLPw5Mr/lmeEpox5rw3RETacE++JgHqQzd2dg+YbJuat3jH4ingc+WPZhxaoFzdv9y33G+F7Nl5O0GBg== dependencies: - loose-envify "^1.1.0" - scheduler "^0.23.2" + scheduler "^0.27.0" react-is@^16.13.1, react-is@^16.7.0: version "16.13.1" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== -react-is@^19.0.0: +react-is@^19.0.0, react-is@^19.2.0: version "19.2.3" resolved "https://registry.yarnpkg.com/react-is/-/react-is-19.2.3.tgz#eec2feb69c7fb31f77d0b5c08c10ae1c88886b29" integrity sha512-qJNJfu81ByyabuG7hPFEbXqNcWSU3+eVus+KJs+0ncpGfMyYdvSmxiJxbWR65lYi1I+/0HBcliO029gc4F+PnA== @@ -4084,12 +4049,10 @@ react-vis@^1.12.1: prop-types "^15.5.8" react-motion "^0.5.2" -react@^18.3.1: - version "18.3.1" - resolved "https://registry.yarnpkg.com/react/-/react-18.3.1.tgz#49ab892009c53933625bd16b2533fc754cab2891" - integrity sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ== - dependencies: - loose-envify "^1.1.0" +react@^19.2.3: + version "19.2.3" + resolved "https://registry.yarnpkg.com/react/-/react-19.2.3.tgz#d83e5e8e7a258cf6b4fe28640515f99b87cd19b8" + integrity sha512-Ku/hhYbVjOQnXDZFv2+RibmLFGwFdeeKHFcOTlrt7xplBnya5OGn/hIRDsqDiSUcfORsDC7MPxwork8jBwsIWA== readable-stream@^2.0.1: version "2.3.8" @@ -4260,12 +4223,10 @@ safe-buffer@5.2.1, safe-buffer@>=5.1.0, safe-buffer@^5.1.0, safe-buffer@~5.2.0: resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== -scheduler@^0.23.2: - version "0.23.2" - resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.23.2.tgz#414ba64a3b282892e944cf2108ecc078d115cdc3" - integrity sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ== - dependencies: - loose-envify "^1.1.0" +scheduler@^0.27.0: + version "0.27.0" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.27.0.tgz#0c4ef82d67d1e5c1e359e8fc76d3a87f045fe5bd" + integrity sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q== schema-utils@^3.0.0: version "3.3.0" diff --git a/package.json b/package.json index 36d9951..41266ab 100644 --- a/package.json +++ b/package.json @@ -11,8 +11,10 @@ "start": "electron .", "start:server": "npx tsc && node dist/src/server.js", "test": "yarn test:app && yarn test:backend", + "test:all": "yarn test:app && yarn test:backend && yarn test:demo-video", "test:app": "cd app && yarn test", "test:backend": "cd backend && yarn test", + "test:demo-video": "npx tsc && node dist/src/spec/demoVideo.js", "test:ui": "tsc && mocha --require source-map-support/register dist/src/spec/ui-tests.spec.js", "test:ui:vnc": "tsc && ./scripts/uiTestsWithVnc.sh", "test:mcp": "tsc && node dist/src/spec/testMcpIntrospection.js", diff --git a/src/spec/scenarios/showNumericPlot.ts b/src/spec/scenarios/showNumericPlot.ts index cd5bce6..ce59e53 100644 --- a/src/spec/scenarios/showNumericPlot.ts +++ b/src/spec/scenarios/showNumericPlot.ts @@ -43,16 +43,12 @@ export async function showNumericPlot(browser: Page) { } async function valuePreviewGuttersShowChartIcon(name: string, browser: Page) { - for (let retries = 0; retries < 2; retries += 1) { - try { - return await browser - .locator(`//*[contains(@data-test-type, "ShowChart")][contains(@data-test, "${name}")]`) - .first() - } catch { - // ignore - } - } - return browser.locator(`//*[contains(@data-test-type, "ShowChart")][contains(@data-test, "${name}")]`).first() + const locator = browser + .locator(`//*[contains(@data-test-type, "ShowChart")][contains(@data-test, "${name}")]`) + .first() + + await locator.waitFor({ state: 'visible', timeout: 30000 }) + return locator } async function chartSettings(name: string, browser: Page) {