Read-only mirror of https://github.com/SFOE/drill-frontend — Bundesamt für Energie. Issues & pull requests at the source. Catalog: https://www.opensource.admin.ch/en/softwares/ctc6f0 https://www.opensource.admin.ch/en/softwares/ctc6f0
  • TypeScript 77.4%
  • Vue 20.3%
  • CSS 1.2%
  • HTML 0.7%
  • JavaScript 0.4%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
monodo 6f08f42367
docs: refresh README and harmonize badges (#231)
- Update unit test inventory to list all current test files and record current coverage figures (stmts 93%, branches 85%, funcs 91%, lines 94%).
- Correct the security section to reflect audit-ci + Amazon Inspector/.inspector-ignore instead of plain npm audit.
- Harmonize the Lighthouse badges (Accessibility / Best Practices / SEO): title-case labels, logo=lighthouse, and colors aligned to the Coverage badge rule (>=80 => brightgreen).
2026-10-08 16:06:08 +02:00
.github fix(ci): add push trigger on main for security workflow badge (#227) 2026-10-07 17:32:10 +02:00
.vscode Initial commit 2025-11-18 13:43:46 +01:00
badges chore: update coverage badge [skip ci] 2026-10-08 13:47:12 +00:00
cypress fix(e2e): wait for dropdown to render before keyboard nav in Enter test (#226) 2026-10-07 16:47:16 +02:00
public fix favico & add SEO tags 2025-12-10 10:34:31 +01:00
scripts Secure (#135) 2026-04-02 14:36:21 +02:00
src test: add unit tests to raise coverage above 80% (#229) 2026-10-08 15:46:35 +02:00
.editorconfig Initial commit 2025-11-18 13:43:46 +01:00
.env.development hardcode backend url for test 2026-01-14 09:21:49 +01:00
.env.production leave .env.production blank 2026-01-16 09:58:37 +01:00
.gitattributes Initial commit 2025-11-18 13:43:46 +01:00
.gitignore Cantonal geoservices failures (#155) 2026-04-23 14:25:34 +02:00
.inspector-ignore fix(ci): allowlist known braces CVE in Amazon Inspector scan (#228) 2026-10-07 17:57:17 +02:00
.npmrc Secure (#135) 2026-04-02 14:36:21 +02:00
.prettierrc.json Initial commit 2025-11-18 13:43:46 +01:00
audit-ci.jsonc chore: update npm packages and resolve audit findings (#224) 2026-10-07 15:53:21 +02:00
cypress.config.ts Initial commit 2025-11-18 13:43:46 +01:00
env.d.ts Code refactor: reduce load time, DRYer code, better accessibility (#182) 2026-05-28 11:26:39 +02:00
eslint.config.ts Code refactor: reduce load time, DRYer code, better accessibility (#182) 2026-05-28 11:26:39 +02:00
index.html Code refactor: reduce load time, DRYer code, better accessibility (#182) 2026-05-28 11:26:39 +02:00
LICENSE Update LICENSE 2025-12-15 09:45:26 +01:00
package-lock.json Bump prettier (#225) 2026-10-07 16:01:35 +02:00
package.json Bump prettier (#225) 2026-10-07 16:01:35 +02:00
publiccode.yml chore: update publiccode.yml to v0.2.6 2026-10-08 05:00:06 +00:00
README.md docs: refresh README and harmonize badges (#231) 2026-10-08 16:06:08 +02:00
tsconfig.app.json Remove deprecation warning (#145) 2026-04-13 14:31:41 +02:00
tsconfig.json Initial commit 2025-11-18 13:43:46 +01:00
tsconfig.node.json Initial commit 2025-11-18 13:43:46 +01:00
tsconfig.vitest.json remove unit tests 2026-01-20 12:27:02 +01:00
vite.config.ts Code refactor: reduce load time, DRYer code, better accessibility (#182) 2026-05-28 11:26:39 +02:00
vitest.config.ts New tests (#197) 2026-07-02 10:35:33 +02:00

Lint Tests Unit Tests Coverage Security Accessibility Best Practices SEO

drill-frontend

Vue.js application with a mapping component to provide information on the possibilities of installing geothermal probes in Switzerland, using the cantons' geoservices.

This application supports languages DE, FR, IT, EN. You can select default using query string ?lang=IT

Project Setup

Backend

ℹ️ This Vue.js app needs a backend to work.

The backend is published here, please follow instructions: https://github.com/SFOE/drillapi

A docker image can also be pulled from https://github.com/SFOE/drillapi/pkgs/container/drillapi

Install Vue.js dev environment

This project uses Node.js. Checkout official documentation in order to manage node versions correctly with Node Version Manager (NVM) at https://nodejs.org/en/download

git clone git@github.com:SFOE/drill-frontend.git
cd drill-frontend
npm ci

⚠️ Never use npm install — the project enforces npm ci via a preinstall guard script.

Compile and Hot-Reload for Development

npm run dev

Upgrade packages

npx npm-check-updates -u
npm install --ignore-scripts

After upgrading, run npm audit to check for vulnerabilities. Known transitive vulnerabilities are pinned via overrides in package.json.

Type-Check, Compile and Minify for Production

npm run build

Run Unit Tests with Vitest

npm run test:unit

Run with coverage report:

npx vitest --run --coverage

Unit test structure

Tests live in __tests__/ folders colocated with their source:

src/
├── __tests__/
│   └── i18n.test.ts                                     # setLocale lazy loading, title/meta side effects
├── components/__tests__/
│   ├── AddressFulltextSearchComponent.test.ts           # Rendering, debounce, ARIA, selection
│   ├── AddressFulltextSearchComponent.branches.test.ts  # Keyboard nav, Enter, request abort/cancel, errors
│   ├── App.test.ts                                      # Router-view outlet
│   ├── FooterComponent.test.ts                          # Links, mailto, copyright year
│   ├── HeaderComponent.test.ts                          # Logo, title, embedded language switcher
│   ├── InfoboxComponent.test.ts                         # Color mapping, loading state, layout
│   ├── InfoboxLinksComponent.test.ts                    # Link rendering, security attrs
│   ├── LanguageSwitcherComponent.test.ts                # Locale options, store binding
│   ├── LoadingSpinner.test.ts                           # Basic rendering
│   ├── MapComponent.test.ts                             # Legend toggle, WMS-layer watcher, map-click geocoding
│   └── StaticElementsComponent.test.ts                  # Info block headings, external links
├── composables/__tests__/
│   ├── useDevice.test.ts                                # Mobile detection, resize handling
│   ├── useGeoadminReverseGeocoding.test.ts              # Address formatting, edge cases
│   └── useProjections.test.ts                           # LV95 / LV03 proj4 definitions
├── router/__tests__/
│   └── index.test.ts                                   # Route registration, history mode
├── stores/__tests__/
│   ├── languageStore.test.ts                            # Locale persistence
│   ├── mapStore.test.ts                                 # fetchGroundCategory, clearSearchState, getters
│   └── searchStore.test.ts                              # State management, clearSearchState
├── utils/__tests__/
│   ├── debounce.test.ts                                 # Timer behavior, argument passing
│   └── stripHtml.test.ts                                # Tag removal, XSS safety, property-based
└── views/__tests__/
    └── DrillVue.test.ts                                 # ?lang= query handling, layout composition

Current coverage: statements 93%, branches 85%, functions 91%, lines 94%. The coverage badge above is regenerated automatically on every push to main by the unit-tests workflow.

Testing patterns used

  • Property-based testing (fast-check) — mapStore tests all 26 Swiss cantons × valid LV95 coordinate ranges; stripHtml verifies invariants (idempotency, no tags in output) against random input.
  • Component testing (@vue/test-utils + @pinia/testing) — shallow rendering with mocked stores to test rendering logic and user interactions.
  • Composable testing — pure function tests with mocked HTTP layer for useGeoAdmin; lifecycle-aware tests via wrapper components for useDevice.

Run End-to-End Tests with Cypress

Interactive mode (opens Cypress UI):

npm run test:e2e:dev

Headless mode (CI):

npm run test:e2e

E2E test structure

cypress/e2e/
├── AddressFultextSearchComponent.cy.ts   # Search input, dropdown display, clearing
├── FooterComponent.cy.ts                 # Footer layout, links, copyright year
├── HeaderComponent.cy.ts                 # Logo, header visibility
├── InfoboxComponent.cy.ts                # All harmonized_value colors, mobile expand/collapse
├── LanguageSwitcherComponent.cy.ts       # DE ↔ EN switching
├── MapComponent.cy.ts                    # Map rendering, click interaction
├── StaticElementsComponent.cy.ts         # Info block, canton info, external links
└── UserJourney.cy.ts                     # Integrated flows (see below)

UserJourney.cy.ts — integrated regression tests

This file covers the scenarios most likely to break during refactoring:

  • Search → select → infobox — full primary user flow
  • Clear button — resets infobox and input after selection
  • Backend error (500) — shows purple error infobox
  • Geoservice unavailable (98) — preserves canton name in error message
  • Loading spinner — visible during fetch, disappears after
  • Keyboard navigation — ArrowDown/Up, Escape, Enter
  • URL query parameter — ?lang=fr / ?lang=it loads correct locale
  • Click outside — closes dropdown

E2E test utilities

  • cypress/support/mock-backend.ts — provides mockDrillCategoryApi() and mockDrillCategoryError() helpers with predefined responses for all harmonized_value states (1-6, 98, 99).

CI

Both test suites run automatically on every PR and push to main via GitHub Actions:

Workflow File What it runs
Unit tests & type check .github/workflows/unit_tests.yml vue-tsc → vitest --coverage → eslint
E2E tests .github/workflows/e2e_tests.yml Builds app → starts preview → cypress run

Lint with ESLint

npm run lint

Format with Prettier

npm run format

Architecture

src/
├── assets/          # CSS (design tokens in base.css), images, SVGs
├── components/      # Vue SFCs (Composition API + script setup)
├── composables/     # Reusable logic (useDevice, useProjections, useGeoAdmin)
├── locales/         # i18n translation files (de, en, fr, it)
├── router/          # Vue Router (single route)
├── stores/          # Pinia stores (mapStore, languageStore)
├── types/           # TypeScript interfaces
├── utils/           # Pure utility functions (debounce, stripHtml)
└── views/           # Page-level components

CSS Design Tokens

Global design tokens (colors, radii, shadows) are defined as CSS custom properties in src/assets/base.css. Components reference these variables instead of hardcoded values:

var(--color-primary)   /* #2f4356 */
var(--color-link)      /* #005ea5 */
var(--radius-md)       /* 8px */
var(--shadow-sm)       /* subtle box shadow */

Security

  • Content-Security-Policy meta tag in index.html
  • npm ci enforced via preinstall guard (no npm install)
  • audit-ci runs in CI (security.yml) against audit-ci.jsonc, failing on high/critical advisories while allowlisting specific reviewed ones
  • Amazon Inspector scans the repository on release (release_and_push_s3.yml); reviewed, non-shipped findings are allowlisted in .inspector-ignore
  • Dependency overrides pin known vulnerable transitive packages
  • stripHtml uses DOMParser (XSS-safe) instead of innerHTML
  • Address search input is debounced (300ms) to prevent API abuse

Environment Variables

Variable Description Default
VITE_BACKEND_URL Backend API base URL http://localhost:8000/ (dev), empty = relative (prod)

Environment files: .env.development, .env.production

Type Support for .vue Imports in TS

TypeScript cannot handle type information for .vue imports by default, so we replace the tsc CLI with vue-tsc for type checking. In editors, we need Volar to make the TypeScript language service aware of .vue types.

Customize configuration

See Vite Configuration Reference.