web: Adjust Wdio MaxInstances, add Knip (#11089)

- Adjust the WebdriverIO configuration so that `maxInstances` can be set by the environment
- `MAX_INSTANCES=1 CI=true npm run test` will run the headless tests from your command line.
- `MAX_INSTANCES=1 npm run test-watch` if you want to watch the test run in-browser.
- Adds `knip` import tracing facility for linting.
- Knip can be accessed by `npm run lint:imports`.

Running `MAX_INSTANCES=10` (the default) would sometimes create conflicts and overwhelm the test
runner, leaving you with 11 open instances of Chrome and no way to know which one is the one you
*don't* want to close. A better choice is `MAX_INSTANCES=1 npm run test-watch`, which would allow
the developer to watch the test run serially.

Knip adds a new linting feature: tracking down which imports are not used, are not exported
correctly, or shouldn't have been exported at all. Despite the "zero-config" promise, it still
required significant configuration to handle the wide variety of "strengths" of ESlint
configurations, as well as pointers to our entries and reminders that web components may export
their classes but their actual use is as part of the component registry.

Knip's analyzer produces a lot of false positives.  It is not intended to be used as part of the
CI/CD pipeline; it is there to help developers figure out what can and should be cleaned up
manually.

Co-authored-by: Jens Langhammer <jens@goauthentik.io>
This commit is contained in:
Ken Sternberg
2024-09-03 06:09:40 -07:00
committed by GitHub
parent 9a26111f1c
commit 78e4370b98
4 changed files with 352 additions and 7 deletions

292
web/package-lock.json generated
View File

@ -83,6 +83,7 @@
"@types/eslint__js": "^8.42.3",
"@types/grecaptcha": "^3.0.9",
"@types/guacamole-common-js": "1.5.2",
"@types/node": "^22.5.0",
"@types/showdown": "^2.0.6",
"@typescript-eslint/eslint-plugin": "^8.0.1",
"@typescript-eslint/parser": "^8.0.1",
@ -102,6 +103,7 @@
"github-slugger": "^2.0.0",
"glob": "^11.0.0",
"globals": "^15.9.0",
"knip": "^5.27.4",
"lit-analyzer": "^2.0.3",
"lockfile-lint": "^4.14.0",
"npm-run-all": "^4.1.5",
@ -6101,6 +6103,50 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/@snyk/github-codeowners": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@snyk/github-codeowners/-/github-codeowners-1.1.0.tgz",
"integrity": "sha512-lGFf08pbkEac0NYgVf4hdANpAgApRjNByLXB+WBip3qj1iendOIyAwP2GKkKbQMNVy2r1xxDf0ssfWscoiC+Vw==",
"dev": true,
"license": "MIT",
"dependencies": {
"commander": "^4.1.1",
"ignore": "^5.1.8",
"p-map": "^4.0.0"
},
"bin": {
"github-codeowners": "dist/cli.js"
},
"engines": {
"node": ">=8.10"
}
},
"node_modules/@snyk/github-codeowners/node_modules/commander": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz",
"integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 6"
}
},
"node_modules/@snyk/github-codeowners/node_modules/p-map": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz",
"integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"aggregate-error": "^3.0.0"
},
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/@spotlightjs/overlay": {
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/@spotlightjs/overlay/-/overlay-2.4.0.tgz",
@ -8911,11 +8957,13 @@
"license": "MIT"
},
"node_modules/@types/node": {
"version": "22.1.0",
"version": "22.5.2",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.2.tgz",
"integrity": "sha512-acJsPTEqYqulZS/Yp/S3GgeE6GZ0qYODUR8aVr/DkhHQ8l9nd4j5x1/ZJy9/gHrRlFMqkO6i0I3E27Alu4jjPg==",
"dev": true,
"license": "MIT",
"dependencies": {
"undici-types": "~6.13.0"
"undici-types": "~6.19.2"
}
},
"node_modules/@types/normalize-package-data": {
@ -10383,6 +10431,20 @@
"node": ">= 14"
}
},
"node_modules/aggregate-error": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz",
"integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==",
"dev": true,
"license": "MIT",
"dependencies": {
"clean-stack": "^2.0.0",
"indent-string": "^4.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/ajv": {
"version": "6.12.6",
"dev": true,
@ -11698,6 +11760,16 @@
"consola": "^3.2.3"
}
},
"node_modules/clean-stack": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz",
"integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=6"
}
},
"node_modules/cli-cursor": {
"version": "3.1.0",
"dev": true,
@ -13238,6 +13310,20 @@
"once": "^1.4.0"
}
},
"node_modules/enhanced-resolve": {
"version": "5.17.1",
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz",
"integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==",
"dev": true,
"license": "MIT",
"dependencies": {
"graceful-fs": "^4.2.4",
"tapable": "^2.2.0"
},
"engines": {
"node": ">=10.13.0"
}
},
"node_modules/enquirer": {
"version": "2.4.1",
"dev": true,
@ -16186,6 +16272,16 @@
"node": ">=0.8.19"
}
},
"node_modules/indent-string": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz",
"integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
}
},
"node_modules/inflight": {
"version": "1.0.6",
"dev": true,
@ -17243,6 +17339,16 @@
"node": ">=8"
}
},
"node_modules/jiti": {
"version": "1.21.6",
"resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.6.tgz",
"integrity": "sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==",
"dev": true,
"license": "MIT",
"bin": {
"jiti": "bin/jiti.js"
}
},
"node_modules/jquery": {
"version": "3.7.1",
"license": "MIT"
@ -17519,6 +17625,131 @@
"node": ">=6"
}
},
"node_modules/knip": {
"version": "5.29.1",
"resolved": "https://registry.npmjs.org/knip/-/knip-5.29.1.tgz",
"integrity": "sha512-l8qFtRqNpCk8xf46VOwhBUva7LBwanoGPJ4KQNwVRl6hmEXStf1BJlfbYRZ+yQpbilbIV6LN+ztX6LaGtyd4TQ==",
"dev": true,
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/webpro"
},
{
"type": "opencollective",
"url": "https://opencollective.com/knip"
},
{
"type": "polar",
"url": "https://polar.sh/webpro-nl"
}
],
"license": "ISC",
"dependencies": {
"@nodelib/fs.walk": "1.2.8",
"@snyk/github-codeowners": "1.1.0",
"easy-table": "1.2.0",
"enhanced-resolve": "^5.17.1",
"fast-glob": "^3.3.2",
"jiti": "^1.21.6",
"js-yaml": "^4.1.0",
"minimist": "^1.2.8",
"picocolors": "^1.0.0",
"picomatch": "^4.0.1",
"pretty-ms": "^9.0.0",
"smol-toml": "^1.1.4",
"strip-json-comments": "5.0.1",
"summary": "2.1.0",
"zod": "^3.22.4",
"zod-validation-error": "^3.0.3"
},
"bin": {
"knip": "bin/knip.js",
"knip-bun": "bin/knip-bun.js"
},
"engines": {
"node": ">=18.6.0"
},
"peerDependencies": {
"@types/node": ">=18",
"typescript": ">=5.0.4"
}
},
"node_modules/knip/node_modules/argparse": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
"dev": true,
"license": "Python-2.0"
},
"node_modules/knip/node_modules/js-yaml": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
"integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
"dev": true,
"license": "MIT",
"dependencies": {
"argparse": "^2.0.1"
},
"bin": {
"js-yaml": "bin/js-yaml.js"
}
},
"node_modules/knip/node_modules/parse-ms": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-4.0.0.tgz",
"integrity": "sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=18"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/knip/node_modules/picomatch": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz",
"integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/jonschlinkert"
}
},
"node_modules/knip/node_modules/pretty-ms": {
"version": "9.1.0",
"resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-9.1.0.tgz",
"integrity": "sha512-o1piW0n3tgKIKCwk2vpM/vOV13zjJzvP37Ioze54YlTHE06m4tjEbzg9WsKkvTuyYln2DHjo5pY4qrZGI0otpw==",
"dev": true,
"license": "MIT",
"dependencies": {
"parse-ms": "^4.0.0"
},
"engines": {
"node": ">=18"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/knip/node_modules/strip-json-comments": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-5.0.1.tgz",
"integrity": "sha512-0fk9zBqO67Nq5M/m45qHCJxylV/DhBlIOVExqgOMiCCrzrhU6tCibRXNqE3jwJLftzE9SNuZtYbpzcO+i9FiKw==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=14.16"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/kolorist": {
"version": "1.8.0",
"resolved": "https://registry.npmjs.org/kolorist/-/kolorist-1.8.0.tgz",
@ -21942,6 +22173,19 @@
"dev": true,
"license": "MIT"
},
"node_modules/smol-toml": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/smol-toml/-/smol-toml-1.3.0.tgz",
"integrity": "sha512-tWpi2TsODPScmi48b/OQZGi2lgUmBCHy6SZrhi/FdnnHiU1GwebbCfuQuxsC3nHaLwtYeJGPrDZDIeodDOc4pA==",
"dev": true,
"license": "BSD-3-Clause",
"engines": {
"node": ">= 18"
},
"funding": {
"url": "https://github.com/sponsors/cyyynthia"
}
},
"node_modules/socks": {
"version": "2.8.3",
"dev": true,
@ -22904,6 +23148,13 @@
"version": "4.3.2",
"license": "MIT"
},
"node_modules/summary": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/summary/-/summary-2.1.0.tgz",
"integrity": "sha512-nMIjMrd5Z2nuB2RZCKJfFMjgS3fygbeyGk9PxPPaJR1RIcyN9yn4A63Isovzm3ZtQuEkLBVgMdPup8UeLH7aQw==",
"dev": true,
"license": "MIT"
},
"node_modules/supports-color": {
"version": "5.5.0",
"dev": true,
@ -23312,6 +23563,16 @@
"node": ">=8"
}
},
"node_modules/tapable": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz",
"integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=6"
}
},
"node_modules/tar": {
"version": "6.2.1",
"dev": true,
@ -23997,7 +24258,9 @@
}
},
"node_modules/undici-types": {
"version": "6.13.0",
"version": "6.19.8",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz",
"integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==",
"dev": true,
"license": "MIT"
},
@ -25294,6 +25557,29 @@
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
}
},
"node_modules/zod": {
"version": "3.23.8",
"resolved": "https://registry.npmjs.org/zod/-/zod-3.23.8.tgz",
"integrity": "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==",
"dev": true,
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/colinhacks"
}
},
"node_modules/zod-validation-error": {
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/zod-validation-error/-/zod-validation-error-3.3.1.tgz",
"integrity": "sha512-uFzCZz7FQis256dqw4AhPQgD6f3pzNca/Zh62RNELavlumQB3nDIUFbF5JQfFLcMbO1s02Q7Xg/gpcOBlEnYZA==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=18.0.0"
},
"peerDependencies": {
"zod": "^3.18.0"
}
},
"packages/sfe": {
"name": "@goauthentik/web-sfe",
"version": "0.0.0",

View File

@ -71,6 +71,7 @@
"@types/eslint__js": "^8.42.3",
"@types/grecaptcha": "^3.0.9",
"@types/guacamole-common-js": "1.5.2",
"@types/node": "^22.5.0",
"@types/showdown": "^2.0.6",
"@typescript-eslint/eslint-plugin": "^8.0.1",
"@typescript-eslint/parser": "^8.0.1",
@ -90,6 +91,7 @@
"github-slugger": "^2.0.0",
"glob": "^11.0.0",
"globals": "^15.9.0",
"knip": "^5.27.4",
"lit-analyzer": "^2.0.3",
"lockfile-lint": "^4.14.0",
"npm-run-all": "^4.1.5",
@ -135,6 +137,7 @@
"extract-locales": "wireit",
"format": "wireit",
"lint": "wireit",
"lint:imports": "wireit",
"lint:lockfile": "wireit",
"lint:nightmare": "wireit",
"lint:package": "wireit",
@ -149,8 +152,7 @@
"storybook:build": "wireit",
"storybook:build-import-map": "wireit",
"test": "wireit",
"test-view": "wireit",
"test-watch": "npx wdio run ./wdio.conf.ts --autoCompileOpts.tsNodeOpts.project=tsconfig.test.json --watch",
"test-watch": "wireit",
"tsc": "wireit",
"watch": "run-s build-locales esbuild:watch"
},
@ -250,6 +252,9 @@
"lint:components": {
"command": "lit-analyzer src"
},
"lint:imports": {
"command": "knip --config scripts/knip.config.ts"
},
"lint:types": {
"command": "tsc --noEmit -p .",
"dependencies": [
@ -330,7 +335,7 @@
"TS_NODE_PROJECT": "tsconfig.test.json"
}
},
"test-view": {
"test-watch": {
"command": "wdio run ./wdio.conf.ts",
"env": {
"TS_NODE_PROJECT": "tsconfig.test.json"

View File

@ -0,0 +1,48 @@
import { type KnipConfig } from "knip";
const config: KnipConfig = {
"entry": [
"./src/admin/AdminInterface/AdminInterface.ts",
"./src/user/UserInterface.ts",
"./src/flow/FlowInterface.ts",
"./src/standalone/api-browser/index.ts",
"./src/enterprise/rac/index.ts",
"./src/standalone/loading/index.ts",
"./src/polyfill/poly.ts",
],
"project": ["src/**/*.ts", "src/**/*.js", "./scripts/*.mjs", ".storybook/*.ts"],
// "ignore": ["src/**/*.test.ts", "src/**/*.stories.ts"],
// Prevent Knip from complaining about web components, which export their classes but also
// export their registration, and we don't always use both.
"ignoreExportsUsedInFile": true,
"typescript": {
config: ["tsconfig.json"],
},
"wireit": {
config: ["package.json"],
},
"storybook": {
config: [".storybook/{main,test-runner}.{js,ts}"],
entry: [
".storybook/{manager,preview}.{js,jsx,ts,tsx}",
"**/*.@(mdx|stories.@(mdx|js|jsx|mjs|ts|tsx))",
],
project: [".storybook/**/*.{js,jsx,ts,tsx}"],
},
"eslint": {
entry: [
"eslint.config.mjs",
"scripts/eslint.precommit.mjs",
"scripts/eslint.nightmare.mjs",
"scripts/eslint-precommit.mjs",
"scripts/eslint-nightmare.mjs",
"scripts/eslint.mjs",
],
config: ["package.json"],
},
"webdriver-io": {
config: ["wdio.conf.js"],
},
};
export default config;

View File

@ -8,6 +8,12 @@ import tsconfigPaths from "vite-tsconfig-paths";
const isProdBuild = process.env.NODE_ENV === "production";
const apiBasePath = process.env.AK_API_BASE_PATH || "";
const runHeadless = process.env.CI !== undefined;
const maxInstances =
process.env.MAX_INSTANCES !== undefined
? parseInt(process.env.MAX_INSTANCES, 10)
: runHeadless
? 10
: 1;
export const config: Options.Testrunner = {
//
@ -81,7 +87,7 @@ export const config: Options.Testrunner = {
// and 30 processes will get spawned. The property handles how many capabilities
// from the same test should run tests.
//
maxInstances: 10,
maxInstances,
//
// If you have trouble getting all important capabilities together, check out the
// Sauce Labs platform configurator - a great tool to configure your capabilities: