test-e2e drove Cypress through act, which fails to start where it cannot resolve a host address for its artifact server. It now starts Flask and Cypress in one shell via scripts/run-e2e.sh, so both share a network namespace; the act path stays available as test-e2e-act. The script guards the cases that made the old target lie: it aborts when something already serves the port instead of testing that server, checks that its own Flask is alive before trusting a response, pins Cypress to the same origin Flask binds, and drops ELECTRON_RUN_AS_NODE, which VS Code exports and which makes Cypress' bundled Electron reject its own flags. 30 YAML and 18 JavaScript files had no linter. yamllint runs correctness rules only, because the repository predates it and its cosmetic findings would be noise; key-duplicates is the one that earns its keep, since PyYAML keeps the last of two identical keys without complaining. eslint runs the recommended set and already found a dead getBoundingClientRect() call in navigation.js. Both get a CI job so make lint and the workflows stop diverging. flask>=3.1 because app.config["TRUSTED_HOSTS"] arrived in 3.1 and an older Flask accepts the key and ignores it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
79 lines
2.3 KiB
JavaScript
79 lines
2.3 KiB
JavaScript
'use strict';
|
|
/**
|
|
* Correctness only — eslint's recommended set, no stylistic rules.
|
|
*
|
|
* The browser scripts are plain <script> tags sharing one global scope: each
|
|
* file declares some functions and calls others declared elsewhere. That is why
|
|
* they are listed as globals and why no-redeclare is off — the declaring file
|
|
* would otherwise be reported for defining its own function.
|
|
*/
|
|
const js = require('@eslint/js');
|
|
const globals = require('globals');
|
|
|
|
// Vendored libraries plus the functions static/js files call across each other.
|
|
// Keep this to names that really cross a file boundary. Every superfluous
|
|
// entry is a permanent no-undef blind spot for a typo of that name.
|
|
const SHARED = {
|
|
bootstrap: 'readonly',
|
|
marked: 'readonly',
|
|
$: 'readonly',
|
|
jQuery: 'readonly',
|
|
openDynamicPopup: 'readonly',
|
|
closeAllModals: 'readonly',
|
|
isSafeUrl: 'readonly',
|
|
openIframe: 'readonly',
|
|
enterFullscreen: 'readonly',
|
|
exitFullscreen: 'readonly',
|
|
setFullWidth: 'readonly',
|
|
initFullWidthFromUrl: 'readonly',
|
|
adjustScrollContainerHeight: 'readonly',
|
|
updateCustomScrollbar: 'readonly',
|
|
};
|
|
|
|
module.exports = [
|
|
{ ignores: ['node_modules/**', 'static/vendor/**', 'cypress/screenshots/**'] },
|
|
{
|
|
files: ['static/js/**/*.js'],
|
|
languageOptions: {
|
|
ecmaVersion: 2022,
|
|
sourceType: 'script',
|
|
globals: { ...globals.browser, ...SHARED },
|
|
},
|
|
rules: {
|
|
...js.configs.recommended.rules,
|
|
'no-redeclare': 'off',
|
|
// vars: 'local' — a top-level function here is the API other files and
|
|
// the templates call, so only unused locals are a defect.
|
|
'no-unused-vars': [
|
|
'error',
|
|
{ vars: 'local', args: 'none', caughtErrors: 'none' },
|
|
],
|
|
},
|
|
},
|
|
{
|
|
files: ['cypress/**/*.js'],
|
|
languageOptions: {
|
|
ecmaVersion: 2022,
|
|
sourceType: 'script',
|
|
globals: {
|
|
...globals.browser,
|
|
...globals.mocha,
|
|
cy: 'readonly',
|
|
Cypress: 'readonly',
|
|
expect: 'readonly',
|
|
assert: 'readonly',
|
|
},
|
|
},
|
|
rules: js.configs.recommended.rules,
|
|
},
|
|
{
|
|
files: ['scripts/**/*.js', 'cypress.config.js', 'eslint.config.js'],
|
|
languageOptions: {
|
|
ecmaVersion: 2022,
|
|
sourceType: 'commonjs',
|
|
globals: globals.node,
|
|
},
|
|
rules: js.configs.recommended.rules,
|
|
},
|
|
];
|