# Instructions

- Following Playwright test failed.
- Explain why, be concise, respect Playwright best practices.
- Provide a snippet of code with the fix, if possible.

# Test info

- Name: tests/ui/map-insets.spec.ts >> /states/ map frames AK, HI and DC insets and a label opens the state page
- Location: tests/ui/map-insets.spec.ts:43:5

# Error details

```
Error: expect(page).toHaveURL(expected) failed

Expected pattern: /\/states\/ak\/$/
Received string:  "http://preview-us-elect-info.electinfo.svc.cluster.local/states/alaska/"
Timeout: 5000ms

Call log:
  - Expect "toHaveURL" with timeout 5000ms
    14 × locator resolved to <html lang="en">…</html>
       - unexpected value "http://preview-us-elect-info.electinfo.svc.cluster.local/states/alaska/"

```

```yaml
- banner:
  - heading "Alaska" [level=1]
  - paragraph: State Campaign Finance Profile
- text: Not signed in
- link "Log in":
  - /url: /outpost.goauthentik.io/start?rd=http%3A%2F%2Fpreview-us-elect-info.electinfo.svc.cluster.local%2Fstates%2Falaska%2F
- link "Create an account":
  - /url: /signin/register?rd=http%3A%2F%2Fpreview-us-elect-info.electinfo.svc.cluster.local%2Fstates%2Falaska%2F
- toolbar "Member tools":
  - button "All cycles (Sign in to use the cycle facet)" [disabled]: All cycles
  - button "Graph (Sign in to use Graph)" [disabled]: Graph
- heading "Overview" [level=2]
- term: State Code
- definition: AK
- term: Senate Seats
- definition: "2"
- term: House Seats
- definition: "1"
- term: Total Candidates
- definition: "301"
- term: Total Committees
- definition: "379"
- term: Active Cycles
- definition:
  - link "2026":
    - /url: https://preview.elect.info/elections/2026/
  - text: ","
  - link "2024":
    - /url: https://preview.elect.info/elections/2024/
  - text: ","
  - link "2022":
    - /url: https://preview.elect.info/elections/2022/
  - text: ","
  - link "2020":
    - /url: https://preview.elect.info/elections/2020/
  - text: ","
  - link "2018":
    - /url: https://preview.elect.info/elections/2018/
  - text: ","
  - link "2016":
    - /url: https://preview.elect.info/elections/2016/
  - text: ","
  - link "2014":
    - /url: https://preview.elect.info/elections/2014/
  - text: ","
  - link "2012":
    - /url: https://preview.elect.info/elections/2012/
  - text: ","
  - link "2010":
    - /url: https://preview.elect.info/elections/2010/
  - text: ","
  - link "2008":
    - /url: https://preview.elect.info/elections/2008/
  - text: ","
  - link "2006":
    - /url: https://preview.elect.info/elections/2006/
  - text: ","
  - link "2004":
    - /url: https://preview.elect.info/elections/2004/
  - text: ","
  - link "2002":
    - /url: https://preview.elect.info/elections/2002/
  - text: ","
  - link "2000":
    - /url: https://preview.elect.info/elections/2000/
  - text: ","
  - link "1998":
    - /url: https://preview.elect.info/elections/1998/
  - text: ","
  - link "1996":
    - /url: https://preview.elect.info/elections/1996/
  - text: ","
  - link "1994":
    - /url: https://preview.elect.info/elections/1994/
  - text: ","
  - link "1992":
    - /url: https://preview.elect.info/elections/1992/
  - text: ","
  - link "1990":
    - /url: https://preview.elect.info/elections/1990/
  - text: ","
  - link "1988":
    - /url: https://preview.elect.info/elections/1988/
  - text: ","
  - link "1986":
    - /url: https://preview.elect.info/elections/1986/
  - text: ","
  - link "1984":
    - /url: https://preview.elect.info/elections/1984/
  - text: ","
  - link "1982":
    - /url: https://preview.elect.info/elections/1982/
  - text: ","
  - link "1980":
    - /url: https://preview.elect.info/elections/1980/
- heading "Candidates" [level=2]
- textbox "Search candidates for this state's offices..."
- button "Search"
- heading "Candidates" [level=3]
- link "MURKOWSKI, LISA REP | $11,932,314":
  - /url: /politicians/40c62658-928d-0c78-b95f-df5d24692b8e/
- link "YOUNG, DONALD E REP | $10,311,825":
  - /url: /politicians/b9f432ca-0fa9-0fec-a6a9-173af899b483/
- link "SULLIVAN, DAN REP | $6,688,115":
  - /url: /politicians/4c649574-181f-4ce7-4b6c-d61dcf5f808b/
- link "STEVENS, THEODORE F (TED) REP | $6,547,616":
  - /url: /politicians/81caa461-623e-67e7-f285-2cef4bddfe06/
- link "BEGICH, MARK DEM | $4,343,871":
  - /url: /politicians/0f5e6106-e966-0e6c-ac72-c2da306ccee2/
- link "MURKOWSKI, FRANK SENATOR REP | $3,405,278":
  - /url: /politicians/5967f0d7-e919-92fa-4cbf-47940273c1cf/
- link "PELTOLA, MARY DEM | $2,359,168":
  - /url: /politicians/5220d211-639a-d377-f85d-7e183958410a/
- link "PELTOLA, MARY DEM | $1,495,925":
  - /url: /politicians/df342087-9cf1-cd1e-3f36-5ee8b5893815/
- link "BEGICH, NICHOLAS III REP | $1,429,588":
  - /url: /politicians/6a7b5260-db82-c6d7-4d0a-34a71c9a7f40/
- link "KNOWLES, TONY DEM | $932,485":
  - /url: /politicians/51a4b2fa-a508-4d6e-1ed9-04f2ca14221c/
- link "GALVIN, ALYSE IND | $744,322":
  - /url: /politicians/ee898688-6b91-a98c-ff58-b85aa4a67bf4/
- link "MILLER, JOSEPH W LIB | $491,294":
  - /url: /politicians/d8c9d0e1-4c3f-8db3-1922-f61a70b34b6a/
- link "GROSS, AL DR. IND | $430,774":
  - /url: /politicians/b188f9e1-83de-14b3-c499-af57fccd3ad9/
- link "MCADAMS, SCOTT DEM | $397,376":
  - /url: /politicians/58e32dcd-294f-b8c0-ba7d-fca49b9d70a5/
- link "SMITH, TONY DEM | $376,103":
  - /url: /politicians/f259c6f8-2cd9-7bf0-a884-2af24759080b/
- link "BERKOWITZ, ETHAN A DEM | $297,289":
  - /url: /politicians/65531d38-e751-6884-e55c-aed3dd0af943/
- link "GRAVEL, MIKE DEM | $265,933":
  - /url: /politicians/dc20e207-062e-09d2-bb76-a1674dcdc7b3/
- link "OLDS, GLENN A DEM | $264,541":
  - /url: /politicians/8df89617-cba4-6691-0b74-5241acbe30e8/
- link "LINDBECK, STEVE DEM | $258,685":
  - /url: /politicians/8b8412d9-456f-6e9b-9e56-995f5b8c673a/
- link "DAHLSTROM, NANCY REP | $247,848":
  - /url: /politicians/2868969a-8188-3e71-c441-d453943fff44/
- link "DEVENS, JOHN S DEM | $173,151":
  - /url: /politicians/2975649a-bf04-9cc3-0457-bd81501cab1a/
- link "DUNCAN, JIM (JAMES W DUNCAN) DEM | $141,597":
  - /url: /politicians/4bbc0f9e-e9c3-54f3-550a-e2e7e0c7e6f6/
- link "GRUENSTEIN, PETER DEM | $127,081":
  - /url: /politicians/5c5820cd-a0cd-7689-3d63-8bfe4ef58740/
- link "BEGICH, MARGARET (PEGGE) DEM | $122,569":
  - /url: /politicians/96c6d941-1f42-8da7-288c-957a8eb3dafb/
- link "SMITH, TONY DEM | $98,124":
  - /url: /politicians/f3fe9b93-2f0f-e04e-39b2-52e8f9ee5a0e/
- link "HILL, BILL IND | $75,460":
  - /url: /politicians/653a2d2f-2d7c-aa0b-5a4e-9a8ef5a43de5/
- link "PALIN, SARAH REP | $56,763":
  - /url: /politicians/c430763c-a6c4-f585-2d8b-3162e8992a6a/
- link "GRUENING, CLARK DEM | $45,012":
  - /url: /politicians/7ae2afc9-47f7-4ee3-3c91-46de8cd04ee5/
- link "DUNBAR, FORREST DEM | $34,217":
  - /url: /politicians/56b37e1f-3a1b-60c9-5e04-24b40d54cb48/
- link "LINCOLN, GEORGIANNA DEM | $33,586":
  - /url: /politicians/d4352f6a-b836-9af7-5853-0b4d0f8f96c7/
- link "SWEENEY, TARA M REP | $31,300":
  - /url: /politicians/8b519f8c-c53c-399b-1b4d-cc3b3f038120/
- link "KENNEDY, ARTHUR RALPH REP | $18,612":
  - /url: /politicians/4b8880e0-1d40-2782-7914-e29ef56e9494/
- link "GROSS, ALAN IND | $16,000":
  - /url: /politicians/ef74021b-b108-2009-f431-fc373d24ac94/
- link "TREADWELL, MEAD REP | $15,850":
  - /url: /politicians/ade1903f-5ca0-6c7c-527b-2b9349718fe1/
- link "BENSON, DIANE E MS DEM | $15,500":
  - /url: /politicians/e6121050-d9ea-4858-a89f-27cf7d61b286/
- link "CRAWFORD, HARRY T JR DEM | $13,560":
  - /url: /politicians/2181e589-878b-10a1-9bc5-b017cc4fe980/
- link "COLLINS, VIRGINIA MARIE REP | $8,500":
  - /url: /politicians/56caba81-a01a-37ca-6b66-053b49b9aff5/
- link "HENSLEY, WILLIAM L DEM | $8,250":
  - /url: /politicians/f46207f0-5198-0f22-1cba-09b5a8b85dfe/
- link "HAVELOCK, JOHN ERIC DEM | $5,850":
  - /url: /politicians/8302e084-0bf8-f13b-c56e-44a60e3eb4bc/
- link "MILLER, MIKE REP | $5,500":
  - /url: /politicians/14cae40c-79a5-895d-7e78-a6b418540e4c/
- link "SCHULTZ, MATTHEW DAMIAN DEM | $5,050":
  - /url: /politicians/a9cde7b2-dbc9-2bab-08d2-c770f57540f2/
- link "METCALFE, JAMES K JAKE DEM | $5,000":
  - /url: /politicians/f85a4e73-a64b-1213-5cc1-4122cb1adf44/
- link "CHESBRO, PATRICIA DEM | $4,975":
  - /url: /politicians/0eaa0537-bcef-47b8-e7df-5bf2808d53c0/
- link "CUDDY, DAVID W REP | $4,537":
  - /url: /politicians/f769332d-a5ad-1953-1075-13fd3abcc2b7/
- link "BEASLEY, MICHAEL J DEM | $4,500":
  - /url: /politicians/5aefec02-fe89-86c1-1904-6eb4249521f2/
- link "STOCK, MARGARET IND | $4,000":
  - /url: /politicians/8233647f-159e-02b6-2e86-bf5449adead7/
- link "DAHL, THOMAS H DEM | $3,700":
  - /url: /politicians/2f00615e-e47d-32e0-9e7e-b42308d1e2bf/
- link "RODEY, PATRICK M DEM | $3,450":
  - /url: /politicians/1e81a818-7585-e4aa-0055-7642a55bbb21/
- link "LEDOUX, GABRIELLE R REP | $3,427":
  - /url: /politicians/f1e81780-a12d-2141-3b25-c8f6e07cd2b4/
- link "BIRD, ROBERT MARIO IND | $3,000":
  - /url: /politicians/5d304b09-9b38-5dcd-d81c-6b84433f0e69/
- text: Showing 1-50
- button "First" [disabled]
- button "Prev" [disabled]
- button "1"
- button "Next"
- heading "Committees" [level=2]
- paragraph: "Top committees headquartered in Alaska:"
- paragraph: Showing top 20 of 379 committees
- heading "Congressional Districts" [level=2]
- paragraph: Alaska has 1 seat in the U.S. House of Representatives.
- contentinfo:
  - paragraph:
    - link "elect.info":
      - /url: https://preview.elect.info/
    - text: "| Data from"
    - link "Federal Election Commission":
      - /url: https://preview.elect.info/datasources/fec.gov/
    - text: "| Generated 2026-10-22"
```

# Test source

```ts
  1  | import { test, expect } from '@playwright/test';
  2  | 
  3  | /*
  4  |  * Relocated states on the Leaflet map pages (electinfo/rundeck#852).
  5  |  *
  6  |  * The states view opens on the contiguous 48. Alaska, Hawaii and Puerto Rico
  7  |  * are drawn again, scaled and moved into open water in roughly their true
  8  |  * direction, dashed and labelled; DC gets a labelled marker. Clicking a label
  9  |  * fires the click of the state's real outline, so the drill-in uses the real
  10 |  * bounds and each page's own rules apply (precincts: HI has no VTD data, so
  11 |  * its click is a no-op there). The insets show at the national zoom only.
  12 |  * A jurisdiction with no boundary file yet (PR until GeoShapeImageSync has
  13 |  * run) simply has no inset.
  14 |  */
  15 | 
  16 | const PAGES = ['/districts/', '/counties/', '/places/', '/postalcodes/', '/tracts/', '/precincts/', '/blocks/'];
  17 | 
  18 | for (const path of PAGES) {
  19 |   test(`${path} map draws AK, HI and DC insets and drills in from a label`, async ({ page, request }) => {
  20 |     test.setTimeout(90000);
  21 |     const geo = await request.get('/geo/states/us-states.geojson');
  22 |     test.skip(geo.status() !== 200, 'state boundaries are not served in this environment');
  23 | 
  24 |     const res = await page.goto(path);
  25 |     expect(res?.status(), `${path} should answer 200`).toBe(200);
  26 |     await page.locator('.toggle-btn[data-view="map"]').click();
  27 | 
  28 |     const labels = page.locator('.map-inset-label');
  29 |     await expect(labels.first()).toBeVisible({ timeout: 30000 });
  30 |     for (const code of ['ak', 'hi', 'dc']) {
  31 |       await expect(page.locator(`.map-inset-label[data-state="${code}"]`)).toBeVisible();
  32 |     }
  33 | 
  34 |     // Alaska has shapes and precinct data on every page, so its label drills in.
  35 |     await page.locator('.map-inset-label[data-state="ak"]').click();
  36 |     await expect(labels).toHaveCount(0);
  37 |     await expect(page.locator('.map-back-btn').first()).toBeVisible({ timeout: 15000 });
  38 |   });
  39 | }
  40 | 
  41 | // /states/ has no drill-in: a state click opens its page, so the AK label
  42 | // lands on /states/ak/. The opening view frames the 48 and every inset.
  43 | test('/states/ map frames AK, HI and DC insets and a label opens the state page', async ({ page, request }) => {
  44 |   test.setTimeout(90000);
  45 |   const geo = await request.get('/geo/states/us-states.geojson');
  46 |   test.skip(geo.status() !== 200, 'state boundaries are not served in this environment');
  47 | 
  48 |   const res = await page.goto('/states/');
  49 |   expect(res?.status(), '/states/ should answer 200').toBe(200);
  50 |   await page.locator('.toggle-btn[data-view="map"]').click();
  51 | 
  52 |   await expect(page.locator('.map-inset-label').first()).toBeVisible({ timeout: 30000 });
  53 |   const map = await page.locator('#map').boundingBox();
  54 |   const codes = (await geo.json()).features.map((f: any) => f.properties.code);
  55 |   for (const code of ['ak', 'hi', 'dc', 'pr'].filter(c => codes.includes(c))) {
  56 |     const label = page.locator(`.map-inset-label[data-state="${code}"]`);
  57 |     await expect(label).toBeVisible();
  58 |     const box = await label.boundingBox();
  59 |     expect(box && map && box.x >= map.x && box.x + box.width <= map.x + map.width
  60 |       && box.y >= map.y && box.y + box.height <= map.y + map.height, `${code} label inside the map frame`).toBeTruthy();
  61 |   }
  62 | 
  63 |   await page.locator('.map-inset-label[data-state="ak"]').click();
> 64 |   await expect(page).toHaveURL(/\/states\/ak\/$/);
     |                      ^ Error: expect(page).toHaveURL(expected) failed
  65 | });
  66 | 
```