# 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/px-employee-creates.spec.ts >> PX Employee Creates Tests >> create QI project - Location: e2e/tests/workflows/px-employee-creates.spec.ts:128:7 # Error details ``` Error: expect(received).toBeTruthy() Received: false ``` # 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]: - link "Back to Projects" [ref=e157] [cursor=pointer]: - /url: /projects/ - img [ref=e158] - generic [ref=e160]: Back to Projects - generic [ref=e163]: - heading "Create QI Project" [level=1] [ref=e164]: - img [ref=e165] - text: Create QI Project - paragraph [ref=e166]: Start a new quality improvement initiative - generic [ref=e167]: - heading "Project Information" [level=2] [ref=e168] - generic [ref=e169]: - generic [ref=e170]: - generic [ref=e171]: - generic [ref=e172]: Project Name * - textbox "Project Name *" [ref=e173]: - /placeholder: Project name - text: E2E QI Project 1778178889237 - generic [ref=e174]: - text: Project Name (Arabic) - textbox "Project Name (Arabic)" [ref=e175]: - /placeholder: Ψ§Ψ³Ω… Ψ§Ω„Ω…Ψ΄Ψ±ΩˆΨΉ - generic [ref=e176]: - generic [ref=e177]: Description * - textbox "Description *" [ref=e178]: - /placeholder: Describe the project objectives and scope... - text: E2E QI project test 1778178889661. Please ignore. - paragraph [ref=e179]: Describe the project objectives and scope - generic [ref=e181]: - text: Department - combobox "Department" [ref=e182]: - 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=e183]: - generic [ref=e184]: - text: Project Lead - combobox "Project Lead" [ref=e185]: - option "---------" [selected] - option "E2E PX Employee (e2e-px-employee@px360.test)" - option "SHAHAD MOSLEH K ALANAZI (sh@gmail.com)" - option "ZEENATH ABBONU KUNHIBI (ZEENATH@hh.med.sa)" - paragraph [ref=e186]: This field is required. - generic [ref=e187]: - generic [ref=e188]: Status * - combobox "Status *" [ref=e189]: - option "Active" - option "Inactive" - option "Pending" [selected] - option "Completed" - option "Cancelled" - generic [ref=e190]: - text: Team Members - listbox "Team Members" [ref=e191]: - option "E2E PX Employee (e2e-px-employee@px360.test)" [ref=e192] - option "SHAHAD MOSLEH K ALANAZI (sh@gmail.com)" [ref=e193] - option "ZEENATH ABBONU KUNHIBI (ZEENATH@hh.med.sa)" [ref=e194] - paragraph [ref=e195]: Hold Ctrl/Cmd to select multiple team members - generic [ref=e196]: - generic [ref=e197]: - text: Start Date - textbox "Start Date" [ref=e198] - generic [ref=e199]: - text: Target Completion Date - textbox "Target Completion Date" [ref=e200] - generic [ref=e201]: - button "Create Project" [ref=e202] [cursor=pointer]: - img [ref=e203] - text: Create Project - link "Cancel" [ref=e207] [cursor=pointer]: - /url: /projects/ - img [ref=e208] - text: Cancel - contentinfo [ref=e211]: - paragraph [ref=e212]: - text: Powered by - link "tenhal.sa" [ref=e213] [cursor=pointer]: - /url: https://tenhal.sa ``` # Test source ```ts 49 | await page.waitForTimeout(800); 50 | }); 51 | 52 | test('create observation via internal form', async ({ page }) => { 53 | const auth = new RoleAuthHelper(page); 54 | await auth.login('px_employee'); 55 | await page.waitForTimeout(800); 56 | 57 | const obsId = await createObsInternal(page); 58 | expect(obsId).toBeTruthy(); 59 | await page.waitForTimeout(800); 60 | }); 61 | 62 | test('create inquiry via internal form', async ({ page }) => { 63 | const auth = new RoleAuthHelper(page); 64 | await auth.login('px_employee'); 65 | await page.waitForTimeout(800); 66 | 67 | await page.goto('/inquiries/new/'); 68 | await page.waitForLoadState('domcontentloaded'); 69 | await page.waitForTimeout(2500); 70 | 71 | const subjectField = page.locator('input[name="subject"], #id_subject'); 72 | if (await subjectField.count() > 0) { await subjectField.fill(`E2E Emp Inquiry ${Date.now()}`); await page.waitForTimeout(400); } 73 | const msgField = page.locator('textarea[name="message"], #id_message'); 74 | if (await msgField.count() > 0) { await msgField.fill(`E2E employee inquiry test ${Date.now()}. Please ignore.`); await page.waitForTimeout(400); } 75 | const categoryField = page.locator('select[name="category"], #id_category'); 76 | if (await categoryField.count() > 0) { await categoryField.selectOption({ index: 1 }); await page.waitForTimeout(400); } 77 | 78 | await submitContentForm(page); 79 | 80 | const url = page.url(); 81 | const ok = url.match(/\/inquiries\/[0-9a-f-]+\/?$/) || !url.includes('/new/'); 82 | expect(ok).toBeTruthy(); 83 | await page.waitForTimeout(800); 84 | }); 85 | 86 | test('create suggestion via internal form', async ({ page }) => { 87 | const auth = new RoleAuthHelper(page); 88 | await auth.login('px_employee'); 89 | await page.waitForTimeout(800); 90 | 91 | await page.goto('/suggestions/create/'); 92 | await page.waitForLoadState('domcontentloaded'); 93 | await page.waitForTimeout(2500); 94 | 95 | const pageText = (await page.textContent('body')) || ''; 96 | if (pageText.includes('Page not found') || pageText.includes('404')) { test.skip(); return; } 97 | 98 | const contactName = page.locator('input[name="contact_name"], #id_contact_name'); 99 | if (await contactName.count() > 0) { await contactName.fill('E2E Test User'); await page.waitForTimeout(300); } 100 | const contactPhone = page.locator('input[name="contact_phone"], #id_contact_phone'); 101 | if (await contactPhone.count() > 0) { await contactPhone.fill('0501112233'); await page.waitForTimeout(300); } 102 | const msgField = page.locator('textarea[name="message"], #id_message'); 103 | if (await msgField.count() > 0) { await msgField.fill(`E2E employee suggestion test ${Date.now()}. Please ignore.`); await page.waitForTimeout(300); } 104 | const hospField = page.locator('select[name="hospital"], #id_hospital'); 105 | if (await hospField.count() > 0) { 106 | const hasValue = await hospField.inputValue(); 107 | if (!hasValue) { await hospField.selectOption(HOSPITAL_ID); await page.waitForTimeout(300); } 108 | } 109 | 110 | await submitContentForm(page); 111 | expect(page.url()).not.toContain('/create/'); 112 | await page.waitForTimeout(800); 113 | }); 114 | 115 | test('create appreciation via public API', async ({ page }) => { 116 | const resp = await page.request.post('/appreciation/public/submit/', { 117 | data: { 118 | contact_name: `E2E Test ${Date.now()}`, 119 | contact_phone: '0504445566', 120 | message: `E2E employee appreciation test ${Date.now()}. Great work!`, 121 | hospital: HOSPITAL_ID, 122 | }, 123 | }); 124 | expect([200, 201].includes(resp.status())).toBeTruthy(); 125 | await page.waitForTimeout(800); 126 | }); 127 | 128 | test('create QI project', async ({ page }) => { 129 | const auth = new RoleAuthHelper(page); 130 | await auth.login('hospital_admin'); 131 | await page.waitForTimeout(800); 132 | 133 | await page.goto('/projects/create/'); 134 | await page.waitForLoadState('domcontentloaded'); 135 | await page.waitForTimeout(2500); 136 | 137 | const pageText = (await page.textContent('body')) || ''; 138 | if (pageText.includes('Page not found') || pageText.includes('403') || pageText.includes('404')) { test.skip(); return; } 139 | 140 | const nameField = page.locator('input[name="name"], #id_name'); 141 | if (await nameField.count() > 0) { await nameField.fill(`E2E QI Project ${Date.now()}`); await page.waitForTimeout(400); } 142 | const descField = page.locator('textarea[name="description"], #id_description'); 143 | if (await descField.count() > 0) { await descField.fill(`E2E QI project test ${Date.now()}. Please ignore.`); await page.waitForTimeout(400); } 144 | 145 | await submitContentForm(page); 146 | 147 | const url = page.url(); 148 | const ok = url.match(/\/projects\/[0-9a-f-]+\/?$/) || !url.includes('/create/'); > 149 | expect(ok).toBeTruthy(); | ^ Error: expect(received).toBeTruthy() 150 | await page.waitForTimeout(800); 151 | }); 152 | }); 153 | ```