Skip to content

ci: Vitest unit tests + ESLint + GitHub Actions (CI & release)#24

Merged
BartM82 merged 3 commits into
review/code-review-fixesfrom
ci/setup-tests-and-actions
May 14, 2026
Merged

ci: Vitest unit tests + ESLint + GitHub Actions (CI & release)#24
BartM82 merged 3 commits into
review/code-review-fixesfrom
ci/setup-tests-and-actions

Conversation

@sebdraven
Copy link
Copy Markdown
Member

Stack sur la PR de review (#23). Contient l'infra qualité qui manquait au projet.

Pourquoi cette PR

Le repo n'avait ni tests, ni lint, ni workflow. Cette PR pose une base minimale mais sérieuse pour:

  • détecter les régressions sur le scoring DIMA et la détection de sites suspects ;
  • attraper les fautes de frappe et la dette JS via ESLint ;
  • générer le .zip Chrome de release automatiquement à partir d'un tag.

Ce qui est ajouté

Tests (tests/)

Vitest + happy-dom, 5 fichiers, 83 tests, ~1.5s :

  • contentExtractor.test.jscleanText préserve cyrillique/chinois/arabe (régression locked-in), detectPageType (14 cas dont edge cases tels que businessnews.example.com → general et example.com/products/12 → commerce), extractTitle, shouldSkipElement (pattern strict avec frontières [-_]|$)
  • techniqueAnalyzer.test.js — bandes de score Faible/Modéré/Élevé/Très Élevé/Critique, findKeywordMatches (frontières de mot, multi-mots, multi-occurrences, case-insensitive), pondération contextuelle (TE0153 sur news → 1.4, TE0221 sur social → 1.6), pondération dynamique (escalade selon occurrences, bonus techniques critiques), cap du score global à 100, filtrage tactique/technique
  • suspiciousSitesManager.test.jscheckSite pour les 3 matchType (exact/contains/pattern), format Storm1516 natif sur X/Twitter et Telegram, refus si plateforme incompatible, extractSocialHandle, getRiskConfig (4 niveaux), gating console.log derrière DIMA_DEBUG
  • uiManager.test.jsescapeHtml (XSS), sanitizeHexColor (rejette shorthand, named colors, payloads d'injection CSS), isSafeHttpUrl (rejette javascript: / data: / file:), adjustColor (clamp black/white), generateTooltip
  • manifest.test.js — JSON valide, MV3, chaque chemin déclaré (content_scripts, icons, web_accessible_resources) existe sur disque

Loader (tests/helpers/loadScript.js) : les content scripts du plugin exposent leurs classes via window.X = X. Un eval indirect dans le window happy-dom de Vitest les rend disponibles sans modifier la source.

Lint

  • eslint.config.js (flat config, ESLint 9) — globals navigateur pour la source, globals Node + Vitest pour les tests, eqeqeq: smart. 0 erreur, 0 warning.

Workflows GitHub Actions

.github/workflows/ci.yml — sur chaque push main et chaque PR :

  • setup Node 20 avec cache npm
  • npm ci
  • npm run lint
  • npm test
  • Validation manifest.json parseable

.github/workflows/release.yml — sur tag v*.*.* :

  • lint + tests d'abord (fail-fast)
  • vérifie que le tag matche manifest.version (sinon erreur explicite)
  • zippe les fichiers runtime uniquement (manifest.json, content.js, modules/, data/, documentation/, README.md, LICENSE, icônes — pas de node_modules, pas de tests)
  • upload comme artifact + crée une release draft GitHub avec le zip attaché et release notes auto

Source touchée

Une seule modif côté source pour rendre la classe testable :

  • modules/Suspicioussitesmanager.js : expose window.SuspiciousSitesManager (la classe, pas seulement l'instance) + gate du console.warn "aucune base chargée" derrière DIMA_DEBUG (cohérent avec le reste).

Comment l'utiliser

Localement :

npm install
npm run ci         # lint + tests
npm run test:watch # mode dev
npm run test:coverage

Pour publier une version :

# 1. bump manifest.json -> "version": "2.1.0"
# 2. commit + merge sur main
git tag v2.1.0
git push origin v2.1.0
# release.yml crée la release draft avec le .zip

Base

Cette branche part de review/code-review-fixes (#23) — les tests verrouillent les comportements corrigés là-bas (Unicode cleanText, escapeHtml, sanitizeHexColor, detectPageType strict). À merger après #23.

🤖 Generated with Claude Code

@sebdraven sebdraven force-pushed the ci/setup-tests-and-actions branch from ce092e7 to e1ba8f6 Compare May 14, 2026 15:18
sebdraven and others added 3 commits May 14, 2026 17:22
Test infrastructure
-------------------
- Vitest + happy-dom: 5 test files, 83 unit tests covering ContentExtractor
  (cleanText keeping Unicode scripts, detectPageType edge cases, title
  extraction), TechniqueAnalyzer (risk bands, keyword matching boundaries,
  weight escalation), SuspiciousSitesManager (exact/contains/pattern matching
  plus the Storm1516 social-account format, handle extraction, logging gate),
  UIManager (escapeHtml, sanitizeHexColor, isSafeHttpUrl, adjustColor clamp,
  tooltip), and manifest sanity (JSON validity, declared paths exist).
- tests/helpers/loadScript.js loads each content-script source as it would
  run in Chrome (indirect eval inside happy-dom's window), keeping the
  production code unchanged.

Source-side adjustments to make the modules testable
----------------------------------------------------
- Suspicioussitesmanager.js: expose `window.SuspiciousSitesManager` (the
  class, in addition to the instance). Gate the "no databases loaded"
  warning behind DIMA_DEBUG — same noise-reduction rationale as the
  previous review pass. Tidy an unused destructure variable.

Tooling
-------
- package.json with vitest, happy-dom, eslint, globals; scripts: test,
  test:watch, test:coverage, lint, lint:fix, ci.
- eslint.config.js (flat config): browser globals for source, node +
  vitest globals for tests, no-eq-eq smart, no-redeclare disabled because
  database files declare their own globals at top level.
- vitest.config.js: happy-dom env, coverage scoped to modules/ + content.js.
- .gitignore.

GitHub Actions
--------------
- ci.yml: lint + tests on every push to main and every PR.
- release.yml: on tag v*.*.*, verify tag matches manifest.version, run
  npm ci, zip the runtime files (manifest, content.js, modules/, data/,
  docs, README, LICENSE, icons), upload as workflow artifact and create
  a draft GitHub release.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
contentExtractor.test.js — add three cases that exercise the matchStem
switch on `article` and `blog`:
  - /articles/foo -> news
  - /blogs/post   -> blog
  - blogs.example.com -> blog

animations.test.js — new file. Scans content.js for @Keyframes
declarations and uiManager.js for `animation:` references, asserting
that every name begins with `dima`. Prevents a future change from
re-introducing a generic keyframe name (fadeIn, slideIn, ...) that
would collide with the host page's CSS namespace.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
accessibility.test.js — exercise createButton() against happy-dom and
assert that the rendered badge:
  - carries role=button and tabindex=0
  - exposes an aria-label including score and risk level
  - hides the decorative 🧠 from screen readers
  - fires showModal on Enter and on Space
  - preventDefault on Space (so the host page doesn't scroll)
  - ignores unrelated keys

syncInit.test.js — guard the bootstrap of Suspicioussitesmanager.js:
  - no setTimeout(...) call in the init block (comments are stripped
    so the historical note explaining why the delay was removed
    doesn't trip the assertion)
  - window.checkSuspiciousSite is callable immediately after the
    module is loaded (no async wait)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@sebdraven sebdraven force-pushed the ci/setup-tests-and-actions branch from e1ba8f6 to 8ac91c8 Compare May 14, 2026 15:24
@BartM82 BartM82 merged commit c72dfa1 into review/code-review-fixes May 14, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants