Skip to content

add tests for deck-layers fourwings heatmap layer#4151

Open
j8seangel wants to merge 1 commit into
developfrom
deck-layers/test
Open

add tests for deck-layers fourwings heatmap layer#4151
j8seangel wants to merge 1 commit into
developfrom
deck-layers/test

Conversation

@j8seangel

Copy link
Copy Markdown
Collaborator

No description provided.

@j8seangel j8seangel requested a review from fernand0q July 6, 2026 14:26
@github-actions

github-actions Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Test Results

❌ deck-layers:test
 RUN  v4.1.8 /home/runner/work/frontend/frontend/libs/deck-layers
 ❯  deck-layers  src/layers/fourwings/heatmap/fourwings-heatmap.utils.spec.ts (0 test)
 ❯  deck-layers  src/layers/fourwings/heatmap/FourwingsHeatmapLayer.spec.ts (0 test)
 ❯  deck-layers  src/layers/fourwings/heatmap/FourwingsHeatmapStaticLayer.spec.ts (0 test)
stderr | src/layers/fourwings/FourwingsLayer.spec.ts
luma.gl: This version of luma.gl has already been initialized
stderr | src/layers/fourwings/heatmap/FourwingsHeatmapTileLayer.spec.ts
luma.gl: This version of luma.gl has already been initialized
 ❯  deck-layers  src/layers/fourwings/heatmap/FourwingsHeatmapTileLayer.spec.ts (0 test)
 ❯  deck-layers  src/layers/fourwings/FourwingsLayer.spec.ts (0 test)
⎯⎯⎯⎯⎯⎯ Failed Suites 5 ⎯⎯⎯⎯⎯⎯⎯
 FAIL   deck-layers  src/layers/fourwings/FourwingsLayer.spec.ts [ src/layers/fourwings/FourwingsLayer.spec.ts ]
Error: Cannot find package '@globalfishingwatch/api-client' imported from /home/runner/work/frontend/frontend/libs/deck-layers/src/layers/fourwings/footprint/FourwingsFootprintTileLayer.ts
 ❯ src/layers/fourwings/footprint/FourwingsFootprintTileLayer.ts:11:1
      9| import { parse } from '@loaders.gl/core'
     10|
     11| import { GFWAPI } from '@globalfishingwatch/api-client'
       | ^
     12| import { filterFeaturesByBounds } from '@globalfishingwatch/data-trans…
     13| import type {
 ❯ src/layers/fourwings/FourwingsLayer.spec.ts:4:1
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/5]⎯
 FAIL   deck-layers  src/layers/fourwings/heatmap/FourwingsHeatmapLayer.spec.ts [ src/layers/fourwings/heatmap/FourwingsHeatmapLayer.spec.ts ]
Error: Cannot find package '@globalfishingwatch/deck-loaders' imported from /home/runner/work/frontend/frontend/libs/deck-layers/src/layers/fourwings/heatmap/fourwings-heatmap.utils.ts
 ❯ src/layers/fourwings/heatmap/fourwings-heatmap.utils.ts:11:1
      9|   TileCell,
     10| } from '@globalfishingwatch/deck-loaders'
     11| import { CONFIG_BY_INTERVAL, getFourwingsInterval } from '@globalfishi…
       | ^
     12|
     13| import { getUTCDateTime } from '../../../utils'
 ❯ src/layers/fourwings/heatmap/FourwingsHeatmapLayer.spec.ts:6:1
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[2/5]⎯
 FAIL   deck-layers  src/layers/fourwings/heatmap/FourwingsHeatmapStaticLayer.spec.ts [ src/layers/fourwings/heatmap/FourwingsHeatmapStaticLayer.spec.ts ]
Error: Cannot find package '@globalfishingwatch/deck-loaders' imported from /home/runner/work/frontend/frontend/libs/deck-layers/src/layers/fourwings/heatmap/fourwings-heatmap.utils.ts
 ❯ src/layers/fourwings/heatmap/fourwings-heatmap.utils.ts:11:1
      9|   TileCell,
     10| } from '@globalfishingwatch/deck-loaders'
     11| import { CONFIG_BY_INTERVAL, getFourwingsInterval } from '@globalfishi…
       | ^
     12|
     13| import { getUTCDateTime } from '../../../utils'
 ❯ src/layers/fourwings/heatmap/FourwingsHeatmapStaticLayer.spec.ts:4:1
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[3/5]⎯
 FAIL   deck-layers  src/layers/fourwings/heatmap/FourwingsHeatmapTileLayer.spec.ts [ src/layers/fourwings/heatmap/FourwingsHeatmapTileLayer.spec.ts ]
Error: Cannot find package '@globalfishingwatch/deck-loaders' imported from /home/runner/work/frontend/frontend/libs/deck-layers/src/layers/fourwings/heatmap/FourwingsHeatmapTileLayer.spec.ts
 ❯ src/layers/fourwings/heatmap/FourwingsHeatmapTileLayer.spec.ts:5:1
      3| import { beforeAll, describe, expect, it, vi } from 'vitest'
      4|
      5| import { getFourwingsInterval } from '@globalfishingwatch/deck-loaders'
       | ^
      6|
      7| import { FourwingsComparisonMode } from './fourwings-heatmap.types'
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[4/5]⎯
 FAIL   deck-layers  src/layers/fourwings/heatmap/fourwings-heatmap.utils.spec.ts [ src/layers/fourwings/heatmap/fourwings-heatmap.utils.spec.ts ]
Error: Cannot find package '@globalfishingwatch/api-client' imported from /home/runner/work/frontend/frontend/libs/deck-layers/src/layers/fourwings/fourwings.config.ts
 ❯ src/layers/fourwings/fourwings.config.ts:4:1
      2| import { DateTime, Duration } from 'luxon'
      3|
      4| import { API_GATEWAY, API_VERSION } from '@globalfishingwatch/api-clie…
       | ^
      5| import type { FourwingsInterval } from '@globalfishingwatch/deck-loade…
      6| import { LIMITS_BY_INTERVAL } from '@globalfishingwatch/deck-loaders'
 ❯ src/layers/fourwings/heatmap/fourwings-heatmap.utils.spec.ts:5:1
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[5/5]⎯
 Test Files  5 failed (5)
      Tests  no tests
   Start at  14:27:28
   Duration  8.35s (transform 7.92s, setup 0ms, import 0ms, tests 0ms, environment 4ms)
❌ fishing-map:test
 RUN  v4.1.8 /home/runner/work/frontend/frontend/apps/fishing-map
◇ injected env (0) from apps/fishing-map/.env // tip: ⌁ auth for agents [www.vestauth.com]
========================================
Authentication Setup Started (chromium)
========================================
Email configured: Yes
Password configured: Yes (hidden)
🔐 Setting up authenticated browser state...
Launching Playwright browser...
Starting auth proxy server...
Navigating to proxy login URL: http://localhost:3000/login
   [BROWSER CONSOLE] error: Connecting to 'https://ad.doubleclick.net/ccm/s/collect?auid=1448662600.1783348071&gtm=45Xe6710h2v810016194za200zd810016194xea' violates the following Content Security Policy directive: "connect-src 'self' https://*.google-analytics.com https://*.analytics.google.com https://*.googletagmanager.com https://*.g.doubleclick.net https://*.google.com https://*.google.es". The action has been blocked.
   [BROWSER CONSOLE] error: Fetch API cannot load https://ad.doubleclick.net/ccm/s/collect?auid=1448662600.1783348071&gtm=45Xe6710h2v810016194za200zd810016194xea. Refused to connect because it violates the document's Content Security Policy.
Navigated to auth page: https://gateway.api.dev.globalfishingwatch.org/v3/auth?client=gfw&locale=en&callback=http%3A%2F%2Flocalhost%3A3000%2Fauth%2Fcallback
Filling in email...
Filling in password...
Clicking login button...
Waiting for redirect to proxy callback with access token...
Access token captured from callback URL: Yes (length: 30)
Exchanging access token for API tokens with GFWAPI...
Token retrieved: Yes (length: 818)
Refresh token retrieved: Yes (length: 92)
✅ Authentication tokens saved to /home/runner/work/frontend/frontend/apps/fishing-map/test/.auth/tokens.json
Auth proxy server stopped
Browser closed
========================================
Authentication Setup Completed Successfully
========================================
========================================
Authentication Setup Started (global-setup)
========================================
✅ Valid tokens found, skipping auth setup
2:27:52 PM [vite] (client) Re-optimizing dependencies because vite config has changed
2:27:53 PM [vite] (client) [optimizer] scanning dependencies...
2:27:54 PM [vite] (client) [optimizer] bundling dependencies...
stderr | test/integration/Reports.spec.tsx > Reports > should navigate to a report from eez
luma.gl: Binding pathStyleUniforms not set: Not found in shader layout.
stderr | test/integration/Reports.spec.tsx > Reports > should navigate to a report from eez
luma.gl: WebGL debug mode activated. Performance reduced.
stderr | test/integration/Reports.spec.tsx > Reports > should navigate to a report from eez
[vitest] Failed to take a screenshot [TimeoutError: locator.screenshot: Timeout 1920.125ms exceeded.
Call log:
  - taking element screenshot
  - waiting for fonts to load...
  - fonts loaded
  - attempting scroll into view action
    - waiting for element to be stable
]
stderr | test/integration/Reports.spec.tsx > Reports > should update report data when filter changes
[Error: Failed to fetch resource (404) : https://gateway.api.dev.globalfi...-layers/5/12/13]
stderr | test/integration/Reports.spec.tsx > Reports > should update report data when filter changes
[Error: Failed to fetch resource (404) : https://gateway.api.dev.globalfi...-layers/5/13/13]
stderr | test/integration/Reports.spec.tsx > Reports > should update report data when filter changes
[Error: Failed to fetch resource (404) : https://gateway.api.dev.globalfi...-layers/5/13/13]
stderr | test/integration/Reports.spec.tsx > Reports > should update report data when filter changes
[Error: Failed to fetch resource (404) : https://gateway.api.dev.globalfi...-layers/5/12/13]
stderr | test/integration/Reports.spec.tsx > Global reports > should open global report when clicking on highlighted workspace in reports category
React-Modal: "parentSelector" prop did not returned any DOM element. Make sure that the parent element is unmounted to avoid any memory leaks.
stderr | test/integration/Reports.spec.tsx > Global reports > should open global report when clicking on highlighted workspace in reports category
DataviewInstance id: viirs doesn't have a valid dataview (undefined)
stderr | test/integration/Reports.spec.tsx > Global reports > should have activity, events and detections tabs
DataviewInstance id: viirs doesn't have a valid dataview (undefined)
stderr | test/integration/Reports.spec.tsx > Global reports > should display the same number in the graph as in the timeseries
DataviewInstance id: viirs doesn't have a valid dataview (undefined)
stderr | test/integration/Reports.spec.tsx > Global reports > should change dataviews when changing tabs
DataviewInstance id: viirs doesn't have a valid dataview (undefined)
stderr | test/integration/Reports.spec.tsx > Global reports > should show detections in detections tab
DataviewInstance id: viirs doesn't have a valid dataview (undefined)
stderr | test/integration/Reports.spec.tsx > Private user reports > should show correct access message for private reports
{
  "message": "Not authorized by permissions",
  "metadata": {},
  "refreshError": true,
  "status": 401,
}
stderr | test/integration/Reports.spec.tsx > Data Comparison > should show both dataviews in graph when compared data is selected
[Error: Failed to fetch resource (404) : https://gateway.api.dev.globalfi...-layers/5/12/13]
stderr | test/integration/Reports.spec.tsx > Data Comparison > should show both dataviews in graph when compared data is selected
[Error: Failed to fetch resource (404) : https://gateway.api.dev.globalfi...-layers/5/13/13]
stderr | test/integration/Reports.spec.tsx > Data Comparison > should show both dataviews in graph when compared data is selected
[Error: Failed to fetch resource (404) : https://gateway.api.dev.globalfi...-layers/5/12/13]
stderr | test/integration/Reports.spec.tsx > Data Comparison > should show both dataviews in graph when compared data is selected
[Error: Failed to fetch resource (404) : https://gateway.api.dev.globalfi...-layers/5/13/13]
stderr | test/integration/Reports.spec.tsx > Data Comparison > should show both dataviews in graph when compared data is selected
[vitest] Failed to take a screenshot [TimeoutError: locator.screenshot: Timeout 5000ms exceeded.
Call log:
  - waiting for locator('[data-vitest="true"]').contentFrame().locator('body')
]
 ❯  fishing-map-chromium  test/integration/Reports.spec.tsx (18 tests | 11 failed) 538873ms
     × should navigate to a report from eez 49069ms
     ✓ should display the date chosen in the timebar with the imprecision tolerance in the report description  16759ms
     × should show same report data at different zoom levels 30168ms
     × should update report data when timebar changes 32557ms
     × should update report data when filter changes 30995ms
     ✓ should show no data message when no data  15629ms
     × should add new subcategory option when new layer is added from layer library 35373ms
     ✓ should open global report when clicking on highlighted workspace in reports category  15662ms
     ✓ should have activity, events and detections tabs  968ms
     × should display the same number in the graph as in the timeseries 30473ms
     ✓ should change dataviews when changing tabs  12330ms
     × should show detections in detections tab 35118ms
     ✓ should show correct access message for private reports  1145ms
     × should show user reports when user is logged in 61464ms
     × should correctly display others points reports data 61065ms
     × should show second selector when choose data comparison mode 30421ms
     ✓ should show both dataviews in map when compared data is selected  28317ms
     × should show both dataviews in graph when compared data is selected 50684ms
stderr | test/integration/Vessels.spec.tsx > Vessel map popup > should open vessel popup on vessel click and show tile related info
luma.gl: WebGL debug mode activated. Performance reduced.
stderr | test/integration/Vessels.spec.tsx > Vessel map popup > should open vessel popup on vessel click and show tile related info
luma.gl: Binding pathStyleUniforms not set: Not found in shader layout.
stderr | test/integration/Vessels.spec.tsx > Vessel map popup > should be able to close an opened popup
[vitest] Failed to take a screenshot [TimeoutError: locator.screenshot: Timeout -402.4799999999814ms exceeded.
Call log:
  - taking element screenshot
]
stderr | test/integration/Vessels.spec.tsx > Vessel map popup > should be able to navigate to vessel viewer inside the vessel popup
[vitest] Failed to take a screenshot [TimeoutError: locator.screenshot: Timeout -403.5030000000261ms exceeded.
Call log:
  - taking element screenshot
]
stderr | test/integration/Vessels.spec.tsx > Vessel map popup > should display the vessel track on the timebar
[vitest] Failed to take a screenshot [TimeoutError: locator.screenshot: Timeout -1537.3839999999618ms exceeded.
Call log:
  - taking element screenshot
]
stderr | test/integration/Vessels.spec.tsx > Vessel map popup > should be able to interact with vessels after filtering by flag
[vitest] Failed to take a screenshot [TimeoutError: locator.screenshot: Timeout -91.5920000000624ms exceeded.
Call log:
  - taking element screenshot
]
 ❯  fishing-map-chromium  test/integration/Vessels.spec.tsx (9 tests | 7 failed) 279229ms
     × should open vessel popup on vessel click and show tile related info 30617ms
     × should be able to close an opened popup 37571ms
     × should be able to navigate to vessel viewer inside the vessel popup 37612ms
     × should display the vessel track on the timebar 38369ms
     × should be able to see vessel info on hover and pin a vessel to the map to see it on the sidebar 23753ms
     ✓ should show vessel info on vessel hover  25324ms
     ✓ should show vessel name, flag and date on vessel name hover on sidebar  18511ms
     × should be able to filter vessels by flag 30130ms
     × should be able to interact with vessels after filtering by flag 37007ms
 ↓  fishing-map-chromium  test/integration/UserDatasets.spec.tsx (7 tests | 7 skipped)
stderr | test/integration/Datasets.spec.tsx > Datasets > should add reference data layer
luma.gl: WebGL debug mode activated. Performance reduced.
stderr | test/integration/Datasets.spec.tsx > Datasets > should add reference data layer
luma.gl: Binding pathStyleUniforms not set: Not found in shader layout.
 ❯  fishing-map-chromium  test/integration/Datasets.spec.tsx (5 tests | 1 failed) 79852ms
     ✓ should add reference data layer  15461ms
     × should add environment data layer 30688ms
     ✓ should add events data layer  9087ms
     ✓ should add activity data layer  9122ms
     ✓ should preserve other layers when removing layer  15365ms
stderr | test/integration/Map.spec.tsx > Map > should pass zoom, latitude and longitude changes of query params to map state
luma.gl: WebGL debug mode activated. Performance reduced.
 ❯  fishing-map-chromium  test/integration/Map.spec.tsx (8 tests | 2 failed) 80940ms
     ✓ should render a map element and it should be loaded and with the default state  2157ms
     ✓ should pass zoom, latitude and longitude changes of query params to map state  12137ms
     ✓ should preserve map state when adding a new layer  8498ms
     ✓ should preserve map state when removing a layer  4000ms
     ✓ should update layers when interacting with the map  6123ms
     × should reflect period changes on the state and map 6057ms
     ✓ should preserve map state when changing period  9540ms
     × should be able to set map visualization to positions and see the corresponding layers on the map 32152ms
stderr | test/integration/VesselViewer.spec.tsx > Vessel viewer > should renders tabs and vessel basic info
luma.gl: WebGL debug mode activated. Performance reduced.
 ❯  fishing-map-chromium  test/integration/VesselViewer.spec.tsx (7 tests | 6 failed) 191887ms
     × should renders tabs and vessel basic info 30123ms
     ✓ should change tab when clicking on a tab  11033ms
     × should render summary tab by type 30114ms
     × should render summary tab by timeline 30117ms
     × should render areas tab and its tabs 30116ms
     × should render related vessels tab 30114ms
     × should render insights tab 30132ms
 ❯  fishing-map-chromium  test/integration/Polygon.spec.tsx (3 tests | 1 failed | 2 skipped) 148ms
     × should be able to navigate to the polygon editor
     ↓ should load the polygon in the map
     ↓ should be able to draw a new polygon, see it in the map and delete it
stderr | test/integration/Timebar.spec.tsx > App Timebar Integration > the map should be interactive after timebar interaction
luma.gl: WebGL debug mode activated. Performance reduced.
stderr | test/integration/Timebar.spec.tsx > App Timebar Integration > the map should be interactive after timebar interaction
luma.gl: Binding pathStyleUniforms not set: Not found in shader layout.
 ✓  fishing-map-chromium  test/integration/Timebar.spec.tsx (3 tests) 38435ms
     ✓ the map should be interactive after timebar interaction  15138ms
     ✓ events should be visible on timebar  6124ms
     ✓ detections should be visible on timebar  17033ms
stderr | test/integration/Sidebar.spec.tsx > Sidebar tools > should change language from selector
React-Modal: "parentSelector" prop did not returned any DOM element. Make sure that the parent element is unmounted to avoid any memory leaks.
stderr | test/integration/Sidebar.spec.tsx > Sidebar tools > should restore help hints when requested
luma.gl: WebGL debug mode activated. Performance reduced.
 ✓  fishing-map-chromium  test/integration/Sidebar.spec.tsx (5 tests) 11383ms
     ✓ should open feedback modal  2888ms
     ✓ should change language from selector  1297ms
     ✓ should toggle sidebar  1023ms
     ✓ should show help hints and allow dismissing one  1244ms
     ✓ should restore help hints when requested  4783ms
 ✓  fishing-map-chromium  test/utils/store/testing-store-middleware.spec.ts (7 tests) 375ms
stderr | test/integration/MarineManager.spec.tsx > Marine Manager > should show workspace layers matching the workspace configuration
DataviewInstance id: context-layer-high-seas doesn't have a valid dataview (undefined)
stderr | test/integration/MarineManager.spec.tsx > Marine Manager > should show workspace layers matching the workspace configuration
DataviewInstance id: global-sea-surface-temperature doesn't have a valid dataview (undefined)
stderr | test/integration/MarineManager.spec.tsx > Marine Manager > should show workspace layers matching the workspace configuration
DataviewInstance id: global-water-salinity doesn't have a valid dataview (undefined)
stderr | test/integration/MarineManager.spec.tsx > Marine Manager > should show workspace layers matching the workspace configuration
DataviewInstance id: global-chlorophyl doesn't have a valid dataview (undefined)
stderr | test/integration/MarineManager.spec.tsx > Marine Manager > should show workspace layers matching the workspace configuration
DataviewInstance id: encounter-events doesn't have a valid dataview (undefined)
stderr | test/integration/MarineManager.spec.tsx > Marine Manager > should show workspace layers matching the workspace configuration
DataviewInstance id: sar-match doesn't have a valid dataview (undefined)
stderr | test/integration/MarineManager.spec.tsx > Marine Manager > should show workspace layers matching the workspace configuration
DataviewInstance id: viirs-match doesn't have a valid dataview (undefined)
 ❯  fishing-map-chromium  test/integration/MarineManager.spec.tsx (2 tests | 2 failed) 24069ms
     × should be able to navigate to marine manager workspace through sidebar 2603ms
     × should show workspace layers matching the workspace configuration 21130ms
 ❯  fishing-map-chromium  test/integration/VesselSearch.spec.tsx (3 tests | 3 failed) 69205ms
     × can search for a vessel and see it on the map 30023ms
     × preserves vessel search value when navigating away and back 7950ms
     × reacts to clearing the search input 31081ms
 ❯  fishing-map-chromium  test/integration/VesselsVMSBrazil.spec.tsx (2 tests | 2 failed) 60873ms
     × should render public VMS Brazil identity fields 30256ms
     × should render private-only VMS Brazil identity fields 30476ms
 ✓  fishing-map-chromium  features/dataviews/dataviews.utils.spec.ts (4 tests) 1425ms
 ❯  fishing-map-chromium  test/integration/PrivateWorkspace.spec.tsx (4 tests | 4 failed) 120578ms
     × should not be able to navigate to the private workspace if not authenticated 30147ms
     × should be able to navigate to the private workspace if authenticated 30085ms
     × should be able to navigate to a password-protected workspace if correct password is used 30115ms
     × should not be able to navigate to a password-protected workspace if incorrect password is used 30097ms
 ✓  fishing-map-chromium  test/integration/App.spec.tsx (2 tests) 6847ms
     ✓ should reflect store changes on layer toggle  2014ms
     ✓ should preserve map previous state on layer toggle  4690ms
stderr | features/timebar/Timebar.spec.tsx > Timebar > should render Timebar component with heatmap visualization by default
Warning: useRouter must be used inside a <RouterProvider> component!
stderr | features/timebar/Timebar.spec.tsx > Timebar > should render Timebar component with heatmap visualization by default
Warning: useRouter must be used inside a <RouterProvider> component!
stderr | features/timebar/Timebar.spec.tsx > Timebar > should render Timebar component with heatmap visualization by default
Warning: useRouter must be used inside a <RouterProvider> component!
stderr | features/timebar/Timebar.spec.tsx > Timebar > should render Timebar component with heatmap visualization by default
Warning: useRouter must be used inside a <RouterProvider> component!
stderr | features/timebar/Timebar.spec.tsx > Timebar > should render Timebar component with heatmap visualization by default
Warning: useRouter must be used inside a <RouterProvider> component!
stderr | features/timebar/Timebar.spec.tsx > Timebar > should render Timebar component with heatmap visualization by default
Warning: useRouter must be used inside a <RouterProvider> component!
stderr | features/timebar/Timebar.spec.tsx > Timebar > should render Timebar component with heatmap visualization by default
Warning: useRouter must be used inside a <RouterProvider> component!
stderr | features/timebar/Timebar.spec.tsx > Timebar > should render Timebar component with heatmap visualization by default
Warning: useRouter must be used inside a <RouterProvider> component!
stderr | features/timebar/Timebar.spec.tsx > Timebar > should render Timebar component with heatmap visualization by default
Warning: useRouter must be used inside a <RouterProvider> component!
stderr | features/timebar/Timebar.spec.tsx > Timebar > should render Timebar component with heatmap visualization by default
Warning: useRouter must be used inside a <RouterProvider> component!
stderr | features/timebar/Timebar.spec.tsx > Timebar > should render Timebar component with heatmap visualization by default
Warning: useRouter must be used inside a <RouterProvider> component!
stderr | features/timebar/Timebar.spec.tsx > Timebar > should render Timebar component with heatmap visualization by default
Warning: useRouter must be used inside a <RouterProvider> component!
stderr | features/timebar/Timebar.spec.tsx > Timebar > should render Timebar component with heatmap visualization by default
Warning: useRouter must be used inside a <RouterProvider> component!
stderr | features/timebar/Timebar.spec.tsx > Timebar > should render Timebar component with heatmap visualization by default
Warning: useRouter must be used inside a <RouterProvider> component!
stderr | features/timebar/Timebar.spec.tsx > Timebar > should render Timebar component with heatmap visualization by default
Warning: useRouter must be used inside a <RouterProvider> component!
stderr | features/timebar/Timebar.spec.tsx > Timebar > should render Timebar component with heatmap visualization by default
Warning: useRouter must be used inside a <RouterProvider> component!
stderr | features/timebar/Timebar.spec.tsx > Timebar > should render Timebar component with heatmap visualization by default
Warning: useRouter must be used inside a <RouterProvider> component!
stderr | features/timebar/Timebar.spec.tsx > Timebar > should render Timebar component with heatmap visualization by default
Warning: useRouter must be used inside a <RouterProvider> component!
stderr | features/timebar/Timebar.spec.tsx > Timebar > should render Timebar component with heatmap visualization by default
Warning: useRouter must be used inside a <RouterProvider> component!
stderr | features/timebar/Timebar.spec.tsx > Timebar > should render Timebar component with heatmap visualization by default
Warning: useRouter must be used inside a <RouterProvider> component!
stderr | features/timebar/Timebar.spec.tsx > Timebar > should render Timebar component with heatmap visualization by default
Warning: useRouter must be used inside a <RouterProvider> component!
stderr | features/timebar/Timebar.spec.tsx > Timebar > should render Timebar component with heatmap visualization by default
Warning: useRouter must be used inside a <RouterProvider> component!
stderr | features/timebar/Timebar.spec.tsx > Timebar > should render Timebar component with heatmap visualization by default
Warning: useRouter must be used inside a <RouterProvider> component!
stderr | features/timebar/Timebar.spec.tsx > Timebar > should render Timebar component with heatmap visualization by default
Warning: useRouter must be used inside a <RouterProvider> component!
stderr | features/timebar/Timebar.spec.tsx > Timebar > should render Timebar component with heatmap visualization by default
Warning: useRouter must be used inside a <RouterProvider> component!
stderr | features/timebar/Timebar.spec.tsx > Timebar > should render Timebar component with heatmap visualization by default
Warning: useRouter must be used inside a <RouterProvider> component!
stderr | features/timebar/Timebar.spec.tsx > Timebar > should render Timebar component with heatmap visualization by default
Warning: useRouter must be used inside a <RouterProvider> component!
stderr | features/timebar/Timebar.spec.tsx > Timebar > should render Timebar component with heatmap visualization by default
Warning: useRouter must be used inside a <RouterProvider> component!
stderr | features/timebar/Timebar.spec.tsx > Timebar > should render Timebar component with heatmap visualization by default
Warning: useRouter must be used inside a <RouterProvider> component!
stderr | features/timebar/Timebar.spec.tsx > Timebar > should render Timebar component with heatmap visualization by default
Warning: useRouter must be used inside a <RouterProvider> component!
stderr | features/timebar/Timebar.spec.tsx > Timebar > should render Timebar component with heatmap visualization by default
Warning: useRouter must be used inside a <RouterProvider> component!
stderr | features/timebar/Timebar.spec.tsx > Timebar > should render Timebar component with heatmap visualization by default
Warning: useRouter must be used inside a <RouterProvider> component!
stderr | features/timebar/Timebar.spec.tsx > Timebar > should render Timebar component with heatmap visualization by default
Warning: useRouter must be used inside a <RouterProvider> component!
stderr | features/timebar/Timebar.spec.tsx > Timebar > should render Timebar component with heatmap visualization by default
Warning: useRouter must be used inside a <RouterProvider> component!
stderr | features/timebar/Timebar.spec.tsx > Timebar > should render Timebar component with heatmap visualization by default
Warning: useRouter must be used inside a <RouterProvider> component!
stderr | features/timebar/Timebar.spec.tsx > Timebar > should call onTimebarChange with new time interval on yearly data button click
Warning: useRouter must be used inside a <RouterProvider> component!
stderr | features/timebar/Timebar.spec.tsx > Timebar > should call onTimebarChange with new time interval on yearly data button click
Warning: useRouter must be used inside a <RouterProvider> component!
stderr | features/timebar/Timebar.spec.tsx > Timebar > should call onTimebarChange with new time interval on yearly data button click
Warning: useRouter must be used inside a <RouterProvider> component!
stderr | features/timebar/Timebar.spec.tsx > Timebar > should call onTimebarChange with new time interval on yearly data button click
Warning: useRouter must be used inside a <RouterProvider> component!
stderr | features/timebar/Timebar.spec.tsx > Timebar > should call onTimebarChange with new time interval on yearly data button click
Warning: useRouter must be used inside a <RouterProvider> component!
stderr | features/timebar/Timebar.spec.tsx > Timebar > should call onTimebarChange with new time interval on yearly data button click
Warning: useRouter must be used inside a <RouterProvider> component!
stderr | features/timebar/Timebar.spec.tsx > Timebar > should call onTimebarChange with new time interval on yearly data button click
Warning: useRouter must be used inside a <RouterProvider> component!
stderr | features/timebar/Timebar.spec.tsx > Timebar > should call onTimebarChange with new time interval on yearly data button click
Warning: useRouter must be used inside a <RouterProvider> component!
stderr | features/timebar/Timebar.spec.tsx > Timebar > should call onTimebarChange with new time interval on yearly data button click
Warning: useRouter must be used inside a <RouterProvider> component!
stderr | features/timebar/Timebar.spec.tsx > Timebar > should call onTimebarChange with new time interval on yearly data button click
Warning: useRouter must be used inside a <RouterProvider> component!
stderr | features/timebar/Timebar.spec.tsx > Timebar > should call onTimebarChange with new time interval on yearly data button click
Warning: useRouter must be used inside a <RouterProvider> component!
stderr | features/timebar/Timebar.spec.tsx > Timebar > should call onTimebarChange with new time interval on yearly data button click
Warning: useRouter must be used inside a <RouterProvider> component!
stderr | features/timebar/Timebar.spec.tsx > Timebar > should call onTimebarChange with new time interval on yearly data button click
Warning: useRouter must be used inside a <RouterProvider> component!
stderr | features/timebar/Timebar.spec.tsx > Timebar > should call onTimebarChange with new time interval on yearly data button click
Warning: useRouter must be used inside a <RouterProvider> component!
stderr | features/timebar/Timebar.spec.tsx > Timebar > should call onTimebarChange with new time interval on yearly data button click
Warning: useRouter must be used inside a <RouterProvider> component!
stderr | features/timebar/Timebar.spec.tsx > Timebar > should call onTimebarChange with new time interval on yearly data button click
Warning: useRouter must be used inside a <RouterProvider> component!
stderr | features/timebar/Timebar.spec.tsx > Timebar > should call onTimebarChange with new time interval on yearly data button click
Warning: useRouter must be used inside a <RouterProvider> component!
stderr | features/timebar/Timebar.spec.tsx > Timebar > should call onTimebarChange with new time interval on yearly data button click
Warning: useRouter must be used inside a <RouterProvider> component!
stderr | features/timebar/Timebar.spec.tsx > Timebar > should call onTimebarChange with new time interval on yearly data button click
Warning: useRouter must be used inside a <RouterProvider> component!
stderr | features/timebar/Timebar.spec.tsx > Timebar > should call onTimebarChange with new time interval on yearly data button click
Warning: useRouter must be used inside a <RouterProvider> component!
stderr | features/timebar/Timebar.spec.tsx > Timebar > should call onTimebarChange with new time interval on yearly data button click
Warning: useRouter must be used inside a <RouterProvider> component!
stderr | features/timebar/Timebar.spec.tsx > Timebar > should call onTimebarChange with new time interval on yearly data button click
Warning: useRouter must be used inside a <RouterProvider> component!
stderr | features/timebar/Timebar.spec.tsx > Timebar > should call onTimebarChange with new time interval on yearly data button click
Warning: useRouter must be used inside a <RouterProvider> component!
stderr | features/timebar/Timebar.spec.tsx > Timebar > should call onTimebarChange with new time interval on yearly data button click
Warning: useRouter must be used inside a <RouterProvider> component!
stderr | features/timebar/Timebar.spec.tsx > Timebar > should call onTimebarChange with new time interval on yearly data button click
Warning: useRouter must be used inside a <RouterProvider> component!
stderr | features/timebar/Timebar.spec.tsx > Timebar > should call onTimebarChange with new time interval on yearly data button click
Warning: useRouter must be used inside a <RouterProvider> component!
stderr | features/timebar/Timebar.spec.tsx > Timebar > should call onTimebarChange with new time interval on yearly data button click
Warning: useRouter must be used inside a <RouterProvider> component!
stderr | features/timebar/Timebar.spec.tsx > Timebar > should call onTimebarChange with new time interval on yearly data button click
Warning: useRouter must be used inside a <RouterProvider> component!
stderr | features/timebar/Timebar.spec.tsx > Timebar > should call onTimebarChange with new time interval on yearly data button click
Warning: useRouter must be used inside a <RouterProvider> component!
stderr | features/timebar/Timebar.spec.tsx > Timebar > should call onTimebarChange with new time interval on yearly data button click
Warning: useRouter must be used inside a <RouterProvider> component!
stderr | features/timebar/Timebar.spec.tsx > Timebar > should call onTimebarChange with new time interval on yearly data button click
Warning: useRouter must be used inside a <RouterProvider> component!
stderr | features/timebar/Timebar.spec.tsx > Timebar > should call onTimebarChange with new time interval on yearly data button click
Warning: useRouter must be used inside a <RouterProvider> component!
stderr | features/timebar/Timebar.spec.tsx > Timebar > should call onTimebarChange with new time interval on yearly data button click
Warning: useRouter must be used inside a <RouterProvider> component!
stderr | features/timebar/Timebar.spec.tsx > Timebar > should call onTimebarChange with new time interval on yearly data button click
Warning: useRouter must be used inside a <RouterProvider> component!
stderr | features/timebar/Timebar.spec.tsx > Timebar > should call onTimebarChange with new time interval on yearly data button click
Warning: useRouter must be used inside a <RouterProvider> component!
stderr | features/timebar/Timebar.spec.tsx > Timebar > should call onTimebarChange with new time interval on yearly data button click
Warning: useRouter must be used inside a <RouterProvider> component!
stderr | features/timebar/Timebar.spec.tsx > Timebar > should call onTimebarChange with new time interval on yearly data button click
Warning: useRouter must be used inside a <RouterProvider> component!
stderr | features/timebar/Timebar.spec.tsx > Timebar > should call onTimebarChange with new time interval on yearly data button click
Warning: useRouter must be used inside a <RouterProvider> component!
stderr | features/timebar/Timebar.spec.tsx > Timebar > should call onTimebarChange with new time interval on yearly data button click
Warning: useRouter must be used inside a <RouterProvider> component!
stderr | features/timebar/Timebar.spec.tsx > Timebar > should call onTimebarChange with new time interval on yearly data button click
Warning: useRouter must be used inside a <RouterProvider> component!
stderr | features/timebar/Timebar.spec.tsx > Timebar > should call onTimebarChange with new time interval on yearly data button click
Warning: useRouter must be used inside a <RouterProvider> component!
stderr | features/timebar/Timebar.spec.tsx > Timebar > should call onTimebarChange with new time interval on yearly data button click
Warning: useRouter must be used inside a <RouterProvider> component!
stderr | features/timebar/Timebar.spec.tsx > Timebar > should call onTimebarChange with new time interval on yearly data button click
Warning: useRouter must be used inside a <RouterProvider> component!
stderr | features/timebar/Timebar.spec.tsx > Timebar > should call onTimebarChange with new time interval on yearly data button click
Warning: useRouter must be used inside a <RouterProvider> component!
 ❯  fishing-map-chromium  features/timebar/Timebar.spec.tsx (2 tests | 1 failed) 472ms
     ✓ should render Timebar component with heatmap visualization by default 91ms
     × should call onTimebarChange with new time interval on yearly data button click 311ms
 ❯  fishing-map-chromium  test/integration/User.spec.tsx (1 test | 1 failed) 31414ms
     × should show expired session warning toast 31267ms
 ❯  fishing-map-chromium  features/workspace/user/UserSection/UserSection.test.tsx (1 test | 1 failed) 30211ms
     × should have a login link if the user is a guest 30143ms
⎯⎯⎯⎯⎯⎯ Failed Tests 42 ⎯⎯⎯⎯⎯⎯⎯
 FAIL   fishing-map-chromium  features/timebar/Timebar.spec.tsx > Timebar > should call onTimebarChange with new time interval on yearly data button click
AssertionError: expected "vi.fn()" to be called with arguments: [ '2012-01-01T00:00:00.000Z', …(1) ]
Received:
  1st vi.fn() call:
  [
    "2012-01-01T00:00:00.000Z",
    "2026-12-31T23:59:59.999Z",
+   "YEAR_INTERVAL_BUTTON",
  ]

Number of calls: 1

Failure screenshot:
  - apps/fishing-map/features/timebar/__screenshots__/Timebar.spec.tsx/Timebar-should-call-onTimebarChange-with-new-time-interval-on-yearly-data-button-click-1.png
 ❯ features/timebar/Timebar.spec.tsx:54:31
     52|
     53|     // Now you can assert on the spy
     54|     expect(onTimebarChangeSpy).toHaveBeenCalledWith(
       |                               ^
     55|       '2012-01-01T00:00:00.000Z',
     56|       '2026-12-31T23:59:59.999Z'
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/42]⎯
 FAIL   fishing-map-chromium  test/integration/Datasets.spec.tsx > Datasets > should add environment data layer
VitestBrowserElementError: Cannot find element with locator: page.getByTestId('map-popup-wrapper').getByRole('heading', { name: 'Bathymetry' })
<body
  class=""
>
  
  

  <div
    id="__root__"
  >
    <a
      class="print-only"
      href="https://globalfishingwatch.org"
    >
      <svg
        aria-label="Global Fishing Watch "
        class="_container_13m0y_1"
        height="60"
        viewBox="20 0 220 60"
        width="200"
        xmlns="http://www.w3.org/2000/svg"
      >
        <g
          aria-hidden="true"
          fill="none"
          fill-rule="evenodd"
          focusable="false"
        >
          <path
            d="M23.1 27.83c-.08.16-2.25 4.5.57 8.76.83 1.25 1.76 2.24 4.1 3.8 3.38 2.26 7.42 6.16 8.4 8.45.1.21.36.59-.06.83-.73.41-1.75.31-2.16.25l-.12-.02c-4.75-.88-14.5-5-13.8-13.8.18-2.21.98-4.87 3.07-8.27zm9.92-8.64c.7-.08 2.98-.15 3.08.08.07.17-.83.5-.87.52-5.22 1.98-6.97 3.16-7.22 3.3-3.3 2.01-4.71 4.35-4.82 4.57 1.48-3.1 5.2-7.93 9.83-8.47z"
            fill="#8ABBC7"
          />
          <path
            d="M40.45 19.2l.64 1.16a17.1 17.1 0 011.52 3.94c.27 1.1.39 2.23.31 3.37a9.39 9.39 0 01-1.72 4.84 12.9 12.9 0 01-3.29 3.2 20.3 20.3 0 01-7.02 3.08c-.4.09-.8.16-1.2.19a3.39 3.39 0 01-1.3-.17c-.43-.17-.5-.43-.28-.83a13.43 13.43 0 012.53-3.4 35.39 35.39 0 015.48-4.56c.76-.53 1.5-1.06 2.15-1.7a8.5 8.5 0 002.55-4.63 8.37 8.37 0 00-.24-3.89l-.18-.59.05-.02zm.64 16.43c.5.03.64.28.4.72-.35.64-.9 1.04-1.6 1.21-.68.16-1.35.13-2.02-.02-.42-.09-.83-.23-1.24-.35l-.11-.06.12-.08c1.02-.53 2.07-.97 3.19-1.26.4-.1.83-.18 1.26-.16zM30.73 10.07c.92.2 1.75.61 2.54 1.11.87.56 1.65 1.21 2.4 1.92a29.78 29.78 0 014.2 5.18l.01.07-.18-.16a14.79 14.79 0 00-3.6-2.45c-1.01-.5-2.06-.9-3.11-1.3-.58-.23-1.16-.44-1.7-.75a1.82 1.82 0 01-.75-.76c-.15-.32-.07-.6.23-.78l.35-.18c-.28-.14-.53-.24-.75-.38-.2-.13-.38-.29-.55-.45a.77.77 0 01-.21-.64c.02-.24.13-.38.35-.46.26-.08.52-.03.77.03z"
            fill="#E84427"
          />
          <text
            class="_mainBrand_13m0y_5 _default_13m0y_10"
            x="52"
            y="37"
          >
            Global Fishing Watch
          </text>
        </g>
      </svg>
    </a>
    <div
      class="_appLayout_d89r9_1"
    >
      <div
        class="_appLayoutContent_d89r9_8"
        id="app-layout-content"
      >
        <div
          class="_container_1gfa5_1 _isOpen_1gfa5_19 _splitContainer_d89r9_66"
        >
          <aside
            class="_aside_1gfa5_8 _aside_d89r9_77"
            style="width: 40rem;"
          >
            <button
              aria-label="Toggle sidebar"
              class="print-hidden _toggleBtn_1gfa5_48"
            >
              <svg … />
            </button>
            <div
              class="_container_10gdv_1"
            >
              <div … />
              <ul … />
            </div>
          </aside>
          <main
            class="_main_1gfa5_23 _main_d89r9_16"
            data-testid="app-main"
            id="app-main"
            style="left: 40rem;"
          >
            <div
              class="_mapContainer_d89r9_22 _withTimebar_d89r9_33"
            >
              <div … />
            </div>
            <div
              class="_timebarWrapper_1pma8_1"
              data-testid="timebar-wrapper"
              role="toolbar"
            >
              <div … />
              <div … />
            </div>
            <footer
              class="print-hidden _footer_1k9s3_1"
            >
              <div … />
              <span … />
            </footer>
          </main>
        </div>
        <section
          aria-atomic="false"
          aria-label="Notifications Alt+T"
          aria-live="polite"
          aria-relevant="additions text"
          class="Toastify"
        />
        <div
          class="ReactModalPortal"
        />
        <div
          class="ReactModalPortal"
        />
        <div
          class="ReactModalPortal"
        />
        <div
          class="ReactModalPortal"
        />
        <div
          class="ReactModalPortal"
        />
      </div>
      <div
        class="_panel_15iap_1 _hidden_15iap_12"
        style="width: 540px; --panel-width: 540px;"
      >
        <div
          class="_panelResizer_15iap_29"
          role="button"
          tabindex="0"
        />
      </div>
    </div>
  </div>
  <div
    class="ReactModalPortal"
  />
</body>...
Failure screenshot:
  - apps/fishing-map/test/integration/__screenshots__/Datasets.spec.tsx/Datasets-should-add-environment-data-layer-1.png
 ❯ test/integration/Datasets.spec.tsx:85:7
     83|     await expect
     84|       .element(getByTestId('map-popup-wrapper').getByRole('heading', {…
     85|       .toBeVisible()
       |       ^
     86|   })
     87|
Caused by: Error: Matcher did not succeed in time.
 ❯ test/integration/Datasets.spec.tsx:83:4
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[2/42]⎯
 FAIL   fishing-map-chromium  test/integration/Map.spec.tsx > Map > should reflect period changes on the state and map
AssertionError: expected { …(2) } to match object { …(2) }
Failure screenshot:
  - apps/fishing-map/test/integration/__screenshots__/Map.spec.tsx/Map-should-reflect-period-changes-on-the-state-and-map-1.png
- Expected
+ Received
  {
-   "end": "2026-12-31T23:59:59.999Z",
+   "end": "2027-01-01T00:00:00.000Z",
    "start": "2012-01-01T00:00:00.000Z",
  }
 ❯ test/integration/Map.spec.tsx:156:22
    154|     const deckLayersState = jotaiStore.get(deckLayersStateAtom)
    155|
    156|     expect(timerange).toMatchObject({
       |                      ^
    157|       start: '2012-01-01T00:00:00.000Z',
    158|       end: '2026-12-31T23:59:59.999Z',
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[3/42]⎯
 FAIL   fishing-map-chromium  test/integration/Map.spec.tsx > Map > should be able to set map visualization to positions and see the corresponding layers on the map
VitestBrowserElementError: Cannot find element with locator: page.getByTestId('map-popup-wrapper').getByText(/No.805 Oryong/i)
<body
  class=""
>
  
  

  <div
    id="__root__"
  >
    <a
      class="print-only"
      href="https://globalfishingwatch.org"
    >
      <svg
        aria-label="Global Fishing Watch "
        class="_container_13m0y_1"
        height="60"
        viewBox="20 0 220 60"
        width="200"
        xmlns="http://www.w3.org/2000/svg"
      >
        <g
          aria-hidden="true"
          fill="none"
          fill-rule="evenodd"
          focusable="false"
        >
          <path
            d="M23.1 27.83c-.08.16-2.25 4.5.57 8.76.83 1.25 1.76 2.24 4.1 3.8 3.38 2.26 7.42 6.16 8.4 8.45.1.21.36.59-.06.83-.73.41-1.75.31-2.16.25l-.12-.02c-4.75-.88-14.5-5-13.8-13.8.18-2.21.98-4.87 3.07-8.27zm9.92-8.64c.7-.08 2.98-.15 3.08.08.07.17-.83.5-.87.52-5.22 1.98-6.97 3.16-7.22 3.3-3.3 2.01-4.71 4.35-4.82 4.57 1.48-3.1 5.2-7.93 9.83-8.47z"
            fill="#8ABBC7"
          />
          <path
            d="M40.45 19.2l.64 1.16a17.1 17.1 0 011.52 3.94c.27 1.1.39 2.23.31 3.37a9.39 9.39 0 01-1.72 4.84 12.9 12.9 0 01-3.29 3.2 20.3 20.3 0 01-7.02 3.08c-.4.09-.8.16-1.2.19a3.39 3.39 0 01-1.3-.17c-.43-.17-.5-.43-.28-.83a13.43 13.43 0 012.53-3.4 35.39 35.39 0 015.48-4.56c.76-.53 1.5-1.06 2.15-1.7a8.5 8.5 0 002.55-4.63 8.37 8.37 0 00-.24-3.89l-.18-.59.05-.02zm.64 16.43c.5.03.64.28.4.72-.35.64-.9 1.04-1.6 1.21-.68.16-1.35.13-2.02-.02-.42-.09-.83-.23-1.24-.35l-.11-.06.12-.08c1.02-.53 2.07-.97 3.19-1.26.4-.1.83-.18 1.26-.16zM30.73 10.07c.92.2 1.75.61 2.54 1.11.87.56 1.65 1.21 2.4 1.92a29.78 29.78 0 014.2 5.18l.01.07-.18-.16a14.79 14.79 0 00-3.6-2.45c-1.01-.5-2.06-.9-3.11-1.3-.58-.23-1.16-.44-1.7-.75a1.82 1.82 0 01-.75-.76c-.15-.32-.07-.6.23-.78l.35-.18c-.28-.14-.53-.24-.75-.38-.2-.13-.38-.29-.55-.45a.77.77 0 01-.21-.64c.02-.24.13-.38.35-.46.26-.08.52-.03.77.03z"
            fill="#E84427"
          />
          <text
            class="_mainBrand_13m0y_5 _default_13m0y_10"
            x="52"
            y="37"
          >
            Global Fishing Watch
          </text>
        </g>
      </svg>
    </a>
    <div
      class="_appLayout_d89r9_1"
    >
      <div
        class="_appLayoutContent_d89r9_8"
        id="app-layout-content"
      >
        <div
          class="_container_1gfa5_1 _isOpen_1gfa5_19 _splitContainer_d89r9_66"
        >
          <aside
            class="_aside_1gfa5_8 _aside_d89r9_77"
            style="width: 40rem;"
          >
            <button
              aria-label="Toggle sidebar"
              class="print-hidden _toggleBtn_1gfa5_48"
            >
              <svg … />
            </button>
            <div
              class="_container_10gdv_1"
            >
              <div … />
              <ul … />
            </div>
          </aside>
          <main
            class="_main_1gfa5_23 _main_d89r9_16"
            data-testid="app-main"
            id="app-main"
            style="left: 40rem;"
          >
            <div
              class="_mapContainer_d89r9_22 _withTimebar_d89r9_33"
            >
              <div … />
            </div>
            <div
              class="_timebarWrapper_1pma8_1"
              data-testid="timebar-wrapper"
              role="toolbar"
            >
              <div … />
              <div … />
            </div>
            <footer
              class="print-hidden _footer_1k9s3_1"
            >
              <div … />
              <span … />
            </footer>
          </main>
        </div>
        <section
          aria-atomic="false"
          aria-label="Notifications Alt+T"
          aria-live="polite"
          aria-relevant="additions text"
          class="Toastify"
        />
        <div
          class="ReactModalPortal"
        />
        <div
          class="ReactModalPortal"
        />
        <div
          class="ReactModalPortal"
        />
        <div
          class="ReactModalPortal"
        />
        <div
          class="ReactModalPortal"
        />
      </div>
      <div
        class="_panel_15iap_1 _hidden_15iap_12"
        style="width: 540px; --panel-width: 540px;"
      >
        <div
          class="_panelResizer_15iap_29"
          role="button"
          tabindex="0"
        />
      </div>
    </div>
  </div>
  <div
    class="ReactModalPortal"
  />
</body>...
Failure screenshot:
  - apps/fishing-map/test/integration/__screenshots__/Map.spec.tsx/Map-should-be-able-to-set-map-visualization-to-positions-and-see-the-corresponding-layers-on-the-map-1.png
 ❯ test/integration/Map.spec.tsx:230:87
    228|     await userEvent.click(getByTestId('app-main'), { position: { x, y …
    229|
    230|     await expect.element(getByTestId('map-popup-wrapper').getByText(/N…
       |                                                                                       ^
    231|   })
    232| })
Caused by: Error: Matcher did not succeed in time.
 ❯ test/integration/Map.spec.tsx:230:4
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[4/42]⎯
 FAIL   fishing-map-chromium  test/integration/MarineManager.spec.tsx > Marine Manager > should be able to navigate to marine manager workspace through sidebar
AssertionError: expected undefined to match object { type: 'WORKSPACE', …(3) }
Failure screenshot:
  - apps/fishing-map/test/integration/__screenshots__/MarineManager.spec.tsx/Marine-Manager-should-be-able-to-navigate-to-marine-manager-workspace-through-sidebar-1.png
- Expected:
{
  "meta": {
    "location": {
      "current": {
        "pathname": "/marine-manager/fiji-public",
        "payload": {
          "category": "marine-manager",
          "workspaceId": "fiji-public",
        },
      },
      "kind": StringMatching /redirect|push/,
      "prev": Any<Object>,
    },
  },
  "payload": {
    "category": "marine-manager",
    "workspaceId": "fiji-public",
  },
  "replaceQuery": true,
  "type": "WORKSPACE",
}
+ Received:
undefined
 ❯ test/integration/MarineManager.spec.tsx:27:19
     25|     const action = testingMiddleware.getLastActionByType('WORKSPACE')
     26|
     27|     expect(action).toMatchObject({
       |                   ^
     28|       type: 'WORKSPACE',
     29|       payload: {
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[5/42]⎯
 FAIL   fishing-map-chromium  test/integration/MarineManager.spec.tsx > Marine Manager > should show workspace layers matching the workspace configuration
AssertionError: expected { …(2) } to match object { …(12) }
(4 matching properties omitted from actual)
Failure screenshot:
  - apps/fishing-map/test/integration/__screenshots__/MarineManager.spec.tsx/Marine-Manager-should-show-workspace-layers-matching-the-workspace-configuration-1.png
- Expected
+ Received
  {
    "basemap": {
      "cacheHash": Any<String>,
      "loaded": Any<Boolean>,
    },
-   "basemap-labels": {
-     "cacheHash": Any<String>,
-     "loaded": Any<Boolean>,
-   },
-   "context-layer-eez": {
-     "cacheHash": Any<String>,
-     "loaded": Any<Boolean>,
-   },
-   "context-layer-graticules": {
-     "cacheHash": Any<String>,
-     "loaded": Any<Boolean>,
-   },
-   "context-layer-high-seas": {
-     "cacheHash": Any<String>,
-     "loaded": Any<Boolean>,
-   },
-   "context-layer-mpa": {
-     "cacheHash": Any<String>,
-     "loaded": Any<Boolean>,
-   },
-   "context-layer-rfmo": {
-     "cacheHash": Any<String>,
-     "loaded": Any<Boolean>,
-   },
-   "encounter-events": {
-     "cacheHash": Any<String>,
-     "loaded": Any<Boolean>,
-   },
-   "global-chlorophyl": {
-     "cacheHash": Any<String>,
-     "loaded": Any<Boolean>,
-   },
-   "global-sea-surface-temperature": {
-     "cacheHash": Any<String>,
-     "loaded": Any<Boolean>,
-   },
-   "global-water-salinity": {
-     "cacheHash": Any<String>,
-     "loaded": Any<Boolean>,
-   },
-   "sentinel2-auxiliar": {
-     "cacheHash": Any<String>,
-     "loaded": Any<Boolean>,
-   },
  }
 ❯ test/integration/MarineManager.spec.tsx:64:7
     62|     await expect
     63|       .poll(() => jotaiStore.get(deckLayersStateAtom), { timeout: 2000…
     64|       .toMatchObject({
       |       ^
     65|         basemap: expectedLayerProps,
     66|         'context-layer-high-seas': expectedLayerProps,
Caused by: Error: Matcher did not succeed in time.
 ❯ test/integration/MarineManager.spec.tsx:62:4
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[6/42]⎯
 FAIL   fishing-map-chromium  test/integration/Polygon.spec.tsx > Polygon > should be able to navigate to the polygon editor
Error: [Vitest] Unexpected .only modifier. Remove it or pass --allowOnly argument to bypass this error
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[7/42]⎯
 FAIL   fishing-map-chromium  test/integration/PrivateWorkspace.spec.tsx > PrivateWorkspace > should not be able to navigate to the private workspace if not authenticated
VitestBrowserElementError: Cannot find element with locator: page.getByText(/This is a private workspace/)
<body>
  
  

  <div
    id="__root__"
  >
    <a
      class="print-only"
      href="https://globalfishingwatch.org"
    >
      <svg
        aria-label="Global Fishing Watch "
        class="_container_13m0y_1"
        height="60"
        viewBox="20 0 220 60"
        width="200"
        xmlns="http://www.w3.org/2000/svg"
      >
        <g
          aria-hidden="true"
          fill="none"
          fill-rule="evenodd"
          focusable="false"
        >
          <path
            d="M23.1 27.83c-.08.16-2.25 4.5.57 8.76.83 1.25 1.76 2.24 4.1 3.8 3.38 2.26 7.42 6.16 8.4 8.45.1.21.36.59-.06.83-.73.41-1.75.31-2.16.25l-.12-.02c-4.75-.88-14.5-5-13.8-13.8.18-2.21.98-4.87 3.07-8.27zm9.92-8.64c.7-.08 2.98-.15 3.08.08.07.17-.83.5-.87.52-5.22 1.98-6.97 3.16-7.22 3.3-3.3 2.01-4.71 4.35-4.82 4.57 1.48-3.1 5.2-7.93 9.83-8.47z"
            fill="#8ABBC7"
          />
          <path
            d="M40.45 19.2l.64 1.16a17.1 17.1 0 011.52 3.94c.27 1.1.39 2.23.31 3.37a9.39 9.39 0 01-1.72 4.84 12.9 12.9 0 01-3.29 3.2 20.3 20.3 0 01-7.02 3.08c-.4.09-.8.16-1.2.19a3.39 3.39 0 01-1.3-.17c-.43-.17-.5-.43-.28-.83a13.43 13.43 0 012.53-3.4 35.39 35.39 0 015.48-4.56c.76-.53 1.5-1.06 2.15-1.7a8.5 8.5 0 002.55-4.63 8.37 8.37 0 00-.24-3.89l-.18-.59.05-.02zm.64 16.43c.5.03.64.28.4.72-.35.64-.9 1.04-1.6 1.21-.68.16-1.35.13-2.02-.02-.42-.09-.83-.23-1.24-.35l-.11-.06.12-.08c1.02-.53 2.07-.97 3.19-1.26.4-.1.83-.18 1.26-.16zM30.73 10.07c.92.2 1.75.61 2.54 1.11.87.56 1.65 1.21 2.4 1.92a29.78 29.78 0 014.2 5.18l.01.07-.18-.16a14.79 14.79 0 00-3.6-2.45c-1.01-.5-2.06-.9-3.11-1.3-.58-.23-1.16-.44-1.7-.75a1.82 1.82 0 01-.75-.76c-.15-.32-.07-.6.23-.78l.35-.18c-.28-.14-.53-.24-.75-.38-.2-.13-.38-.29-.55-.45a.77.77 0 01-.21-.64c.02-.24.13-.38.35-.46.26-.08.52-.03.77.03z"
            fill="#E84427"
          />
          <text
            class="_mainBrand_13m0y_5 _default_13m0y_10"
            x="52"
            y="37"
          >
            Global Fishing Watch
          </text>
        </g>
      </svg>
    </a>
    <div
      class="_appLayout_d89r9_1"
    >
      <div
        class="_appLayoutContent_d89r9_8"
        id="app-layout-content"
      >
        <div
          class="_container_1gfa5_1 _isOpen_1gfa5_19 _splitContainer_d89r9_66"
        >
          <aside
            class="_aside_1gfa5_8 _aside_d89r9_77"
            style="width: 40rem;"
          >
            <button
              aria-label="Toggle sidebar"
              class="print-hidden _toggleBtn_1gfa5_48"
            >
              <svg … />
            </button>
            <div
              class="_container_10gdv_1"
            >
              <div … />
              <ul … />
            </div>
          </aside>
          <main
            class="_main_1gfa5_23 _main_d89r9_16"
            data-testid="app-main"
            id="app-main"
            style="left: 40rem;"
          >
            <div
              class="_mapContainer_d89r9_22"
            />
            <footer
              class="print-hidden _footer_1k9s3_1"
            >
              <div … />
              <span … />
            </footer>
          </main>
        </div>
        <section
          aria-atomic="false"
          aria-label="Notifications Alt+T"
          aria-live="polite"
          aria-relevant="additions text"
          class="Toastify"
        />
        <div
          class="ReactModalPortal"
        />
        <div
          class="ReactModalPortal"
        />
        <div
          class="ReactModalPortal"
        />
        <div
          class="ReactModalPortal"
        />
      </div>
      <div
        class="_panel_15iap_1 _hidden_15iap_12"
        style="width: 540px; --panel-width: 540px;"
      >
        <div
          class="_panelResizer_15iap_29"
          role="button"
          tabindex="0"
        />
      </div>
    </div>
  </div>
  <div
    class="ReactModalPortal"
  />
</body>...
Failure screenshot:
  - apps/fishing-map/test/integration/__screenshots__/PrivateWorkspace.spec.tsx/PrivateWorkspace-should-not-be-able-to-navigate-to-the-private-workspace-if-not-authenticated-1.png
 ❯ test/integration/PrivateWorkspace.spec.tsx:18:67
     16|
     17|     await expect.element(getByText(/Workspace01/)).not.toBeInTheDocume…
     18|     await expect.element(getByText(/This is a private workspace/)).toB…
       |                                                                   ^
     19|   })
     20|
Caused by: Error: Matcher did not succeed in time.
 ❯ test/integration/PrivateWorkspace.spec.tsx:18:4
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[8/42]⎯
 FAIL   fishing-map-chromium  test/integration/PrivateWorkspace.spec.tsx > PrivateWorkspace > should be able to navigate to the private workspace if authenticated
VitestBrowserElementError: Cannot find element with locator: page.getByText(/Workspace01/)
<body>
  
  

  <div
    id="__root__"
  >
    <a
      class="print-only"
      href="https://globalfishingwatch.org"
    >
      <svg
        aria-label="Global Fishing Watch "
        class="_container_13m0y_1"
        height="60"
        viewBox="20 0 220 60"
        width="200"
        xmlns="http://www.w3.org/2000/svg"
      >
        <g
          aria-hidden="true"
          fill="none"
          fill-rule="evenodd"
          focusable="false"
        >
          <path
            d="M23.1 27.83c-.08.16-2.25 4.5.57 8.76.83 1.25 1.76 2.24 4.1 3.8 3.38 2.26 7.42 6.16 8.4 8.45.1.21.36.59-.06.83-.73.41-1.75.31-2.16.25l-.12-.02c-4.75-.88-14.5-5-13.8-13.8.18-2.21.98-4.87 3.07-8.27zm9.92-8.64c.7-.08 2.98-.15 3.08.08.07.17-.83.5-.87.52-5.22 1.98-6.97 3.16-7.22 3.3-3.3 2.01-4.71 4.35-4.82 4.57 1.48-3.1 5.2-7.93 9.83-8.47z"
            fill="#8ABBC7"
          />
          <path
            d="M40.45 19.2l.64 1.16a17.1 17.1 0 011.52 3.94c.27 1.1.39 2.23.31 3.37a9.39 9.39 0 01-1.72 4.84 12.9 12.9 0 01-3.29 3.2 20.3 20.3 0 01-7.02 3.08c-.4.09-.8.16-1.2.19a3.39 3.39 0 01-1.3-.17c-.43-.17-.5-.43-.28-.83a13.43 13.43 0 012.53-3.4 35.39 35.39 0 015.48-4.56c.76-.53 1.5-1.06 2.15-1.7a8.5 8.5 0 002.55-4.63 8.37 8.37 0 00-.24-3.89l-.18-.59.05-.02zm.64 16.43c.5.03.64.28.4.72-.35.64-.9 1.04-1.6 1.21-.68.16-1.35.13-2.02-.02-.42-.09-.83-.23-1.24-.35l-.11-.06.12-.08c1.02-.53 2.07-.97 3.19-1.26.4-.1.83-.18 1.26-.16zM30.73 10.07c.92.2 1.75.61 2.54 1.11.87.56 1.65 1.21 2.4 1.92a29.78 29.78 0 014.2 5.18l.01.07-.18-.16a14.79 14.79 0 00-3.6-2.45c-1.01-.5-2.06-.9-3.11-1.3-.58-.23-1.16-.44-1.7-.75a1.82 1.82 0 01-.75-.76c-.15-.32-.07-.6.23-.78l.35-.18c-.28-.14-.53-.24-.75-.38-.2-.13-.38-.29-.55-.45a.77.77 0 01-.21-.64c.02-.24.13-.38.35-.46.26-.08.52-.03.77.03z"
            fill="#E84427"
          />
          <text
            class="_mainBrand_13m0y_5 _default_13m0y_10"
            x="52"
            y="37"
          >
            Global Fishing Watch
          </text>
        </g>
      </svg>
    </a>
    <div
      class="_appLayout_d89r9_1"
    >
      <div
        class="_appLayoutContent_d89r9_8"
        id="app-layout-content"
      >
        <div
          class="_container_1gfa5_1 _isOpen_1gfa5_19 _splitContainer_d89r9_66"
        >
          <aside
            class="_aside_1gfa5_8 _aside_d89r9_77"
            style="width: 40rem;"
          >
            <button
              aria-label="Toggle sidebar"
              class="print-hidden _toggleBtn_1gfa5_48"
            >
              <svg … />
            </button>
            <div
              class="_container_10gdv_1"
            >
              <div … />
              <ul … />
            </div>
          </aside>
          <main
            class="_main_1gfa5_23 _main_d89r9_16"
            data-testid="app-main"
            id="app-main"
            style="left: 40rem;"
          >
            <div
              class="_mapContainer_d89r9_22"
            />
            <footer
              class="print-hidden _footer_1k9s3_1"
            >
              <div … />
              <span … />
            </footer>
          </main>
        </div>
        <section
          aria-atomic="false"
          aria-label="Notifications Alt+T"
          aria-live="polite"
          aria-relevant="additions text"
          class="Toastify"
        />
        <div
          class="ReactModalPortal"
        />
        <div
          class="ReactModalPortal"
        />
        <div
          class="ReactModalPortal"
        />
        <div
          class="ReactModalPortal"
        />
      </div>
      <div
        class="_panel_15iap_1 _hidden_15iap_12"
        style="width: 540px; --panel-width: 540px;"
      >
        <div
          class="_panelResizer_15iap_29"
          role="button"
          tabindex="0"
        />
      </div>
    </div>
  </div>
  <div
    class="ReactModalPortal"
  />
</body>...
Failure screenshot:
  - apps/fishing-map/test/integration/__screenshots__/PrivateWorkspace.spec.tsx/PrivateWorkspace-should-be-able-to-navigate-to-the-private-workspace-if-authenticated-1.png
 ❯ test/integration/PrivateWorkspace.spec.tsx:27:51
     25|     await router.navigate(navigateToWorkspace01())
     26|
     27|     await expect.element(getByText(/Workspace01/)).toBeVisible()
       |                                                   ^
     28|   })
     29|
Caused by: Error: Matcher did not succeed in time.
 ❯ test/integration/PrivateWorkspace.spec.tsx:27:4
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[9/42]⎯
 FAIL   fishing-map-chromium  test/integration/PrivateWorkspace.spec.tsx > PrivateWorkspace > should be able to navigate to a password-protected workspace if correct password is used
VitestBrowserElementError: Cannot find element with locator: page.getByTestId('create-workspace-password')
<body>
  
  

  <div
    id="__root__"
  >
    <a
      class="print-only"
      href="https://globalfishingwatch.org"
    >
      <svg
        aria-label="Global Fishing Watch "
        class="_container_13m0y_1"
        height="60"
        viewBox="20 0 220 60"
        width="200"
        xmlns="http://www.w3.org/2000/svg"
      >
        <g
          aria-hidden="true"
          fill="none"
          fill-rule="evenodd"
          focusable="false"
        >
          <path
            d="M23.1 27.83c-.08.16-2.25 4.5.57 8.76.83 1.25 1.76 2.24 4.1 3.8 3.38 2.26 7.42 6.16 8.4 8.45.1.21.36.59-.06.83-.73.41-1.75.31-2.16.25l-.12-.02c-4.75-.88-14.5-5-13.8-13.8.18-2.21.98-4.87 3.07-8.27zm9.92-8.64c.7-.08 2.98-.15 3.08.08.07.17-.83.5-.87.52-5.22 1.98-6.97 3.16-7.22 3.3-3.3 2.01-4.71 4.35-4.82 4.57 1.48-3.1 5.2-7.93 9.83-8.47z"
            fill="#8ABBC7"
          />
          <path
            d="M40.45 19.2l.64 1.16a17.1 17.1 0 011.52 3.94c.27 1.1.39 2.23.31 3.37a9.39 9.39 0 01-1.72 4.84 12.9 12.9 0 01-3.29 3.2 20.3 20.3 0 01-7.02 3.08c-.4.09-.8.16-1.2.19a3.39 3.39 0 01-1.3-.17c-.43-.17-.5-.43-.28-.83a13.43 13.43 0 012.53-3.4 35.39 35.39 0 015.48-4.56c.76-.53 1.5-1.06 2.15-1.7a8.5 8.5 0 002.55-4.63 8.37 8.37 0 00-.24-3.89l-.18-.59.05-.02zm.64 16.43c.5.03.64.28.4.72-.35.64-.9 1.04-1.6 1.21-.68.16-1.35.13-2.02-.02-.42-.09-.83-.23-1.24-.35l-.11-.06.12-.08c1.02-.53 2.07-.97 3.19-1.26.4-.1.83-.18 1.26-.16zM30.73 10.07c.92.2 1.75.61 2.54 1.11.87.56 1.65 1.21 2.4 1.92a29.78 29.78 0 014.2 5.18l.01.07-.18-.16a14.79 14.79 0 00-3.6-2.45c-1.01-.5-2.06-.9-3.11-1.3-.58-.23-1.16-.44-1.7-.75a1.82 1.82 0 01-.75-.76c-.15-.32-.07-.6.23-.78l.35-.18c-.28-.14-.53-.24-.75-.38-.2-.13-.38-.29-.55-.45a.77.77 0 01-.21-.64c.02-.24.13-.38.35-.46.26-.08.52-.03.77.03z"
            fill="#E84427"
          />
          <text
            class="_mainBrand_13m0y_5 _default_13m0y_10"
            x="52"
            y="37"
          >
            Global Fishing Watch
          </text>
        </g>
      </svg>
    </a>
    <div
      class="_appLayout_d89r9_1"
    >
      <div
        class="_appLayoutContent_d89r9_8"
        id="app-layout-content"
      >
        <div
          class="_container_1gfa5_1 _isOpen_1gfa5_19 _splitContainer_d89r9_66"
        >
          <aside
            class="_aside_1gfa5_8 _aside_d89r9_77"
            style="width: 40rem;"
          >
            <button
              aria-label="Toggle sidebar"
              class="print-hidden _toggleBtn_1gfa5_48"
            >
              <svg … />
            </button>
            <div
              class="_container_10gdv_1"
            >
              <div … />
              <ul … />
            </div>
          </aside>
          <main
            class="_main_1gfa5_23 _main_d89r9_16"
            data-testid="app-main"
            id="app-main"
            style="left: 40rem;"
          >
            <div
              class="_mapContainer_d89r9_22"
            />
            <footer
              class="print-hidden _footer_1k9s3_1"
            >
              <div … />
              <span … />
            </footer>
          </main>
        </div>
        <section
          aria-atomic="false"
          aria-label="Notifications Alt+T"
          aria-live="polite"
          aria-relevant="additions text"
          class="Toastify"
        />
        <div
          class="ReactModalPortal"
        />
        <div
          class="ReactModalPortal"
        />
        <div
          class="ReactModalPortal"
        />
        <div
          class="ReactModalPortal"
        />
      </div>
      <div
        class="_panel_15iap_1 _hidden_15iap_12"
        style="width: 540px; --panel-width: 540px;"
      >
        <div
          class="_panelResizer_15iap_29"
          role="button"
          tabindex="0"
        />
      </div>
    </div>
  </div>
  <div
    class="ReactModalPortal"
  />
</body>...
Failure screenshot:
  - apps/fishing-map/test/integration/__screenshots__/PrivateWorkspace.spec.tsx/PrivateWorkspace-should-be-able-to-navigate-to-a-password-protected-workspace-if-correct-password-is-used-1.png
 ❯ test/integration/PrivateWorkspace.spec.tsx:36:67
     34|     await router.navigate(navigateToWorkspace02())
     35|
     36|     await expect.element(getByTestId('create-workspace-password')).toB…
       |                                                                   ^
     37|
     38|     await userEvent.type(getByTestId('create-workspace-password'), 'te…
Caused by: Error: Matcher did not succeed in time.
 ❯ test/integration/PrivateWorkspace.spec.tsx:36:4
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[10/42]⎯
 FAIL   fishing-map-chromium  test/integration/PrivateWorkspace.spec.tsx > PrivateWorkspace > should not be able to navigate to a password-protected workspace if incorrect password is used
VitestBrowserElementError: Cannot find element with locator: page.getByTestId('create-workspace-password')
<body>
  
  

  <div
    id="__root__"
  >
    <a
      class="print-only"
      href="https://globalfishingwatch.org"
    >
      <svg
        aria-label="Global Fishing Watch "
        class="_container_13m0y_1"
        height="60"
        viewBox="20 0 220 60"
        width="200"
        xmlns="http://www.w3.org/2000/svg"
      >
        <g
          aria-hidden="true"
          fill="none"
          fill-rule="evenodd"
          focusable="false"
        >
          <path
            d="M23.1 27.83c-.08.16-2.25 4.5.57 8.76.83 1.25 1.76 2.24 4.1 3.8 3.38 2.26 7.42 6.16 8.4 8.45.1.21.36.59-.06.83-.73.41-1.75.31-2.16.25l-.12-.02c-4.75-.88-14.5-5-13.8-13.8.18-2.21.98-4.87 3.07-8.27zm9.92-8.64c.7-.08 2.98-.15 3.08.08.07.17-.83.5-.87.52-5.22 1.98-6.97 3.16-7.22 3.3-3.3 2.01-4.71 4.35-4.82 4.57 1.48-3.1 5.2-7.93 9.83-8.47z"
            fill="#8ABBC7"
          />
          <path
            d="M40.45 19.2l.64 1.16a17.1 17.1 0 011.52 3.94c.27 1.1.39 2.23.31 3.37a9.39 9.39 0 01-1.72 4.84 12.9 12.9 0 01-3.29 3.2 20.3 20.3 0 01-7.02 3.08c-.4.09-.8.16-1.2.19a3.39 3.39 0 01-1.3-.17c-.43-.17-.5-.43-.28-.83a13.43 13.43 0 012.53-3.4 35.39 35.39 0 015.48-4.56c.76-.53 1.5-1.06 2.15-1.7a8.5 8.5 0 002.55-4.63 8.37 8.37 0 00-.24-3.89l-.18-.59.05-.02zm.64 16.43c.5.03.64.28.4.72-.35.64-.9 1.04-1.6 1.21-.68.16-1.35.13-2.02-.02-.42-.09-.83-.23-1.24-.35l-.11-.06.12-.08c1.02-.53 2.07-.97 3.19-1.26.4-.1.83-.18 1.26-.16zM30.73 10.07c.92.2 1.75.61 2.54 1.11.87.56 1.65 1.21 2.4 1.92a29.78 29.78 0 014.2 5.18l.01.07-.18-.16a14.79 14.79 0 00-3.6-2.45c-1.01-.5-2.06-.9-3.11-1.3-.58-.23-1.16-.44-1.7-.75a1.82 1.82 0 01-.75-.76c-.15-.32-.07-.6.23-.78l.35-.18c-.28-.14-.53-.24-.75-.38-.2-.13-.38-.29-.55-.45a.77.77 0 01-.21-.64c.02-.24.13-.38.35-.46.26-.08.52-.03.77.03z"
            fill="#E84427"
          />
          <text
            class="_mainBrand_13m0y_5 _default_13m0y_10"
            x="52"
            y="37"
          >
            Global Fishing Watch
          </text>
        </g>
      </svg>
    </a>
    <div
      class="_appLayout_d89r9_1"
    >
      <div
        class="_appLayoutContent_d89r9_8"
        id="app-layout-content"
      >
        <div
          class="_container_1gfa5_1 _isOpen_1gfa5_19 _splitContainer_d89r9_66"
        >
          <aside
            class="_aside_1gfa5_8 _aside_d89r9_77"
            style="width: 40rem;"
          >
            <button
              aria-label="Toggle sidebar"
              class="print-hidden _toggleBtn_1gfa5_48"
            >
              <svg … />
            </button>
            <div
              class="_container_10gdv_1"
            >
              <div … />
              <ul … />
            </div>
          </aside>
          <main
            class="_main_1gfa5_23 _main_d89r9_16"
            data-testid="app-main"
            id="app-main"
            style="left: 40rem;"
          >
            <div
              class="_mapContainer_d89r9_22"
            />
            <footer
              class="print-hidden _footer_1k9s3_1"
            >
              <div … />
              <span … />
            </footer>
          </main>
        </div>
        <section
          aria-atomic="false"
          aria-label="Notifications Alt+T"
          aria-live="polite"
          aria-relevant="additions text"
          class="Toastify"
        />
        <div
          class="ReactModalPortal"
        />
        <div
          class="ReactModalPortal"
        />
        <div
          class="ReactModalPortal"
        />
        <div
          class="ReactModalPortal"
        />
      </div>
      <div
        class="_panel_15iap_1 _hidden_15iap_12"
        style="width: 540px; --panel-width: 540px;"
      >
        <div
          class="_panelResizer_15iap_29"
          role="button"
          tabindex="0"
        />
      </div>
    </div>
  </div>
  <div
    class="ReactModalPortal"
  />
</body>...
Failure screenshot:
  - apps/fishing-map/test/integration/__screenshots__/PrivateWorkspace.spec.tsx/PrivateWorkspace-should-not-be-able-to-navigate-to-a-password-protected-workspace-if-incorrect-password-is-used-1.png
 ❯ test/integration/PrivateWorkspace.spec.tsx:51:67
     49|     await router.navigate(navigateToWorkspace02())
     50|
     51|     await expect.element(getByTestId('create-workspace-password')).toB…
       |                                                                   ^
     52|
     53|     await userEvent.type(getByTestId('create-workspace-password'), 'wr…
Caused by: Error: Matcher did not succeed in time.
 ❯ test/integration/PrivateWorkspace.spec.tsx:51:4
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[11/42]⎯
 FAIL   fishing-map-chromium  test/integration/Reports.spec.tsx > Reports > should navigate to a report from eez
Error: Test timed out in 30000ms.
If this is a long-running test, pass a timeout value as the last argument or configure it globally with "testTimeout".
 ❯ test/integration/Reports.spec.tsx:130:2
    128|   })
    129|
    130|   it('should navigate to a report from eez', async () => {
       |  ^
    131|     const store = makeStore(defaultState)
    132|     const jotaiStore = createJotaiStore()
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[12/42]⎯
 FAIL   fishing-map-chromium  test/integration/Reports.spec.tsx > Reports > should show same report data at different zoom levels
TimeoutError: locator.click: Timeout -16ms exceeded.
Call log:
  - waiting for locator('[data-vitest="true"]').contentFrame().getByTestId('__vitest_0__').getByTestId('map-control-zoom-in')

Failure screenshot:
  - apps/fishing-map/test/integration/__screenshots__/Reports.spec.tsx/Reports-should-show-same-report-data-at-different-zoom-levels-1.png
 ❯ test/integration/Reports.spec.tsx:204:20
    202|     const initialReportData = jotaiStore.get(reportStateAtom)
    203|
    204|     await userEvent.click(getByTestId('map-control-zoom-in'))
       |                    ^
    205|     const zoomedReportData = jotaiStore.get(reportStateAtom)
    206|     expect(zoomedReportData).toEqual(initialReportData)
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[13/42]⎯
 FAIL   fishing-map-chromium  test/integration/Reports.spec.tsx > Reports > should update report data when timebar changes
Error: Test timed out in 30000ms.
If this is a long-running test, pass a timeout value as the last argument or configure it globally with "testTimeout".
Failure screenshot:
  - apps/fishing-map/test/integration/__screenshots__/Reports.spec.tsx/Reports-should-update-report-data-when-timebar-changes-1.png
 ❯ test/integration/Reports.spec.tsx:209:2
    207|   })
    208|
    209|   it('should update report data when timebar changes', async () => {
       |  ^
    210|     const store = makeStore(defaultState)
    211|     const jotaiStore = createJotaiStore()
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[14/42]⎯
 FAIL   fishing-map-chromium  test/integration/Reports.spec.tsx > Reports > should update report data when filter changes
Error: Test timed out in 30000ms.
If this is a long-running test, pass a timeout value as the last argument or configure it globally with "testTimeout".
Failure screenshot:
  - apps/fishing-map/test/integration/__screenshots__/Reports.spec.tsx/Reports-should-update-report-data-when-filter-changes-1.png
 ❯ test/integration/Reports.spec.tsx:242:2
    240|   })
    241|
    242|   it('should update report data when filter changes', async () => {
       |  ^
    243|     const store = makeStore(defaultState)
    244|     const jotaiStore = createJotaiStore()
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[15/42]⎯
 FAIL   fishing-map-chromium  test/integration/Reports.spec.tsx > Reports > should add new subcategory option when new layer is added from layer library
Error: Test timed out in 30000ms.
If this is a long-running test, pass a timeout value as the last argument or configure it globally with "testTimeout".
Failure screenshot:
  - apps/fishing-map/test/integration/__screenshots__/Reports.spec.tsx/Reports-should-add-new-subcategory-option-when-new-layer-is-added-from-layer-library-1.png
 ❯ test/integration/Reports.spec.tsx:289:2
    287|   })
    288|
    289|   it('should add new subcategory option when new layer is added from l…
       |  ^
    290|     const store = makeStore(defaultState)
    291|     const jotaiStore = createJotaiStore()
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[16/42]⎯
 FAIL   fishing-map-chromium  test/integration/Reports.spec.tsx > Global reports > should display the same number in the graph as in the timeseries
VitestBrowserElementError: Cannot find element with locator: page.getByTestId('evolution-timeseries-chart')
<body
  class=""
>
  
  

  <span
    aria-hidden="true"
    id="recharts_measurement_span"
    style="position: absolute; top: -20000px; left: 0px; padding: 0px; margin: 0px; border-width: medium; border-style: none; border-color: currentcolor; border-image: initial; white-space: pre; font-size: 12px; letter-spacing: normal;"
  >
    20
  </span>
  <div
    id="__root__"
  >
    <a
      class="print-only"
      href="https://globalfishingwatch.org"
    >
      <svg
        aria-label="Global Fishing Watch "
        class="_container_13m0y_1"
        height="60"
        viewBox="20 0 220 60"
        width="200"
        xmlns="http://www.w3.org/2000/svg"
      >
        <g
          aria-hidden="true"
          fill="none"
          fill-rule="evenodd"
          focusable="false"
        >
          <path
            d="M23.1 27.83c-.08.16-2.25 4.5.57 8.76.83 1.25 1.76 2.24 4.1 3.8 3.38 2.26 7.42 6.16 8.4 8.45.1.21.36.59-.06.83-.73.41-1.75.31-2.16.25l-.12-.02c-4.75-.88-14.5-5-13.8-13.8.18-2.21.98-4.87 3.07-8.27zm9.92-8.64c.7-.08 2.98-.15 3.08.08.07.17-.83.5-.87.52-5.22 1.98-6.97 3.16-7.22 3.3-3.3 2.01-4.71 4.35-4.82 4.57 1.48-3.1 5.2-7.93 9.83-8.47z"
            fill="#8ABBC7"
          />
          <path
            d="M40.45 19.2l.64 1.16a17.1 17.1 0 011.52 3.94c.27 1.1.39 2.23.31 3.37a9.39 9.39 0 01-1.72 4.84 12.9 12.9 0 01-3.29 3.2 20.3 20.3 0 01-7.02 3.08c-.4.09-.8.16-1.2.19a3.39 3.39 0 01-1.3-.17c-.43-.17-.5-.43-.28-.83a13.43 13.43 0 012.53-3.4 35.39 35.39 0 015.48-4.56c.76-.53 1.5-1.06 2.15-1.7a8.5 8.5 0 002.55-4.63 8.37 8.37 0 00-.24-3.89l-.18-.59.05-.02zm.64 16.43c.5.03.64.28.4.72-.35.64-.9 1.04-1.6 1.21-.68.16-1.35.13-2.02-.02-.42-.09-.83-.23-1.24-.35l-.11-.06.12-.08c1.02-.53 2.07-.97 3.19-1.26.4-.1.83-.18 1.26-.16zM30.73 10.07c.92.2 1.75.61 2.54 1.11.87.56 1.65 1.21 2.4 1.92a29.78 29.78 0 014.2 5.18l.01.07-.18-.16a14.79 14.79 0 00-3.6-2.45c-1.01-.5-2.06-.9-3.11-1.3-.58-.23-1.16-.44-1.7-.75a1.82 1.82 0 01-.75-.76c-.15-.32-.07-.6.23-.78l.35-.18c-.28-.14-.53-.24-.75-.38-.2-.13-.38-.29-.55-.45a.77.77 0 01-.21-.64c.02-.24.13-.38.35-.46.26-.08.52-.03.77.03z"
            fill="#E84427"
          />
          <text
            class="_mainBrand_13m0y_5 _default_13m0y_10"
            x="52"
            y="37"
          >
            Global Fishing Watch
          </text>
        </g>
      </svg>
    </a>
    <div
      class="_appLayout_d89r9_1"
    >
      <div
        class="_appLayoutContent_d89r9_8"
        id="app-layout-content"
      >
        <div
          class="_container_1gfa5_1 _isOpen_1gfa5_19 _splitContainer_d89r9_66"
        >
          <aside
            class="_aside_1gfa5_8 _aside_d89r9_77"
            style="width: 50%;"
          >
            <div
              aria-label="Resize sidebar"
              class="_resizer_1gfa5_32 print-hidden"
              role="button"
              tabindex="0"
            />
            <div
              class="_container_10gdv_1"
            >
              <div … />
              <ul … />
            </div>
          </aside>
          <main
            class="_main_1gfa5_23 _main_d89r9_16"
            data-testid="app-main"
            id="app-main"
            style="left: 50%;"
          >
            <div
              class="_mapContainer_d89r9_22 _withTimebar_d89r9_33"
            >
              <div … />
            </div>
            <div
              class="_timebarWrapper_1pma8_1"
              data-testid="timebar-wrapper"
              role="toolbar"
            >
              <div … />
              <div … />
            </div>
            <footer
              class="print-hidden _footer_1k9s3_1"
            >
              <div … />
              <span … />
            </footer>
          </main>
        </div>
        <section
          aria-atomic="false"
          aria-label="Notifications Alt+T"
          aria-live="polite"
          aria-relevant="additions text"
          class="Toastify"
        />
        <div
          class="ReactModalPortal"
        />
        <div
          class="ReactModalPortal"
        />
        <div
          class="ReactModalPortal"
        />
        <div
          class="ReactModalPortal"
        />
        <div
          class="ReactModalPortal"
        />
      </div>
      <div
        class="_panel_15iap_1 _hidden_15iap_12"
        style="width: 540px; --panel-width: 540px;"
      >
        <div
          class="_panelResizer_15iap_29"
          role="button"
          tabindex="0"
        />
      </div>
    </div>
  </div>
  <div
    class="ReactModalPortal"
  />
</body>...
Failure screenshot:
  - apps/fishing-map/test/integration/__screenshots__/Reports.spec.tsx/Global-reports-should-display-the-same-number-in-the-graph-as-in-the-timeseries-1.png
 ❯ test/integration/Reports.spec.tsx:379:68
    377|     expect(statsData).toBeDefined()
    378|     const latestStatsData = (await waitForStatsQueryLoaded(store))?.da…
    379|     await expect.element(getByTestId('evolution-timeseries-chart')).to…
       |                                                                    ^
    380|     const timeseries = latestStatsData?.[0]?.timeseries
    381|     if (!timeseries?.length) {
Caused by: Error: Matcher did not succeed in time.
 ❯ test/integration/Reports.spec.tsx:379:4
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[17/42]⎯
 FAIL   fishing-map-chromium  test/integration/Reports.spec.tsx > Global reports > should show detections in detections tab
Error: Test timed out in 30000ms.
If this is a long-running test, pass a timeout value as the last argument or configure it globally with "testTimeout".
Failure screenshot:
  - apps/fishing-map/test/integration/__screenshots__/Reports.spec.tsx/Global-reports-should-show-detections-in-detections-tab-1.png
 ❯ test/integration/Reports.spec.tsx:445:2
    443|   })
    444|
    445|   it('should show detections in detections tab', async () => {
       |  ^
    446|     const store = makeStore(defaultState)
    447|     const jotaiStore = createJotaiStore()
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[18/42]⎯
 FAIL   fishing-map-chromium  test/integration/Reports.spec.tsx > Private user reports > should show user reports when user is logged in
AssertionError: expected 'idle' to be 'finished' // Object.is equality
Failure screenshot:
  - apps/fishing-map/test/integration/__screenshots__/Reports.spec.tsx/Private-user-reports-should-show-user-reports-when-user-is-logged-in-1.png
Expected: "finished"
Received: "idle"
 ❯ waitForUserReportsReady test/integration/Reports.spec.tsx:59:5
     57|   await expect
     58|     .poll(() => store.getState().reports.status, { timeout })
     59|     .toBe(AsyncReducerStatus.Finished)
       |     ^
     60| }
     61|
 ❯ test/integration/Reports.spec.tsx:491:10
Caused by: Error: Matcher did not succeed in time.
 ❯ waitForUserReportsReady test/integration/Reports.spec.tsx:57:2
 ❯ test/integration/Reports.spec.tsx:491:4
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[19/42]⎯
 FAIL   fishing-map-chromium  test/integration/Reports.spec.tsx > Private user reports > should correctly display others points reports data
AssertionError: expected 'idle' to be 'finished' // Object.is equality
Failure screenshot:
  - apps/fishing-map/test/integration/__screenshots__/Reports.spec.tsx/Private-user-reports-should-correctly-display-others-points-reports-data-1.png
Expected: "finished"
Received: "idle"
 ❯ waitForUserReportsReady test/integration/Reports.spec.tsx:59:5
     57|   await expect
     58|     .poll(() => store.getState().reports.status, { timeout })
     59|     .toBe(AsyncReducerStatus.Finished)
       |     ^
     60| }
     61|
 ❯ test/integration/Reports.spec.tsx:516:10
Caused by: Error: Matcher did not succeed in time.
 ❯ waitForUserReportsReady test/integration/Reports.spec.tsx:57:2
 ❯ test/integration/Reports.spec.tsx:516:4
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[20/42]⎯
 FAIL   fishing-map-chromium  test/integration/Reports.spec.tsx > Data Comparison > should show second selector when choose data comparison mode
Error: Test timed out in 30000ms.
If this is a long-running test, pass a timeout value as the last argument or configure it globally with "testTimeout".
Failure screenshot:
  - apps/fishing-map/test/integration/__screenshots__/Reports.spec.tsx/Data-Comparison-should-show-second-selector-when-choose-data-comparison-mode-1.png
 ❯ test/integration/Reports.spec.tsx:544:2
    542|
    543| describe('Data Comparison', () => {
    544|   it('should show second selector when choose data comparison mode', a…
       |  ^
    545|     const store = makeStore(defaultState)
    546|     const jotaiStore = createJotaiStore()
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[21/42]⎯
 FAIL   fishing-map-chromium  test/integration/Reports.spec.tsx > Data Comparison > should show both dataviews in graph when compared data is selected
Error: Test timed out in 30000ms.
If this is a long-running test, pass a timeout value as the last argument or configure it globally with "testTimeout".
 ❯ test/integration/Reports.spec.tsx:590:2
    588|   })
    589|
    590|   it('should show both dataviews in graph when compared data is select…
       |  ^
    591|     const store = makeStore(defaultState)
    592|     const jotaiStore = createJotaiStore()
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[22/42]⎯
 FAIL   fishing-map-chromium  test/integration/User.spec.tsx > User expiration > should show expired session warning toast
VitestBrowserElementError: Cannot find element with locator: page.getByText(/Your session has expired/i)
<body>
  
  

  <div
    id="__root__"
  >
    <a
      class="print-only"
      href="https://globalfishingwatch.org"
    >
      <svg
        aria-label="Global Fishing Watch "
        class="_container_13m0y_1"
        height="60"
        viewBox="20 0 220 60"
        width="200"
        xmlns="http://www.w3.org/2000/svg"
      >
        <g
          aria-hidden="true"
          fill="none"
          fill-rule="evenodd"
          focusable="false"
        >
          <path
            d="M23.1 27.83c-.08.16-2.25 4.5.57 8.76.83 1.25 1.76 2.24 4.1 3.8 3.38 2.26 7.42 6.16 8.4 8.45.1.21.36.59-.06.83-.73.41-1.75.31-2.16.25l-.12-.02c-4.75-.88-14.5-5-13.8-13.8.18-2.21.98-4.87 3.07-8.27zm9.92-8.64c.7-.08 2.98-.15 3.08.08.07.17-.83.5-.87.52-5.22 1.98-6.97 3.16-7.22 3.3-3.3 2.01-4.71 4.35-4.82 4.57 1.48-3.1 5.2-7.93 9.83-8.47z"
            fill="#8ABBC7"
          />
          <path
            d="M40.45 19.2l.64 1.16a17.1 17.1 0 011.52 3.94c.27 1.1.39 2.23.31 3.37a9.39 9.39 0 01-1.72 4.84 12.9 12.9 0 01-3.29 3.2 20.3 20.3 0 01-7.02 3.08c-.4.09-.8.16-1.2.19a3.39 3.39 0 01-1.3-.17c-.43-.17-.5-.43-.28-.83a13.43 13.43 0 012.53-3.4 35.39 35.39 0 015.48-4.56c.76-.53 1.5-1.06 2.15-1.7a8.5 8.5 0 002.55-4.63 8.37 8.37 0 00-.24-3.89l-.18-.59.05-.02zm.64 16.43c.5.03.64.28.4.72-.35.64-.9 1.04-1.6 1.21-.68.16-1.35.13-2.02-.02-.42-.09-.83-.23-1.24-.35l-.11-.06.12-.08c1.02-.53 2.07-.97 3.19-1.26.4-.1.83-.18 1.26-.16zM30.73 10.07c.92.2 1.75.61 2.54 1.11.87.56 1.65 1.21 2.4 1.92a29.78 29.78 0 014.2 5.18l.01.07-.18-.16a14.79 14.79 0 00-3.6-2.45c-1.01-.5-2.06-.9-3.11-1.3-.58-.23-1.16-.44-1.7-.75a1.82 1.82 0 01-.75-.76c-.15-.32-.07-.6.23-.78l.35-.18c-.28-.14-.53-.24-.75-.38-.2-.13-.38-.29-.55-.45a.77.77 0 01-.21-.64c.02-.24.13-.38.35-.46.26-.08.52-.03.77.03z"
            fill="#E84427"
          />
          <text
            class="_mainBrand_13m0y_5 _default_13m0y_10"
            x="52"
            y="37"
          >
            Global Fishing Watch
          </text>
        </g>
      </svg>
    </a>
    <div
      class="_appLayout_d89r9_1"
    >
      <div
        class="_appLayoutContent_d89r9_8"
        id="app-layout-content"
      >
        <div
          class="_container_1gfa5_1 _isOpen_1gfa5_19 _splitContainer_d89r9_66"
        >
          <aside
            class="_aside_1gfa5_8 _aside_d89r9_77"
            style="width: 40rem;"
          >
            <button
              aria-label="Toggle sidebar"
              class="print-hidden _toggleBtn_1gfa5_48"
            >
              <svg … />
            </button>
            <div
              class="_container_10gdv_1"
            >
              <div … />
              <ul … />
            </div>
          </aside>
          <main
            class="_main_1gfa5_23 _main_d89r9_16"
            data-testid="app-main"
            id="app-main"
            style="left: 40rem;"
          >
            <div
              class="_mapContainer_d89r9_22 _withTimebar_d89r9_33"
            >
              <div … />
            </div>
            <div
              class="_timebarWrapper_1pma8_1"
              data-testid="timebar-wrapper"
              role="toolbar"
            >
              <div … />
              <div … />
            </div>
            <footer
              class="print-hidden _footer_1k9s3_1"
            >
              <div … />
              <span … />
            </footer>
          </main>
        </div>
        <section
          aria-atomic="false"
          aria-label="Notifications Alt+T"
          aria-live="polite"
          aria-relevant="additions text"
          class="Toastify"
        />
        <div
          class="ReactModalPortal"
        />
        <div
          class="ReactModalPortal"
        />
        <div
          class="ReactModalPortal"
        />
        <div
          class="ReactModalPortal"
        />
        <div
          class="ReactModalPortal"
        />
      </div>
      <div
        class="_panel_15iap_1 _hidden_15iap_12"
        style="width: 540px; --panel-width: 540px;"
      >
        <div
          class="_panelResizer_15iap_29"
          role="button"
          tabindex="0"
        />
      </div>
    </div>
  </div>
  <div
    class="ReactModalPortal"
  />
</body>...
Failure screenshot:
  - apps/fishing-map/test/integration/__screenshots__/User.spec.tsx/User-expiration-should-show-expired-session-warning-toast-1.png
 ❯ test/integration/User.spec.tsx:19:65
     17|     const { getByText, getByTestId } = await render({ store })
     18|
     19|     await expect.element(getByText(/Your session has expired/i)).toBeV…
       |                                                                 ^
     20|     await expect.element(getByTestId('login-link').first()).toBeVisibl…
     21|   })
Caused by: Error: Matcher did not succeed in time.
 ❯ test/integration/User.spec.tsx:19:4
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[23/42]⎯
 FAIL   fishing-map-chromium  test/integration/VesselSearch.spec.tsx > Vessel search > can search for a vessel and see it on the map
TimeoutError: locator.click: Timeout 26886ms exceeded.
Call log:
  - waiting for locator('[data-vitest="true"]').contentFrame().getByTestId('__vitest_0__').getByTestId('link-vessel-profile')

Failure screenshot:
  - apps/fishing-map/test/integration/__screenshots__/VesselSearch.spec.tsx/Vessel-search-can-search-for-a-vessel-and-see-it-on-the-map-1.png
 ❯ test/integration/VesselSearch.spec.tsx:28:20
     26|
     27|     await userEvent.type(getByTestId('search-vessels-basic-input'), 'G…
     28|     await userEvent.click(getByTestId('link-vessel-profile'))
       |                    ^
     29|
     30|     await waitForVesselTrackReady(jotaiStore, getByTestId)
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[24/42]⎯
 FAIL   fishing-map-chromium  test/integration/VesselSearch.spec.tsx > Vessel search > preserves vessel search value when navigating away and back
AssertionError: expected undefined to be 'Gabu Reefer' // Object.is equality
Failure screenshot:
  - apps/fishing-map/test/integration/__screenshots__/VesselSearch.spec.tsx/Vessel-search-preserves-vessel-search-value-when-navigating-away-and-back-1.png
- Expected:
"Gabu Reefer"
+ Received:
undefined
 ❯ test/integration/VesselSearch.spec.tsx:53:7
     51|     await expect
     52|       .poll(() => store.getState().location.query.query, { timeout: 50…
     53|       .toBe('Gabu Reefer')
       |       ^
     54|     await router.navigate({
     55|       to: ROUTE_PATHS.WORKSPACE,
Caused by: Error: Matcher did not succeed in time.
 ❯ test/integration/VesselSearch.spec.tsx:51:4
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[25/42]⎯
 FAIL   fishing-map-chromium  test/integration/VesselSearch.spec.tsx > Vessel search > reacts to clearing the search input
VitestBrowserElementError: Cannot find element with locator: page.getByTestId('link-vessel-profile')
<body>
  
  

  <div
    id="__root__"
  >
    <a
      class="print-only"
      href="https://globalfishingwatch.org"
    >
      <svg
        aria-label="Global Fishing Watch "
        class="_container_13m0y_1"
        height="60"
        viewBox="20 0 220 60"
        width="200"
        xmlns="http://www.w3.org/2000/svg"
      >
        <g
          aria-hidden="true"
          fill="none"
          fill-rule="evenodd"
          focusable="false"
        >
          <path
            d="M23.1 27.83c-.08.16-2.25 4.5.57 8.76.83 1.25 1.76 2.24 4.1 3.8 3.38 2.26 7.42 6.16 8.4 8.45.1.21.36.59-.06.83-.73.41-1.75.31-2.16.25l-.12-.02c-4.75-.88-14.5-5-13.8-13.8.18-2.21.98-4.87 3.07-8.27zm9.92-8.64c.7-.08 2.98-.15 3.08.08.07.17-.83.5-.87.52-5.22 1.98-6.97 3.16-7.22 3.3-3.3 2.01-4.71 4.35-4.82 4.57 1.48-3.1 5.2-7.93 9.83-8.47z"
            fill="#8ABBC7"
          />
          <path
            d="M40.45 19.2l.64 1.16a17.1 17.1 0 011.52 3.94c.27 1.1.39 2.23.31 3.37a9.39 9.39 0 01-1.72 4.84 12.9 12.9 0 01-3.29 3.2 20.3 20.3 0 01-7.02 3.08c-.4.09-.8.16-1.2.19a3.39 3.39 0 01-1.3-.17c-.43-.17-.5-.43-.28-.83a13.43 13.43 0 012.53-3.4 35.39 35.39 0 015.48-4.56c.76-.53 1.5-1.06 2.15-1.7a8.5 8.5 0 002.55-4.63 8.37 8.37 0 00-.24-3.89l-.18-.59.05-.02zm.64 16.43c.5.03.64.28.4.72-.35.64-.9 1.04-1.6 1.21-.68.16-1.35.13-2.02-.02-.42-.09-.83-.23-1.24-.35l-.11-.06.12-.08c1.02-.53 2.07-.97 3.19-1.26.4-.1.83-.18 1.26-.16zM30.73 10.07c.92.2 1.75.61 2.54 1.11.87.56 1.65 1.21 2.4 1.92a29.78 29.78 0 014.2 5.18l.01.07-.18-.16a14.79 14.79 0 00-3.6-2.45c-1.01-.5-2.06-.9-3.11-1.3-.58-.23-1.16-.44-1.7-.75a1.82 1.82 0 01-.75-.76c-.15-.32-.07-.6.23-.78l.35-.18c-.28-.14-.53-.24-.75-.38-.2-.13-.38-.29-.55-.45a.77.77 0 01-.21-.64c.02-.24.13-.38.35-.46.26-.08.52-.03.77.03z"
            fill="#E84427"
          />
          <text
            class="_mainBrand_13m0y_5 _default_13m0y_10"
            x="52"
            y="37"
          >
            Global Fishing Watch
          </text>
        </g>
      </svg>
    </a>
    <div
      class="_appLayout_d89r9_1"
    >
      <div
        class="_appLayoutContent_d89r9_8"
        id="app-layout-content"
      >
        <div
          class="_container_1gfa5_1 _isOpen_1gfa5_19 _splitContainer_d89r9_66"
        >
          <aside
            class="_aside_1gfa5_8 _aside_d89r9_77"
            style="width: 100%;"
          >
            <div
              class="_container_10gdv_1"
            >
              <div … />
              <ul … />
            </div>
          </aside>
          <main
            class="_main_1gfa5_23 _main_d89r9_16"
            data-testid="app-main"
            id="app-main"
            style="left: 100%;"
          >
            <div
              class="_mapContainer_d89r9_22"
            >
              <div … />
            </div>
            <footer
              class="print-hidden _footer_1k9s3_1"
            >
              <div … />
              <span … />
            </footer>
          </main>
        </div>
        <section
          aria-atomic="false"
          aria-label="Notifications Alt+T"
          aria-live="polite"
          aria-relevant="additions text"
          class="Toastify"
        />
        <div
          class="ReactModalPortal"
        />
        <div
          class="ReactModalPortal"
        />
        <div
          class="ReactModalPortal"
        />
        <div
          class="ReactModalPortal"
        />
      </div>
      <div
        class="_panel_15iap_1 _hidden_15iap_12"
        style="width: 540px; --panel-width: 540px;"
      >
        <div
          class="_panelResizer_15iap_29"
          role="button"
          tabindex="0"
        />
      </div>
    </div>
  </div>
  <div
    class="ReactModalPortal"
  />
</body>...
Failure screenshot:
  - apps/fishing-map/test/integration/__screenshots__/VesselSearch.spec.tsx/Vessel-search-reacts-to-clearing-the-search-input-1.png
 ❯ test/integration/VesselSearch.spec.tsx:81:61
     79|     await userEvent.type(searchVesselInput, 'Gabu Reefer')
     80|
     81|     await expect.element(getByTestId('link-vessel-profile')).toBeVisib…
       |                                                             ^
     82|
     83|     await userEvent.clear(searchVesselInput)
Caused by: Error: Matcher did not succeed in time.
 ❯ test/integration/VesselSearch.spec.tsx:81:4
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[26/42]⎯
 FAIL   fishing-map-chromium  test/integration/VesselViewer.spec.tsx > Vessel viewer > should renders tabs and vessel basic info
Error: expect(element).toHaveTextContent()
Expected element to have text content:
  Gabu Reefer
Received:
  GabureeferCheck the vessel profile here
Failure screenshot:
  - apps/fishing-map/test/integration/__screenshots__/VesselViewer.spec.tsx/Vessel-viewer-should-renders-tabs-and-vessel-basic-info-1.png
 ❯ test/integration/VesselViewer.spec.tsx:17:56
     15|     await router.navigate(navigateToVesselViewer())
     16|
     17|     await expect.element(getByTestId('vv-vessel-name')).toHaveTextCont…
       |                                                        ^
     18|     await expect.element(getByText('Registry', { exact: true })).toBeV…
     19|     await expect.element(getByText('AIS', { exact: true })).toBeVisibl…
Caused by: Error: Matcher did not succeed in time.
 ❯ test/integration/VesselViewer.spec.tsx:17:4
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[27/42]⎯
 FAIL   fishing-map-chromium  test/integration/VesselViewer.spec.tsx > Vessel viewer > should render summary tab by type
TimeoutError: locator.click: Timeout 27110ms exceeded.
Call log:
  - waiting for locator('[data-vitest="true"]').contentFrame().getByTestId('__vitest_0__').getByTestId('vv-summary-tab')

Failure screenshot:
  - apps/fishing-map/test/integration/__screenshots__/VesselViewer.spec.tsx/Vessel-viewer-should-render-summary-tab-by-type-1.png
 ❯ test/integration/VesselViewer.spec.tsx:88:20
     86|
     87|     await GFWAPITest.waitForRequest('/events')
     88|     await userEvent.click(getByTestId('vv-summary-tab'))
       |                    ^
     89|     await expect.element(getByTestId('vv-list-port_visit')).toBeVisibl…
     90|   })
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[28/42]⎯
 FAIL   fishing-map-chromium  test/integration/VesselViewer.spec.tsx > Vessel viewer > should render summary tab by timeline
TimeoutError: locator.click: Timeout 29175ms exceeded.
Call log:
  - waiting for locator('[data-vitest="true"]').contentFrame().getByTestId('__vitest_0__').getByRole('button').filter({ hasText: 'Timeline by voyages' })

Failure screenshot:
  - apps/fishing-map/test/integration/__screenshots__/VesselViewer.spec.tsx/Vessel-viewer-should-render-summary-tab-by-timeline-1.png
 ❯ test/integration/VesselViewer.spec.tsx:100:20
     98|
     99|     await GFWAPITest.waitForRequest('/events')
    100|     await userEvent.click(getByRole('button').filter({ hasText: 'Timel…
       |                    ^
    101|     await expect.element(getByText(/\d+ Events? between .+ and .+/).fi…
    102|   })
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[29/42]⎯
 FAIL   fishing-map-chromium  test/integration/VesselViewer.spec.tsx > Vessel viewer > should render areas tab and its tabs
TimeoutError: locator.click: Timeout 29224ms exceeded.
Call log:
  - waiting for locator('[data-vitest="true"]').contentFrame().getByTestId('__vitest_0__').getByTestId('vv-areas-tab')

Failure screenshot:
  - apps/fishing-map/test/integration/__screenshots__/VesselViewer.spec.tsx/Vessel-viewer-should-render-areas-tab-and-its-tabs-1.png
 ❯ test/integration/VesselViewer.spec.tsx:109:20
    107|     const { getByTestId, router } = await render({ store, authenticate…
    108|     await router.navigate(navigateToVesselViewer())
    109|     await userEvent.click(getByTestId('vv-areas-tab'))
       |                    ^
    110|
    111|     await expect.element(getByTestId('vv-area-eez')).toBeVisible()
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[30/42]⎯
 FAIL   fishing-map-chromium  test/integration/VesselViewer.spec.tsx > Vessel viewer > should render related vessels tab
TimeoutError: locator.click: Timeout 29224ms exceeded.
Call log:
  - waiting for locator('[data-vitest="true"]').contentFrame().getByTestId('__vitest_0__').getByTestId('vv-related-tab')

Failure screenshot:
  - apps/fishing-map/test/integration/__screenshots__/VesselViewer.spec.tsx/Vessel-viewer-should-render-related-vessels-tab-1.png
 ❯ test/integration/VesselViewer.spec.tsx:125:20
    123|     })
    124|     await router.navigate(navigateToVesselViewer())
    125|     await userEvent.click(getByTestId('vv-related-tab'))
       |                    ^
    126|
    127|     await expect
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[31/42]⎯
 FAIL   fishing-map-chromium  test/integration/VesselViewer.spec.tsx > Vessel viewer > should render insights tab
TimeoutError: locator.click: Timeout 29137ms exceeded.
Call log:
  - waiting for locator('[data-vitest="true"]').contentFrame().getByTestId('__vitest_0__').getByTestId('vv-insights-tab')

Failure screenshot:
  - apps/fishing-map/test/integration/__screenshots__/VesselViewer.spec.tsx/Vessel-viewer-should-render-insights-tab-1.png
 ❯ test/integration/VesselViewer.spec.tsx:140:20
    138|     const { getByTestId, getByText, router } = await render({ store, a…
    139|     await router.navigate(navigateToVesselViewer())
    140|     await userEvent.click(getByTestId('vv-insights-tab'))
       |                    ^
    141|
    142|     await expect
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[32/42]⎯
 FAIL   fishing-map-chromium  test/integration/Vessels.spec.tsx > Vessel map popup > should open vessel popup on vessel click and show tile related info
VitestBrowserElementError: Cannot find element with locator: page.getByTestId('map-popup-wrapper').getByText('Gabu Reefer')
<body>
  
  

  <div
    id="__root__"
  >
    <a
      class="print-only"
      href="https://globalfishingwatch.org"
    >
      <svg
        aria-label="Global Fishing Watch "
        class="_container_13m0y_1"
        height="60"
        viewBox="20 0 220 60"
        width="200"
        xmlns="http://www.w3.org/2000/svg"
      >
        <g
          aria-hidden="true"
          fill="none"
          fill-rule="evenodd"
          focusable="false"
        >
          <path
            d="M23.1 27.83c-.08.16-2.25 4.5.57 8.76.83 1.25 1.76 2.24 4.1 3.8 3.38 2.26 7.42 6.16 8.4 8.45.1.21.36.59-.06.83-.73.41-1.75.31-2.16.25l-.12-.02c-4.75-.88-14.5-5-13.8-13.8.18-2.21.98-4.87 3.07-8.27zm9.92-8.64c.7-.08 2.98-.15 3.08.08.07.17-.83.5-.87.52-5.22 1.98-6.97 3.16-7.22 3.3-3.3 2.01-4.71 4.35-4.82 4.57 1.48-3.1 5.2-7.93 9.83-8.47z"
            fill="#8ABBC7"
          />
          <path
            d="M40.45 19.2l.64 1.16a17.1 17.1 0 011.52 3.94c.27 1.1.39 2.23.31 3.37a9.39 9.39 0 01-1.72 4.84 12.9 12.9 0 01-3.29 3.2 20.3 20.3 0 01-7.02 3.08c-.4.09-.8.16-1.2.19a3.39 3.39 0 01-1.3-.17c-.43-.17-.5-.43-.28-.83a13.43 13.43 0 012.53-3.4 35.39 35.39 0 015.48-4.56c.76-.53 1.5-1.06 2.15-1.7a8.5 8.5 0 002.55-4.63 8.37 8.37 0 00-.24-3.89l-.18-.59.05-.02zm.64 16.43c.5.03.64.28.4.72-.35.64-.9 1.04-1.6 1.21-.68.16-1.35.13-2.02-.02-.42-.09-.83-.23-1.24-.35l-.11-.06.12-.08c1.02-.53 2.07-.97 3.19-1.26.4-.1.83-.18 1.26-.16zM30.73 10.07c.92.2 1.75.61 2.54 1.11.87.56 1.65 1.21 2.4 1.92a29.78 29.78 0 014.2 5.18l.01.07-.18-.16a14.79 14.79 0 00-3.6-2.45c-1.01-.5-2.06-.9-3.11-1.3-.58-.23-1.16-.44-1.7-.75a1.82 1.82 0 01-.75-.76c-.15-.32-.07-.6.23-.78l.35-.18c-.28-.14-.53-.24-.75-.38-.2-.13-.38-.29-.55-.45a.77.77 0 01-.21-.64c.02-.24.13-.38.35-.46.26-.08.52-.03.77.03z"
            fill="#E84427"
          />
          <text
            class="_mainBrand_13m0y_5 _default_13m0y_10"
            x="52"
            y="37"
          >
            Global Fishing Watch
          </text>
        </g>
      </svg>
    </a>
    <div
      class="_appLayout_d89r9_1"
    >
      <div
        class="_appLayoutContent_d89r9_8"
        id="app-layout-content"
      >
        <div
          class="_container_1gfa5_1 _isOpen_1gfa5_19 _splitContainer_d89r9_66"
        >
          <aside
            class="_aside_1gfa5_8 _aside_d89r9_77"
            style="width: 40rem;"
          >
            <button
              aria-label="Toggle sidebar"
              class="print-hidden _toggleBtn_1gfa5_48"
            >
              <svg … />
            </button>
            <div
              class="_container_10gdv_1"
            >
              <div … />
              <ul … />
            </div>
          </aside>
          <main
            class="_main_1gfa5_23 _main_d89r9_16"
            data-testid="app-main"
            id="app-main"
            style="left: 40rem;"
          >
            <div
              class="_mapContainer_d89r9_22 _withTimebar_d89r9_33"
            >
              <div … />
            </div>
            <div
              class="_timebarWrapper_1pma8_1"
              data-testid="timebar-wrapper"
              role="toolbar"
            >
              <div … />
              <div … />
            </div>
            <footer
              class="print-hidden _footer_1k9s3_1"
            >
              <div … />
              <span … />
            </footer>
          </main>
        </div>
        <section
          aria-atomic="false"
          aria-label="Notifications Alt+T"
          aria-live="polite"
          aria-relevant="additions text"
          class="Toastify"
        />
        <div
          class="ReactModalPortal"
        />
        <div
          class="ReactModalPortal"
        />
        <div
          class="ReactModalPortal"
        />
        <div
          class="ReactModalPortal"
        />
        <div
          class="ReactModalPortal"
        />
      </div>
      <div
        class="_panel_15iap_1 _hidden_15iap_12"
        style="width: 540px; --panel-width: 540px;"
      >
        <div
          class="_panelResizer_15iap_29"
          role="button"
          tabindex="0"
        />
      </div>
    </div>
  </div>
  <div
    class="ReactModalPortal"
  />
</body>...
Failure screenshot:
  - apps/fishing-map/test/integration/__screenshots__/Vessels.spec.tsx/Vessel-map-popup-should-open-vessel-popup-on-vessel-click-and-show-tile-related-info-1.png
 ❯ test/integration/Vessels.spec.tsx:50:60
     48|     await userEvent.click(mapElement, { position: { x, y } })
     49|
     50|     await expect.element(mapPopup.getByText('Gabu Reefer')).toBeVisibl…
       |                                                            ^
     51|     await expect.element(mapPopup.getByText(/Speed: [\d.]+ knots/)).to…
     52|     await expect.element(mapPopup.getByText(/Depth: -?[\d.]+ meters/))…
Caused by: Error: Matcher did not succeed in time.
 ❯ test/integration/Vessels.spec.tsx:50:4
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[33/42]⎯
 FAIL   fishing-map-chromium  test/integration/Vessels.spec.tsx > Vessel map popup > should be able to close an opened popup
Error: Test timed out in 30000ms.
If this is a long-running test, pass a timeout value as the last argument or configure it globally with "testTimeout".
 ❯ test/integration/Vessels.spec.tsx:55:2
     53|   })
     54|
     55|   it('should be able to close an opened popup', async () => {
       |  ^
     56|     const store = makeStore(defaultState, [])
     57|     const jotaiStore = createJotaiStore()
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[34/42]⎯
 FAIL   fishing-map-chromium  test/integration/Vessels.spec.tsx > Vessel map popup > should be able to navigate to vessel viewer inside the vessel popup
Error: Test timed out in 30000ms.
If this is a long-running test, pass a timeout value as the last argument or configure it globally with "testTimeout".
 ❯ test/integration/Vessels.spec.tsx:88:2
     86|   })
     87|
     88|   it('should be able to navigate to vessel viewer inside the vessel po…
       |  ^
     89|     const store = makeStore(defaultState, [])
     90|     const jotaiStore = createJotaiStore()
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[35/42]⎯
 FAIL   fishing-map-chromium  test/integration/Vessels.spec.tsx > Vessel map popup > should display the vessel track on the timebar
Error: Test timed out in 30000ms.
If this is a long-running test, pass a timeout value as the last argument or configure it globally with "testTimeout".
 ❯ test/integration/Vessels.spec.tsx:120:2
    118|   })
    119|
    120|   it('should display the vessel track on the timebar', async () => {
       |  ^
    121|     const GFWAPITest = new GFWAPITestUtils()
    122|     const store = makeStore(defaultState, [])
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[36/42]⎯
 FAIL   fishing-map-chromium  test/integration/Vessels.spec.tsx > Vessel map popup > should be able to see vessel info on hover and pin a vessel to the map to see it on the sidebar
AssertionError: expected undefined to strictly equal { dataviewInstances: [ …(4) ], …(5) }
Failure screenshot:
  - apps/fishing-map/test/integration/__screenshots__/Vessels.spec.tsx/Vessel-map-popup-should-be-able-to-see-vessel-info-on-hover-and-pin-a-vessel-to-the-map-to-see-it-on-the-sidebar-1.png
- Expected:
{
  "bivariateDataviews": null,
  "dataviewInstances": [
    {
      "config": {
        "color": "#F95E5E",
        "colorCyclingType": undefined,
        "events": [
          "public-global-fishing-events:v4.0",
          "public-global-port-visits-events:v4.0",
          "public-global-encounters-events:v4.0",
          "public-global-loitering-events:v4.0",
          "public-global-gaps-events:v4.0",
        ],
        "info": "public-global-vessel-identity:v4.0",
        "relatedVesselIds": [
          "19630081d-d249-9b1d-2b6d-46113987f976",
          "9126f54fd-d5b3-2c09-0552-abcceccd10ff",
        ],
        "track": "public-global-all-tracks:v4.0",
      },
      "dataviewId": "fishing-map-vessel-track-v-4",
      "deleted": false,
      "id": "vessel-9375434a0-0b91-7247-5a95-57a10d2b08df:v4.0",
    },
    {
      "config": {
        "visible": true,
      },
      "id": "presence",
    },
    {
      "config": {
        "visible": false,
      },
      "id": "vms",
    },
    {
      "config": {
        "visible": false,
      },
      "id": "ais",
    },
  ],
  "latitude": 19,
  "longitude": 26,
  "timebarVisualisation": "vessel",
  "zoom": 1.49,
}
+ Received:
undefined
 ❯ test/integration/Vessels.spec.tsx:180:29
    178|     const pinAction = actions.findLast((action) => action.type === 'HO…
    179|
    180|     expect(pinAction?.query).toStrictEqual({
       |                             ^
    181|       dataviewInstances: [
    182|         {
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[37/42]⎯
 FAIL   fishing-map-chromium  test/integration/Vessels.spec.tsx > Vessel map popup > should be able to filter vessels by flag
AssertionError: expected [ <button …(2)></button> ] to have a length of 6 but got 1
Failure screenshot:
  - apps/fishing-map/test/integration/__screenshots__/Vessels.spec.tsx/Vessel-map-popup-should-be-able-to-filter-vessels-by-flag-1.png
- Expected
+ Received
- 6
+ 1
 ❯ test/integration/Vessels.spec.tsx:323:43
    321|     await userEvent.click(getByTestId('app-main'), { position: { x, y …
    322|
    323|     await expect.element(getByText('ESP')).toHaveLength(6)
       |                                           ^
    324|   })
    325|
Caused by: Error: Matcher did not succeed in time.
 ❯ test/integration/Vessels.spec.tsx:323:4
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[38/42]⎯
 FAIL   fishing-map-chromium  test/integration/Vessels.spec.tsx > Vessel map popup > should be able to interact with vessels after filtering by flag
Error: Test timed out in 30000ms.
If this is a long-running test, pass a timeout value as the last argument or configure it globally with "testTimeout".
 ❯ test/integration/Vessels.spec.tsx:326:2
    324|   })
    325|
    326|   it('should be able to interact with vessels after filtering by flag'…
       |  ^
    327|     const store = makeStore(defaultState, [])
    328|     const jotaiStore = createJotaiStore()
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[39/42]⎯
 FAIL   fishing-map-chromium  test/integration/VesselsVMSBrazil.spec.tsx > Vessel identity properties based on the VMS source > should render public VMS Brazil identity fields
VitestBrowserElementError: Cannot find element with locator: page.getByText('Fishing zone')
<body>
  
  

  <div
    id="__root__"
  >
    <a
      class="print-only"
      href="https://globalfishingwatch.org"
    >
      <svg
        aria-label="Global Fishing Watch "
        class="_container_13m0y_1"
        height="60"
        viewBox="20 0 220 60"
        width="200"
        xmlns="http://www.w3.org/2000/svg"
      >
        <g
          aria-hidden="true"
          fill="none"
          fill-rule="evenodd"
          focusable="false"
        >
          <path
            d="M23.1 27.83c-.08.16-2.25 4.5.57 8.76.83 1.25 1.76 2.24 4.1 3.8 3.38 2.26 7.42 6.16 8.4 8.45.1.21.36.59-.06.83-.73.41-1.75.31-2.16.25l-.12-.02c-4.75-.88-14.5-5-13.8-13.8.18-2.21.98-4.87 3.07-8.27zm9.92-8.64c.7-.08 2.98-.15 3.08.08.07.17-.83.5-.87.52-5.22 1.98-6.97 3.16-7.22 3.3-3.3 2.01-4.71 4.35-4.82 4.57 1.48-3.1 5.2-7.93 9.83-8.47z"
            fill="#8ABBC7"
          />
          <path
            d="M40.45 19.2l.64 1.16a17.1 17.1 0 011.52 3.94c.27 1.1.39 2.23.31 3.37a9.39 9.39 0 01-1.72 4.84 12.9 12.9 0 01-3.29 3.2 20.3 20.3 0 01-7.02 3.08c-.4.09-.8.16-1.2.19a3.39 3.39 0 01-1.3-.17c-.43-.17-.5-.43-.28-.83a13.43 13.43 0 012.53-3.4 35.39 35.39 0 015.48-4.56c.76-.53 1.5-1.06 2.15-1.7a8.5 8.5 0 002.55-4.63 8.37 8.37 0 00-.24-3.89l-.18-.59.05-.02zm.64 16.43c.5.03.64.28.4.72-.35.64-.9 1.04-1.6 1.21-.68.16-1.35.13-2.02-.02-.42-.09-.83-.23-1.24-.35l-.11-.06.12-.08c1.02-.53 2.07-.97 3.19-1.26.4-.1.83-.18 1.26-.16zM30.73 10.07c.92.2 1.75.61 2.54 1.11.87.56 1.65 1.21 2.4 1.92a29.78 29.78 0 014.2 5.18l.01.07-.18-.16a14.79 14.79 0 00-3.6-2.45c-1.01-.5-2.06-.9-3.11-1.3-.58-.23-1.16-.44-1.7-.75a1.82 1.82 0 01-.75-.76c-.15-.32-.07-.6.23-.78l.35-.18c-.28-.14-.53-.24-.75-.38-.2-.13-.38-.29-.55-.45a.77.77 0 01-.21-.64c.02-.24.13-.38.35-.46.26-.08.52-.03.77.03z"
            fill="#E84427"
          />
          <text
            class="_mainBrand_13m0y_5 _default_13m0y_10"
            x="52"
            y="37"
          >
            Global Fishing Watch
          </text>
        </g>
      </svg>
    </a>
    <div
      class="_appLayout_d89r9_1"
    >
      <div
        class="_appLayoutContent_d89r9_8"
        id="app-layout-content"
      >
        <div
          class="_container_1gfa5_1 _isOpen_1gfa5_19 _splitContainer_d89r9_66"
        >
          <aside
            class="_aside_1gfa5_8 _aside_d89r9_77"
            style="width: 50%;"
          >
            <div
              aria-label="Resize sidebar"
              class="_resizer_1gfa5_32 print-hidden"
              role="button"
              tabindex="0"
            />
            <div
              class="_container_10gdv_1"
            >
              <div … />
              <ul … />
            </div>
          </aside>
          <main
            class="_main_1gfa5_23 _main_d89r9_16"
            data-testid="app-main"
            id="app-main"
            style="left: 50%;"
          >
            <div
              class="_mapContainer_d89r9_22 _withTimebar_d89r9_33"
            >
              <div … />
            </div>
            <div
              class="_timebarWrapper_1pma8_1"
              data-testid="timebar-wrapper"
              role="toolbar"
            >
              <div … />
              <div … />
            </div>
            <footer
              class="print-hidden _footer_1k9s3_1"
            >
              <div … />
              <span … />
            </footer>
          </main>
        </div>
        <section
          aria-atomic="false"
          aria-label="Notifications Alt+T"
          aria-live="polite"
          aria-relevant="additions text"
          class="Toastify"
        />
        <div
          class="ReactModalPortal"
        />
        <div
          class="ReactModalPortal"
        />
        <div
          class="ReactModalPortal"
        />
        <div
          class="ReactModalPortal"
        />
        <div
          class="ReactModalPortal"
        />
      </div>
      <div
        class="_panel_15iap_1 _hidden_15iap_12"
        style="width: 540px; --panel-width: 540px;"
      >
        <div
          class="_panelResizer_15iap_29"
          role="button"
          tabindex="0"
        />
      </div>
    </div>
  </div>
  <div
    class="ReactModalPortal"
  />
</body>...
Failure screenshot:
  - apps/fishing-map/test/integration/__screenshots__/VesselsVMSBrazil.spec.tsx/Vessel-identity-properties-based-on-the-VMS-source-should-render-public-VMS-Brazil-identity-fields-1.png
 ❯ test/integration/VesselsVMSBrazil.spec.tsx:34:52
     32|     await router.navigate(navigateToPublicBrazilVMSViewer())
     33|
     34|     await expect.element(getByText('Fishing zone')).toBeVisible()
       |                                                    ^
     35|     await expect.element(getByText('Main gear')).toBeVisible()
     36|     await expect.element(getByText('Target species')).toBeVisible()
Caused by: Error: Matcher did not succeed in time.
 ❯ test/integration/VesselsVMSBrazil.spec.tsx:34:4
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[40/42]⎯
 FAIL   fishing-map-chromium  test/integration/VesselsVMSBrazil.spec.tsx > Vessel identity properties based on the VMS source > should render private-only VMS Brazil identity fields
VitestBrowserElementError: Cannot find element with locator: page.getByText('Vessel registration number')
<body>
  
  

  <div
    id="__root__"
  >
    <a
      class="print-only"
      href="https://globalfishingwatch.org"
    >
      <svg
        aria-label="Global Fishing Watch "
        class="_container_13m0y_1"
        height="60"
        viewBox="20 0 220 60"
        width="200"
        xmlns="http://www.w3.org/2000/svg"
      >
        <g
          aria-hidden="true"
          fill="none"
          fill-rule="evenodd"
          focusable="false"
        >
          <path
            d="M23.1 27.83c-.08.16-2.25 4.5.57 8.76.83 1.25 1.76 2.24 4.1 3.8 3.38 2.26 7.42 6.16 8.4 8.45.1.21.36.59-.06.83-.73.41-1.75.31-2.16.25l-.12-.02c-4.75-.88-14.5-5-13.8-13.8.18-2.21.98-4.87 3.07-8.27zm9.92-8.64c.7-.08 2.98-.15 3.08.08.07.17-.83.5-.87.52-5.22 1.98-6.97 3.16-7.22 3.3-3.3 2.01-4.71 4.35-4.82 4.57 1.48-3.1 5.2-7.93 9.83-8.47z"
            fill="#8ABBC7"
          />
          <path
            d="M40.45 19.2l.64 1.16a17.1 17.1 0 011.52 3.94c.27 1.1.39 2.23.31 3.37a9.39 9.39 0 01-1.72 4.84 12.9 12.9 0 01-3.29 3.2 20.3 20.3 0 01-7.02 3.08c-.4.09-.8.16-1.2.19a3.39 3.39 0 01-1.3-.17c-.43-.17-.5-.43-.28-.83a13.43 13.43 0 012.53-3.4 35.39 35.39 0 015.48-4.56c.76-.53 1.5-1.06 2.15-1.7a8.5 8.5 0 002.55-4.63 8.37 8.37 0 00-.24-3.89l-.18-.59.05-.02zm.64 16.43c.5.03.64.28.4.72-.35.64-.9 1.04-1.6 1.21-.68.16-1.35.13-2.02-.02-.42-.09-.83-.23-1.24-.35l-.11-.06.12-.08c1.02-.53 2.07-.97 3.19-1.26.4-.1.83-.18 1.26-.16zM30.73 10.07c.92.2 1.75.61 2.54 1.11.87.56 1.65 1.21 2.4 1.92a29.78 29.78 0 014.2 5.18l.01.07-.18-.16a14.79 14.79 0 00-3.6-2.45c-1.01-.5-2.06-.9-3.11-1.3-.58-.23-1.16-.44-1.7-.75a1.82 1.82 0 01-.75-.76c-.15-.32-.07-.6.23-.78l.35-.18c-.28-.14-.53-.24-.75-.38-.2-.13-.38-.29-.55-.45a.77.77 0 01-.21-.64c.02-.24.13-.38.35-.46.26-.08.52-.03.77.03z"
            fill="#E84427"
          />
          <text
            class="_mainBrand_13m0y_5 _default_13m0y_10"
            x="52"
            y="37"
          >
            Global Fishing Watch
          </text>
        </g>
      </svg>
    </a>
    <div
      class="_appLayout_d89r9_1"
    >
      <div
        class="_appLayoutContent_d89r9_8"
        id="app-layout-content"
      >
        <div
          class="_container_1gfa5_1 _isOpen_1gfa5_19 _splitContainer_d89r9_66"
        >
          <aside
            class="_aside_1gfa5_8 _aside_d89r9_77"
            style="width: 50%;"
          >
            <div
              aria-label="Resize sidebar"
              class="_resizer_1gfa5_32 print-hidden"
              role="button"
              tabindex="0"
            />
            <div
              class="_container_10gdv_1"
            >
              <div … />
              <ul … />
            </div>
          </aside>
          <main
            class="_main_1gfa5_23 _main_d89r9_16"
            data-testid="app-main"
            id="app-main"
            style="left: 50%;"
          >
            <div
              class="_mapContainer_d89r9_22 _withTimebar_d89r9_33"
            >
              <div … />
            </div>
            <div
              class="_timebarWrapper_1pma8_1"
              data-testid="timebar-wrapper"
              role="toolbar"
            >
              <div … />
              <div … />
            </div>
            <footer
              class="print-hidden _footer_1k9s3_1"
            >
              <div … />
              <span … />
            </footer>
          </main>
        </div>
        <section
          aria-atomic="false"
          aria-label="Notifications Alt+T"
          aria-live="polite"
          aria-relevant="additions text"
          class="Toastify"
        />
        <div
          class="ReactModalPortal"
        />
        <div
          class="ReactModalPortal"
        />
        <div
          class="ReactModalPortal"
        />
        <div
          class="ReactModalPortal"
        />
        <div
          class="ReactModalPortal"
        />
      </div>
      <div
        class="_panel_15iap_1 _hidden_15iap_12"
        style="width: 540px; --panel-width: 540px;"
      >
        <div
          class="_panelResizer_15iap_29"
          role="button"
          tabindex="0"
        />
      </div>
    </div>
  </div>
  <div
    class="ReactModalPortal"
  />
</body>...
Failure screenshot:
  - apps/fishing-map/test/integration/__screenshots__/VesselsVMSBrazil.spec.tsx/Vessel-identity-properties-based-on-the-VMS-source-should-render-private-only-VMS-Brazil-identity-fields-1.png
 ❯ test/integration/VesselsVMSBrazil.spec.tsx:50:66
     48|     await router.navigate(navigateToPrivateBrazilVMSViewer())
     49|
     50|     await expect.element(getByText('Vessel registration number')).toBe…
       |                                                                  ^
     51|     await expect.element(getByText('Fleet code')).toBeVisible()
     52|     await expect.element(getByText('Fishing license code')).toBeVisibl…
Caused by: Error: Matcher did not succeed in time.
 ❯ test/integration/VesselsVMSBrazil.spec.tsx:50:4
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[41/42]⎯
 FAIL   fishing-map-chromium  features/workspace/user/UserSection/UserSection.test.tsx > UserSection > should have a login link if the user is a guest
VitestBrowserElementError: Cannot find element with locator: page.getByText('Register')
<body>
  
  

  <div
    id="__root__"
  >
    <a
      class="print-only"
      href="https://globalfishingwatch.org"
    >
      <svg
        aria-label="Global Fishing Watch "
        class="_container_13m0y_1"
        height="60"
        viewBox="20 0 220 60"
        width="200"
        xmlns="http://www.w3.org/2000/svg"
      >
        <g
          aria-hidden="true"
          fill="none"
          fill-rule="evenodd"
          focusable="false"
        >
          <path
            d="M23.1 27.83c-.08.16-2.25 4.5.57 8.76.83 1.25 1.76 2.24 4.1 3.8 3.38 2.26 7.42 6.16 8.4 8.45.1.21.36.59-.06.83-.73.41-1.75.31-2.16.25l-.12-.02c-4.75-.88-14.5-5-13.8-13.8.18-2.21.98-4.87 3.07-8.27zm9.92-8.64c.7-.08 2.98-.15 3.08.08.07.17-.83.5-.87.52-5.22 1.98-6.97 3.16-7.22 3.3-3.3 2.01-4.71 4.35-4.82 4.57 1.48-3.1 5.2-7.93 9.83-8.47z"
            fill="#8ABBC7"
          />
          <path
            d="M40.45 19.2l.64 1.16a17.1 17.1 0 011.52 3.94c.27 1.1.39 2.23.31 3.37a9.39 9.39 0 01-1.72 4.84 12.9 12.9 0 01-3.29 3.2 20.3 20.3 0 01-7.02 3.08c-.4.09-.8.16-1.2.19a3.39 3.39 0 01-1.3-.17c-.43-.17-.5-.43-.28-.83a13.43 13.43 0 012.53-3.4 35.39 35.39 0 015.48-4.56c.76-.53 1.5-1.06 2.15-1.7a8.5 8.5 0 002.55-4.63 8.37 8.37 0 00-.24-3.89l-.18-.59.05-.02zm.64 16.43c.5.03.64.28.4.72-.35.64-.9 1.04-1.6 1.21-.68.16-1.35.13-2.02-.02-.42-.09-.83-.23-1.24-.35l-.11-.06.12-.08c1.02-.53 2.07-.97 3.19-1.26.4-.1.83-.18 1.26-.16zM30.73 10.07c.92.2 1.75.61 2.54 1.11.87.56 1.65 1.21 2.4 1.92a29.78 29.78 0 014.2 5.18l.01.07-.18-.16a14.79 14.79 0 00-3.6-2.45c-1.01-.5-2.06-.9-3.11-1.3-.58-.23-1.16-.44-1.7-.75a1.82 1.82 0 01-.75-.76c-.15-.32-.07-.6.23-.78l.35-.18c-.28-.14-.53-.24-.75-.38-.2-.13-.38-.29-.55-.45a.77.77 0 01-.21-.64c.02-.24.13-.38.35-.46.26-.08.52-.03.77.03z"
            fill="#E84427"
          />
          <text
            class="_mainBrand_13m0y_5 _default_13m0y_10"
            x="52"
            y="37"
          >
            Global Fishing Watch
          </text>
        </g>
      </svg>
    </a>
    <div
      class="_appLayout_d89r9_1"
    >
      <div
        class="_appLayoutContent_d89r9_8"
        id="app-layout-content"
      >
        <div
          class="_container_1gfa5_1 _isOpen_1gfa5_19 _splitContainer_d89r9_66"
        >
          <aside
            class="_aside_1gfa5_8 _aside_d89r9_77"
            style="width: 40rem;"
          >
            <button
              aria-label="Toggle sidebar"
              class="print-hidden _toggleBtn_1gfa5_48"
            >
              <svg … />
            </button>
            <div
              class="_container_10gdv_1"
            >
              <div … />
              <ul … />
            </div>
          </aside>
          <main
            class="_main_1gfa5_23 _main_d89r9_16"
            data-testid="app-main"
            id="app-main"
            style="left: 40rem;"
          >
            <div
              class="_mapContainer_d89r9_22"
            />
            <footer
              class="print-hidden _footer_1k9s3_1"
            >
              <div … />
              <span … />
            </footer>
          </main>
        </div>
        <section
          aria-atomic="false"
          aria-label="Notifications Alt+T"
          aria-live="polite"
          aria-relevant="additions text"
          class="Toastify"
        />
        <div
          class="ReactModalPortal"
        />
        <div
          class="ReactModalPortal"
        />
        <div
          class="ReactModalPortal"
        />
        <div
          class="ReactModalPortal"
        />
      </div>
      <div
        class="_panel_15iap_1 _hidden_15iap_12"
        style="width: 540px; --panel-width: 540px;"
      >
        <div
          class="_panelResizer_15iap_29"
          role="button"
          tabindex="0"
        />
      </div>
    </div>
  </div>
  <div
    class="ReactModalPortal"
  />
</body>...
Failure screenshot:
  - apps/fishing-map/features/workspace/user/UserSection/__screenshots__/UserSection.test.tsx/UserSection-should-have-a-login-link-if-the-user-is-a-guest-1.png
 ❯ features/workspace/user/UserSection/UserSection.test.tsx:16:48
     14|     expect(store.getState().user.data?.type === 'guest').toBe(true)
     15|
     16|     await expect.element(getByText('Register')).toBeInTheDocument()
       |                                                ^
     17|   })
     18| })
Caused by: Error: Matcher did not succeed in time.
 ❯ features/workspace/user/UserSection/UserSection.test.tsx:16:4
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[42/42]⎯
 Test Files  13 failed | 5 passed | 1 skipped (19)
      Tests  42 failed | 42 passed | 9 skipped (93)
   Start at  14:27:41
   Duration  1664.23s (transform 0ms, setup 1.24s, import 63.85s, tests 1566.22s, environment 0ms)
✅ timebar:test
 RUN  v4.1.8 /home/runner/work/frontend/frontend/libs/timebar
 ❯  timebar  src/timebar.spec.tsx (0 test)
 ❯  timebar  src/timeline/timeline-drag.utils.spec.ts (0 test)
 ❯  timebar  src/timebar-range.spec.tsx (0 test)
 ❯  timebar  src/components/playback.spec.tsx (0 test)
 ❯  timebar  src/timeline/timeline.interaction.spec.tsx (0 test)
 ❯  timebar  src/components/timerange-selector.spec.tsx (0 test)
 ✓  timebar  src/charts/charts-store.atom.spec.tsx (2 tests) 24ms
 ❯  timebar  src/charts/charts.hooks.spec.tsx (0 test)
⎯⎯⎯⎯⎯⎯ Failed Suites 7 ⎯⎯⎯⎯⎯⎯⎯
 FAIL   timebar  src/timebar-range.spec.tsx [ src/timebar-range.spec.tsx ]
Error: Failed to resolve import "@globalfishingwatch/data-transforms" from "libs/timebar/src/timebar-range.ts". Does the file exist?
  Plugin: vite:import-analysis
  File: /home/runner/work/frontend/frontend/libs/timebar/src/timebar-range.ts:3:27
  1  |  import { useCallback, useEffect, useRef, useState } from "react";
  2  |  import { getUTCDate } from "@globalfishingwatch/data-transforms";
     |                              ^
  3  |  const clampToMinAndMax = (start, end, minMs, maxMs, clampToEnd) => {
  4  |  	const delta = getUTCDate(end).getTime() - getUTCDate(start).getTime();
 ❯ TransformPluginContext._formatLog ../../node_modules/.pnpm/vite@8.0.16_@types+node@25.9.1_@vitejs+devtools@0.3.1_esbuild@0.28.1_jiti@2.7.0_less@4._a7c07b7e3edb290c34748eebaad75d68/node_modules/vite/dist/node/chunks/node.js:30602:39
 ❯ TransformPluginContext.error ../../node_modules/.pnpm/vite@8.0.16_@types+node@25.9.1_@vitejs+devtools@0.3.1_esbuild@0.28.1_jiti@2.7.0_less@4._a7c07b7e3edb290c34748eebaad75d68/node_modules/vite/dist/node/chunks/node.js:30599:14
 ❯ normalizeUrl ../../node_modules/.pnpm/vite@8.0.16_@types+node@25.9.1_@vitejs+devtools@0.3.1_esbuild@0.28.1_jiti@2.7.0_less@4._a7c07b7e3edb290c34748eebaad75d68/node_modules/vite/dist/node/chunks/node.js:27842:18
 ❯ ../../node_modules/.pnpm/vite@8.0.16_@types+node@25.9.1_@vitejs+devtools@0.3.1_esbuild@0.28.1_jiti@2.7.0_less@4._a7c07b7e3edb290c34748eebaad75d68/node_modules/vite/dist/node/chunks/node.js:27905:30
 ❯ TransformPluginContext.transform ../../node_modules/.pnpm/vite@8.0.16_@types+node@25.9.1_@vitejs+devtools@0.3.1_esbuild@0.28.1_jiti@2.7.0_less@4._a7c07b7e3edb290c34748eebaad75d68/node_modules/vite/dist/node/chunks/node.js:27873:4
 ❯ EnvironmentPluginContainer.transform ../../node_modules/.pnpm/vite@8.0.16_@types+node@25.9.1_@vitejs+devtools@0.3.1_esbuild@0.28.1_jiti@2.7.0_less@4._a7c07b7e3edb290c34748eebaad75d68/node_modules/vite/dist/node/chunks/node.js:30387:14
 ❯ loadAndTransform ../../node_modules/.pnpm/vite@8.0.16_@types+node@25.9.1_@vitejs+devtools@0.3.1_esbuild@0.28.1_jiti@2.7.0_less@4._a7c07b7e3edb290c34748eebaad75d68/node_modules/vite/dist/node/chunks/node.js:24646:26
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/7]⎯
 FAIL   timebar  src/timebar.spec.tsx [ src/timebar.spec.tsx ]
Error: Failed to resolve import "@globalfishingwatch/deck-loaders" from "libs/timebar/src/timebar.spec.tsx". Does the file exist?
  Plugin: vite:import-analysis
  File: /home/runner/work/frontend/frontend/libs/timebar/src/timebar.spec.tsx:4:0
  23 |  }, this) }));
  24 |  const __vi_import_0__ = await import("@testing-library/react");
  25 |  const __vi_import_1__ = await import("@globalfishingwatch/deck-loaders");
     |                                       ^
  26 |  const __vi_import_2__ = await import("./timeline/timeline-context");
  27 |  const __vi_import_3__ = await import("./charts");
 ❯ TransformPluginContext._formatLog ../../node_modules/.pnpm/vite@8.0.16_@types+node@25.9.1_@vitejs+devtools@0.3.1_esbuild@0.28.1_jiti@2.7.0_less@4._a7c07b7e3edb290c34748eebaad75d68/node_modules/vite/dist/node/chunks/node.js:30602:39
 ❯ TransformPluginContext.error ../../node_modules/.pnpm/vite@8.0.16_@types+node@25.9.1_@vitejs+devtools@0.3.1_esbuild@0.28.1_jiti@2.7.0_less@4._a7c07b7e3edb290c34748eebaad75d68/node_modules/vite/dist/node/chunks/node.js:30599:14
 ❯ normalizeUrl ../../node_modules/.pnpm/vite@8.0.16_@types+node@25.9.1_@vitejs+devtools@0.3.1_esbuild@0.28.1_jiti@2.7.0_less@4._a7c07b7e3edb290c34748eebaad75d68/node_modules/vite/dist/node/chunks/node.js:27842:18
 ❯ ../../node_modules/.pnpm/vite@8.0.16_@types+node@25.9.1_@vitejs+devtools@0.3.1_esbuild@0.28.1_jiti@2.7.0_less@4._a7c07b7e3edb290c34748eebaad75d68/node_modules/vite/dist/node/chunks/node.js:27905:30
 ❯ TransformPluginContext.transform ../../node_modules/.pnpm/vite@8.0.16_@types+node@25.9.1_@vitejs+devtools@0.3.1_esbuild@0.28.1_jiti@2.7.0_less@4._a7c07b7e3edb290c34748eebaad75d68/node_modules/vite/dist/node/chunks/node.js:27873:4
 ❯ EnvironmentPluginContainer.transform ../../node_modules/.pnpm/vite@8.0.16_@types+node@25.9.1_@vitejs+devtools@0.3.1_esbuild@0.28.1_jiti@2.7.0_less@4._a7c07b7e3edb290c34748eebaad75d68/node_modules/vite/dist/node/chunks/node.js:30387:14
 ❯ loadAndTransform ../../node_modules/.pnpm/vite@8.0.16_@types+node@25.9.1_@vitejs+devtools@0.3.1_esbuild@0.28.1_jiti@2.7.0_less@4._a7c07b7e3edb290c34748eebaad75d68/node_modules/vite/dist/node/chunks/node.js:24646:26
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[2/7]⎯
 FAIL   timebar  src/charts/charts.hooks.spec.tsx [ src/charts/charts.hooks.spec.tsx ]
Error: Failed to resolve import "@globalfishingwatch/data-transforms" from "libs/timebar/src/charts/charts.hooks.ts". Does the file exist?
  Plugin: vite:import-analysis
  File: /home/runner/work/frontend/frontend/libs/timebar/src/charts/charts.hooks.ts:5:27
  2  |  import { scaleTime } from "d3-scale";
  3  |  import { EventTypes } from "@globalfishingwatch/api-types";
  4  |  import { getUTCDate } from "@globalfishingwatch/data-transforms";
     |                              ^
  5  |  import { useTimelineContext } from "../timeline/timeline-context";
  6  |  export const filterData = (data, start, end) => {
 ❯ TransformPluginContext._formatLog ../../node_modules/.pnpm/vite@8.0.16_@types+node@25.9.1_@vitejs+devtools@0.3.1_esbuild@0.28.1_jiti@2.7.0_less@4._a7c07b7e3edb290c34748eebaad75d68/node_modules/vite/dist/node/chunks/node.js:30602:39
 ❯ TransformPluginContext.error ../../node_modules/.pnpm/vite@8.0.16_@types+node@25.9.1_@vitejs+devtools@0.3.1_esbuild@0.28.1_jiti@2.7.0_less@4._a7c07b7e3edb290c34748eebaad75d68/node_modules/vite/dist/node/chunks/node.js:30599:14
 ❯ normalizeUrl ../../node_modules/.pnpm/vite@8.0.16_@types+node@25.9.1_@vitejs+devtools@0.3.1_esbuild@0.28.1_jiti@2.7.0_less@4._a7c07b7e3edb290c34748eebaad75d68/node_modules/vite/dist/node/chunks/node.js:27842:18
 ❯ ../../node_modules/.pnpm/vite@8.0.16_@types+node@25.9.1_@vitejs+devtools@0.3.1_esbuild@0.28.1_jiti@2.7.0_less@4._a7c07b7e3edb290c34748eebaad75d68/node_modules/vite/dist/node/chunks/node.js:27905:30
 ❯ TransformPluginContext.transform ../../node_modules/.pnpm/vite@8.0.16_@types+node@25.9.1_@vitejs+devtools@0.3.1_esbuild@0.28.1_jiti@2.7.0_less@4._a7c07b7e3edb290c34748eebaad75d68/node_modules/vite/dist/node/chunks/node.js:27873:4
 ❯ EnvironmentPluginContainer.transform ../../node_modules/.pnpm/vite@8.0.16_@types+node@25.9.1_@vitejs+devtools@0.3.1_esbuild@0.28.1_jiti@2.7.0_less@4._a7c07b7e3edb290c34748eebaad75d68/node_modules/vite/dist/node/chunks/node.js:30387:14
 ❯ loadAndTransform ../../node_modules/.pnpm/vite@8.0.16_@types+node@25.9.1_@vitejs+devtools@0.3.1_esbuild@0.28.1_jiti@2.7.0_less@4._a7c07b7e3edb290c34748eebaad75d68/node_modules/vite/dist/node/chunks/node.js:24646:26
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[3/7]⎯
 FAIL   timebar  src/components/playback.spec.tsx [ src/components/playback.spec.tsx ]
Error: Failed to resolve import "@globalfishingwatch/deck-loaders" from "libs/timebar/src/components/playback.spec.tsx". Does the file exist?
  Plugin: vite:import-analysis
  File: /home/runner/work/frontend/frontend/libs/timebar/src/components/playback.spec.tsx:4:0
  23 |  }, this) }));
  24 |  const __vi_import_0__ = await import("@testing-library/react");
  25 |  const __vi_import_1__ = await import("@globalfishingwatch/deck-loaders");
     |                                       ^
  26 |  const __vi_import_2__ = await import("../constants");
  27 |  const __vi_import_3__ = await import("../timebar");
 ❯ TransformPluginContext._formatLog ../../node_modules/.pnpm/vite@8.0.16_@types+node@25.9.1_@vitejs+devtools@0.3.1_esbuild@0.28.1_jiti@2.7.0_less@4._a7c07b7e3edb290c34748eebaad75d68/node_modules/vite/dist/node/chunks/node.js:30602:39
 ❯ TransformPluginContext.error ../../node_modules/.pnpm/vite@8.0.16_@types+node@25.9.1_@vitejs+devtools@0.3.1_esbuild@0.28.1_jiti@2.7.0_less@4._a7c07b7e3edb290c34748eebaad75d68/node_modules/vite/dist/node/chunks/node.js:30599:14
 ❯ normalizeUrl ../../node_modules/.pnpm/vite@8.0.16_@types+node@25.9.1_@vitejs+devtools@0.3.1_esbuild@0.28.1_jiti@2.7.0_less@4._a7c07b7e3edb290c34748eebaad75d68/node_modules/vite/dist/node/chunks/node.js:27842:18
 ❯ ../../node_modules/.pnpm/vite@8.0.16_@types+node@25.9.1_@vitejs+devtools@0.3.1_esbuild@0.28.1_jiti@2.7.0_less@4._a7c07b7e3edb290c34748eebaad75d68/node_modules/vite/dist/node/chunks/node.js:27905:30
 ❯ TransformPluginContext.transform ../../node_modules/.pnpm/vite@8.0.16_@types+node@25.9.1_@vitejs+devtools@0.3.1_esbuild@0.28.1_jiti@2.7.0_less@4._a7c07b7e3edb290c34748eebaad75d68/node_modules/vite/dist/node/chunks/node.js:27873:4
 ❯ EnvironmentPluginContainer.transform ../../node_modules/.pnpm/vite@8.0.16_@types+node@25.9.1_@vitejs+devtools@0.3.1_esbuild@0.28.1_jiti@2.7.0_less@4._a7c07b7e3edb290c34748eebaad75d68/node_modules/vite/dist/node/chunks/node.js:30387:14
 ❯ loadAndTransform ../../node_modules/.pnpm/vite@8.0.16_@types+node@25.9.1_@vitejs+devtools@0.3.1_esbuild@0.28.1_jiti@2.7.0_less@4._a7c07b7e3edb290c34748eebaad75d68/node_modules/vite/dist/node/chunks/node.js:24646:26
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[4/7]⎯
 FAIL   timebar  src/components/timerange-selector.spec.tsx [ src/components/timerange-selector.spec.tsx ]
Error: Failed to resolve import "@globalfishingwatch/deck-loaders" from "libs/timebar/src/components/timerange-selector.tsx". Does the file exist?
  Plugin: vite:import-analysis
  File: /home/runner/work/frontend/frontend/libs/timebar/src/components/timerange-selector.tsx:12:7
  2  |  import classNames from "classnames";
  3  |  import { DateTime } from "luxon";
  4  |  import { FOURWINGS_INTERVALS_ORDER, getFourwingsInterval, LIMITS_BY_INTERVAL } from "@globalfishingwatch/deck-loaders";
     |                                                                                       ^
  5  |  import { Select } from "@globalfishingwatch/ui-components/select";
  6  |  import { Tooltip } from "@globalfishingwatch/ui-components/tooltip";
 ❯ TransformPluginContext._formatLog ../../node_modules/.pnpm/vite@8.0.16_@types+node@25.9.1_@vitejs+devtools@0.3.1_esbuild@0.28.1_jiti@2.7.0_less@4._a7c07b7e3edb290c34748eebaad75d68/node_modules/vite/dist/node/chunks/node.js:30602:39
 ❯ TransformPluginContext.error ../../node_modules/.pnpm/vite@8.0.16_@types+node@25.9.1_@vitejs+devtools@0.3.1_esbuild@0.28.1_jiti@2.7.0_less@4._a7c07b7e3edb290c34748eebaad75d68/node_modules/vite/dist/node/chunks/node.js:30599:14
 ❯ normalizeUrl ../../node_modules/.pnpm/vite@8.0.16_@types+node@25.9.1_@vitejs+devtools@0.3.1_esbuild@0.28.1_jiti@2.7.0_less@4._a7c07b7e3edb290c34748eebaad75d68/node_modules/vite/dist/node/chunks/node.js:27842:18
 ❯ ../../node_modules/.pnpm/vite@8.0.16_@types+node@25.9.1_@vitejs+devtools@0.3.1_esbuild@0.28.1_jiti@2.7.0_less@4._a7c07b7e3edb290c34748eebaad75d68/node_modules/vite/dist/node/chunks/node.js:27905:30
 ❯ TransformPluginContext.transform ../../node_modules/.pnpm/vite@8.0.16_@types+node@25.9.1_@vitejs+devtools@0.3.1_esbuild@0.28.1_jiti@2.7.0_less@4._a7c07b7e3edb290c34748eebaad75d68/node_modules/vite/dist/node/chunks/node.js:27873:4
 ❯ EnvironmentPluginContainer.transform ../../node_modules/.pnpm/vite@8.0.16_@types+node@25.9.1_@vitejs+devtools@0.3.1_esbuild@0.28.1_jiti@2.7.0_less@4._a7c07b7e3edb290c34748eebaad75d68/node_modules/vite/dist/node/chunks/node.js:30387:14
 ❯ loadAndTransform ../../node_modules/.pnpm/vite@8.0.16_@types+node@25.9.1_@vitejs+devtools@0.3.1_esbuild@0.28.1_jiti@2.7.0_less@4._a7c07b7e3edb290c34748eebaad75d68/node_modules/vite/dist/node/chunks/node.js:24646:26
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[5/7]⎯
 FAIL   timebar  src/timeline/timeline-drag.utils.spec.ts [ src/timeline/timeline-drag.utils.spec.ts ]
Error: Failed to resolve import "@globalfishingwatch/deck-loaders" from "libs/timebar/src/timeline/timeline-drag.utils.ts". Does the file exist?
  Plugin: vite:import-analysis
  File: /home/runner/work/frontend/frontend/libs/timebar/src/timeline/timeline-drag.utils.ts:6:64
  1  |  import { DateTime } from "luxon";
  2  |  import { FOURWINGS_INTERVALS_ORDER, getFourwingsInterval } from "@globalfishingwatch/deck-loaders";
     |                                                                   ^
  3  |  import { EVENT_SOURCE } from "../constants";
  4  |  import { stickToClosestUnit } from "../utils";
 ❯ TransformPluginContext._formatLog ../../node_modules/.pnpm/vite@8.0.16_@types+node@25.9.1_@vitejs+devtools@0.3.1_esbuild@0.28.1_jiti@2.7.0_less@4._a7c07b7e3edb290c34748eebaad75d68/node_modules/vite/dist/node/chunks/node.js:30602:39
 ❯ TransformPluginContext.error ../../node_modules/.pnpm/vite@8.0.16_@types+node@25.9.1_@vitejs+devtools@0.3.1_esbuild@0.28.1_jiti@2.7.0_less@4._a7c07b7e3edb290c34748eebaad75d68/node_modules/vite/dist/node/chunks/node.js:30599:14
 ❯ normalizeUrl ../../node_modules/.pnpm/vite@8.0.16_@types+node@25.9.1_@vitejs+devtools@0.3.1_esbuild@0.28.1_jiti@2.7.0_less@4._a7c07b7e3edb290c34748eebaad75d68/node_modules/vite/dist/node/chunks/node.js:27842:18
 ❯ ../../node_modules/.pnpm/vite@8.0.16_@types+node@25.9.1_@vitejs+devtools@0.3.1_esbuild@0.28.1_jiti@2.7.0_less@4._a7c07b7e3edb290c34748eebaad75d68/node_modules/vite/dist/node/chunks/node.js:27905:30
 ❯ TransformPluginContext.transform ../../node_modules/.pnpm/vite@8.0.16_@types+node@25.9.1_@vitejs+devtools@0.3.1_esbuild@0.28.1_jiti@2.7.0_less@4._a7c07b7e3edb290c34748eebaad75d68/node_modules/vite/dist/node/chunks/node.js:27873:4
 ❯ EnvironmentPluginContainer.transform ../../node_modules/.pnpm/vite@8.0.16_@types+node@25.9.1_@vitejs+devtools@0.3.1_esbuild@0.28.1_jiti@2.7.0_less@4._a7c07b7e3edb290c34748eebaad75d68/node_modules/vite/dist/node/chunks/node.js:30387:14
 ❯ loadAndTransform ../../node_modules/.pnpm/vite@8.0.16_@types+node@25.9.1_@vitejs+devtools@0.3.1_esbuild@0.28.1_jiti@2.7.0_less@4._a7c07b7e3edb290c34748eebaad75d68/node_modules/vite/dist/node/chunks/node.js:24646:26
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[6/7]⎯
 FAIL   timebar  src/timeline/timeline.interaction.spec.tsx [ src/timeline/timeline.interaction.spec.tsx ]
Error: Failed to resolve import "@globalfishingwatch/data-transforms" from "libs/timebar/src/charts/highlighter.tsx". Does the file exist?
  Plugin: vite:import-analysis
  File: /home/runner/work/frontend/frontend/libs/timebar/src/charts/highlighter.tsx:7:27
  4  |  import { useAtomValue } from "jotai";
  5  |  import { DateTime } from "luxon";
  6  |  import { getUTCDate } from "@globalfishingwatch/data-transforms";
     |                              ^
  7  |  import { Icon } from "@globalfishingwatch/ui-components/icon";
  8  |  import { IconButton } from "@globalfishingwatch/ui-components/icon-button";
 ❯ TransformPluginContext._formatLog ../../node_modules/.pnpm/vite@8.0.16_@types+node@25.9.1_@vitejs+devtools@0.3.1_esbuild@0.28.1_jiti@2.7.0_less@4._a7c07b7e3edb290c34748eebaad75d68/node_modules/vite/dist/node/chunks/node.js:30602:39
 ❯ TransformPluginContext.error ../../node_modules/.pnpm/vite@8.0.16_@types+node@25.9.1_@vitejs+devtools@0.3.1_esbuild@0.28.1_jiti@2.7.0_less@4._a7c07b7e3edb290c34748eebaad75d68/node_modules/vite/dist/node/chunks/node.js:30599:14
 ❯ normalizeUrl ../../node_modules/.pnpm/vite@8.0.16_@types+node@25.9.1_@vitejs+devtools@0.3.1_esbuild@0.28.1_jiti@2.7.0_less@4._a7c07b7e3edb290c34748eebaad75d68/node_modules/vite/dist/node/chunks/node.js:27842:18
 ❯ ../../node_modules/.pnpm/vite@8.0.16_@types+node@25.9.1_@vitejs+devtools@0.3.1_esbuild@0.28.1_jiti@2.7.0_less@4._a7c07b7e3edb290c34748eebaad75d68/node_modules/vite/dist/node/chunks/node.js:27905:30
 ❯ TransformPluginContext.transform ../../node_modules/.pnpm/vite@8.0.16_@types+node@25.9.1_@vitejs+devtools@0.3.1_esbuild@0.28.1_jiti@2.7.0_less@4._a7c07b7e3edb290c34748eebaad75d68/node_modules/vite/dist/node/chunks/node.js:27873:4
 ❯ EnvironmentPluginContainer.transform ../../node_modules/.pnpm/vite@8.0.16_@types+node@25.9.1_@vitejs+devtools@0.3.1_esbuild@0.28.1_jiti@2.7.0_less@4._a7c07b7e3edb290c34748eebaad75d68/node_modules/vite/dist/node/chunks/node.js:30387:14
 ❯ loadAndTransform ../../node_modules/.pnpm/vite@8.0.16_@types+node@25.9.1_@vitejs+devtools@0.3.1_esbuild@0.28.1_jiti@2.7.0_less@4._a7c07b7e3edb290c34748eebaad75d68/node_modules/vite/dist/node/chunks/node.js:24646:26
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[7/7]⎯
 Test Files  7 failed | 1 passed (8)
      Tests  2 passed (2)
   Start at  14:27:37
   Duration  7.59s (transform 490ms, setup 0ms, import 159ms, tests 24ms, environment 14.48s)
✅ api-client:test
 RUN  v4.1.8 /home/runner/work/frontend/frontend/libs/api-client
Compiling TypeScript files for project "api-client"...
 ✓  api-client  src/utils/search.spec.ts (14 tests) 26ms
stderr | src/api-client.spec.ts > api-client > GFW_API_CLASS > fetch > should continue fetch after login rejects when logging is in progress
GFWAPI: _login — Invalid access token { status: 401, message: 'Invalid', messages: undefined }
stdout | src/api-client.spec.ts > api-client > GFW_API_CLASS > logout > should log warn when logout API fails
GFWAPI: GFW API Client initialized with the following config {
  debug: true,
  baseUrl: 'https://api.example.com',
  storageKeys: {
    token: 'GFW_API_USER_TOKEN',
    refreshToken: 'GFW_API_USER_REFRESH_TOKEN'
  },
  token: '',
  refreshToken: ''
}
GFWAPI: logout start {
  hasAccessToken: true,
  hasLocalRefreshToken: true,
  hasRefreshStrategy: false,
  hasSessionInvalidateStrategy: false,
  status: 'idle',
  loginInProgress: false,
  refreshInProgress: false
}
GFWAPI: logout — revoking session on gateway
GFWAPI: Fetching URL: /v3/auth/logout
stdout | src/api-client.spec.ts > api-client > GFW_API_CLASS > logout > should log warn when logout API fails
GFWAPI: invalidateClientSession — clearing local session
GFWAPI: updated token with 
GFWAPI: updated refreshToken with 
GFWAPI: logout finished
 ✓  api-client  src/api-client.spec.ts (82 tests) 395ms
 Test Files  2 passed (2)
      Tests  96 passed (96)
   Start at  14:27:33
   Duration  3.02s (transform 636ms, setup 0ms, import 875ms, tests 421ms, environment 3.65s)
Done compiling TypeScript files for project "api-client".
✅ deck-loaders:test
 RUN  v4.1.8 /home/runner/work/frontend/frontend/libs/deck-loaders
 ✓  deck-loaders  src/user/lib/parse-user-tracks.spec.ts (10 tests) 59ms
 ✓  deck-loaders  src/fourwings/helpers/time.spec.ts (17 tests) 63ms
 ✓  deck-loaders  src/fourwings/lib/parse-fourwings-clusters.spec.ts (7 tests) 44ms
 ✓  deck-loaders  src/user/lib/utils.spec.ts (6 tests) 28ms
src/vessels/lib/vessel-track-proto.gen.js 563ms
 ✓  deck-loaders  src/fourwings/helpers/fourwings-graph-aggregation.spec.ts (5 tests) 8ms
src/vessels/lib/vessel-track-proto.gen.d.ts 202ms
 ✓  deck-loaders  src/user/lib/features.utils.spec.ts (11 tests) 26ms
 ✓  deck-loaders  src/fourwings/lib/parse-fourwings.spec.ts (5 tests) 26ms
 ✓  deck-loaders  src/vessels/lib/parse-events.spec.ts (6 tests) 123ms
 ✓  deck-loaders  src/fourwings/lib/parse-fourwings-vectors.spec.ts (4 tests) 37ms
 ✓  deck-loaders  src/vessels/lib/parse-tracks.spec.ts (7 tests) 19ms
 ✓  deck-loaders  src/fourwings/helpers/byte-length.spec.ts (3 tests) 7ms
 ✓  deck-loaders  src/fourwings/helpers/timestamps.spec.ts (6 tests) 29ms
 Test Files  12 passed (12)
      Tests  87 passed (87)
   Start at  14:27:24
   Duration  2.91s (transform 857ms, setup 0ms, import 2.79s, tests 468ms, environment 7ms)
cp: copyFileSync: could not write to dest file (code=ENOENT):dist/vessels/lib/

Summary: 3 passed, 2 failed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant