From 05d8068e71b86cb6ccb242b509a253860ebcebba Mon Sep 17 00:00:00 2001 From: Lucas Bustamante Date: Sun, 4 May 2025 00:00:13 -0300 Subject: [PATCH 1/4] Add mermaid support --- docusaurus.config.js | 8 + package-lock.json | 1471 ++++++++++++++++++++++++++++++++++++++++-- package.json | 1 + 3 files changed, 1409 insertions(+), 71 deletions(-) diff --git a/docusaurus.config.js b/docusaurus.config.js index a3cfe79..eda6290 100644 --- a/docusaurus.config.js +++ b/docusaurus.config.js @@ -33,6 +33,9 @@ const config = { defaultLocale: 'en', locales: ['en'], }, + markdown: { + mermaid: true, + }, presets: [ [ @@ -70,6 +73,7 @@ const config = { }), ], ], + themes: ['@docusaurus/theme-mermaid'], themeConfig: /** @type {import('@docusaurus/preset-classic').ThemeConfig} */ @@ -111,6 +115,10 @@ const config = { indexName: 'qit-woo', contextualSearch: false, }, + mermaid: { + options: { + } + } }), }; diff --git a/package-lock.json b/package-lock.json index d5e0235..8cac90e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,6 +10,7 @@ "dependencies": { "@docusaurus/core": "^3.7.0", "@docusaurus/preset-classic": "^3.7.0", + "@docusaurus/theme-mermaid": "^3.7.0", "@jongwooo/prism-theme-github": "^1.14.0", "@mdx-js/react": "^3.0.0", "clsx": "^2.0.0", @@ -268,6 +269,28 @@ "node": ">=6.0.0" } }, + "node_modules/@antfu/install-pkg": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@antfu/install-pkg/-/install-pkg-1.0.0.tgz", + "integrity": "sha512-xvX6P/lo1B3ej0OsaErAjqgFYzYVcJpamjLAFLYh9vRJngBrMoUG7aVnrGTeqM7yxbyTD5p3F2+0/QUEh8Vzhw==", + "license": "MIT", + "dependencies": { + "package-manager-detector": "^0.2.8", + "tinyexec": "^0.3.2" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@antfu/utils": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/@antfu/utils/-/utils-8.1.1.tgz", + "integrity": "sha512-Mex9nXf9vR6AhcXmMrlz/HVgYYZpVGJ6YlPgwl7UnaFpnshXs6EK/oa5Gpf3CzENMjkvEx2tQtntGnb7UtSTOQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, "node_modules/@babel/code-frame": { "version": "7.26.2", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", @@ -1935,6 +1958,51 @@ "node": ">=6.9.0" } }, + "node_modules/@braintree/sanitize-url": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/@braintree/sanitize-url/-/sanitize-url-7.1.1.tgz", + "integrity": "sha512-i1L7noDNxtFyL5DmZafWy1wRVhGehQmzZaz1HiN5e7iylJMSZR7ekOV7NsIqa5qBldlLrsKv4HbgFUVlQrz8Mw==", + "license": "MIT" + }, + "node_modules/@chevrotain/cst-dts-gen": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/@chevrotain/cst-dts-gen/-/cst-dts-gen-11.0.3.tgz", + "integrity": "sha512-BvIKpRLeS/8UbfxXxgC33xOumsacaeCKAjAeLyOn7Pcp95HiRbrpl14S+9vaZLolnbssPIUuiUd8IvgkRyt6NQ==", + "license": "Apache-2.0", + "dependencies": { + "@chevrotain/gast": "11.0.3", + "@chevrotain/types": "11.0.3", + "lodash-es": "4.17.21" + } + }, + "node_modules/@chevrotain/gast": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/@chevrotain/gast/-/gast-11.0.3.tgz", + "integrity": "sha512-+qNfcoNk70PyS/uxmj3li5NiECO+2YKZZQMbmjTqRI3Qchu8Hig/Q9vgkHpI3alNjr7M+a2St5pw5w5F6NL5/Q==", + "license": "Apache-2.0", + "dependencies": { + "@chevrotain/types": "11.0.3", + "lodash-es": "4.17.21" + } + }, + "node_modules/@chevrotain/regexp-to-ast": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/@chevrotain/regexp-to-ast/-/regexp-to-ast-11.0.3.tgz", + "integrity": "sha512-1fMHaBZxLFvWI067AVbGJav1eRY7N8DDvYCTwGBiE/ytKBgP8azTdgyrKyWZ9Mfh09eHWb5PgTSO8wi7U824RA==", + "license": "Apache-2.0" + }, + "node_modules/@chevrotain/types": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/@chevrotain/types/-/types-11.0.3.tgz", + "integrity": "sha512-gsiM3G8b58kZC2HaWR50gu6Y1440cHiJ+i3JUvcp/35JchYejb2+5MVeJK0iKThYpAa/P2PYFV4hoi44HD+aHQ==", + "license": "Apache-2.0" + }, + "node_modules/@chevrotain/utils": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/@chevrotain/utils/-/utils-11.0.3.tgz", + "integrity": "sha512-YslZMgtJUyuMbZ+aKvfF3x1f5liK4mWNxghFRv7jqRR9C3R3fAOGTTKvxXDa2Y1s9zSbcpuO0cAxDYsc9SrXoQ==", + "license": "Apache-2.0" + }, "node_modules/@colors/colors": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", @@ -4386,6 +4454,28 @@ "react-dom": "^18.0.0 || ^19.0.0" } }, + "node_modules/@docusaurus/theme-mermaid": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/@docusaurus/theme-mermaid/-/theme-mermaid-3.7.0.tgz", + "integrity": "sha512-7kNDvL7hm+tshjxSxIqYMtsLUPsEBYnkevej/ext6ru9xyLgCed+zkvTfGzTWNeq8rJIEe2YSS8/OV5gCVaPCw==", + "license": "MIT", + "dependencies": { + "@docusaurus/core": "3.7.0", + "@docusaurus/module-type-aliases": "3.7.0", + "@docusaurus/theme-common": "3.7.0", + "@docusaurus/types": "3.7.0", + "@docusaurus/utils-validation": "3.7.0", + "mermaid": ">=10.4", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + } + }, "node_modules/@docusaurus/theme-search-algolia": { "version": "3.7.0", "resolved": "https://registry.npmjs.org/@docusaurus/theme-search-algolia/-/theme-search-algolia-3.7.0.tgz", @@ -4527,6 +4617,40 @@ "@hapi/hoek": "^9.0.0" } }, + "node_modules/@iconify/types": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@iconify/types/-/types-2.0.0.tgz", + "integrity": "sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==", + "license": "MIT" + }, + "node_modules/@iconify/utils": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@iconify/utils/-/utils-2.3.0.tgz", + "integrity": "sha512-GmQ78prtwYW6EtzXRU1rY+KwOKfz32PD7iJh6Iyqw68GiKuoZ2A6pRtzWONz5VQJbp50mEjXh/7NkumtrAgRKA==", + "license": "MIT", + "dependencies": { + "@antfu/install-pkg": "^1.0.0", + "@antfu/utils": "^8.1.0", + "@iconify/types": "^2.0.0", + "debug": "^4.4.0", + "globals": "^15.14.0", + "kolorist": "^1.8.0", + "local-pkg": "^1.0.0", + "mlly": "^1.7.4" + } + }, + "node_modules/@iconify/utils/node_modules/globals": { + "version": "15.15.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-15.15.0.tgz", + "integrity": "sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/@jest/schemas": { "version": "29.6.3", "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", @@ -4666,6 +4790,15 @@ "react": ">=16" } }, + "node_modules/@mermaid-js/parser": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@mermaid-js/parser/-/parser-0.4.0.tgz", + "integrity": "sha512-wla8XOWvQAwuqy+gxiZqY+c7FokraOTHRWMsbB4AgRx9Sy7zKslNyejy7E+a77qHfey5GXw/ik3IXv/NHMJgaA==", + "license": "MIT", + "dependencies": { + "langium": "3.3.1" + } + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -5104,6 +5237,259 @@ "@types/node": "*" } }, + "node_modules/@types/d3": { + "version": "7.4.3", + "resolved": "https://registry.npmjs.org/@types/d3/-/d3-7.4.3.tgz", + "integrity": "sha512-lZXZ9ckh5R8uiFVt8ogUNf+pIrK4EsWrx2Np75WvF/eTpJ0FMHNhjXk8CKEx/+gpHbNQyJWehbFaTvqmHWB3ww==", + "license": "MIT", + "dependencies": { + "@types/d3-array": "*", + "@types/d3-axis": "*", + "@types/d3-brush": "*", + "@types/d3-chord": "*", + "@types/d3-color": "*", + "@types/d3-contour": "*", + "@types/d3-delaunay": "*", + "@types/d3-dispatch": "*", + "@types/d3-drag": "*", + "@types/d3-dsv": "*", + "@types/d3-ease": "*", + "@types/d3-fetch": "*", + "@types/d3-force": "*", + "@types/d3-format": "*", + "@types/d3-geo": "*", + "@types/d3-hierarchy": "*", + "@types/d3-interpolate": "*", + "@types/d3-path": "*", + "@types/d3-polygon": "*", + "@types/d3-quadtree": "*", + "@types/d3-random": "*", + "@types/d3-scale": "*", + "@types/d3-scale-chromatic": "*", + "@types/d3-selection": "*", + "@types/d3-shape": "*", + "@types/d3-time": "*", + "@types/d3-time-format": "*", + "@types/d3-timer": "*", + "@types/d3-transition": "*", + "@types/d3-zoom": "*" + } + }, + "node_modules/@types/d3-array": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.1.tgz", + "integrity": "sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg==", + "license": "MIT" + }, + "node_modules/@types/d3-axis": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-axis/-/d3-axis-3.0.6.tgz", + "integrity": "sha512-pYeijfZuBd87T0hGn0FO1vQ/cgLk6E1ALJjfkC0oJ8cbwkZl3TpgS8bVBLZN+2jjGgg38epgxb2zmoGtSfvgMw==", + "license": "MIT", + "dependencies": { + "@types/d3-selection": "*" + } + }, + "node_modules/@types/d3-brush": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-brush/-/d3-brush-3.0.6.tgz", + "integrity": "sha512-nH60IZNNxEcrh6L1ZSMNA28rj27ut/2ZmI3r96Zd+1jrZD++zD3LsMIjWlvg4AYrHn/Pqz4CF3veCxGjtbqt7A==", + "license": "MIT", + "dependencies": { + "@types/d3-selection": "*" + } + }, + "node_modules/@types/d3-chord": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-chord/-/d3-chord-3.0.6.tgz", + "integrity": "sha512-LFYWWd8nwfwEmTZG9PfQxd17HbNPksHBiJHaKuY1XeqscXacsS2tyoo6OdRsjf+NQYeB6XrNL3a25E3gH69lcg==", + "license": "MIT" + }, + "node_modules/@types/d3-color": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz", + "integrity": "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==", + "license": "MIT" + }, + "node_modules/@types/d3-contour": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-contour/-/d3-contour-3.0.6.tgz", + "integrity": "sha512-BjzLgXGnCWjUSYGfH1cpdo41/hgdWETu4YxpezoztawmqsvCeep+8QGfiY6YbDvfgHz/DkjeIkkZVJavB4a3rg==", + "license": "MIT", + "dependencies": { + "@types/d3-array": "*", + "@types/geojson": "*" + } + }, + "node_modules/@types/d3-delaunay": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-delaunay/-/d3-delaunay-6.0.4.tgz", + "integrity": "sha512-ZMaSKu4THYCU6sV64Lhg6qjf1orxBthaC161plr5KuPHo3CNm8DTHiLw/5Eq2b6TsNP0W0iJrUOFscY6Q450Hw==", + "license": "MIT" + }, + "node_modules/@types/d3-dispatch": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-dispatch/-/d3-dispatch-3.0.6.tgz", + "integrity": "sha512-4fvZhzMeeuBJYZXRXrRIQnvUYfyXwYmLsdiN7XXmVNQKKw1cM8a5WdID0g1hVFZDqT9ZqZEY5pD44p24VS7iZQ==", + "license": "MIT" + }, + "node_modules/@types/d3-drag": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@types/d3-drag/-/d3-drag-3.0.7.tgz", + "integrity": "sha512-HE3jVKlzU9AaMazNufooRJ5ZpWmLIoc90A37WU2JMmeq28w1FQqCZswHZ3xR+SuxYftzHq6WU6KJHvqxKzTxxQ==", + "license": "MIT", + "dependencies": { + "@types/d3-selection": "*" + } + }, + "node_modules/@types/d3-dsv": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@types/d3-dsv/-/d3-dsv-3.0.7.tgz", + "integrity": "sha512-n6QBF9/+XASqcKK6waudgL0pf/S5XHPPI8APyMLLUHd8NqouBGLsU8MgtO7NINGtPBtk9Kko/W4ea0oAspwh9g==", + "license": "MIT" + }, + "node_modules/@types/d3-ease": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-3.0.2.tgz", + "integrity": "sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==", + "license": "MIT" + }, + "node_modules/@types/d3-fetch": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@types/d3-fetch/-/d3-fetch-3.0.7.tgz", + "integrity": "sha512-fTAfNmxSb9SOWNB9IoG5c8Hg6R+AzUHDRlsXsDZsNp6sxAEOP0tkP3gKkNSO/qmHPoBFTxNrjDprVHDQDvo5aA==", + "license": "MIT", + "dependencies": { + "@types/d3-dsv": "*" + } + }, + "node_modules/@types/d3-force": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@types/d3-force/-/d3-force-3.0.10.tgz", + "integrity": "sha512-ZYeSaCF3p73RdOKcjj+swRlZfnYpK1EbaDiYICEEp5Q6sUiqFaFQ9qgoshp5CzIyyb/yD09kD9o2zEltCexlgw==", + "license": "MIT" + }, + "node_modules/@types/d3-format": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-format/-/d3-format-3.0.4.tgz", + "integrity": "sha512-fALi2aI6shfg7vM5KiR1wNJnZ7r6UuggVqtDA+xiEdPZQwy/trcQaHnwShLuLdta2rTymCNpxYTiMZX/e09F4g==", + "license": "MIT" + }, + "node_modules/@types/d3-geo": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@types/d3-geo/-/d3-geo-3.1.0.tgz", + "integrity": "sha512-856sckF0oP/diXtS4jNsiQw/UuK5fQG8l/a9VVLeSouf1/PPbBE1i1W852zVwKwYCBkFJJB7nCFTbk6UMEXBOQ==", + "license": "MIT", + "dependencies": { + "@types/geojson": "*" + } + }, + "node_modules/@types/d3-hierarchy": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/@types/d3-hierarchy/-/d3-hierarchy-3.1.7.tgz", + "integrity": "sha512-tJFtNoYBtRtkNysX1Xq4sxtjK8YgoWUNpIiUee0/jHGRwqvzYxkq0hGVbbOGSz+JgFxxRu4K8nb3YpG3CMARtg==", + "license": "MIT" + }, + "node_modules/@types/d3-interpolate": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz", + "integrity": "sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==", + "license": "MIT", + "dependencies": { + "@types/d3-color": "*" + } + }, + "node_modules/@types/d3-path": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.1.tgz", + "integrity": "sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg==", + "license": "MIT" + }, + "node_modules/@types/d3-polygon": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-polygon/-/d3-polygon-3.0.2.tgz", + "integrity": "sha512-ZuWOtMaHCkN9xoeEMr1ubW2nGWsp4nIql+OPQRstu4ypeZ+zk3YKqQT0CXVe/PYqrKpZAi+J9mTs05TKwjXSRA==", + "license": "MIT" + }, + "node_modules/@types/d3-quadtree": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-quadtree/-/d3-quadtree-3.0.6.tgz", + "integrity": "sha512-oUzyO1/Zm6rsxKRHA1vH0NEDG58HrT5icx/azi9MF1TWdtttWl0UIUsjEQBBh+SIkrpd21ZjEv7ptxWys1ncsg==", + "license": "MIT" + }, + "node_modules/@types/d3-random": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/d3-random/-/d3-random-3.0.3.tgz", + "integrity": "sha512-Imagg1vJ3y76Y2ea0871wpabqp613+8/r0mCLEBfdtqC7xMSfj9idOnmBYyMoULfHePJyxMAw3nWhJxzc+LFwQ==", + "license": "MIT" + }, + "node_modules/@types/d3-scale": { + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.9.tgz", + "integrity": "sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw==", + "license": "MIT", + "dependencies": { + "@types/d3-time": "*" + } + }, + "node_modules/@types/d3-scale-chromatic": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@types/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz", + "integrity": "sha512-iWMJgwkK7yTRmWqRB5plb1kadXyQ5Sj8V/zYlFGMUBbIPKQScw+Dku9cAAMgJG+z5GYDoMjWGLVOvjghDEFnKQ==", + "license": "MIT" + }, + "node_modules/@types/d3-selection": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/@types/d3-selection/-/d3-selection-3.0.11.tgz", + "integrity": "sha512-bhAXu23DJWsrI45xafYpkQ4NtcKMwWnAC/vKrd2l+nxMFuvOT3XMYTIj2opv8vq8AO5Yh7Qac/nSeP/3zjTK0w==", + "license": "MIT" + }, + "node_modules/@types/d3-shape": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.7.tgz", + "integrity": "sha512-VLvUQ33C+3J+8p+Daf+nYSOsjB4GXp19/S/aGo60m9h1v6XaxjiT82lKVWJCfzhtuZ3yD7i/TPeC/fuKLLOSmg==", + "license": "MIT", + "dependencies": { + "@types/d3-path": "*" + } + }, + "node_modules/@types/d3-time": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.4.tgz", + "integrity": "sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g==", + "license": "MIT" + }, + "node_modules/@types/d3-time-format": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@types/d3-time-format/-/d3-time-format-4.0.3.tgz", + "integrity": "sha512-5xg9rC+wWL8kdDj153qZcsJ0FWiFt0J5RB6LYUNZjwSnesfblqrI/bJ1wBdJ8OQfncgbJG5+2F+qfqnqyzYxyg==", + "license": "MIT" + }, + "node_modules/@types/d3-timer": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.2.tgz", + "integrity": "sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==", + "license": "MIT" + }, + "node_modules/@types/d3-transition": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/@types/d3-transition/-/d3-transition-3.0.9.tgz", + "integrity": "sha512-uZS5shfxzO3rGlu0cC3bjmMFKsXv+SmZZcgp0KD22ts4uGXp5EVYGzu/0YdwZeKmddhcAccYtREJKkPfXkZuCg==", + "license": "MIT", + "dependencies": { + "@types/d3-selection": "*" + } + }, + "node_modules/@types/d3-zoom": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@types/d3-zoom/-/d3-zoom-3.0.8.tgz", + "integrity": "sha512-iqMC4/YlFCSlO8+2Ii1GGGliCAY4XdeG748w5vQUbevlbDu0zSjH/+jojorQVBK/se0j6DUFNPBGSqD3YWYnDw==", + "license": "MIT", + "dependencies": { + "@types/d3-interpolate": "*", + "@types/d3-selection": "*" + } + }, "node_modules/@types/debug": { "version": "4.1.12", "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", @@ -5166,6 +5552,12 @@ "@types/send": "*" } }, + "node_modules/@types/geojson": { + "version": "7946.0.16", + "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.16.tgz", + "integrity": "sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg==", + "license": "MIT" + }, "node_modules/@types/gtag.js": { "version": "0.0.12", "resolved": "https://registry.npmjs.org/@types/gtag.js/-/gtag.js-0.0.12.tgz", @@ -5390,6 +5782,13 @@ "@types/node": "*" } }, + "node_modules/@types/trusted-types": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", + "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==", + "license": "MIT", + "optional": true + }, "node_modules/@types/unist": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", @@ -6383,6 +6782,32 @@ "url": "https://github.com/sponsors/fb55" } }, + "node_modules/chevrotain": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/chevrotain/-/chevrotain-11.0.3.tgz", + "integrity": "sha512-ci2iJH6LeIkvP9eJW6gpueU8cnZhv85ELY8w8WiFtNjMHA5ad6pQLaJo9mEly/9qUyCpvqX8/POVUTf18/HFdw==", + "license": "Apache-2.0", + "dependencies": { + "@chevrotain/cst-dts-gen": "11.0.3", + "@chevrotain/gast": "11.0.3", + "@chevrotain/regexp-to-ast": "11.0.3", + "@chevrotain/types": "11.0.3", + "@chevrotain/utils": "11.0.3", + "lodash-es": "4.17.21" + } + }, + "node_modules/chevrotain-allstar": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/chevrotain-allstar/-/chevrotain-allstar-0.3.1.tgz", + "integrity": "sha512-b7g+y9A0v4mxCW1qUhf3BSVPg+/NvGErk/dOkrDaHA0nQIQGAtrOjlX//9OQtRlSCy+x9rfB5N8yC71lH1nvMw==", + "license": "MIT", + "dependencies": { + "lodash-es": "^4.17.21" + }, + "peerDependencies": { + "chevrotain": "^11.0.0" + } + }, "node_modules/chokidar": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", @@ -6655,6 +7080,12 @@ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" }, + "node_modules/confbox": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.2.2.tgz", + "integrity": "sha512-1NB+BKqhtNipMsov4xI/NnhCKp9XG9NamYp5PVm9klAT0fsrNPjaFICsCFhNhwZJKNh7zB/3q8qXz0E9oaMNtQ==", + "license": "MIT" + }, "node_modules/config-chain": { "version": "1.1.13", "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz", @@ -6837,6 +7268,15 @@ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" }, + "node_modules/cose-base": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/cose-base/-/cose-base-1.0.3.tgz", + "integrity": "sha512-s9whTXInMSgAp/NVXVNuVxVKzGH2qck3aQlVHxDCdAEPgtMKwc4Wq6/QKhgdEdgbLSi9rBTAcPoRa6JpiG4ksg==", + "license": "MIT", + "dependencies": { + "layout-base": "^1.0.0" + } + }, "node_modules/cosmiconfig": { "version": "8.3.6", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", @@ -7082,84 +7522,610 @@ "source-map-js": "^1.0.1" }, "engines": { - "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" + } + }, + "node_modules/css-what": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", + "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/cssdb": { + "version": "8.2.4", + "resolved": "https://registry.npmjs.org/cssdb/-/cssdb-8.2.4.tgz", + "integrity": "sha512-3KSCVkjZJe/QxicVXnbyYSY26WsFc1YoMY7jep1ZKWMEVc7jEm6V2Xq2r+MX8WKQIuB7ofGbnr5iVI+aZpoSzg==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + } + ], + "license": "MIT-0" + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/csso": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/csso/-/csso-5.0.5.tgz", + "integrity": "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==", + "license": "MIT", + "dependencies": { + "css-tree": "~2.2.0" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/csso/node_modules/css-tree": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.2.1.tgz", + "integrity": "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==", + "license": "MIT", + "dependencies": { + "mdn-data": "2.0.28", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/csso/node_modules/mdn-data": { + "version": "2.0.28", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.28.tgz", + "integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==", + "license": "CC0-1.0" + }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" + }, + "node_modules/cytoscape": { + "version": "3.32.0", + "resolved": "https://registry.npmjs.org/cytoscape/-/cytoscape-3.32.0.tgz", + "integrity": "sha512-5JHBC9n75kz5851jeklCPmZWcg3hUe6sjqJvyk3+hVqFaKcHwHgxsjeN1yLmggoUc6STbtm9/NQyabQehfjvWQ==", + "license": "MIT", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/cytoscape-cose-bilkent": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cytoscape-cose-bilkent/-/cytoscape-cose-bilkent-4.1.0.tgz", + "integrity": "sha512-wgQlVIUJF13Quxiv5e1gstZ08rnZj2XaLHGoFMYXz7SkNfCDOOteKBE6SYRfA9WxxI/iBc3ajfDoc6hb/MRAHQ==", + "license": "MIT", + "dependencies": { + "cose-base": "^1.0.0" + }, + "peerDependencies": { + "cytoscape": "^3.2.0" + } + }, + "node_modules/cytoscape-fcose": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cytoscape-fcose/-/cytoscape-fcose-2.2.0.tgz", + "integrity": "sha512-ki1/VuRIHFCzxWNrsshHYPs6L7TvLu3DL+TyIGEsRcvVERmxokbf5Gdk7mFxZnTdiGtnA4cfSmjZJMviqSuZrQ==", + "license": "MIT", + "dependencies": { + "cose-base": "^2.2.0" + }, + "peerDependencies": { + "cytoscape": "^3.2.0" + } + }, + "node_modules/cytoscape-fcose/node_modules/cose-base": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cose-base/-/cose-base-2.2.0.tgz", + "integrity": "sha512-AzlgcsCbUMymkADOJtQm3wO9S3ltPfYOFD5033keQn9NJzIbtnZj+UdBJe7DYml/8TdbtHJW3j58SOnKhWY/5g==", + "license": "MIT", + "dependencies": { + "layout-base": "^2.0.0" + } + }, + "node_modules/cytoscape-fcose/node_modules/layout-base": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/layout-base/-/layout-base-2.0.1.tgz", + "integrity": "sha512-dp3s92+uNI1hWIpPGH3jK2kxE2lMjdXdr+DH8ynZHpd6PUlH6x6cbuXnoMmiNumznqaNO31xu9e79F0uuZ0JFg==", + "license": "MIT" + }, + "node_modules/d3": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/d3/-/d3-7.9.0.tgz", + "integrity": "sha512-e1U46jVP+w7Iut8Jt8ri1YsPOvFpg46k+K8TpCb0P+zjCkjkPnV7WzfDJzMHy1LnA+wj5pLT1wjO901gLXeEhA==", + "license": "ISC", + "dependencies": { + "d3-array": "3", + "d3-axis": "3", + "d3-brush": "3", + "d3-chord": "3", + "d3-color": "3", + "d3-contour": "4", + "d3-delaunay": "6", + "d3-dispatch": "3", + "d3-drag": "3", + "d3-dsv": "3", + "d3-ease": "3", + "d3-fetch": "3", + "d3-force": "3", + "d3-format": "3", + "d3-geo": "3", + "d3-hierarchy": "3", + "d3-interpolate": "3", + "d3-path": "3", + "d3-polygon": "3", + "d3-quadtree": "3", + "d3-random": "3", + "d3-scale": "4", + "d3-scale-chromatic": "3", + "d3-selection": "3", + "d3-shape": "3", + "d3-time": "3", + "d3-time-format": "4", + "d3-timer": "3", + "d3-transition": "3", + "d3-zoom": "3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-array": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz", + "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==", + "license": "ISC", + "dependencies": { + "internmap": "1 - 2" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-axis": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-axis/-/d3-axis-3.0.0.tgz", + "integrity": "sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-brush": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-brush/-/d3-brush-3.0.0.tgz", + "integrity": "sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ==", + "license": "ISC", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-drag": "2 - 3", + "d3-interpolate": "1 - 3", + "d3-selection": "3", + "d3-transition": "3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-chord": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-chord/-/d3-chord-3.0.1.tgz", + "integrity": "sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g==", + "license": "ISC", + "dependencies": { + "d3-path": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-color": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", + "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-contour": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/d3-contour/-/d3-contour-4.0.2.tgz", + "integrity": "sha512-4EzFTRIikzs47RGmdxbeUvLWtGedDUNkTcmzoeyg4sP/dvCexO47AaQL7VKy/gul85TOxw+IBgA8US2xwbToNA==", + "license": "ISC", + "dependencies": { + "d3-array": "^3.2.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-delaunay": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/d3-delaunay/-/d3-delaunay-6.0.4.tgz", + "integrity": "sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A==", + "license": "ISC", + "dependencies": { + "delaunator": "5" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-dispatch": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz", + "integrity": "sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-drag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-3.0.0.tgz", + "integrity": "sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==", + "license": "ISC", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-selection": "3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-dsv": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-dsv/-/d3-dsv-3.0.1.tgz", + "integrity": "sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==", + "license": "ISC", + "dependencies": { + "commander": "7", + "iconv-lite": "0.6", + "rw": "1" + }, + "bin": { + "csv2json": "bin/dsv2json.js", + "csv2tsv": "bin/dsv2dsv.js", + "dsv2dsv": "bin/dsv2dsv.js", + "dsv2json": "bin/dsv2json.js", + "json2csv": "bin/json2dsv.js", + "json2dsv": "bin/json2dsv.js", + "json2tsv": "bin/json2dsv.js", + "tsv2csv": "bin/dsv2dsv.js", + "tsv2json": "bin/dsv2json.js" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-dsv/node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/d3-dsv/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/d3-ease": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", + "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-fetch": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-fetch/-/d3-fetch-3.0.1.tgz", + "integrity": "sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw==", + "license": "ISC", + "dependencies": { + "d3-dsv": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-force": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-force/-/d3-force-3.0.0.tgz", + "integrity": "sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==", + "license": "ISC", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-quadtree": "1 - 3", + "d3-timer": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-format": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz", + "integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-geo": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-3.1.1.tgz", + "integrity": "sha512-637ln3gXKXOwhalDzinUgY83KzNWZRKbYubaG+fGVuc/dxO64RRljtCTnf5ecMyE1RIdtqpkVcq0IbtU2S8j2Q==", + "license": "ISC", + "dependencies": { + "d3-array": "2.5.0 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-hierarchy": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-3.1.2.tgz", + "integrity": "sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-interpolate": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", + "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", + "license": "ISC", + "dependencies": { + "d3-color": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-path": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz", + "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-polygon": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-polygon/-/d3-polygon-3.0.1.tgz", + "integrity": "sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-quadtree": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-3.0.1.tgz", + "integrity": "sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-random": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-random/-/d3-random-3.0.1.tgz", + "integrity": "sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-sankey": { + "version": "0.12.3", + "resolved": "https://registry.npmjs.org/d3-sankey/-/d3-sankey-0.12.3.tgz", + "integrity": "sha512-nQhsBRmM19Ax5xEIPLMY9ZmJ/cDvd1BG3UVvt5h3WRxKg5zGRbvnteTyWAbzeSvlh3tW7ZEmq4VwR5mB3tutmQ==", + "license": "BSD-3-Clause", + "dependencies": { + "d3-array": "1 - 2", + "d3-shape": "^1.2.0" + } + }, + "node_modules/d3-sankey/node_modules/d3-array": { + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.12.1.tgz", + "integrity": "sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==", + "license": "BSD-3-Clause", + "dependencies": { + "internmap": "^1.0.0" + } + }, + "node_modules/d3-sankey/node_modules/d3-path": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-1.0.9.tgz", + "integrity": "sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg==", + "license": "BSD-3-Clause" + }, + "node_modules/d3-sankey/node_modules/d3-shape": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-1.3.7.tgz", + "integrity": "sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw==", + "license": "BSD-3-Clause", + "dependencies": { + "d3-path": "1" + } + }, + "node_modules/d3-sankey/node_modules/internmap": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/internmap/-/internmap-1.0.1.tgz", + "integrity": "sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==", + "license": "ISC" + }, + "node_modules/d3-scale": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz", + "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==", + "license": "ISC", + "dependencies": { + "d3-array": "2.10.0 - 3", + "d3-format": "1 - 3", + "d3-interpolate": "1.2.0 - 3", + "d3-time": "2.1.1 - 3", + "d3-time-format": "2 - 4" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-scale-chromatic": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz", + "integrity": "sha512-A3s5PWiZ9YCXFye1o246KoscMWqf8BsD9eRiJ3He7C9OBaxKhAd5TFCdEx/7VbKtxxTsu//1mMJFrEt572cEyQ==", + "license": "ISC", + "dependencies": { + "d3-color": "1 - 3", + "d3-interpolate": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-selection": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz", + "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-shape": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz", + "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==", + "license": "ISC", + "dependencies": { + "d3-path": "^3.1.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz", + "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==", + "license": "ISC", + "dependencies": { + "d3-array": "2 - 3" + }, + "engines": { + "node": ">=12" } }, - "node_modules/css-what": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", - "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", - "engines": { - "node": ">= 6" + "node_modules/d3-time-format": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz", + "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==", + "license": "ISC", + "dependencies": { + "d3-time": "1 - 3" }, - "funding": { - "url": "https://github.com/sponsors/fb55" + "engines": { + "node": ">=12" } }, - "node_modules/cssdb": { - "version": "8.2.4", - "resolved": "https://registry.npmjs.org/cssdb/-/cssdb-8.2.4.tgz", - "integrity": "sha512-3KSCVkjZJe/QxicVXnbyYSY26WsFc1YoMY7jep1ZKWMEVc7jEm6V2Xq2r+MX8WKQIuB7ofGbnr5iVI+aZpoSzg==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - } - ], - "license": "MIT-0" - }, - "node_modules/cssesc": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", - "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", - "bin": { - "cssesc": "bin/cssesc" - }, + "node_modules/d3-timer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz", + "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==", + "license": "ISC", "engines": { - "node": ">=4" + "node": ">=12" } }, - "node_modules/csso": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/csso/-/csso-5.0.5.tgz", - "integrity": "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==", - "license": "MIT", + "node_modules/d3-transition": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-3.0.1.tgz", + "integrity": "sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==", + "license": "ISC", "dependencies": { - "css-tree": "~2.2.0" + "d3-color": "1 - 3", + "d3-dispatch": "1 - 3", + "d3-ease": "1 - 3", + "d3-interpolate": "1 - 3", + "d3-timer": "1 - 3" }, "engines": { - "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", - "npm": ">=7.0.0" + "node": ">=12" + }, + "peerDependencies": { + "d3-selection": "2 - 3" } }, - "node_modules/csso/node_modules/css-tree": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.2.1.tgz", - "integrity": "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==", - "license": "MIT", + "node_modules/d3-zoom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-3.0.0.tgz", + "integrity": "sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==", + "license": "ISC", "dependencies": { - "mdn-data": "2.0.28", - "source-map-js": "^1.0.1" + "d3-dispatch": "1 - 3", + "d3-drag": "2 - 3", + "d3-interpolate": "1 - 3", + "d3-selection": "2 - 3", + "d3-transition": "2 - 3" }, "engines": { - "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", - "npm": ">=7.0.0" + "node": ">=12" } }, - "node_modules/csso/node_modules/mdn-data": { - "version": "2.0.28", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.28.tgz", - "integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==", - "license": "CC0-1.0" + "node_modules/dagre-d3-es": { + "version": "7.0.11", + "resolved": "https://registry.npmjs.org/dagre-d3-es/-/dagre-d3-es-7.0.11.tgz", + "integrity": "sha512-tvlJLyQf834SylNKax8Wkzco/1ias1OPw8DcUMDE7oUIoSEW25riQVuiu/0OWEFqT0cxHT3Pa9/D82Jr47IONw==", + "license": "MIT", + "dependencies": { + "d3": "^7.9.0", + "lodash-es": "^4.17.21" + } }, - "node_modules/csstype": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", - "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" + "node_modules/dayjs": { + "version": "1.11.13", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.13.tgz", + "integrity": "sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==", + "license": "MIT" }, "node_modules/debounce": { "version": "1.2.1", @@ -7167,11 +8133,12 @@ "integrity": "sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==" }, "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "license": "MIT", "dependencies": { - "ms": "2.1.2" + "ms": "^2.1.3" }, "engines": { "node": ">=6.0" @@ -7315,6 +8282,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/delaunator": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/delaunator/-/delaunator-5.0.1.tgz", + "integrity": "sha512-8nvh+XBe96aCESrGOqMp/84b13H9cdKbG5P2ejQCh4d4sK9RL4371qou9drQjMhvnPmhWl5hnmqbEE0fXr9Xnw==", + "license": "ISC", + "dependencies": { + "robust-predicates": "^3.0.2" + } + }, "node_modules/depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", @@ -7467,6 +8443,15 @@ "url": "https://github.com/fb55/domhandler?sponsor=1" } }, + "node_modules/dompurify": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.2.5.tgz", + "integrity": "sha512-mLPd29uoRe9HpvwP2TxClGQBzGXeEC/we/q+bFlmPPmj2p2Ugl3r6ATu/UU1v77DXNcehiBg9zsr1dREyA/dJQ==", + "license": "(MPL-2.0 OR Apache-2.0)", + "optionalDependencies": { + "@types/trusted-types": "^2.0.7" + } + }, "node_modules/domutils": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", @@ -7947,6 +8932,12 @@ "node": ">= 0.6" } }, + "node_modules/exsolve": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/exsolve/-/exsolve-1.0.5.tgz", + "integrity": "sha512-pz5dvkYYKQ1AHVrgOzBKWeP4u4FRb3a6DNK2ucr0OoNwYIU4QWsJ+NM36LLzORT+z845MzKHHhpXiUF5nvQoJg==", + "license": "MIT" + }, "node_modules/extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", @@ -8700,6 +9691,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/hachure-fill": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/hachure-fill/-/hachure-fill-0.5.2.tgz", + "integrity": "sha512-3GKBOn+m2LX9iq+JC1064cSFprJY4jL1jCXTcpnfER5HYE2l/4EfWSGzkPa/ZDBmYI0ZOEj5VHV/eKnPGkHuOg==", + "license": "MIT" + }, "node_modules/handle-thing": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", @@ -9402,6 +10399,15 @@ "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.1.1.tgz", "integrity": "sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==" }, + "node_modules/internmap": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz", + "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, "node_modules/interpret": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", @@ -9830,6 +10836,31 @@ "graceful-fs": "^4.1.6" } }, + "node_modules/katex": { + "version": "0.16.22", + "resolved": "https://registry.npmjs.org/katex/-/katex-0.16.22.tgz", + "integrity": "sha512-XCHRdUw4lf3SKBaJe4EvgqIuWwkPSo9XoeO8GjQW94Bp7TWv9hNhzZjZ+OH9yf1UmLygb7DIT5GSFQiyt16zYg==", + "funding": [ + "https://opencollective.com/katex", + "https://github.com/sponsors/katex" + ], + "license": "MIT", + "dependencies": { + "commander": "^8.3.0" + }, + "bin": { + "katex": "cli.js" + } + }, + "node_modules/katex/node_modules/commander": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, "node_modules/keyv": { "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", @@ -9838,6 +10869,11 @@ "json-buffer": "3.0.1" } }, + "node_modules/khroma": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/khroma/-/khroma-2.1.0.tgz", + "integrity": "sha512-Ls993zuzfayK269Svk9hzpeGUKob/sIgZzyHYdjQoAdQetRKpOLj+k/QQQ/6Qi0Yz65mlROrfd+Ev+1+7dz9Kw==" + }, "node_modules/kind-of": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", @@ -9854,6 +10890,28 @@ "node": ">=6" } }, + "node_modules/kolorist": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/kolorist/-/kolorist-1.8.0.tgz", + "integrity": "sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==", + "license": "MIT" + }, + "node_modules/langium": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/langium/-/langium-3.3.1.tgz", + "integrity": "sha512-QJv/h939gDpvT+9SiLVlY7tZC3xB2qK57v0J04Sh9wpMb6MP1q8gB21L3WIo8T5P1MSMg3Ep14L7KkDCFG3y4w==", + "license": "MIT", + "dependencies": { + "chevrotain": "~11.0.3", + "chevrotain-allstar": "~0.3.0", + "vscode-languageserver": "~9.0.1", + "vscode-languageserver-textdocument": "~1.0.11", + "vscode-uri": "~3.0.8" + }, + "engines": { + "node": ">=16.0.0" + } + }, "node_modules/latest-version": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-7.0.0.tgz", @@ -9877,6 +10935,12 @@ "shell-quote": "^1.8.1" } }, + "node_modules/layout-base": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/layout-base/-/layout-base-1.0.2.tgz", + "integrity": "sha512-8h2oVEZNktL4BH2JCOI90iD1yXwL6iNW7KcCKT2QZgQJR2vbqDsldCTPRU9NifTCqHZci57XvQQ15YTu+sTYPg==", + "license": "MIT" + }, "node_modules/leven": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", @@ -9911,6 +10975,23 @@ "node": ">=8.9.0" } }, + "node_modules/local-pkg": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-1.1.1.tgz", + "integrity": "sha512-WunYko2W1NcdfAFpuLUoucsgULmgDBRkdxHxWQ7mK0cQqwPiy8E1enjuRBrhLtZkB5iScJ1XIPdhVEFK8aOLSg==", + "license": "MIT", + "dependencies": { + "mlly": "^1.7.4", + "pkg-types": "^2.0.1", + "quansync": "^0.2.8" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, "node_modules/locate-path": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", @@ -9930,6 +11011,12 @@ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, + "node_modules/lodash-es": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==", + "license": "MIT" + }, "node_modules/lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", @@ -10013,6 +11100,18 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/marked": { + "version": "15.0.11", + "resolved": "https://registry.npmjs.org/marked/-/marked-15.0.11.tgz", + "integrity": "sha512-1BEXAU2euRCG3xwgLVT1y0xbJEld1XOrmRJpUwRCcy7rxhSCwMrmEu9LXoPhHSCJG41V7YcQ2mjKRr5BA3ITIA==", + "license": "MIT", + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 18" + } + }, "node_modules/mdast-util-directive": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/mdast-util-directive/-/mdast-util-directive-3.1.0.tgz", @@ -10448,6 +11547,47 @@ "node": ">= 8" } }, + "node_modules/mermaid": { + "version": "11.6.0", + "resolved": "https://registry.npmjs.org/mermaid/-/mermaid-11.6.0.tgz", + "integrity": "sha512-PE8hGUy1LDlWIHWBP05SFdqUHGmRcCcK4IzpOKPE35eOw+G9zZgcnMpyunJVUEOgb//KBORPjysKndw8bFLuRg==", + "license": "MIT", + "dependencies": { + "@braintree/sanitize-url": "^7.0.4", + "@iconify/utils": "^2.1.33", + "@mermaid-js/parser": "^0.4.0", + "@types/d3": "^7.4.3", + "cytoscape": "^3.29.3", + "cytoscape-cose-bilkent": "^4.1.0", + "cytoscape-fcose": "^2.2.0", + "d3": "^7.9.0", + "d3-sankey": "^0.12.3", + "dagre-d3-es": "7.0.11", + "dayjs": "^1.11.13", + "dompurify": "^3.2.4", + "katex": "^0.16.9", + "khroma": "^2.1.0", + "lodash-es": "^4.17.21", + "marked": "^15.0.7", + "roughjs": "^4.6.6", + "stylis": "^4.3.6", + "ts-dedent": "^2.2.0", + "uuid": "^11.1.0" + } + }, + "node_modules/mermaid/node_modules/uuid": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.1.0.tgz", + "integrity": "sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist/esm/bin/uuid" + } + }, "node_modules/methods": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", @@ -12263,6 +13403,35 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/mlly": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.7.4.tgz", + "integrity": "sha512-qmdSIPC4bDJXgZTCR7XosJiNKySV7O215tsPtDN9iEO/7q/76b/ijtgRu/+epFXSJhijtTCCGp3DWS549P3xKw==", + "license": "MIT", + "dependencies": { + "acorn": "^8.14.0", + "pathe": "^2.0.1", + "pkg-types": "^1.3.0", + "ufo": "^1.5.4" + } + }, + "node_modules/mlly/node_modules/confbox": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz", + "integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==", + "license": "MIT" + }, + "node_modules/mlly/node_modules/pkg-types": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.3.1.tgz", + "integrity": "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==", + "license": "MIT", + "dependencies": { + "confbox": "^0.1.8", + "mlly": "^1.7.4", + "pathe": "^2.0.1" + } + }, "node_modules/mrmime": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.0.tgz", @@ -12272,9 +13441,10 @@ } }, "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" }, "node_modules/multicast-dns": { "version": "7.2.5", @@ -12668,6 +13838,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/package-manager-detector": { + "version": "0.2.11", + "resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-0.2.11.tgz", + "integrity": "sha512-BEnLolu+yuz22S56CU1SUKq3XC3PkwD5wv4ikR4MfGvnRVcmzXR9DwSlW2fEamyTPyXHomBJRzgapeuBvRNzJQ==", + "license": "MIT", + "dependencies": { + "quansync": "^0.2.7" + } + }, "node_modules/param-case": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", @@ -12777,6 +13956,12 @@ "tslib": "^2.0.3" } }, + "node_modules/path-data-parser": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/path-data-parser/-/path-data-parser-0.1.0.tgz", + "integrity": "sha512-NOnmBpt5Y2RWbuv0LMzsayp3lVylAHLPUTut412ZA3l+C4uw4ZVkQbjShYCQ8TCpUMdPapr4YjUqLYD6v68j+w==", + "license": "MIT" + }, "node_modules/path-exists": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", @@ -12827,6 +14012,12 @@ "node": ">=8" } }, + "node_modules/pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "license": "MIT" + }, "node_modules/periscopic": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/periscopic/-/periscopic-3.1.0.tgz", @@ -12868,6 +14059,17 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/pkg-types": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-2.1.0.tgz", + "integrity": "sha512-wmJwA+8ihJixSoHKxZJRBQG1oY8Yr9pGLzRmSsNms0iNWyHHAlZCa7mmKiFR10YPZuz/2k169JiS/inOjBCZ2A==", + "license": "MIT", + "dependencies": { + "confbox": "^0.2.1", + "exsolve": "^1.0.1", + "pathe": "^2.0.3" + } + }, "node_modules/pkg-up": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz", @@ -12935,6 +14137,22 @@ "node": ">=4" } }, + "node_modules/points-on-curve": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/points-on-curve/-/points-on-curve-0.2.0.tgz", + "integrity": "sha512-0mYKnYYe9ZcqMCWhUjItv/oHjvgEsfKvnUTg8sAtnHr3GVy7rGkXCb6d5cSyqrWqL4k81b9CPg3urd+T7aop3A==", + "license": "MIT" + }, + "node_modules/points-on-path": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/points-on-path/-/points-on-path-0.2.1.tgz", + "integrity": "sha512-25ClnWWuw7JbWZcgqY/gJ4FQWadKxGWk+3kR/7kD0tCaDtPPMj7oHu2ToLaVhfpnHrZzYby2w6tUA0eOIuUg8g==", + "license": "MIT", + "dependencies": { + "path-data-parser": "0.1.0", + "points-on-curve": "0.2.0" + } + }, "node_modules/postcss": { "version": "8.5.3", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.3.tgz", @@ -14004,6 +15222,22 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/quansync": { + "version": "0.2.10", + "resolved": "https://registry.npmjs.org/quansync/-/quansync-0.2.10.tgz", + "integrity": "sha512-t41VRkMYbkHyCYmOvx/6URnN80H7k4X0lLdBMGsz+maAwrJQYB1djpV6vHrQIBE0WBSGqhtEHrK9U3DWWH8v7A==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/antfu" + }, + { + "type": "individual", + "url": "https://github.com/sponsors/sxzz" + } + ], + "license": "MIT" + }, "node_modules/queue": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/queue/-/queue-6.0.2.tgz", @@ -14869,6 +16103,24 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/robust-predicates": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-3.0.2.tgz", + "integrity": "sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==", + "license": "Unlicense" + }, + "node_modules/roughjs": { + "version": "4.6.6", + "resolved": "https://registry.npmjs.org/roughjs/-/roughjs-4.6.6.tgz", + "integrity": "sha512-ZUz/69+SYpFN/g/lUlo2FXcIjRkSu3nDarreVdGGndHEBJ6cXPdKguS8JGxwj5HA5xIbVKSmLgr5b3AWxtRfvQ==", + "license": "MIT", + "dependencies": { + "hachure-fill": "^0.5.2", + "path-data-parser": "^0.1.0", + "points-on-curve": "^0.2.0", + "points-on-path": "^0.2.1" + } + }, "node_modules/rtlcss": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/rtlcss/-/rtlcss-4.3.0.tgz", @@ -14909,6 +16161,12 @@ "queue-microtask": "^1.2.2" } }, + "node_modules/rw": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz", + "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==", + "license": "BSD-3-Clause" + }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -15081,11 +16339,6 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, - "node_modules/send/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - }, "node_modules/send/node_modules/range-parser": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", @@ -15614,6 +16867,12 @@ "inline-style-parser": "0.1.1" } }, + "node_modules/stylis": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.6.tgz", + "integrity": "sha512-yQ3rwFWRfwNUY7H5vpU0wfdkNSnvnJinhF9830Swlaxl03zsOjCfmX0ugac+3LtK0lYSgwL/KXc8oYL3mG4YFQ==", + "license": "MIT" + }, "node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -15788,6 +17047,12 @@ "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==" }, + "node_modules/tinyexec": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz", + "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==", + "license": "MIT" + }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -15833,6 +17098,15 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/ts-dedent": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ts-dedent/-/ts-dedent-2.2.0.tgz", + "integrity": "sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==", + "license": "MIT", + "engines": { + "node": ">=6.10" + } + }, "node_modules/tslib": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", @@ -15901,6 +17175,12 @@ "node": ">=14.17" } }, + "node_modules/ufo": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.6.1.tgz", + "integrity": "sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==", + "license": "MIT" + }, "node_modules/undici-types": { "version": "5.26.5", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", @@ -16385,6 +17665,55 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/vscode-jsonrpc": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-8.2.0.tgz", + "integrity": "sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA==", + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/vscode-languageserver": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-9.0.1.tgz", + "integrity": "sha512-woByF3PDpkHFUreUa7Hos7+pUWdeWMXRd26+ZX2A8cFx6v/JPTtd4/uN0/jB6XQHYaOlHbio03NTHCqrgG5n7g==", + "license": "MIT", + "dependencies": { + "vscode-languageserver-protocol": "3.17.5" + }, + "bin": { + "installServerIntoExtension": "bin/installServerIntoExtension" + } + }, + "node_modules/vscode-languageserver-protocol": { + "version": "3.17.5", + "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.5.tgz", + "integrity": "sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg==", + "license": "MIT", + "dependencies": { + "vscode-jsonrpc": "8.2.0", + "vscode-languageserver-types": "3.17.5" + } + }, + "node_modules/vscode-languageserver-textdocument": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.12.tgz", + "integrity": "sha512-cxWNPesCnQCcMPeenjKKsOCKQZ/L6Tv19DTRIGuLWe32lyzWhihGVJ/rcckZXJxfdKCFvRLS3fpBIsV/ZGX4zA==", + "license": "MIT" + }, + "node_modules/vscode-languageserver-types": { + "version": "3.17.5", + "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.5.tgz", + "integrity": "sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg==", + "license": "MIT" + }, + "node_modules/vscode-uri": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.0.8.tgz", + "integrity": "sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw==", + "license": "MIT" + }, "node_modules/watchpack": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.1.tgz", diff --git a/package.json b/package.json index d41d88a..f9499af 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ "dependencies": { "@docusaurus/core": "^3.7.0", "@docusaurus/preset-classic": "^3.7.0", + "@docusaurus/theme-mermaid": "^3.7.0", "@jongwooo/prism-theme-github": "^1.14.0", "@mdx-js/react": "^3.0.0", "clsx": "^2.0.0", From 954ec5683550ab43bc44a371f773316bc232a3ca Mon Sep 17 00:00:00 2001 From: Lucas Bustamante Date: Sun, 4 May 2025 00:00:30 -0300 Subject: [PATCH 2/4] Add initial custom tests docs --- .../architecture.md | 133 ++++++++++++++ .../introduction.md | 23 +++ .../custom-tests-specification/quick-start.md | 74 ++++++++ .../quick-start/existing-playwright.md | 173 ++++++++++++++++++ .../quick-start/new-playwright.md | 61 ++++++ .../quick-start/other-frameworks.md | 71 +++++++ .../specification.md | 150 +++++++++++++++ sidebars.js | 24 +-- 8 files changed, 698 insertions(+), 11 deletions(-) create mode 100644 docs/custom-tests-specification/architecture.md create mode 100644 docs/custom-tests-specification/introduction.md create mode 100644 docs/custom-tests-specification/quick-start.md create mode 100644 docs/custom-tests-specification/quick-start/existing-playwright.md create mode 100644 docs/custom-tests-specification/quick-start/new-playwright.md create mode 100644 docs/custom-tests-specification/quick-start/other-frameworks.md create mode 100644 docs/custom-tests-specification/specification.md diff --git a/docs/custom-tests-specification/architecture.md b/docs/custom-tests-specification/architecture.md new file mode 100644 index 0000000..b3e02fe --- /dev/null +++ b/docs/custom-tests-specification/architecture.md @@ -0,0 +1,133 @@ +# Architecture + +#### Understand how QIT runs Custom E2E Tests + +### Single Plugin + +QIT can run a single plugin in a disposable environment. This is useful for testing a plugin in isolation. + +```mermaid +sequenceDiagram + participant QIT + participant TestEnvironment + + activate QIT + + %% --- Environment Setup --- + Note over QIT,TestEnvironment: Environment Setup Phase + QIT->>TestEnvironment: 1. Create Environment + activate TestEnvironment + Note right of TestEnvironment: Creates a disposable, dockerized environment.
Installs WordPress, PHP
and the plugin under test. + + QIT->>TestEnvironment: 2. Run Shared Setup (if defined) + Note right of TestEnvironment: Executes `lifecycle.sharedSetup` script
if defined in plugin-a's qit-e2e.json. + %% DB Snapshot/Import steps are omitted for single-plugin tests + + %% --- Test Execution for plugin-a --- + Note over QIT,TestEnvironment: Executing tests for plugin-a + QIT->>TestEnvironment: 3. Run Plugin A Setup (`lifecycle.setup` in plugin-a's qit-e2e.json) + QIT->>TestEnvironment: 4. Run Plugin A E2E test (`test_command` in plugin-a's qit-e2e.json) + activate TestEnvironment # LightSkyBlue + Note right of TestEnvironment: (Runs plugin-a E2E Tests) + deactivate TestEnvironment # LightSkyBlue + QIT->>TestEnvironment: 5. Run Plugin A Teardown (`lifecycle.teardown` in plugin-a's qit-e2e.json) + QIT->>TestEnvironment: 6. Collect Results for plugin-a (From plugin-a's `test_results` paths) + TestEnvironment-->>QIT: (Raw results & logs for plugin-a) + + %% --- Teardown Phase --- + Note over QIT,TestEnvironment: Teardown Phase + QIT->>TestEnvironment: 7. Run Shared Teardown (if defined) + Note right of TestEnvironment: Executes `lifecycle.sharedTeardown` script
if defined in plugin-a's qit-e2e.json. + + %% --- Result Processing & Reporting --- + Note over QIT,TestEnvironment: Result Processing & Reporting Phase + QIT->>QIT: 8. Process Results + Note right of QIT: Processes results from plugin-a,
captures logs, and prepares the final report. + + QIT->>TestEnvironment: 9. Destroy Environment + deactivate TestEnvironment + + Note over QIT: Show Final Status & Report URL + deactivate QIT +``` + +### Multiple Plugins + +QIT can run multiple plugins in a single environment. This is useful for testing compatibility between plugins or themes. + +When running in a multi-plugin environment, QIT will create a single environment and run the tests for each plugin in sequence, restoring a snapshot of the database state between each plugin's tests. This ensures that each plugin's tests run in a clean environment, without any interference from the other plugins. + +```mermaid +sequenceDiagram + participant QIT + participant TestEnvironment + + activate QIT + + %% --- Environment Setup --- + Note over QIT,TestEnvironment: Environment Setup Phase + QIT->>TestEnvironment: 1. Create Environment + activate TestEnvironment + Note right of TestEnvironment: Creates a disposable, dockerized environment.
Installs WordPress, PHP
AND specified plugins (plugin-a, plugin-b, plugin-c)
based on CLI options / qit-env.json. + + QIT->>TestEnvironment: 2. Run Shared Setup (if defined) + Note right of TestEnvironment: Executes combined `lifecycle.sharedSetup` scripts
from relevant plugins (e.g., plugin-a, plugin-b, plugin-c if defined in qit-e2e.json). + + QIT->>TestEnvironment: 3. Snapshot Initial Database State + Note right of TestEnvironment: Saves the DB state after shared setup. + + %% --- Test Execution for plugin-a --- + Note over QIT,TestEnvironment: Executing tests for plugin-a + QIT->>TestEnvironment: Import Initial Database State + Note right of TestEnvironment: Resets DB to the state saved after Shared Setup. + QIT->>TestEnvironment: Run Plugin-Specific Setup (plugin-a's `lifecycle.setup`) + QIT->>TestEnvironment: Run Plugin's Test Command (plugin-a's `test.command`) + activate TestEnvironment # LightSkyBlue + Note right of TestEnvironment: (plugin-a Test Execution...) + deactivate TestEnvironment # LightSkyBlue + QIT->>TestEnvironment: Run Plugin-Specific Teardown (plugin-a's `lifecycle.teardown`) + QIT->>TestEnvironment: Collect Results for plugin-a (From plugin-a's `test.results` paths) + TestEnvironment-->>QIT: (Raw results & logs for plugin-a) + + %% --- Test Execution for plugin-b --- + Note over QIT,TestEnvironment: Executing tests for plugin-b + QIT->>TestEnvironment: Import Initial Database State + Note right of TestEnvironment: Resets DB to the state saved after Shared Setup. + QIT->>TestEnvironment: Run Plugin-Specific Setup (plugin-b's `lifecycle.setup`) + QIT->>TestEnvironment: Run Plugin's Test Command (plugin-b's `test.command`) + activate TestEnvironment # LightSkyBlue + Note right of TestEnvironment: (plugin-b Test Execution...) + deactivate TestEnvironment # LightSkyBlue + QIT->>TestEnvironment: Run Plugin-Specific Teardown (plugin-b's `lifecycle.teardown`) + QIT->>TestEnvironment: Collect Results for plugin-b (From plugin-b's `test.results` paths) + TestEnvironment-->>QIT: (Raw results & logs for plugin-b) + + %% --- Test Execution for plugin-c --- + Note over QIT,TestEnvironment: Executing tests for plugin-c + QIT->>TestEnvironment: Import Initial Database State + Note right of TestEnvironment: Resets DB to the state saved after Shared Setup. + QIT->>TestEnvironment: Run Plugin-Specific Setup (plugin-c's `lifecycle.setup`) + QIT->>TestEnvironment: Run Plugin's Test Command (plugin-c's `test.command`) + activate TestEnvironment # LightSkyBlue + Note right of TestEnvironment: (plugin-c Test Execution...) + deactivate TestEnvironment # LightSkyBlue + QIT->>TestEnvironment: Run Plugin-Specific Teardown (plugin-c's `lifecycle.teardown`) + QIT->>TestEnvironment: Collect Results for plugin-c (From plugin-c's `test.results` paths) + TestEnvironment-->>QIT: (Raw results & logs for plugin-c) + + %% --- Final Steps --- + Note over QIT,TestEnvironment: Teardown Phase + QIT->>TestEnvironment: 4. Run Shared Teardown (if defined) + Note right of TestEnvironment: Executes combined `lifecycle.sharedTeardown` scripts
from relevant plugins (e.g., plugin-a, plugin-b, plugin-c if defined in qit-e2e.json). + + %% --- Result Processing & Reporting --- + Note over QIT,TestEnvironment: Result Processing & Reporting Phase + QIT->>QIT: 5. Process & Merge All Results + Note right of QIT: Combines results from plugin-a, plugin-b, plugin-c,
captures logs, and prepares the final report. + + QIT->>TestEnvironment: 6. Destroy Environment + deactivate TestEnvironment + + Note over QIT: Show Final Status & Report URL + deactivate QIT +``` diff --git a/docs/custom-tests-specification/introduction.md b/docs/custom-tests-specification/introduction.md new file mode 100644 index 0000000..a784843 --- /dev/null +++ b/docs/custom-tests-specification/introduction.md @@ -0,0 +1,23 @@ +# Introduction + +**QIT Custom Tests** is a developer-friendly testing solution that lets WordPress plugin and theme authors ship their own end-to-end test suites. It eliminates environment setup hassles so you can focus on writing meaningful tests. + +## Key Features + +- **Write tests, not infrastructure code**: QIT handles Docker setup, WordPress configuration, and environment teardown +- **Playwright by default, flexible by design**: Built for Playwright but supports any test framework that outputs CTRF results +- **Multi-plugin orchestration**: Test multiple plugins in one environment with shared setup and isolated test cycles +- **Standardized Test Definition**: Each plugin includes a `qit-e2e.json` manifest file, defining how its tests integrate with and are executed by the QIT CLI. This file acts as the key configuration, ensuring compatibility with QIT Custom Tests. +- **Disposable Docker environments:** QIT builds a fresh WordPress instance for every run, then cleans up automatically. +- **Standardised reporting:** CTRF results are merged and surfaced consistently in local runs, CI pipelines, and marketplace checks. + +## Compatibility Testing + +QIT's orchestration system helps plugin and theme developers identify cross-plugin compatibility issues before they affect users. During the shared setup phase, each participating plugin performs its own initialization steps (e.g., a payment gateway plugin connects to its sandbox, another plugin dismisses the onboarding wizard they add, etc). QIT then captures a database snapshot of this fully prepared environment before systematically running each plugin's test suite in isolation. This approach reveals how plugins interact in real-world conditions while maintaining test isolation and separation of concerns. + +- Validate your plugin against popular extensions your users likely have installed +- Test compatibility with different versions of companion plugins +- Ensure consistent functionality when multiple plugins modify the same WordPress areas + +> **Industry adoption** +> Leading plugin marketplaces—such as [WooCommerce.com](https://woocommerce.com)—use QIT to run **quality checks** on extensions submitted to their platforms. Making your E2E tests **compliant with the QIT Custom Test Specification** signals that your plugin is serious about quality and reliability, helps you pass automated reviews, and makes your product stand out in a crowded marketplace. \ No newline at end of file diff --git a/docs/custom-tests-specification/quick-start.md b/docs/custom-tests-specification/quick-start.md new file mode 100644 index 0000000..4fd0db8 --- /dev/null +++ b/docs/custom-tests-specification/quick-start.md @@ -0,0 +1,74 @@ +# Quick Start + +### Get started with QIT Custom Tests + +Custom End-to-End (E2E) Tests allow you to define and run compatibility tests for WordPress plugins/themes directly in Dockerized environments. Choose your scenario: + +#### [1. New Playwright Tests](#new-playwright) +Create a new test suite from scratch using Playwright. + +#### [2. Existing Playwright Tests](#existing-playwright) +Integrate QIT into an existing project with minimal setup. + +#### [3. Other test frameworks](#other-frameworks) +Use any framework that outputs results in the [CTRF format](https://ctrf.io). + +## 1. New Playwright Tests + +1. Run the following command to create a new test suite: + + ```qitbash + qit scaffold:e2e ./tests/e2e + ``` +2. This creates a new directory `tests/e2e` with the following structure: + + ```bash + tests/e2e/ + ├── qit-e2e.json + ├── playwright.config.js + ├── package.json + ├── bootstrap/ + │ ├── setup.sh + │ └── mu-plugin.php + └── tests/ + └── example.spec.ts + ``` + +3. Run the tests: + + ```qitbash + qit run:e2e your-plugin-slug ./tests/e2e + ``` + +4. Develop the tests with Playwright. For example, you can spin up a persistent environment for development: + + ```qitbash + qit run:e2e your-plugin-slug ./tests/e2e --persistent + ``` + + Then run the test several times while developing: + + ```qitbash + cd tests/e2e + QIT_SITE_URL=http://localhost:8080 npx playwright test + ``` + + You can also run in Playwright Codegen or Headed mode. + + ```qitbash + npx playwright codegen http://localhost:8080 + ``` + + Check out the [Playwright documentation](https://playwright.dev/docs/codegen-intro) for more options. + + You can always reset the environment to a clean state by running: + + ```qitbash + qit reset + ``` + + When you are happy with the results, you can publish your tests to QIT with: + + ```qitbash + qit publish:e2e your-plugin-slug ./tests/e2e + ``` \ No newline at end of file diff --git a/docs/custom-tests-specification/quick-start/existing-playwright.md b/docs/custom-tests-specification/quick-start/existing-playwright.md new file mode 100644 index 0000000..e924dbe --- /dev/null +++ b/docs/custom-tests-specification/quick-start/existing-playwright.md @@ -0,0 +1,173 @@ +# Existing Playwright Tests + +To make your existing Playwright tests work with QIT, follow these steps: + +1. Add a `qit-e2e.json` file to root of your test directory (the same directory where `playwright.config.js` is). + +To start, you can use this simplified example: + ```json + { + "test_command": "npx playwright test", + "test_results": { + "ctrf": "./results/ctrf.json" + }, + "lifecycle": { + "setup": "./bootstrap/setup.sh" + } + } + ``` + +See more options for the `qit-e2e.json` file in the [specification](./../specification.md). + +2. Add `QIT_SITE_URL` to your `playwright.config.js` file, example: + +```javascript +module.exports = { + use: { + baseURL: process.env.QIT_SITE_URL || 'http://localhost:8888', + }, +}; +``` + +2. Install a CTRF Reporter: + +```bash +npm i playwright-ctrf-json-reporter +``` + +And then in your `playwright.config.js` file, add the reporter: + +```javascript +module.exports = { + reporter: [ + [ + 'playwright-ctrf-json-reporter', + { + outputFile: 'ctrf.json', + outputDir: './results', + } + ], + ], +}; +``` + +3. Optionally add an Allure Reporter if you want screenshots and videos of your test runs in QIT reports: + +```bash +npm i allure-playwright +``` + +And then in your `playwright.config.js` file, add the reporter: + +```javascript +module.exports = { + reporter: [ + [ + 'allure-playwright', + { + resultsDir: './results/allure', + detail: true, + suiteTitle: true, + }, + ], + ], +}; +``` + +4. Add a `bootstrap/setup.sh` file to your test suite, use it to personalize your environment. For example, if you want to install a theme, you can add the following: + +```bash +#!/bin/bash + +wp theme install some-example-theme +wp theme activate some-example-theme +``` + +### Putting it all together: + +`playwright.config.js`: + +```javascript +module.exports = { + use: { + baseURL: process.env.QIT_SITE_URL || 'http://localhost:8888', + }, + reporter: [ + ['list'], + [ + 'playwright-ctrf-json-reporter', + { + outputFile: 'ctrf.json', + outputDir: './results', + } + ], + [ + 'allure-playwright', + { + resultsDir: './results/allure', + detail: true, + suiteTitle: true, + }, + ], + ], +}; +``` + +### Extra tips + +- Remember that your tests should be self-contained (like a WordPress plugin), so they should NOT reference files OUTSIDE of your test directory (the directory where your `qit-e2e.json` file is located). + +### Example structure + + ```bash + tests/e2e/ + ├── qit-e2e.json + ├── playwright.config.js + ├── package.json + ├── bootstrap/ + │ ├── setup.sh + │ └── mu-plugin.php + └── tests/ + └── example.spec.ts + ``` + +### Run the tests + + ```qitbash + qit run:e2e your-plugin-slug ./tests/e2e + ``` + +### Develop the tests with Playwright + +For example, you can spin up a persistent environment for development: + + ```qitbash + qit run:e2e your-plugin-slug ./tests/e2e --persistent + ``` + + Then run the test several times while developing: + + ```qitbash + cd tests/e2e + QIT_SITE_URL=http://localhost:8080 npx playwright test + ``` + + You can also run in Playwright Codegen or Headed mode. + + ```qitbash + npx playwright codegen http://localhost:8080 + ``` + + Check out the [Playwright documentation](https://playwright.dev/docs/codegen-intro) for more options. + + You can always reset the environment to a clean state by running: + + ```qitbash + qit reset + ``` + + When you are happy with the results, you can publish your tests to QIT with: + + ```qitbash + qit publish:e2e your-plugin-slug ./tests/e2e + ``` \ No newline at end of file diff --git a/docs/custom-tests-specification/quick-start/new-playwright.md b/docs/custom-tests-specification/quick-start/new-playwright.md new file mode 100644 index 0000000..9edb51e --- /dev/null +++ b/docs/custom-tests-specification/quick-start/new-playwright.md @@ -0,0 +1,61 @@ +# New Playright Tests + +To create a new Playwright test suite with QIT, follow these steps: + +1. Run the following command to create a new test suite: + + ```qitbash + qit scaffold:e2e ./tests/e2e + ``` +2. This creates a new directory `tests/e2e` with the following structure: + + ```bash + tests/e2e/ + ├── qit-e2e.json + ├── playwright.config.js + ├── package.json + ├── bootstrap/ + │ ├── setup.sh + │ └── mu-plugin.php + └── tests/ + └── example.spec.ts + ``` + +3. Run the tests: + + ```qitbash + qit run:e2e your-plugin-slug ./tests/e2e + ``` + +4. Develop the tests with Playwright. For example, you can spin up a persistent environment for development: + + ```qitbash + qit run:e2e your-plugin-slug ./tests/e2e --persistent + ``` + + Then run the test several times while developing: + + ```qitbash + cd tests/e2e + QIT_SITE_URL=http://localhost:8080 npx playwright test + ``` + + You can also run in Playwright Codegen or Headed mode. + + ```qitbash + npx playwright codegen http://localhost:8080 + ``` + + Check out the [Playwright documentation](https://playwright.dev/docs/codegen-intro) for more options. + + You can always reset the environment to a clean state by running: + + ```qitbash + qit reset + ``` + + When you are happy with the results, you can publish your tests to QIT with: + + ```qitbash + qit publish:e2e your-plugin-slug ./tests/e2e + ``` \ No newline at end of file diff --git a/docs/custom-tests-specification/quick-start/other-frameworks.md b/docs/custom-tests-specification/quick-start/other-frameworks.md new file mode 100644 index 0000000..d9313da --- /dev/null +++ b/docs/custom-tests-specification/quick-start/other-frameworks.md @@ -0,0 +1,71 @@ +# Other Frameworks + +QIT Custom E2E Tests **uses Playwright by default, but it is framework-agnostic by design**. Runners that emit **[CTRF](https://ctrf.io)** results can be integrated, although such setups are considered *experimental* and must be maintained by the implementer. + +#### Prerequisites + +1. **CTRF output** – Your framework **must** produce results in CTRF so QIT can parse them. +2. **Environment constraints** – Tests must run within QIT's environment constraints. See the full list in the [specification](../specification.md). + +#### Integration steps + +1. **Create `qit-e2e.json`** + +Create a `qit-e2e.json` file in the root of your test directory. This file is essential for QIT to understand how to run your tests. + + ```json + { + "test_command": "your-test-command", + "test_results": { + "ctrf": "./results/ctrf.json" + }, + "lifecycle": { + "setup": "./bootstrap/setup.sh" + } + } + ``` + + See more options for the `qit-e2e.json` file in the [specification](../specification.md). + +**Use `QIT_SITE_URL`** environment variable in your test framework to point to the QIT environment. This is crucial for your tests to run correctly. + +### Run the tests + + ```qitbash + qit run:e2e your-plugin-slug ./tests/e2e + ``` + +### Develop the tests with Playwright + +For example, you can spin up a persistent environment for development: + + ```qitbash + qit run:e2e your-plugin-slug ./tests/e2e --persistent + ``` + +Then run the test several times while developing: + + ```qitbash + cd tests/e2e + QIT_SITE_URL=http://localhost:8080 npx playwright test + ``` + +You can also run in Playwright Codegen or Headed mode. + + ```qitbash + npx playwright codegen http://localhost:8080 + ``` + +Check out the [Playwright documentation](https://playwright.dev/docs/codegen-intro) for more options. + +You can always reset the environment to a clean state by running: + + ```qitbash + qit reset + ``` + +When you are happy with the results, you can publish your tests to QIT with: + + ```qitbash + qit publish:e2e your-plugin-slug ./tests/e2e + ``` \ No newline at end of file diff --git a/docs/custom-tests-specification/specification.md b/docs/custom-tests-specification/specification.md new file mode 100644 index 0000000..c6b1194 --- /dev/null +++ b/docs/custom-tests-specification/specification.md @@ -0,0 +1,150 @@ +# Specification + +## Document + +This document specifies the requirements and format for declaring custom end-to-end (E2E) tests in WooCommerce’s **Quality Insights Toolkit (QIT)**. It defines the structure and content of the **`qit-e2e.json`** configuration file that accompanies a WooCommerce extension’s custom tests, as well as the expected behavior of the test execution within the QIT environment. All requirements are stated in a declarative, standards-style format. + +The key words **“MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHOULD”,** and **“MAY”** in this document are to be interpreted as described in \[RFC 2119]\[1] (BCP 14). They indicate normative requirements for test configuration and behavior. An extension’s test suite is **conformant** to this specification if it meets all the MUST and REQUIRED directives herein. + +## Context + +**Quality Insights Toolkit (QIT)** provides an automated platform to run plugin-specific E2E tests in a disposable WordPress/WooCommerce environment. This specification ensures that custom E2E tests for a WooCommerce extension are declared in a consistent, machine-readable way so QIT can orchestrate them reliably. By using a standardized JSON config file (`qit-e2e.json`), developers explicitly specify how their tests should execute, rather than relying on implicit conventions or manual steps. + +Under QIT, tests run inside an isolated Dockerized environment that includes WordPress, WooCommerce, PHP, and Node.js. The environment guarantees a clean WordPress installation for each test run, with the extension (and any additional plugins) installed. QIT coordinates test lifecycle phases – from environment setup to test execution and teardown – to ensure reproducible outcomes even when multiple extensions are tested together. The **`qit-e2e.json`** file is the single source of truth for how to run an extension’s tests within this environment. + +Critically, QIT requires that test results be produced in the **Common Test Report Format (CTRF)** – a standardized JSON schema for reporting test outcomes. This ensures consistency across different test frameworks. By adhering to CTRF, QIT can aggregate and interpret results uniformly, regardless of whether the extension’s tests use Playwright, Jest, or another framework. All custom E2E test suites MUST integrate with a CTRF-compliant reporter to produce a JSON results file (see **test\_results** in **Structure** below). + +Finally, note that QIT supports WordPress plugins running on a range of PHP versions (typically PHP 7.4 and above) and executes tests using Node.js (a recent LTS release, e.g. Node 18 or later). Extension tests MUST be compatible with these runtime versions. For example, tests should not use Node features newer than the QIT environment provides, and the extension’s PHP code must support the PHP version under test. The QIT CLI and environment will enforce these compatibility constraints during test execution. + +## Structure + +**`qit-e2e.json`** is a JSON document that declaratively configures how to execute an extension’s custom E2E tests. It MUST be included with the extension’s test files (typically at the root of the extension’s E2E test directory). QIT will look for this file when running custom tests for the extension. The file’s root is a JSON object with the following required fields: **`test_command`**, **`test_results`**, **`lifecycle`**, and **`muPlugins`**. No field is optional – all MUST be present, even if some are left empty (e.g. an empty list for `muPlugins` if none are used). QIT will not apply any default conventions or assume any file locations; every key aspect of the test run must be explicitly declared in this config. + +All file or path values in `qit-e2e.json` are interpreted relative to the directory containing the `qit-e2e.json` file (unless an absolute path is given). In practice, if your custom tests reside in a directory (for example, an `e2e/` folder in your project), the `qit-e2e.json` should be placed in that folder and paths inside it (for test scripts, results, etc.) should be relative to that folder. QIT will use that folder as the working directory when executing your tests. + +The required fields in the configuration are defined as follows: + +* **`test_command`** (string): **The command to execute the test suite.** This is the exact shell command QIT will run to kick off your extension’s tests in the containerized environment. It may include CLI arguments and should invoke your chosen test runner (for example, a Playwright or Jest command). The command **MUST** be non-interactive and fully automated – it **MUST NOT** expect any user input or interactive prompts. It **MUST** also run in “headless” or CI mode (for example, if using Playwright, ensure the browser launches headlessly, and if using a test runner with an interactive UI, disable it). QIT will execute this command once per test run for your extension (during the “test phase” of that extension). The working directory for the command is the location of `qit-e2e.json`, so the command can use relative paths to files in the test directory. The `test_command` is responsible for running all test cases and producing a test results report. If the command exits with a non-zero status, QIT will treat it as a failure (indicating the tests did not run to completion successfully). + +* **`test_results`** (string): **The output path of the test results report.** This path must point to a JSON file that the test command will generate, containing the results of the test run in the Common Test Report Format (CTRF). The file path can be relative (preferred) or absolute. For example, a value might be `"test-results/ctrf.json"` or `"./results/output.json"`. After the `test_command` finishes, QIT will look for this file to determine the outcome of the tests. The results file **MUST** conform to the CTRF schema – i.e., it should contain fields like `tool`, `summary`, and an array of test case results with names, statuses, durations, etc., as defined by the CTRF standard. (CTRF is a framework-agnostic JSON report format that ensures consistency across different testing tools.) The test runner’s configuration should be set up to write its results to the exact location specified by `test_results`. QIT will not assume any default filename or directory; if this field is incorrect or the file is not present after test execution, the run is considered a failure. + + *Behavior:* QIT may set an environment variable indicating this output path when running the test command (for example, it might set `CTRF_OUTPUT_PATH` to the resolved `test_results` path) to assist test reporter configuration. If such an environment variable is set, the test suite SHOULD honor it (i.e. ensure the reporter writes to that path). Regardless of how it’s achieved, by the end of `test_command` execution, the specified `test_results` file **MUST** exist and contain a valid CTRF JSON report. The absence of this file or a malformed report will cause QIT to mark the test run as failed or invalid. + +* **`lifecycle`** (object): **Lifecycle script definitions for test setup/teardown.** This object defines scripts that QIT will run at specific phases of the test lifecycle, enabling you to prepare or clean up the environment before/after tests. All scripts are optional, but if a given phase is needed, its path MUST be specified here (QIT will not auto-detect scripts by naming convention — you must declare each script you intend to use). The lifecycle object can include the following keys, each mapping to a script file path (string, relative to the test directory): + + * `shared_setup`: Script to execute once **before all plugin tests** in a multi-plugin run (or before your plugin’s tests begin, if it’s the sole plugin under test). This “shared setup” runs at the very start of a test run to establish a global baseline state. For example, you might disable WooCommerce onboarding screens or set global settings that apply to all tests. If provided, QIT will run this script *before* any isolated plugin setup or tests occur. Any changes made here will be captured in the baseline database snapshot that QIT takes (if multiple plugins are involved). If no `shared_setup` is specified, QIT will skip this phase (and assume no global preconfiguration beyond the default environment). + + * `shared_teardown`: Script to execute once **after all plugin tests** have finished in a run. This “shared teardown” runs at the very end of the test run to clean up any persistent changes made by the shared setup or by the tests overall. For example, you might re-enable settings that were turned off or simply log final diagnostics. QIT will run this after all isolated tests and teardowns are done, when the environment is about to be destroyed. If not specified, QIT will perform no extra steps at the end beyond its normal environment shutdown. (It’s worth noting that because QIT’s environment is ephemeral, explicit shared teardown is often not needed unless you have external side-effects to reverse.) + + * `isolated_setup`: Script to execute **before this plugin’s test cases**, every time the plugin is about to be tested. This “isolated setup” runs *per test suite*, ensuring the extension’s specific preconditions are met. For example, you might install a specific theme required for your plugin, seed the database with test data, or configure plugin-specific settings. QIT executes this script after restoring the baseline database (which includes any shared setup effects) and before running the `test_command` for your plugin. Any changes here apply only to this plugin’s testing session; QIT will rollback these changes afterward (by importing the baseline snapshot for the next plugin or discarding the environment at run end). If no `isolated_setup` is given, it is assumed that the plugin’s tests can run with just the baseline environment. + + * `isolated_teardown`: Script to execute **after this plugin’s tests complete**, every time after running the plugin’s `test_command`. This “isolated teardown” runs *per test suite* and is intended to clean up anything the isolated setup or the tests changed, restoring the environment to the baseline. For example, you might deactivate a feature flag, remove test data, or reset environment state specific to the plugin. QIT will run this script after collecting the test results. Once it finishes, QIT will either proceed to the next plugin’s test (restoring baseline first) or, if this was the last plugin, proceed to shared teardown and then shut down the environment. If not provided, QIT assumes no special cleanup is needed beyond its automatic database snapshot restores. + + Each script path listed in `lifecycle` MUST point to an executable script file (shell script, Node script, etc.) that can run in the test container. These scripts execute inside the WordPress/PHP container (the same environment where WordPress is running). For shell scripts, the container provides a Unix-like environment (Alpine Linux base). For Node or JavaScript scripts (if used), Node.js is available as well. Ensure the script has appropriate shebang or file extension so the container knows how to run it (e.g., a `.sh` file will be run with Bash/sh, a `.js` could be run with Node if invoked accordingly). QIT does not impose a specific language for these; it simply executes them in the container context. + + **No Implicit Execution:** QIT **MUST NOT** run any lifecycle scripts that are not declared in this object. In other words, if a script file exists in the tests directory but is not referenced here, it will be ignored. There is no fallback where QIT automatically picks up files named e.g. `shared-setup.sh` or similar – all execution must be opt-in via this config. This explicit declaration requirement is to avoid “hidden” test behavior and ensure the test process is fully described by `qit-e2e.json`. Conversely, if a key is present in `lifecycle` but the path is empty or the file is not found, QIT will treat that as a configuration error. Provide only the keys you intend to use, with valid paths. (You may include all four keys for clarity, setting those you don’t use to `null` or an empty string, but it’s not required to include unused keys.) + +* **`muPlugins`** (array of strings): **List of must-use plugin files to load.** This field allows you to specify WordPress MU-Plugins that QIT should install and activate in the test environment *before* running any tests. Must-use plugins (MU-plugins) are special plugins that live in the `wp-content/mu-plugins` directory and are automatically loaded by WordPress on every page load (they cannot be deactivated via the admin). In the context of QIT, this is typically used for any auxiliary code needed for your tests that must always be active. For example, you might have a small plugin that hooks into WordPress to expose test utilities or modify behavior for testing purposes, or to include compatibility shims when testing alongside another plugin. + + Each entry in the `muPlugins` list should be a path to a PHP plugin file (or a directory containing a plugin) that exists in your extension’s test package. For instance: `"mu-plugins/test-helper.php"` could refer to a file in your test directory that contains plugin header comments and some PHP code to run during tests. QIT will ensure all listed MU-Plugins are copied into the WordPress installation’s `wp-content/mu-plugins/` folder prior to starting the tests. They will remain active for the duration of the environment uptime (including across shared and isolated phases). Order is not guaranteed, so if there are dependencies between these, combine them into a single file or ensure they don’t conflict. + + If no must-use plugins are required, specify an empty list (`"muPlugins": []`). Do **not** omit the field; an explicit empty array clarifies that no MU-Plugins are needed. As with other fields, QIT will not implicitly load anything not listed. In particular, QIT will *only* install additional plugins as MU-Plugins if they are declared here. (Note: This `muPlugins` field is specifically for custom plugin files packaged with your tests. It is distinct from the main **plugins** list in the general environment configuration, which is used to install normal plugins via repository slugs. Any extension you list in the environment config’s plugins will be installed as a regular plugin. In contrast, `muPlugins` here are meant for test-specific code, always-on during the test run.) + +**Example:** A minimal `qit-e2e.json` might look like: + +```json +{ + "test_command": "npx playwright test --reporter ctrf-json", + "test_results": "artifacts/ctrf.json", + "lifecycle": { + "shared_setup": "bootstrap/global-setup.sh", + "shared_teardown": "bootstrap/global-teardown.sh", + "isolated_setup": "bootstrap/setup.sh", + "isolated_teardown": "bootstrap/teardown.sh" + }, + "muPlugins": [ + "mu-plugins/qit-helpers.php" + ] +} +``` + +This configuration declares that QIT should run the Playwright test suite using a CTRF JSON reporter, outputting results to `artifacts/ctrf.json`. It specifies four lifecycle scripts (shell scripts in a `bootstrap` folder) to handle global setup/teardown and per-test setup/teardown. It also lists one must-use plugin (`qit-helpers.php`) to be loaded for the tests (perhaps providing helper functions or hooks needed during the tests). QIT will strictly follow this specification: it will run each named script at the proper phase (if the file exists), run the test command, and expect the results file. Nothing outside of what’s described will be assumed or executed. + +## Constraints + +This section enumerates additional requirements and constraints that apply to the custom E2E test configuration and its execution under QIT: + +* **File Presence and Location:** An extension providing custom E2E tests **MUST** include a `qit-e2e.json` file as defined above. The file SHOULD reside at the root of the test directory (if a specific test directory is used) or at the root of the extension if the tests are in the top-level. When invoking `qit run:e2e`, the path given to QIT (or default path, if supported) **MUST** contain `qit-e2e.json`. If QIT cannot find this file, it will not attempt to run custom tests (older behavior of guessing test commands or paths is deprecated). In a multi-plugin compatibility test run, each plugin with tests must have its own `qit-e2e.json`; plugins without one will be treated as having no custom tests (they might still be activated for the run, but no special commands/scripts are run for them). + +* **Single Test Command:** The `test_command` should encompass all test execution. QIT will invoke this command once for the plugin’s entire test suite. Sub-processes or multiple internal test files can be handled by your test runner, but QIT expects one encompassing command. Do not assume QIT will run multiple commands or pick up individual test files automatically – any such logic must be part of your command or scripts. Likewise, QIT will not automatically retry tests or split them; if you require retries or parallelism, handle that within your test framework configuration (ensuring it still outputs a single combined CTRF report in the end). + +* **No Convention Fallbacks:** This specification eliminates all “fallback to convention” behaviors that may have existed in earlier QIT versions. For clarity: + + * If `test_command` is not provided (or is empty), QIT **SHALL NOT** guess an npm script or default command – the test run will be considered misconfigured. There is no default like `npm test` or similar. + * If `test_results` is not specified, QIT **CANNOT** determine where to find results – the run will error. There is no default results path (such as assuming a file named `ctrf.json` in the working directory) without an explicit declaration. + * If `lifecycle` scripts are omitted, QIT assumes none are needed and will not run anything for those phases (aside from its built-in DB snapshot handling). It will not scan directories for any scripts. Conversely, if `lifecycle` is present, QIT will trust only the specified paths. For example, having a file named `setup.sh` in a folder is ineffective unless referenced in `lifecycle.isolated_setup`. + * If `muPlugins` is empty, QIT will not load any extra must-use plugins. It does not, for instance, automatically include a “compatibility mu-plugin” or any helper unless you list it. (QIT itself manages any internal helpers on its side; from the extension’s perspective, only what you declare will be added.) + +* **Compatibility of Test Environment:** The custom tests must run within the bounds of the QIT environment: + + * **Node.js**: The Docker environment that runs the tests comes with Node.js (typically a recent Long-Term-Support version, e.g. Node 18.x in 2025). Your test scripts and frameworks **MUST** be compatible with that Node.js version. If your tests require a specific Node version (or features of a newer version), you must ensure QIT supports it (QIT may update its base images over time, but you cannot assume beyond documented versions). In practice, use widely-supported JavaScript features or transpile your tests if needed to run on the provided Node version. + * **PHP**: You can specify the PHP version of the WordPress environment via QIT’s environment config (outside this spec), but QIT itself supports PHP 7.4+ (and up to the latest 8.x) for test environments. Your extension and any test-related PHP code (including mu-plugins or setup scripts that call WP CLI or WP functions) **MUST** be compatible with the PHP versions you intend to test on. For example, if your extension’s minimum PHP is 7.4, ensure none of your test code uses features that require PHP 8.0 unless you restrict the environment to PHP 8.0+. QIT will fail tests that crash due to syntax errors or incompatibilities in the chosen PHP runtime. + * **WordPress/WooCommerce**: Similar to PHP, the version of WordPress and WooCommerce used in the test environment can be configured (e.g., latest, specific versions). Your tests should be written with those in mind (especially if using selectors or admin UI flows that might change across versions). While this spec doesn’t define those versions, it is expected that the extension’s tests are kept compatible with the range of WP/WC versions the extension supports, and QIT’s environment will be set accordingly by the tester. + * **Networking and External Services**: The test environment is isolated. If your tests require external network calls (e.g., to a remote API), be aware of any environment variables or settings needed for that. QIT permits internet access from the container by default, but you should ensure any keys or endpoints are configurable via environment variables (and use QIT’s `--env` or `--env_file` to supply them, rather than hardcoding secrets). The `process.env` and `getenv()` mechanisms can retrieve variables set through QIT’s CLI. + * **Environment Variables (internal)**: QIT may set certain environment variables in the container to convey context. For example, QIT will set **`CI=true`** (a common convention in CI systems) to indicate a non-interactive environment. It may also set `QIT_RUN_ID` or similar identifiers for logging. Your tests **SHOULD NOT** override these. In particular, some test frameworks detect `CI=true` to automatically disable interactive features – do not unset this. If you have conditional logic in tests based on environment (e.g., skipping certain slow steps if an env var is present), document and handle that carefully. Additionally, if QIT sets a `BASE_URL` or similar for the WordPress site address, you should use it or the QIT Helper functions to get the site URL, rather than assuming `http://localhost` or hard-coding an address. + +* **Test Lifecycle Behavior:** QIT’s handling of the lifecycle phases follows a defined sequence: + + 1. **Environment setup**: QIT prepares the WordPress environment (installs WordPress, WooCommerce, sets up the database, installs the extension and any other plugins). The extension under test is installed as a normal plugin but not yet activated (unless it’s meant to auto-load via MU-plugin). + 2. **Shared Setup**: If `lifecycle.shared_setup` is defined, QIT runs that script. If multiple plugins in the run have a `shared_setup`, typically only one shared setup is executed (usually the one from the primary plugin under test, or one combined step for all – QIT avoids running duplicate global setups). This detail is managed by QIT’s orchestration logic; from the perspective of your plugin, include a `shared_setup` only if it’s intended to be the primary global setup for the compatibility scenario. After this phase, QIT takes a snapshot of the database state to use as a baseline. + 3. **Per-Plugin Test Loop**: For each plugin designated to run tests (`action: test` in QIT orchestration terms), QIT will: + + * **DB Restore**: Reset the DB to the baseline (so each plugin’s tests start with the same base state). + * **Isolated Setup**: Run that plugin’s `isolated_setup` script, if provided. + * **Test Execution**: Activate the plugin (if not already active) and run its `test_command`. During this time, the plugin is active and any MU-plugins are also active. QIT captures output and waits for completion. + * **Test Results**: After the command finishes, QIT expects the `test_results` file to be present. QIT reads the CTRF JSON file and records the outcomes (for reporting or determining pass/fail). + * **Isolated Teardown**: Run the plugin’s `isolated_teardown` script, if provided. This should revert changes specific to this plugin’s test. + * Proceed to the next plugin (if any). + 4. **Shared Teardown**: If `lifecycle.shared_teardown` is defined (and if shared setup ran earlier), QIT runs that script after all plugin tests are done. + 5. **Environment shutdown**: QIT then destroys the environment (containers), unless running in a persistent mode. All temporary data is discarded (except the test results that were extracted). + + Within this sequence, your scripts and tests must operate as follows: + + * The **shared setup** script can assume WordPress is installed and running, all declared MU-plugins are loaded, and any base plugins (like WooCommerce) are active. It should not activate the extension under test (QIT will handle actual plugin activation per test if needed). Shared setup should be idempotent (if by chance it ran twice, it shouldn’t break anything) and should avoid heavy operations that could be done in isolated setup unless truly global. + * **Isolated setup** can assume the extension under test’s code is present (files installed) but not yet active (unless the extension itself was placed as an MU-plugin, which is uncommon). Typically QIT will activate the extension as part of running the test command (for example, the test command might use WP-CLI to activate plugins or the Playwright tests activate via UI if needed). If your extension must be active to run tests, you should activate it either in the isolated setup (e.g., via a WP-CLI command) or at the start of your test workflow. Ensure to deactivate in isolated teardown if needed to restore state. + * **Isolated teardown** should clean up both changes made in isolated setup and any persistent changes made by the tests (like created orders, settings changes, etc.), unless those are automatically wiped by restoring DB (note: QIT’s design is to use DB snapshots to automatically isolate plugin tests, so if QIT reliably restores the baseline for each plugin, isolated teardown might mainly be for external side-effects or for courtesy cleanup). + * Shared teardown should undo anything from shared setup that would persist beyond the test run if the environment were kept alive. Often the environment is torn down anyway, so shared teardown is mostly for completeness or to send final logs/notifications. + +* **Result Format and Evaluation:** The CTRF JSON results file must indicate individual test case outcomes. QIT will consider the test run successful (pass) if all test cases in the report have a passing status. If any test case is marked as failed in the CTRF results, QIT will mark the overall custom E2E test as failed (and reflect those failures in its reporting). If the `test_command` itself exits with an error or the results file is missing/corrupt, QIT may mark the entire run as an error (as opposed to a mere test failure). Essentially, to get a “green” test run in QIT, two things are needed: the test command exits normally, and the CTRF report indicates zero failures. It is the developer’s responsibility to ensure their testing framework properly sets its exit code and output when tests fail. For example, many test runners will exit with a non-zero code if any test fails – this is good, as QIT can quickly catch that. But even if it didn’t, QIT would rely on the CTRF JSON content to see the failures. Make sure your CTRF reporter flushes output to file by the end of the run (some reporters may write after all tests or on process exit; in container context, the process exit and file write order is usually fine, but it’s worth verifying). + +* **Conventions for Paths and Names:** While QIT doesn’t enforce specific naming conventions (due to the explicit config approach), we recommend a few practices for consistency: + + * Name your CTRF results file clearly (e.g., `ctrf.json` or `test-results.json`) and store it in a subfolder like `results/` or `artifacts/`. This keeps the root clean and signals its purpose. + * Put setup/teardown scripts in a dedicated folder (commonly `bootstrap/` or `scripts/`) and use descriptive names (`shared-setup.sh`, `teardown.js`, etc.). Even though you must list them in config, a consistent naming scheme helps maintain clarity. + * If using multiple MU-plugins, consider prefixing them (e.g., `mu-plugins/001-preload.php`, `mu-plugins/002-helper.php`) if load order matters. But ideally, combine into one file to avoid order issues. + * Use your extension slug or name in any outward-facing output or tag inside the CTRF (the CTRF has fields for tool name or environment – you might include your plugin name there for clarity). This can help when reviewing aggregated reports from multiple extensions. + +## Conformance + +An extension’s custom E2E test package is considered **conformant** to the QIT Custom E2E Test Specification if it meets all the structural and behavioral requirements outlined above. In practical terms, this means: + +* The extension includes a valid `qit-e2e.json` file with all required fields properly defined. +* The test command and scripts, when executed by QIT, consistently produce the expected outcomes (CTRF results, no unexpected prompts, etc.) in the QIT environment. +* No deprecated or implicit behaviors are relied upon; all necessary configuration is explicitly declared. +* The test results adhere to the CTRF format and accurately reflect test success or failure. + +QIT’s automation will enforce many of these rules. For example, the QIT CLI may perform a validation of `qit-e2e.json` on startup (ensuring required keys exist and are of correct types). It will also halt execution with an error message if, say, the `test_command` is missing or if the `test_results` file can’t be found. To be conformant, your configuration should pass all such validations and run to completion in QIT without manual intervention or out-of-band tweaks. + +**Backward Compatibility:** Extensions that previously relied on convention (for instance, those that had an `e2e-tests` folder without a `qit-e2e.json`, expecting QIT to auto-detect test files) are **not** conformant to this specification. They should be updated to include the explicit config. QIT may continue to offer limited legacy support for a transition period, but such usage is outside this spec’s scope and may be removed in future releases. To claim conformance, the extension MUST use the declarative approach described here. + +**Multi-Plugin Runs:** When multiple extensions are involved in a single orchestrated test run (for compatibility testing), each extension that is actively tested must individually conform to this spec (i.e., each has its own `qit-e2e.json`). QIT will combine these according to its orchestration rules (for example, running the shared setup from one of them, running each test command in turn, etc.). If any extension’s config is non-conformant, it may cause the entire run to be marked as non-conformant or failed. Extensions that are only present as additional activated plugins (with no tests of their own) need not have a `qit-e2e.json` – they are effectively outside the scope of custom test spec (treated as normal dependencies). In summary, conformance is evaluated per extension test suite. + +**Conformance Verification:** Developers can verify conformance by running their tests via the QIT CLI in a local environment prior to publishing. A fully conformant test suite will run successfully with `qit run:e2e` and produce a CTRF report that QIT can parse, without any warnings or errors about missing configuration. Additionally, code reviews or automated checks may lint the `qit-e2e.json` format. If an extension is submitted to the WooCommerce Marketplace with custom tests, WooCommerce’s integration will expect this standardized format; non-conformant test configs might be rejected or cause automated tests to fail. + +By following this specification, developers ensure their custom E2E tests integrate seamlessly with QIT’s tooling. This not only helps in their own development process (catching bugs, verifying compatibility) but also contributes to a more stable ecosystem where every extension’s tests can run under a unified system. Adhering to the standard means any developer or automation system can understand how to run your extension’s tests simply by reading `qit-e2e.json`, without guesswork. This aligns with the broader goal of MCP-style declarative configs: making integration predictable and reducing ambiguity. The end result is a robust, machine-readable contract for testing your extension’s quality and compatibility. + +**References:** + +1. BCP 14 / RFC 2119 – Key words for use in RFCs to Indicate Requirement Levels +2. QIT Documentation – Compatibility testing and lifecycle overview +3. Jenkins Plugin Introduction – Common Test Report Format (CTRF) definition diff --git a/sidebars.js b/sidebars.js index aa2e16b..3cbb76c 100644 --- a/sidebars.js +++ b/sidebars.js @@ -63,17 +63,19 @@ const sidebars = { label: 'Custom E2E Tests', collapsed: true, items: [ - 'custom-tests/introduction', - 'custom-tests/generating-tests', - 'custom-tests/tagging-tests', - 'custom-tests/running-tests', - 'custom-tests/downloading-extensions-and-tests', - 'custom-tests/understanding-lifecycle', - 'custom-tests/orchestration', - 'custom-tests/compatibility-tests', - 'custom-tests/themes', - 'custom-tests/security-architecture', - 'custom-tests/qit-helpers', + 'custom-tests-specification/introduction', + { + type: 'category', + label: 'Quick Start', + collapsed: true, + items: [ + 'custom-tests-specification/quick-start/new-playwright', + 'custom-tests-specification/quick-start/existing-playwright', + 'custom-tests-specification/quick-start/other-frameworks', + ], + }, + 'custom-tests-specification/architecture', + 'custom-tests-specification/specification', ], }, { From 08878b579718fd9890f7a78f6939b4cfd4e7fa90 Mon Sep 17 00:00:00 2001 From: Lucas Bustamante Date: Sun, 4 May 2025 00:00:59 -0300 Subject: [PATCH 3/4] Typo --- docs/custom-tests-specification/introduction.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/custom-tests-specification/introduction.md b/docs/custom-tests-specification/introduction.md index a784843..9640152 100644 --- a/docs/custom-tests-specification/introduction.md +++ b/docs/custom-tests-specification/introduction.md @@ -13,7 +13,7 @@ ## Compatibility Testing -QIT's orchestration system helps plugin and theme developers identify cross-plugin compatibility issues before they affect users. During the shared setup phase, each participating plugin performs its own initialization steps (e.g., a payment gateway plugin connects to its sandbox, another plugin dismisses the onboarding wizard they add, etc). QIT then captures a database snapshot of this fully prepared environment before systematically running each plugin's test suite in isolation. This approach reveals how plugins interact in real-world conditions while maintaining test isolation and separation of concerns. +QIT's orchestration system helps plugin and theme developers identify cross-plugin compatibility issues before they affect users. During the shared setup phase, each participating plugin performs its own initialization steps (e.g., a payment gateway plugin connects to its sandbox, another plugin dismisses the onboarding wizard it adds, etc). QIT then captures a database snapshot of this fully prepared environment before systematically running each plugin's test suite in isolation. This approach reveals how plugins interact in real-world conditions while maintaining test isolation and separation of concerns. - Validate your plugin against popular extensions your users likely have installed - Test compatibility with different versions of companion plugins From cce51dcc22ef338135e96038b3eea056dda7bdf3 Mon Sep 17 00:00:00 2001 From: Lucas Bustamante Date: Sun, 4 May 2025 11:22:58 -0300 Subject: [PATCH 4/4] Tweak wording --- .../quick-start/existing-playwright.md | 129 +++++++++++------- .../quick-start/new-playwright.md | 107 +++++++++------ .../quick-start/other-frameworks.md | 89 ++++++------ 3 files changed, 191 insertions(+), 134 deletions(-) diff --git a/docs/custom-tests-specification/quick-start/existing-playwright.md b/docs/custom-tests-specification/quick-start/existing-playwright.md index e924dbe..6efecaf 100644 --- a/docs/custom-tests-specification/quick-start/existing-playwright.md +++ b/docs/custom-tests-specification/quick-start/existing-playwright.md @@ -1,8 +1,10 @@ # Existing Playwright Tests -To make your existing Playwright tests work with QIT, follow these steps: +This guide shows you how to adapt your **existing Playwright tests** to work with QIT in a WordPress environment - whether you are developing a plugin or a theme. -1. Add a `qit-e2e.json` file to root of your test directory (the same directory where `playwright.config.js` is). +### 1. Add a `qit-e2e.json` file + +In the **root of your test directory** (where `playwright.config.js` is located), add a file named `qit-e2e.json`. Use this simplified example as a starting point: To start, you can use this simplified example: ```json @@ -17,9 +19,11 @@ To start, you can use this simplified example: } ``` -See more options for the `qit-e2e.json` file in the [specification](./../specification.md). - -2. Add `QIT_SITE_URL` to your `playwright.config.js` file, example: +You can find more options in the `qit-e2e.json` [specification](./../specification.md). + +### 2. Add `QIT_SITE_URL` to Your Playwright Configuration + +In your `playwright.config.js` file, set a `baseURL` using the `QIT_SITE_URL` environment variable: ```javascript module.exports = { @@ -29,13 +33,17 @@ module.exports = { }; ``` -2. Install a CTRF Reporter: +**Why this matters:** QIT dynamically assigns a local WordPress site URL when spinning up the test environment, so your Playwright tests need to rely on the `QIT_SITE_URL` variable to know where WordPress is running. + +### 3. Install a CTRF Reporter + +Install the [CTRF JSON Reporter](https://www.npmjs.com/package/playwright-ctrf-json-reporter) so QIT can ingest your test results: ```bash npm i playwright-ctrf-json-reporter ``` -And then in your `playwright.config.js` file, add the reporter: +Then, reference it in your `playwright.config.js` file: ```javascript module.exports = { @@ -51,13 +59,16 @@ module.exports = { }; ``` -3. Optionally add an Allure Reporter if you want screenshots and videos of your test runs in QIT reports: + +### 4. (Optional) Add an Allure Reporter + +If you want screenshots and videos to show up in your QIT reports, install and configure the Allure Reporter: ```bash npm i allure-playwright ``` -And then in your `playwright.config.js` file, add the reporter: +Update your `playwright.config.js` to include it: ```javascript module.exports = { @@ -74,7 +85,9 @@ module.exports = { }; ``` -4. Add a `bootstrap/setup.sh` file to your test suite, use it to personalize your environment. For example, if you want to install a theme, you can add the following: +### 5. Personalize your test environment + +Create or modify a `bootstrap/setup.sh` script to customize your WordPress environment. For example, to install and activate a theme: ```bash #!/bin/bash @@ -83,9 +96,11 @@ wp theme install some-example-theme wp theme activate some-example-theme ``` +Feel free to add any other commands needed before your tests run. + ### Putting it all together: -`playwright.config.js`: +Below is an example `playwright.config.js` illustrating how you can combine all your reporters and environment settings: ```javascript module.exports = { @@ -113,61 +128,75 @@ module.exports = { }; ``` -### Extra tips - -- Remember that your tests should be self-contained (like a WordPress plugin), so they should NOT reference files OUTSIDE of your test directory (the directory where your `qit-e2e.json` file is located). ### Example structure - ```bash - tests/e2e/ - ├── qit-e2e.json - ├── playwright.config.js - ├── package.json - ├── bootstrap/ - │ ├── setup.sh - │ └── mu-plugin.php - └── tests/ - └── example.spec.ts - ``` +Below is an example of how your directory might look after adding QIT-specific files and your Playwright tests: + +```bash +your-plugin/ +├── your-plugin.php +├── tests/e2e/ +├──── qit-e2e.json +├──── playwright.config.js +├──── package.json +├──── bootstrap/ +│ ├── setup.sh +│ └── mu-plugin.php +└──── tests/ + └── example.spec.ts +``` + +Make sure your tests are **self-contained** within your test directory. They should not reference files outside the folder containing `qit-e2e.json`. ### Run the tests - ```qitbash - qit run:e2e your-plugin-slug ./tests/e2e - ``` +From the root of your plugin or theme, run: + +```qitbash +qit run:e2e your-plugin-slug ./tests/e2e +``` + +:::info +Replace `your-plugin-slug` with your actual plugin or theme slug. If you are building a WordPress theme, you might use a placeholder like `your-theme-slug` instead. +::: ### Develop the tests with Playwright -For example, you can spin up a persistent environment for development: +For iterative development, spin up a **persistent** QIT environment: - ```qitbash - qit run:e2e your-plugin-slug ./tests/e2e --persistent - ``` +```qitbash +qit run:e2e your-plugin-slug ./tests/e2e --persistent +``` - Then run the test several times while developing: +Then, in a separate terminal, navigate to your tests directory and run them repeatedly: - ```qitbash - cd tests/e2e - QIT_SITE_URL=http://localhost:8080 npx playwright test - ``` +```qitbash +cd tests/e2e +export QIT_SITE_URL= +npx playwright test +``` - You can also run in Playwright Codegen or Headed mode. +To visually debug or generate test code, you can use Playwright Codegen: - ```qitbash - npx playwright codegen http://localhost:8080 - ``` +```qitbash +npx playwright codegen +``` - Check out the [Playwright documentation](https://playwright.dev/docs/codegen-intro) for more options. +Check out the [Playwright documentation](https://playwright.dev/docs/codegen-intro) for additional details on recording and debugging test steps. - You can always reset the environment to a clean state by running: +### Reset or Publish - ```qitbash - qit reset - ``` +You can always reset your QIT environment to a fresh WordPress install: - When you are happy with the results, you can publish your tests to QIT with: +```qitbash +qit reset +``` + +Finally, once your existing tests are validated and running smoothly: + +```qitbash +qit publish:e2e your-plugin-slug ./tests/e2e +``` - ```qitbash - qit publish:e2e your-plugin-slug ./tests/e2e - ``` \ No newline at end of file +That’s it! By following these steps, you’ve adapted your existing Playwright tests to be **QIT-ready** for a WordPress plugin or theme. \ No newline at end of file diff --git a/docs/custom-tests-specification/quick-start/new-playwright.md b/docs/custom-tests-specification/quick-start/new-playwright.md index 9edb51e..0ea6b45 100644 --- a/docs/custom-tests-specification/quick-start/new-playwright.md +++ b/docs/custom-tests-specification/quick-start/new-playwright.md @@ -1,61 +1,82 @@ # New Playright Tests -To create a new Playwright test suite with QIT, follow these steps: +This guide shows you how to set up and run end-to-end Playwright tests with QIT for your WordPress plugin or theme. -1. Run the following command to create a new test suite: +### 1. Scaffold your test suite - ```qitbash - qit scaffold:e2e ./tests/e2e - ``` -2. This creates a new directory `tests/e2e` with the following structure: +In the root directory of your WordPress plugin or theme, run: - ```bash - tests/e2e/ - ├── qit-e2e.json - ├── playwright.config.js - ├── package.json - ├── bootstrap/ - │ ├── setup.sh - │ └── mu-plugin.php - └── tests/ - └── example.spec.ts - ``` +```qitbash +qit scaffold:e2e ./tests/e2e +``` +This command will create a new `tests/e2e` folder with the following structure: -3. Run the tests: +```bash +tests/e2e/ +├── qit-e2e.json +├── playwright.config.js +├── package.json +├── bootstrap/ +│ ├── setup.sh +│ └── mu-plugin.php +└── tests/ + └── example.spec.ts +``` - ```qitbash - qit run:e2e your-plugin-slug ./tests/e2e - ``` +### 2. Run your tests -4. Develop the tests with Playwright. For example, you can spin up a persistent environment for development: +Still in your plugin or theme directory, use: - ```qitbash - qit run:e2e your-plugin-slug ./tests/e2e --persistent - ``` +```qitbash +qit run:e2e your-plugin-slug ./tests/e2e +``` - Then run the test several times while developing: +:::info +Replace `your-plugin-slug` with your actual plugin or theme slug. If you are building a WordPress theme, you might use a placeholder like `your-theme-slug` instead. +::: - ```qitbash - cd tests/e2e - QIT_SITE_URL=http://localhost:8080 npx playwright test - ``` +### 3. Develop the tests with Playwright. - You can also run in Playwright Codegen or Headed mode. +To spin up a persistent environment for development, run: - ```qitbash - npx playwright codegen http://localhost:8080 - ``` +```qitbash +qit run:e2e your-plugin-slug ./tests/e2e --persistent +``` - Check out the [Playwright documentation](https://playwright.dev/docs/codegen-intro) for more options. +Within this environment, you can quickly re-run tests as you code: - You can always reset the environment to a clean state by running: +```qitbash +cd tests/e2e +export QIT_SITE_URL= +npx playwright test +``` - ```qitbash - qit reset - ``` +#### Using Playwright Codegen or Headed mode - When you are happy with the results, you can publish your tests to QIT with: +If you want to record or visually debug your test interactions, use: - ```qitbash - qit publish:e2e your-plugin-slug ./tests/e2e - ``` \ No newline at end of file +```qitbash +npx playwright codegen +``` + +Check the [Playwright documentation](https://playwright.dev/docs/codegen-intro) for additional tips on recording and debugging. + +### 4. Reset or Publish + +You can reset to a clean WordPress test environment at any time: + +```qitbash +qit reset +``` + +When your tests are stable and ready to share or integrate into CI, publish them to QIT: + +```qitbash +qit publish:e2e your-plugin-slug ./tests/e2e +``` + +**That’s it!** You’ve successfully set up end-to-end Playwright tests for your WordPress plugin or theme using QIT. + +:::tip +Remember to exclude the `tests` directory from your plugin or theme zip file before publishing it to a marketplace for distribution. +::: \ No newline at end of file diff --git a/docs/custom-tests-specification/quick-start/other-frameworks.md b/docs/custom-tests-specification/quick-start/other-frameworks.md index d9313da..42d8136 100644 --- a/docs/custom-tests-specification/quick-start/other-frameworks.md +++ b/docs/custom-tests-specification/quick-start/other-frameworks.md @@ -2,70 +2,77 @@ QIT Custom E2E Tests **uses Playwright by default, but it is framework-agnostic by design**. Runners that emit **[CTRF](https://ctrf.io)** results can be integrated, although such setups are considered *experimental* and must be maintained by the implementer. -#### Prerequisites +### 1. Prerequisites -1. **CTRF output** – Your framework **must** produce results in CTRF so QIT can parse them. +1. **CTRF output** – Your framework **must** produce results in [CTRF](https://ctrf.io) format so QIT can parse them. 2. **Environment constraints** – Tests must run within QIT's environment constraints. See the full list in the [specification](../specification.md). -#### Integration steps +Make sure your tests are self-contained in your test directory (similar to a plugin). This ensures everything QIT needs is packaged together. -1. **Create `qit-e2e.json`** +### 2. Integration steps -Create a `qit-e2e.json` file in the root of your test directory. This file is essential for QIT to understand how to run your tests. +**Create `qit-e2e.json`** - ```json - { - "test_command": "your-test-command", - "test_results": { - "ctrf": "./results/ctrf.json" - }, - "lifecycle": { - "setup": "./bootstrap/setup.sh" - } +In the **root of your test directory** (where your test framework’s config typically lives), add a `qit-e2e.json` file. QIT relies on this file to know how to set up and run your tests. Start with an example like this: + +```json +{ + "test_command": "your-test-command", + "test_results": { + "ctrf": "./results/ctrf.json" + }, + "lifecycle": { + "setup": "./bootstrap/setup.sh" } - ``` +} +``` - See more options for the `qit-e2e.json` file in the [specification](../specification.md). +See more options for the `qit-e2e.json` file in the [specification](../specification.md). **Use `QIT_SITE_URL`** environment variable in your test framework to point to the QIT environment. This is crucial for your tests to run correctly. -### Run the tests +### 3. Run the tests + +From your WordPress plugin or theme directory, run: + +```qitbash +qit run:e2e your-plugin-slug ./tests/e2e +``` - ```qitbash - qit run:e2e your-plugin-slug ./tests/e2e - ``` +Replace `your-plugin-slug` with your actual plugin or theme slug. If you’re developing a WordPress theme, you might use `your-theme-slug` instead. -### Develop the tests with Playwright +### 4. Develop the tests For example, you can spin up a persistent environment for development: - ```qitbash - qit run:e2e your-plugin-slug ./tests/e2e --persistent - ``` +```qitbash +qit run:e2e your-plugin-slug ./tests/e2e --persistent +``` -Then run the test several times while developing: +Then, while the environment is running, open another terminal and run your tests repeatedly: - ```qitbash - cd tests/e2e - QIT_SITE_URL=http://localhost:8080 npx playwright test - ``` +```qitbash +cd tests/e2e +export QIT_SITE_URL= + +``` You can also run in Playwright Codegen or Headed mode. - ```qitbash - npx playwright codegen http://localhost:8080 - ``` +```qitbash +npx playwright codegen +``` -Check out the [Playwright documentation](https://playwright.dev/docs/codegen-intro) for more options. +### 5. Reset or Publish -You can always reset the environment to a clean state by running: +If you need a clean WordPress install at any time: - ```qitbash - qit reset - ``` +```qitbash +qit reset +``` -When you are happy with the results, you can publish your tests to QIT with: +When you’re satisfied with your tests, publish them to QIT: - ```qitbash - qit publish:e2e your-plugin-slug ./tests/e2e - ``` \ No newline at end of file +```qitbash +qit publish:e2e your-plugin-slug ./tests/e2e +``` \ No newline at end of file