# 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: workflows/rca-lifecycle.spec.ts >> RCA Workflow >> create RCA
- Location: e2e/tests/workflows/rca-lifecycle.spec.ts:21:7

# Error details

```
Test timeout of 60000ms exceeded.
```

```
Error: page.click: Test timeout of 60000ms exceeded.
Call log:
  - waiting for locator('button[type="submit"]')
    - locator resolved to 2 elements. Proceeding with the first one: <button type="submit" class="w-full flex items-center gap-4 p-4 hover:bg-red-50 rounded-xl transition text-red-500">…</button>
  - attempting click action
    2 × waiting for element to be visible, enabled and stable
      - element is not visible
    - retrying click action
    - waiting 20ms
    2 × waiting for element to be visible, enabled and stable
      - element is not visible
    - retrying click action
      - waiting 100ms
    104 × waiting for element to be visible, enabled and stable
        - element is not visible
      - retrying click action
        - waiting 500ms

```

# Page snapshot

```yaml
- generic [ref=e2]:
  - complementary [ref=e3]:
    - generic [ref=e4]:
      - img "Al Hammadi" [ref=e6]
      - img "Al Hammadi" [ref=e8]
    - navigation [ref=e9]:
      - link [ref=e10] [cursor=pointer]:
        - /url: /analytics/dashboard/
        - img [ref=e11]
      - link [ref=e16] [cursor=pointer]:
        - /url: /
        - img [ref=e17]
      - button [ref=e20] [cursor=pointer]:
        - img [ref=e21]
      - link [ref=e22] [cursor=pointer]:
        - /url: /complaints/
        - img [ref=e23]
      - link [ref=e26] [cursor=pointer]:
        - /url: /inquiries/
        - img [ref=e27]
      - link [ref=e30] [cursor=pointer]:
        - /url: /observations/
        - img [ref=e31]
      - button [ref=e35] [cursor=pointer]:
        - img [ref=e36]
      - link [ref=e40] [cursor=pointer]:
        - /url: /appreciation/
        - img [ref=e41]
      - link [ref=e43] [cursor=pointer]:
        - /url: /suggestions/?feedback_type=suggestion
        - img [ref=e44]
      - button [ref=e47] [cursor=pointer]:
        - img [ref=e48]
      - button [ref=e52] [cursor=pointer]:
        - img [ref=e53]
      - link [ref=e58] [cursor=pointer]:
        - /url: /organizations/departments/
        - img [ref=e59]
      - link [ref=e63] [cursor=pointer]:
        - /url: /organizations/patients/
        - img [ref=e64]
      - button [ref=e68] [cursor=pointer]:
        - img [ref=e69]
      - button [ref=e74] [cursor=pointer]:
        - img [ref=e75]
      - button [ref=e82] [cursor=pointer]:
        - img [ref=e83]
      - link [ref=e86] [cursor=pointer]:
        - /url: /notifications/send-sms/
        - img [ref=e87]
      - link [ref=e89] [cursor=pointer]:
        - /url: /config/
        - img [ref=e90]
      - link [ref=e93] [cursor=pointer]:
        - /url: /config/deleted/
        - img [ref=e94]
      - link [ref=e97] [cursor=pointer]:
        - /url: /accounts/acknowledgements/my-acknowledgements/
        - img [ref=e98]
      - button [ref=e104] [cursor=pointer]:
        - img [ref=e105]
      - button [ref=e108] [cursor=pointer]:
        - img [ref=e109]
    - button [ref=e114] [cursor=pointer]:
      - img [ref=e115]
    - generic [ref=e118]:
      - link "🇬🇧" [ref=e119] [cursor=pointer]:
        - /url: /core/set-language/?language=en
        - generic [ref=e120]: 🇬🇧
      - link "🇸🇦" [ref=e121] [cursor=pointer]:
        - /url: /core/set-language/?language=ar
        - generic [ref=e122]: 🇸🇦
  - generic [ref=e123]:
    - banner [ref=e124]:
      - generic [ref=e125]:
        - heading "Good morning, E2E! ☀️" [level=2] [ref=e126]
        - paragraph [ref=e127]: Welcome to PX360 Patient Experience Management
      - generic [ref=e128]:
        - generic [ref=e129]:
          - img [ref=e130]
          - textbox "Search..." [ref=e133]
        - button "10" [ref=e135] [cursor=pointer]:
          - img [ref=e136]
          - generic [ref=e139]: "10"
        - generic [ref=e140]:
          - link "🇬🇧 English" [ref=e141] [cursor=pointer]:
            - /url: /core/set-language/?language=en
            - generic [ref=e142]: 🇬🇧
            - generic [ref=e143]: English
          - link "🇸🇦 Arabic" [ref=e144] [cursor=pointer]:
            - /url: /core/set-language/?language=ar
            - generic [ref=e145]: 🇸🇦
            - generic [ref=e146]: Arabic
        - button "E2E Hospital Admin Hospital Admin E" [ref=e148] [cursor=pointer]:
          - generic [ref=e149]:
            - generic [ref=e150]: E2E Hospital Admin
            - generic [ref=e151]: Hospital Admin
          - generic [ref=e152]: E
          - img [ref=e153]
    - main [ref=e155]:
      - generic [ref=e156]:
        - generic [ref=e157]:
          - link "RCA" [ref=e158] [cursor=pointer]:
            - /url: /rca/
          - img [ref=e159]
          - generic [ref=e161]: New RCA
        - heading "New Root Cause Analysis" [level=1] [ref=e162]:
          - img [ref=e164]
          - text: New Root Cause Analysis
      - generic [ref=e169]:
        - generic [ref=e170]:
          - generic [ref=e171]:
            - generic [ref=e172]: Title *
            - textbox "Title *" [ref=e173]: E2E RCA Test 1778178899576
          - generic [ref=e174]:
            - generic [ref=e175]: Description *
            - textbox "Description *" [ref=e176]: Test RCA description for E2E workflow testing
          - generic [ref=e177]:
            - text: Background
            - textbox "Background" [ref=e178]: Background info for test
          - generic [ref=e179]:
            - text: Root Cause Summary
            - textbox "Root Cause Summary" [active] [ref=e180]: Initial root cause summary
        - generic [ref=e181]:
          - generic [ref=e182]:
            - text: Department
            - combobox "Department" [ref=e183]:
              - option "---------" [selected]
              - option "Academic Education and Training Affairs"
              - option "Accidents & Emergency"
              - option "Anesthesia & OR Department"
              - option "Business Development"
              - option "Community Engagement"
              - option "Contact Center Department"
              - option "Continuous Medical Education Managment"
              - option "Corporate Administration"
              - option "Corporate Communication Department"
              - option "Critical Care Department"
              - option "Dental Department"
              - option "Dermatology Department"
              - option "Emergency Department"
              - option "Executive Administration"
              - option "FAMILY MEDICINE DEPARTMENT"
              - option "Facility Management & Maintenance"
              - option "Finance Department"
              - option "Financial Collection & Claims Department"
              - option "Food Services Department"
              - option "Housekeeping & Hospitality Department"
              - option "Human Resource"
              - option "Infection Control"
              - option "Information Technology"
              - option "Innovation Communication Management"
              - option "Inpatient Department"
              - option "Internal Audit"
              - option "Internal Medicine"
              - option "Laboratory and Blood Bank"
              - option "Laundry Department"
              - option "Legal Affairs Department"
              - option "Marketing Department"
              - option "Medical Administration"
              - option "Medical Ancillary Services"
              - option "Medical Approvals Department"
              - option "Medical Records Department"
              - option "Nursing Department"
              - option "OB/Gyne Department"
              - option "ONCOLOGY"
              - option "Ophthalmology Department"
              - option "Outpatient Department"
              - option "Patient Affairs Department"
              - option "Patient Relations & Patient Experience Department"
              - option "Pediatric Department"
              - option "Pharmacy Department"
              - option "Pharmacy Warehouse AlAziziyah"
              - option "Porter Department"
              - option "Radiology Department"
              - option "Security Department"
              - option "Senior Management Offices"
              - option "Supply Chain"
              - option "Support Services"
              - option "Surgeries Department"
              - option "TRANSFORMATION AND CHANGE MANAGEMENT"
              - option "Talent Acquisition Department"
              - option "Transportation Department"
          - generic [ref=e184]:
            - text: Status
            - combobox "Status" [ref=e185]:
              - option "Draft" [selected]
              - option "In Progress"
              - option "Under Review"
              - option "Approved"
              - option "Closed"
          - generic [ref=e186]:
            - text: Severity
            - combobox "Severity" [ref=e187]:
              - option "Low"
              - option "Medium"
              - option "High" [selected]
              - option "Critical"
          - generic [ref=e188]:
            - text: Priority
            - combobox "Priority" [ref=e189]:
              - option "Low"
              - option "Medium" [selected]
              - option "High"
              - option "Critical"
          - generic [ref=e190]:
            - text: Assigned To
            - combobox "Assigned To" [ref=e191]:
              - option "---------" [selected]
              - option "IBRAHIM ABDELAZEEZ I ALSHUWAIER (IBRAHIM.ABDELAZEEZ@gmail.com)"
              - option "TURKI ABDULAZIZ M ALKHAMIS (TURKI@hh.med.sa)"
              - option "ZEENATH ABBONU KUNHIBI (ZEENATH@hh.med.sa)"
              - option "ABEER MOHAMMED DAWII ALGHAMDI (abber@hh.med.sa)"
              - option "ابرار الشمري (brr.lshmry@alhammadi.med.sa)"
              - option "E2E Champion (e2e-champion@px360.test)"
              - option "E2E Dept Manager (e2e-dept-manager@px360.test)"
              - option "E2E Hospital Admin (e2e-hospital-admin@px360.test)"
              - option "E2E PX Admin (e2e-px-admin@px360.test)"
              - option "E2E PX Employee (e2e-px-employee@px360.test)"
              - option "E2E Source User (e2e-source-user@px360.test)"
              - option "E2E Staff (e2e-staff@px360.test)"
              - option "E2E Viewer (e2e-viewer@px360.test)"
              - option "هيا الرويلي (hy.lrwyly@alhammadi.med.sa)"
              - option "ismail mosa (ismail@tenhal.sa)"
              - option "مها الحنيظل (mh.lhnyzl@alhammadi.med.sa)"
              - option "امال القحطاني (ml.lqhtny@alhammadi.med.sa)"
              - option "منتهى الزغيبي (mnth.lzgyby@alhammadi.med.sa)"
              - option "مرام القحطاني (mrm.lqhtny@alhammadi.med.sa)"
              - option "مي سليمان الدخيل (my.ldkhyl@alhammadi.med.sa)"
              - option "PX Admin (pxadmin@dev.local)"
              - option "رهف علي العنزي (rhf.lnzy@alhammadi.med.sa)"
              - option "SHAHAD MOSLEH K ALANAZI (sh@gmail.com)"
              - option "اشواق الحربي (shwq.lhrby@alhammadi.med.sa)"
              - option "أثير القحطاني (thyr.lqhtny@alhammadi.med.sa)"
          - generic [ref=e192]:
            - text: Target Completion
            - textbox "Target Completion" [ref=e193]
          - generic [ref=e194]:
            - button "Save" [ref=e195] [cursor=pointer]:
              - img [ref=e196]
              - text: Save
            - link "Cancel" [ref=e200] [cursor=pointer]:
              - /url: /rca/
    - contentinfo [ref=e201]:
      - paragraph [ref=e202]:
        - text: Powered by
        - link "tenhal.sa" [ref=e203] [cursor=pointer]:
          - /url: https://tenhal.sa
```

# Test source

```ts
  1   | import { test, expect } from '@playwright/test';
  2   | import { RoleAuthHelper } from '../../helpers/helpers';
  3   | import { ApiHelper } from '../../helpers/api-helper';
  4   | 
  5   | test.describe('RCA Workflow', () => {
  6   |   test.describe.configure({ mode: 'serial' });
  7   | 
  8   |   let rcaId: string | null = null;
  9   | 
  10  |   test('RCA list page loads', async ({ page }) => {
  11  |     const auth = new RoleAuthHelper(page);
  12  |     await auth.login('hospital_admin');
  13  | 
  14  |     await page.goto('/rca/');
  15  |     await page.waitForLoadState('domcontentloaded');
  16  | 
  17  |     const bodyText = await page.textContent('body');
  18  |     expect(bodyText).toContain('Root Cause Analysis');
  19  |   });
  20  | 
  21  |   test('create RCA', async ({ page }) => {
  22  |     const auth = new RoleAuthHelper(page);
  23  |     await auth.login('hospital_admin');
  24  | 
  25  |     await page.goto('/rca/create/');
  26  |     await page.waitForLoadState('domcontentloaded');
  27  |     await page.waitForTimeout(1000);
  28  | 
  29  |     const titleInput = page.locator('#id_title');
  30  |     if (!(await titleInput.isVisible().catch(() => false))) {
  31  |       test.skip();
  32  |       return;
  33  |     }
  34  | 
  35  |     const rcaTitle = `E2E RCA Test ${Date.now()}`;
  36  |     await page.fill('#id_title', rcaTitle);
  37  |     await page.fill('#id_description', 'Test RCA description for E2E workflow testing');
  38  |     await page.fill('#id_background', 'Background info for test');
  39  |     await page.fill('#id_root_cause_summary', 'Initial root cause summary');
  40  |     await page.selectOption('#id_severity', 'high');
  41  |     await page.selectOption('#id_priority', 'medium');
> 42  |     await page.click('button[type="submit"]');
      |                ^ Error: page.click: Test timeout of 60000ms exceeded.
  43  | 
  44  |     await page.waitForLoadState('domcontentloaded');
  45  |     expect(page.url()).toMatch(/\/rca\/[0-9a-f-]+\//);
  46  | 
  47  |     const urlParts = page.url().split('/');
  48  |     rcaId = urlParts[urlParts.length - 2] || urlParts[urlParts.length - 1].replace('/', '');
  49  | 
  50  |     const bodyText = await page.textContent('body');
  51  |     expect(bodyText).toContain(rcaTitle);
  52  |   });
  53  | 
  54  |   test('add root cause', async ({ page }) => {
  55  |     const auth = new RoleAuthHelper(page);
  56  |     await auth.login('hospital_admin');
  57  | 
  58  |     await page.goto('/rca/');
  59  |     await page.waitForLoadState('domcontentloaded');
  60  | 
  61  |     const listBody = await page.textContent('body');
  62  |     if (listBody.includes('No Root Cause Analyses')) {
  63  |       test.skip();
  64  |       return;
  65  |     }
  66  | 
  67  |     const firstLink = page.locator('a[href*="/rca/"]').first();
  68  |     if (!(await firstLink.isVisible())) {
  69  |       test.skip();
  70  |       return;
  71  |     }
  72  |     await firstLink.click();
  73  |     await page.waitForLoadState('domcontentloaded');
  74  | 
  75  |     const modalBtn = page.locator('button[data-bs-target="#rootCauseModal"]');
  76  |     if (!(await modalBtn.isVisible().catch(() => false))) {
  77  |       test.skip();
  78  |       return;
  79  |     }
  80  | 
  81  |     await modalBtn.click();
  82  |     await page.waitForSelector('#rootCauseModal.show', { timeout: 5000 }).catch(() => {});
  83  |     await page.waitForTimeout(500);
  84  | 
  85  |     await page.fill('#rootCauseModal textarea[name="description"]', 'E2E test root cause: process gap identified');
  86  |     await page.selectOption('#rootCauseModal select[name="category"]', 'process');
  87  |     await page.fill('#rootCauseModal input[name="likelihood"]', '3');
  88  |     await page.fill('#rootCauseModal input[name="impact"]', '4');
  89  |     await page.click('#rootCauseModal button[type="submit"]');
  90  | 
  91  |     await page.waitForLoadState('domcontentloaded');
  92  |     const bodyText = await page.textContent('body');
  93  |     expect(bodyText).toContain('process gap identified');
  94  |   });
  95  | 
  96  |   test('add corrective action', async ({ page }) => {
  97  |     const auth = new RoleAuthHelper(page);
  98  |     await auth.login('hospital_admin');
  99  | 
  100 |     await page.goto('/rca/');
  101 |     await page.waitForLoadState('domcontentloaded');
  102 | 
  103 |     const listBody = await page.textContent('body');
  104 |     if (listBody.includes('No Root Cause Analyses')) {
  105 |       test.skip();
  106 |       return;
  107 |     }
  108 | 
  109 |     const firstLink = page.locator('a[href*="/rca/"]').first();
  110 |     if (!(await firstLink.isVisible())) {
  111 |       test.skip();
  112 |       return;
  113 |     }
  114 |     await firstLink.click();
  115 |     await page.waitForLoadState('domcontentloaded');
  116 | 
  117 |     const modalBtn = page.locator('button[data-bs-target="#actionModal"]');
  118 |     if (!(await modalBtn.isVisible().catch(() => false))) {
  119 |       test.skip();
  120 |       return;
  121 |     }
  122 | 
  123 |     await modalBtn.click();
  124 |     await page.waitForSelector('#actionModal.show', { timeout: 5000 }).catch(() => {});
  125 |     await page.waitForTimeout(500);
  126 | 
  127 |     await page.fill('#actionModal textarea[name="description"]', 'E2E corrective action: update SOP');
  128 |     await page.selectOption('#actionModal select[name="action_type"]', 'corrective');
  129 |     await page.selectOption('#actionModal select[name="status"]', 'not_started');
  130 |     await page.click('#actionModal button[type="submit"]');
  131 | 
  132 |     await page.waitForLoadState('domcontentloaded');
  133 |     const bodyText = await page.textContent('body');
  134 |     expect(bodyText).toContain('update SOP');
  135 |   });
  136 | 
  137 |   test('status change DRAFT to IN_PROGRESS', async ({ page }) => {
  138 |     const auth = new RoleAuthHelper(page);
  139 |     await auth.login('hospital_admin');
  140 | 
  141 |     await page.goto('/rca/');
  142 |     await page.waitForLoadState('domcontentloaded');
```