# 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/money-flow-mount.spec.ts >> Vendor: two-column mount still toggles and disposes
- Location: tests/ui/money-flow-mount.spec.ts:10:7

# Error details

```
Test timeout of 30000ms exceeded.
```

```
Error: apiRequestContext.get: Test timeout of 30000ms exceeded.
Call log:
  - → GET http://10.1.105.75/js/money-flow.js
    - user-agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/156.0.8078.4 Safari/537.36
    - accept: */*
    - accept-encoding: gzip,deflate,br

```

# Page snapshot

```yaml
- generic [ref=e2]:
  - heading "Payments" [level=2] [ref=e3]
  - table [ref=e4]:
    - rowgroup [ref=e5]:
      - row [ref=e6]:
        - cell "Original table" [ref=e7]
```

# Test source

```ts
  1  | import { test, expect } from '@playwright/test';
  2  | 
  3  | // Exercise the shared mount contract with the real ECharts bundle, independent
  4  | // of graph data. In particular, middle-column support must not alter old cards.
  5  | for (const [kind, side, counterparty] of [
  6  |   ['Candidate', 'in', 'Committee'],
  7  |   ['Committee', 'out', 'Vendor'],
  8  |   ['Vendor', 'in', 'Committee'],
  9  | ] as const) {
  10 |   test(`${kind}: two-column mount still toggles and disposes`, async ({ page }) => {
  11 |     const errors: string[] = [];
  12 |     page.on('pageerror', error => errors.push(error.message));
  13 |     await page.route('**/mock-money-flow/', route => route.fulfill({
  14 |       contentType: 'text/html', body: '<!doctype html><html><head></head><body><section id="flow"><h2>Payments</h2><table><tbody><tr><td>Original table</td></tr></tbody></table></section></body></html>',
  15 |     }));
  16 |     await page.goto('/mock-money-flow/');
  17 |     // A route-fulfilled HTTP document has no real network address space.
  18 |     // Chromium blocks its script request to the private preview Service (LNA),
  19 |     // even though the bundle is available. Fetch through the authenticated
  20 |     // request context, then inject those exact served bytes, not a local build.
> 21 |     const bundle = await page.request.get('/js/money-flow.js');
     |                                       ^ Error: apiRequestContext.get: Test timeout of 30000ms exceeded.
  22 |     expect(bundle.status(), 'served money-flow bundle should load').toBe(200);
  23 |     expect(bundle.headers()['content-type']).toMatch(/(?:java|ecma)script/);
  24 |     await page.addScriptTag({ content: await bundle.text() });
  25 |     const mounted = await page.evaluate(({ kind, side, counterparty }) => {
  26 |       localStorage.removeItem('electinfo:money-flow-view');
  27 |       const base = { fecId: null, entityId: null, party: null, affinityDem: null, affinityRep: null, amount: 100, count: 1, otherCount: null };
  28 |       const section = document.getElementById('flow')!;
  29 |       return window.electinfoMoneyFlow!.mount({
  30 |         section, heading: section.querySelector('h2')!, list: section.querySelector('table')!, side,
  31 |         nodes: [
  32 |           { ...base, id: 'focal', name: 'Focal entity', kind, side: 'focal' },
  33 |           { ...base, id: 'counterparty', name: 'Counterparty', kind: counterparty, side },
  34 |         ],
  35 |         links: [{ source: side === 'in' ? 'counterparty' : 'focal', target: side === 'in' ? 'focal' : 'counterparty', amount: 100, count: 1, flow: 'payment' }],
  36 |       });
  37 |     }, { kind, side, counterparty });
  38 |     expect(mounted).toBe(true);
  39 |     await expect(page.locator('#flow canvas')).toBeVisible();
  40 |     expect(await page.locator('#flow').evaluate(el => (window.electinfoMoneyFlow!.inspect!(el)!.option as any).animation)).not.toBe(false);
  41 |     await page.getByRole('button', { name: 'Table view', exact: true }).click();
  42 |     await expect(page.locator('#flow table')).toBeVisible();
  43 |     await expect(page.locator('#flow canvas')).toBeHidden();
  44 |     await page.getByRole('button', { name: 'Sankey view', exact: true }).click();
  45 |     await expect(page.locator('#flow canvas')).toBeVisible();
  46 |     await page.evaluate(() => window.electinfoMoneyFlow!.unmount!(document.getElementById('flow')!));
  47 |     await expect(page.locator('#flow canvas')).toHaveCount(0);
  48 |     await expect(page.locator('#flow .mf-toggle')).toHaveCount(0);
  49 |     await expect(page.locator('#flow table')).toBeVisible();
  50 |     await expect(page.locator('#flow > h2')).toHaveText('Payments');
  51 |     expect(errors).toEqual([]);
  52 |   });
  53 | }
  54 | 
```