Style dock testing
The style dock is a capability-driven authoring surface. Each layer gets a
bounded abstract preview and the tabs its renderer supports. Vector layers use
Symbol, Labels, 3D, Rendering, and More; LiDAR classification controls
live in a Classifications section under More. Preview changes stay in a
local draft. Save is the only action that applies that draft to the project.
The dedicated Travels style document records local style edits, while provider
refreshes, map navigation, and project operations outside the style document
remain outside that journal.
Running the suites
Run one heavy command at a time under the repository’s Windows Job Object limit of 16 GB for the complete process tree. A Node heap setting does not enforce that limit, and a repository-wide lint run is not a local substitute for the file-scoped check.
bun run test:styles:types
bun run test:styles:unit
bun run test:styles:e2e
bun run test:styles
test:styles:types checks the browser workflow project, including the temporal
configuration test. test:styles:unit runs the scoped style, format, raster,
provider, map, command, project, and temporal suites, including
tests/temporal/config.test.ts.
test:styles:e2e builds the style host and runs Playwright from
config/e2e/playwright.styles.config.ts on its fixed 4187 port; it writes
build and failure artifacts under output/playwright. Run Oxlint with the
explicit changed-file list and run formatting separately.
Acceptance record
Web acceptance: COMPLETE within the documented scope. The evidence below is bounded, current evidence for the redesign. Native Tauri dialogs, external QGIS drawing, and pixel-level renderer parity remain outside this web acceptance. No pending final checks remain for this document.
bun run test:styles:unit: 1,891 passed, 0 failed, across 197 files in 48.71 seconds (styles-final-unit-17.log). This production-logic run is unchanged and includes the seven native style-preview checks, including the all-classifications LiDAR sample.- The workflow TypeScript check exited 0
(
styles-final-workflow-types-19.log) and includes the latest style changes. - The whole application TypeScript check exited 0
(
styles-final-app-types-17.log). Its output contains Effect language-service suggestions, not type errors. - The final scoped Oxlint run exited 0
(
styles-final-lint-19.log). It covers the seven late files, including the frame and layer preview, Time Slider section and registry, temporal config, mounted-section test, and preview and Time Slider E2E files. - The broad browser run (
styles-final-browser-6.log) covered 39 workflows and reported 36 passed, 3 failed. Subsequent focused runs covered every affected workflow: the unchanged LiDAR cold-open provider passed in run 7, the categorized/3D preview passed in runs 7 and 8, and Time Slider persistence passed in run 8. The cumulative evidence covers all 39 workflow cases; it is not a fresh 39-test pass from one build. - The final focused browser run (
styles-final-browser-8.log) exited 0 in 3.7 minutes with 10 passed: all fivestyle-dock-designchecks (288, 336, and 400px widths, keyboard tabs, and search), fourstyle-previewchecks (categorized/3D, automatic preview history and explicit Save, raster camera independence, and LiDAR variable classification), and the Time Slider project persistence workflow. - The transient
Added layernotice is handled by waiting fordrop-statusto disappear. Basemap suppression applies to the main map during authored- geometry snapshots, not to the abstract preview. - The Time Slider persistence diagnosis is resolved. A runtime probe proves the
serializer and
manager.getProjectConfigretain valid Time Slider settings. The E2E fixture had selectedRemove from filein the credential prompt;credentials.tsintentionally redacts all plugin settings in that mode. The corrected fixture selectsKeep in local file, preserving the security behavior and the project settings. The earlier optional-undefinedand COG-to-Mosaic NoData normalization fixes are covered; neither represents a remaining production persistence failure. - The final8 built page reported 0 application errors and 0 network errors, with 19 warnings: 17 basemap sprite misses and 2 offline changestream warnings. A separate earlier cold LiDAR run recorded one warning and remains a historical provider diagnostic. This is not a zero-warning build.
All recorded browser artifacts are under
C:\Users\Santiago\.codex\visualizations\2026\09\07\01a079ac-59df-7170-8f4a-ebceedaeb85e.
Manual browser evidence
The following behaviors were verified in the current built UI:
- The abstract category preview remains fixed while keyboard zoom changes from 14.85 to 13.85. It does not use source coordinates or the main map camera.
- Changing label size to 16 updates the preview while the main map stays at 12. Save then updates the main map. Undo after Save stages 12 as a pending draft, which requires another Save.
- External hide and layer-removal operations do not add entries to the style document’s Travels history. The global project Undo and Redo controls still remove and restore the layer; the external remove action removes a layer, not the project.
- Style Library Apply uses the pending draft. The project changes only after Save.
- A model scale of 100 keeps the abstract glyph legible. Scale 200 survives Save and a layer switch.
- LiDAR classifications live under
More>Classifications, while the renderer modes areElevationandClassification. The synthetic preview contains every available code. Independent manual checks hid 2 (Ground), 5 (Vegetation), 6 (Building), and 9 (Water); switching modes or layers retained those choices, and the main map stayed unchanged before Save. - Categorized duplicate values block Save until the duplicate is corrected or removed. Extrusion, line dash and gap, and raster RGB, index, and gamma workflows were also verified.
- Time Slider sprite palettes for
winter,twilight,Wistia,YlGn, andYlGnBuresolved in the built UI. On the final build, the gray baseline has history disabled; changing the preview towinterleaves the main map gray until explicit Save colors it. Undo after Save returns the preview to gray while the main map stays winter and Save becomes enabled; Redo restores winter. RGB bands3,2,1hide the color ramp, and the saved RGB state is retained. Automatic NoData uses the full row width and fits the 287px dock. - The final Time Slider screenshots are
final8-time-slider-pending.png,final8-time-slider-saved.png, andfinal8-time-slider-undo-pending.pngin the artifact directory above. - The preview canvas measured 287x99 DOM pixels with a 320x100 intrinsic
canvas, uses
objectFit: contain, and keeps the full canvas bounds inside the preview. The fit was also verified in the final10 flow-width checks; mockup fidelity is documented behaviorally and has no numeric score. - A flat
LineStringhas no3Dtab. InRendering, Ctrl+Z stages the numeric draft from 8 to 2 with Save disabled; Ctrl+Shift+Z restores 8 and leaves Save pending.
Format checks have semantic QML, SLD, and Mapbox round-trip coverage in unit
tests. Manual QML testing has started and the earlier replaceAll crash is
gone. The native host file picker and Tauri file dialogs were not completed,
and external QGIS drawing was not verified. Web tests do not exercise those
native dialogs.
Coverage map
| Area | Unit and integration contracts | Browser workflows |
|---|---|---|
| Geometry and capability gating | geometry-capabilities, capability-transitions, vector-3d-eligibility, style ownership | style-panel-default, style-workflows cover point, line, polygon, and capability changes |
| Category and renderer state | thematic, categorized-visibility, classification-settings, rule boundaries | style-workflows covers single, categorized, graduated, rule-based, and expression edits |
| Symbols and cartography | native-cartography, base-symbol-stack, cartography, stroke-width units, sync | style-workflows covers symbol rows, dash and gap, casing, reorder, and base visibility |
| Labels | label-capabilities, label-layout, label-dedup, label-sync, native labels | style-workflows and style-optional-workflows cover fields, named rules, layout, and retention |
| 3D and globe | three-d, extrusion-height, globe-projection-history, Cesium label style | style-workflows covers extrusion and 2D retention; provider workflows cover native scenes |
| Raster | raster lifecycle, colormap, band, rescale, readiness, and no-data tests | style-providers covers RGB, index, pseudocolor, gamma, stretch, and conversion failure |
| LiDAR and native providers | lidar-dock, provider style workflows, runtime lifecycle and ownership tests | style-providers covers LAS point size, classification, layer switching, and history |
| Optional vector controls | diagrams, generated geometry, fill patterns, proportional bounds, and symbol stack tests | style-optional-workflows covers diagram, generator, SVG pattern, and unrelated-style retention |
| Formats and libraries | Mapbox, QML, SLD, style library, clipboard, and manager I/O tests | style-workflows covers Library and formats import/export feedback and reopen |
| History and persistence | command, draft-history, undo/redo, provider recovery, and project tests | style-workflows and provider/deck workflows cover edits across layers, save, undo, redo, and reopen |
| Layout and frame actions | style-dock presentation, preview, and footer contracts | style-dock-design checks the preview, tabs, persistent footer, keyboard navigation, and narrow widths |
Invariants
- Switching to an inactive tab or an incompatible renderer preserves authored settings. Returning to a compatible capability restores the values rather than resetting them.
- A disabled category disables its geometry and labels and follows the documented fallback behavior. Category values, display labels, colors, and enabled states remain authored data.
- A missing
baseSymbolsvalue is the legacy default. An explicitbaseSymbolsobject is authoritative, including independent Fill, Outline, and Marker visibility. - All style edits share one dock Save action. Save commits pending changes atomically; switching tabs or layers does not commit a partial draft.
- The Travels journal records only local style edits. Its Undo and Redo controls start disabled. Provider refreshes, map navigation, external hide/layer removal operations, and project mutations outside the style document do not add entries. Saving establishes a new dirty baseline without discarding style history.
- Duplicate category values are invalid after the renderer’s string normalization. The editor reports the error, prevents saving the invalid draft, and retains the last valid classification preview while the duplicate is corrected or removed.
- Legacy or imported category styles can already contain duplicate values. Their renderer uses the first valid enabled branch for each normalized key, leaving authored rows intact and keeping generated MapLibre match expressions valid.
- Fractional numeric inputs keep their authored precision. Reordering or removing rows preserves stable row identities so an edit cannot move to a different stop or symbol.
- Preview samples use bounded, deterministic synthetic geometry and values. The LiDAR sample includes every available classification code. Loaded properties can provide examples for field expressions, but source coordinates and the main map’s camera do not determine the sample. Pending style changes update the sample before Save. There is no preview toggle, and a layer switch cannot reuse another layer’s image.
- Raster samples calculate band combinations, indices, ramps, and appearance from the current editable settings. Source-band statistics cannot stand in for index statistics, and a disabled statistics query must not show a perpetual loading state.
- Time Slider authoring is a four-field contract: color ramp, band list, rescale window, and no-data mode. Save writes the mirrored layer metadata and the native provider state together.
Boundaries
These are web-host browser tests. They do not exercise native Tauri file dialogs, large remote datasets, or pixel-level parity with the full QGIS renderer. The application’s format and persistence tests show what can round-trip; they do not claim that QGIS or a remote SLD server will draw every expression identically. See the style dock and QGIS comparison for the documented renderer gaps and format contracts.
Mixed-geometry GeoJSON rejected by the file provider is a different path from mixed inline geometry loaded from a project. A provider rejection must not be treated as a failure of the inline capability tests. Provider-native ordering, LiDAR drawing, deck scenegraphs, Cesium scenes, and raster rendering remain owned by their respective runtimes; the dock tests the authoring boundary and state ownership around them.