# 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

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

Locator: getByRole('table', { name: /Weekly schedule/i })
Expected: visible
Timeout: 20000ms
Error: element(s) not found

Call log:
  - Expect "toBeVisible" with timeout 20000ms
  - waiting for getByRole('table', { name: /Weekly schedule/i })

```

```yaml
- alert
- complementary:
  - link "Alqove":
    - /url: /seller
    - img "Alqove"
  - paragraph: Seller Dashboard
  - text: Store
  - combobox "Store":
    - option "E2E-fcbd96e7b97048ba Store A" [selected]
    - option "E2E-fcbd96e7b97048ba Store B"
  - navigation:
    - link "Dashboard":
      - /url: /seller
    - link "Inbox":
      - /url: /seller/inbox
    - link "Listings":
      - /url: /seller/listings
    - link "Orders":
      - /url: /seller/orders
    - link "Returns":
      - /url: /seller/returns
    - link "Payouts":
      - /url: /seller/payouts
    - link "Statements":
      - /url: /seller/statements
    - link "Reviews":
      - /url: /seller/reviews
    - link "Team":
      - /url: /seller/team
    - link "Schedule":
      - /url: /seller/schedule
    - link "Timesheets":
      - /url: /seller/timesheets
    - link "Payroll":
      - /url: /seller/payroll
    - link "Schedule settings":
      - /url: /seller/settings/schedule
    - link "Settings":
      - /url: /seller/settings
- banner:
  - text: E2E-fcbd96e7b97048ba Store A
  - button "Notifications"
- main:
  - main:
    - heading "Schedule" [level=1]
    - button "Previous week" [disabled]
    - text: Week containing
    - textbox "Week containing": 2026-10-05
    - button "Next week" [disabled]
    - button "Reload week"
    - alert: Could not load the schedule. Reload to try again.
```

# 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();
     |                                                                       ^ Error: expect(locator).toBeVisible() failed
  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);
  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 | 
```