# 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: 20-schedule-browser.spec.ts >> owner creates assigned/open drafts, publishes to staff/team, edits back to draft and switches tenants
- Location: e2e-scheduling-real/20-schedule-browser.spec.ts:3:5

# Error details

```
Test timeout of 90000ms exceeded.
```

```
Error: locator.selectOption: Test timeout of 90000ms exceeded.
Call log:
  - waiting for getByRole('dialog').getByLabel('Employee', { exact: true })

```

# Page snapshot

```yaml
- generic [active] [ref=e1]:
  - button "Open Next.js Dev Tools" [ref=e7] [cursor=pointer]:
    - img [ref=e8]
  - alert [ref=e11]: Alqove — Resale Marketplace
  - generic [ref=e12]: Loading…
```

# Test source

```ts
  1  | import { test, expect, fixture, login, api, dbRows, evidence } from './helpers';
  2  | 
  3  | test('owner creates assigned/open drafts, publishes to staff/team, edits back to draft and switches tenants', async ({ page, request, browser }) => {
  4  |   const week = '2026-10-05';
  5  |   const assignedNote = fixture.marker + ' assigned';
  6  |   const openNote = fixture.marker + ' open';
  7  |   await login(page, 'owner', '/seller/schedule');
  8  |   await page.getByLabel('Week containing', { exact: true }).fill(week);
  9  |   await expect(page.getByRole('table', { name: /Weekly schedule/i })).toBeVisible();
  10 |   for (const [membership, notes, day] of [[fixture.actors.staff.memberships.a, assignedNote, week], ['', openNote, '2026-10-06']]) {
  11 |     await page.getByRole('button', { name: 'Add shift', exact: true }).click();
  12 |     const dialog = page.getByRole('dialog');
> 13 |     await dialog.getByLabel('Employee', { exact: true }).selectOption(membership);
     |                                                          ^ Error: locator.selectOption: Test timeout of 90000ms exceeded.
  14 |     await dialog.getByLabel('Starts (store time)', { exact: true }).fill(`${day}T09:00`);
  15 |     await dialog.getByLabel('Ends (store time)', { exact: true }).fill(`${day}T17:00`);
  16 |     await dialog.getByLabel('Notes', { exact: true }).fill(notes);
  17 |     await dialog.getByRole('button', { name: 'Save shift', exact: true }).click();
  18 |     await expect(dialog).toHaveCount(0);
  19 |   }
  20 |   const drafts = await api(request, 'owner', 'GET', `/schedule/week?week_start=${week}`);
  21 |   expect(drafts.shifts).toHaveLength(2);
  22 |   expect(drafts.shifts.every((s: any) => s.published_at === null)).toBe(true);
  23 |   expect(drafts.shifts.filter((s: any) => s.store_membership_id === null)).toHaveLength(1);
  24 |   const assigned = drafts.shifts.find((s: any) => s.notes === assignedNote);
  25 |   expect(dbRows('shifts').find((s: any) => s.id === assigned.id).published_at).toBeNull();
  26 |   expect((await api(request, 'staff', 'GET', `/my/schedule?week_start=${week}`)).shifts).toHaveLength(0);
  27 |   expect((await api(request, 'staff', 'GET', `/schedule/week?week_start=${week}`)).shifts).toHaveLength(0);
  28 |   const context = await browser.newContext();
  29 |   const staff = await context.newPage();
  30 |   try {
  31 |     await login(staff, 'staff', '/staff/schedule');
  32 |     await staff.getByLabel('Week containing', { exact: true }).fill(week);
  33 |     await expect(staff.getByText(assignedNote, { exact: true })).toHaveCount(0);
  34 |     await page.getByRole('button', { name: 'Publish week', exact: true }).click();
  35 |     await expect.poll(async () => (await api(request, 'staff', 'GET', `/my/schedule?week_start=${week}`)).shifts.length).toBe(1);
  36 |     await staff.getByRole('button', { name: 'Reload week', exact: true }).click();
  37 |     await expect(staff.getByText(assignedNote, { exact: true })).toBeVisible();
  38 |     expect((await api(request, 'staff', 'GET', `/schedule/week?week_start=${week}`)).shifts).toHaveLength(2);
  39 |     // Editing a published shift uses its fresh opaque revision and hides it again.
  40 |     await page.getByRole('button', { name: new RegExp(fixture.actors.staff.name + '.*09:00') }).click();
  41 |     const dialog = page.getByRole('dialog');
  42 |     await dialog.getByLabel('Notes', { exact: true }).fill(assignedNote + ' revised');
  43 |     await dialog.getByRole('button', { name: 'Save shift', exact: true }).click();
  44 |     await expect(dialog).toHaveCount(0);
  45 |     const after = await api(request, 'owner', 'GET', `/schedule/week?week_start=${week}`);
  46 |     expect(after.shifts.find((s: any) => s.id === assigned.id).published_at).toBeNull();
  47 |     await staff.getByRole('button', { name: 'Reload week', exact: true }).click();
  48 |     await expect(staff.getByText(assignedNote, { exact: true })).toHaveCount(0);
  49 |     expect((await api(request, 'staff', 'GET', `/my/schedule?week_start=${week}`)).shifts).toHaveLength(0);
  50 |     await page.getByRole('combobox', { name: 'Store', exact: true }).selectOption(fixture.stores.b.id);
  51 |     await page.getByLabel('Week containing', { exact: true }).fill(week);
  52 |     await expect(page.getByText(openNote, { exact: true })).toHaveCount(0);
  53 |     await expect(page.getByText(assignedNote + ' revised', { exact: true })).toHaveCount(0);
  54 |     expect((await api(request, 'owner', 'GET', `/schedule/week?week_start=${week}`, undefined, 200, 'b')).shifts).toHaveLength(0);
  55 |     await evidence('schedule-browser-draft-publish-edit-switch', { drafts, after, sql: dbRows('shifts') });
  56 |   } finally { await context.close(); }
  57 | });
  58 | 
```