# 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: 30-clock-payroll.spec.ts >> staff clocks and breaks through real buttons with durable idempotent replay
- Location: e2e-scheduling-real/30-clock-payroll.spec.ts:7:5

# Error details

```
Error: expect(locator).toBeVisible() failed

Locator: getByRole('combobox', { name: 'Store', exact: true })
Expected: visible
Timeout: 20000ms
Error: element(s) not found

Call log:
  - Expect "toBeVisible" with timeout 20000ms
  - waiting for getByRole('combobox', { name: 'Store', exact: true })

```

```yaml
- img
- heading "This page couldn’t load" [level=1]
- paragraph: Reload to try again, or go back.
- button "Reload"
- button "Back"
```

# Test source

```ts
  1  | import { test, expect, type Page, type APIRequestContext } from '@playwright/test';
  2  | import fs from 'node:fs';
  3  | import path from 'node:path';
  4  | import { execFileSync } from 'node:child_process';
  5  | 
  6  | export { test, expect };
  7  | export const runDir = process.env.QA_RUN_DIR!;
  8  | export const fixture = JSON.parse(fs.readFileSync(path.join(runDir, 'manifest.json'), 'utf8'));
  9  | if (fixture.marker !== process.env.QA_MARKER || fixture.database !== path.join(runDir, 'database.sqlite')) throw new Error('Fixture identity mismatch');
  10 | export type Actor = 'owner' | 'manager' | 'staff' | 'outsider';
  11 | export const API = 'http://127.0.0.1:8105';
  12 | export const storePath = (suffix: string, store: 'a' | 'b' = 'a') => `/v1/stores/${fixture.stores[store].id}${suffix}`;
  13 | 
  14 | export async function api(request: APIRequestContext, actor: Actor, method: string, suffix: string, data?: unknown, status = 200, store: 'a' | 'b' = 'a', key?: string) {
  15 |   const response = await request.fetch(API + storePath(suffix, store), {
  16 |     method, data, headers: { Authorization: `Bearer ${fixture.actors[actor].token}`, Accept: 'application/json', ...(key ? { 'Idempotency-Key': key } : {}) },
  17 |   });
  18 |   // Never include request options/credentials in failure messages.
  19 |   const text = await response.text();
  20 |   expect(response.status(), `${method} ${suffix}: ${text.slice(0, 1800)}`).toBe(status);
  21 |   return text ? JSON.parse(text).data : undefined;
  22 | }
  23 | 
  24 | export async function login(page: Page, actor: Actor, target: string, store: 'a' | 'b' = 'a') {
  25 |   await page.goto(`/login?next=${encodeURIComponent(target)}`);
  26 |   await page.getByLabel('Email', { exact: true }).fill(fixture.actors[actor].email);
  27 |   await page.getByLabel('Password', { exact: true }).fill(fixture.actors[actor].password);
  28 |   await page.getByRole('button', { name: 'Sign In', exact: true }).click();
  29 |   await expect.poll(async () => page.evaluate(() => !!localStorage.getItem('auth_token'))).toBe(true);
  30 |   await page.goto(target);
  31 |   const selector = page.getByRole('combobox', { name: 'Store', exact: true });
> 32 |   await expect(selector).toBeVisible();
     |                          ^ Error: expect(locator).toBeVisible() failed
  33 |   await selector.selectOption(fixture.stores[store].id);
  34 | }
  35 | 
  36 | export function dbRows(table: 'shifts' | 'time_punches' | 'timesheets' | 'payroll_exports', store: 'a' | 'b' = 'a') {
  37 |   return JSON.parse(execFileSync('python3', [path.join(__dirname, 'readback.py'), runDir, table, fixture.stores[store].id], { encoding: 'utf8' }));
  38 | }
  39 | 
  40 | export async function evidence(name: string, value: unknown) {
  41 |   const body = JSON.stringify(value, null, 2);
  42 |   fs.writeFileSync(path.join(runDir, `${name}.json`), body, { mode: 0o600 });
  43 |   await test.info().attach(name, { body, contentType: 'application/json' });
  44 | }
  45 | 
```