17 KiB
17 KiB
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-source-workflow.spec.ts >> PX Source Workflow Tests >> assign user to source
- Location: e2e/tests/workflows/px-source-workflow.spec.ts:42:7
Error details
Test timeout of 120000ms exceeded.
Error: locator.fill: Test timeout of 120000ms exceeded.
Call log:
- waiting for locator('input[name="email"]')
Page snapshot
- 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 "11" [ref=e135] [cursor=pointer]:
- img [ref=e136]
- generic [ref=e139]: "11"
- 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]:
- navigation [ref=e157]:
- list [ref=e158]:
- listitem [ref=e159]:
- link "PX Sources" [ref=e160] [cursor=pointer]:
- /url: /px-sources/
- listitem [ref=e161]:
- img [ref=e162]
- listitem [ref=e164]:
- link "E2E Test Source 1778178890341" [ref=e165] [cursor=pointer]:
- /url: /px-sources/acd2176e-4471-47a1-94b2-5c0c0a2c9233/
- listitem [ref=e166]:
- img [ref=e167]
- listitem [ref=e169]: Create Source User
- generic [ref=e171]:
- generic [ref=e172]:
- heading "Create Source User" [level=1] [ref=e173]:
- img [ref=e174]
- text: Create Source User
- paragraph [ref=e177]: E2E Test Source 1778178890341
- link "Back to Source" [ref=e178] [cursor=pointer]:
- /url: /px-sources/acd2176e-4471-47a1-94b2-5c0c0a2c9233/
- img [ref=e179]
- text: Back to Source
- generic [ref=e182]:
- generic [ref=e184]:
- button "Select Existing User" [ref=e185] [cursor=pointer]:
- img [ref=e186]
- text: Select Existing User
- button "Create New User" [ref=e191] [cursor=pointer]:
- img [ref=e192]
- text: Create New User
- generic [ref=e196]:
- generic [ref=e197]:
- generic [ref=e198]:
- generic [ref=e199]: Select User *
- combobox "Select User *" [ref=e200]:
- option "Choose a user..." [selected]
- option "IBRAHIM.ABDELAZEEZ@gmail.com - IBRAHIM ABDELAZEEZ I ALSHUWAIER (Staff)"
- option "TURKI@hh.med.sa - TURKI ABDULAZIZ M ALKHAMIS (Director)"
- option "ZEENATH@hh.med.sa - ZEENATH ABBONU KUNHIBI (PX Employee)"
- option "abber@hh.med.sa - ABEER MOHAMMED DAWII ALGHAMDI (Staff)"
- option "brr.lshmry@alhammadi.med.sa - ابرار الشمري"
- option "e2e-champion@px360.test - E2E Champion (Champion)"
- option "e2e-dept-manager@px360.test - E2E Dept Manager (Department Manager)"
- option "e2e-hospital-admin@px360.test - E2E Hospital Admin (Hospital Admin)"
- option "e2e-px-admin@px360.test - E2E PX Admin (PX Admin)"
- option "e2e-px-employee@px360.test - E2E PX Employee (PX Employee)"
- option "e2e-source-user@px360.test - E2E Source User (PX Source User)"
- option "e2e-staff@px360.test - E2E Staff (Staff)"
- option "e2e-viewer@px360.test - E2E Viewer (Viewer)"
- option "hy.lrwyly@alhammadi.med.sa - هيا الرويلي"
- option "ismail@tenhal.sa - ismail mosa"
- 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 "pxadmin@dev.local - PX Admin (PX Admin)"
- option "rhf.lnzy@alhammadi.med.sa - رهف علي العنزي"
- option "sh@gmail.com - SHAHAD MOSLEH K ALANAZI (PX Employee)"
- option "shwq.lhrby@alhammadi.med.sa - اشواق الحربي"
- option "thny.lqrny@alhammadi.med.sa - تهاني عبدالله القرني"
- option "thyr.lqhtny@alhammadi.med.sa - أثير القحطاني"
- paragraph [ref=e201]:
- img [ref=e202]
- text: Select an existing user to assign as source user. A user can only manage one source.
- generic [ref=e205]:
- img [ref=e206]
- generic [ref=e208]:
- paragraph [ref=e209]: Quick Tip
- paragraph [ref=e210]: If you need to create a new user account first, switch to the 'Create New User' tab above.
- generic [ref=e212]:
- text: Status
- generic [ref=e213] [cursor=pointer]:
- checkbox "Active" [checked] [ref=e214]
- generic [ref=e215]: Active
- paragraph [ref=e216]: Inactive users will not be able to access their dashboard.
- heading "Permissions" [level=5] [ref=e218]
- generic [ref=e219]:
- generic [ref=e221] [cursor=pointer]:
- checkbox "Can create complaints" [checked] [ref=e222]
- generic [ref=e223]: Can create complaints
- generic [ref=e225] [cursor=pointer]:
- checkbox "Can create inquiries" [checked] [ref=e226]
- generic [ref=e227]: Can create inquiries
- generic [ref=e229] [cursor=pointer]:
- checkbox "Can create observations" [checked] [ref=e230]
- generic [ref=e231]: Can create observations
- generic [ref=e233] [cursor=pointer]:
- checkbox "Can create suggestions" [checked] [ref=e234]
- generic [ref=e235]: Can create suggestions
- generic [ref=e237]:
- img [ref=e238]
- generic [ref=e240]: Permissions control what the source user can do in their dashboard. Uncheck to restrict access.
- generic [ref=e241]:
- button "Create Source User" [ref=e242] [cursor=pointer]:
- img [ref=e243]
- text: Create Source User
- link "Cancel" [ref=e245] [cursor=pointer]:
- /url: /px-sources/acd2176e-4471-47a1-94b2-5c0c0a2c9233/
- img [ref=e246]
- text: Cancel
- contentinfo [ref=e249]:
- paragraph [ref=e250]:
- text: Powered by
- link "tenhal.sa" [ref=e251] [cursor=pointer]:
- /url: https://tenhal.sa
Test source
1 | import { test, expect } from '@playwright/test';
2 | import { RoleAuthHelper, submitContentForm } from '../../helpers/helpers';
3 | import { HOSPITAL_ID } from '../../helpers/api-helper';
4 |
5 | test.describe('PX Source Workflow Tests', () => {
6 | test.setTimeout(120000);
7 | test.describe.configure({ mode: 'serial' });
8 |
9 | let sourceId: string;
10 |
11 | test('create PX source', async ({ page }) => {
12 | const auth = new RoleAuthHelper(page);
13 | await auth.login('hospital_admin');
14 | await page.waitForTimeout(800);
15 |
16 | await page.goto('/px-sources/new/');
17 | await page.waitForLoadState('domcontentloaded');
18 | await page.waitForTimeout(2500);
19 |
20 | const pageText = (await page.textContent('body')) || '';
21 | if (pageText.includes('404') || pageText.includes('403')) {
22 | test.skip();
23 | return;
24 | }
25 |
26 | await page.locator('input[name="name_en"]').fill(`E2E Test Source ${Date.now()}`);
27 | await page.waitForTimeout(300);
28 | await page.locator('input[name="code"]').fill(`E2E-${Date.now()}`);
29 | await page.waitForTimeout(300);
30 | await page.locator('input[name="contact_email"]').fill('e2e-source-test@px360.test');
31 | await page.waitForTimeout(300);
32 |
33 | await submitContentForm(page);
34 |
35 | const url = page.url();
36 | const m = url.match(/\/px-sources\/([0-9a-f-]+)\/?$/);
37 | sourceId = m ? m[1] : '';
38 | expect(url).not.toContain('/new/');
39 | await page.waitForTimeout(800);
40 | });
41 |
42 | test('assign user to source', async ({ page }) => {
43 | if (!sourceId) { test.skip(); return; }
44 |
45 | const auth = new RoleAuthHelper(page);
46 | await auth.login('hospital_admin');
47 | await page.waitForTimeout(800);
48 |
49 | await page.goto(`/px-sources/${sourceId}/users/create/`);
50 | await page.waitForLoadState('domcontentloaded');
51 | await page.waitForTimeout(2500);
52 |
> 53 | await page.locator('input[name="email"]').fill(`e2e-source-test-${Date.now()}@px360.test`);
| ^ Error: locator.fill: Test timeout of 120000ms exceeded.
54 | await page.waitForTimeout(300);
55 | await page.locator('input[name="first_name"]').fill('E2E');
56 | await page.waitForTimeout(300);
57 | await page.locator('input[name="last_name"]').fill('SourceTest');
58 | await page.waitForTimeout(300);
59 |
60 | await submitContentForm(page);
61 | expect(page.url()).not.toContain('/users/create');
62 | await page.waitForTimeout(800);
63 | });
64 |
65 | test('login as source user and access dashboard', async ({ page }) => {
66 | const auth = new RoleAuthHelper(page);
67 | await auth.login('source_user');
68 | await page.waitForTimeout(800);
69 |
70 | await page.waitForURL(/\/px-sources\/dashboard/, { timeout: 10000 }).catch(() => {});
71 | await page.waitForLoadState('domcontentloaded');
72 | await page.waitForTimeout(2500);
73 |
74 | expect(page.url()).toContain('/px-sources/');
75 | await page.waitForTimeout(800);
76 | });
77 |
78 | test('source user creates complaint', async ({ page }) => {
79 | const auth = new RoleAuthHelper(page);
80 | await auth.login('source_user');
81 | await page.waitForTimeout(800);
82 |
83 | await page.goto('/px-sources/complaints/new/');
84 | await page.waitForLoadState('domcontentloaded');
85 | await page.waitForTimeout(2500);
86 |
87 | const fields: [string, string][] = [
88 | ['complainant_name', `E2E Source User ${Date.now()}`],
89 | ['mobile_number', '0509998877'],
90 | ['patient_name', `E2E Patient ${Date.now()}`],
91 | ['national_id', `E2E${Date.now()}`.substring(0, 20)],
92 | ['complaint_details', `E2E source complaint test ${Date.now()}. Please ignore.`],
93 | ];
94 | for (const [name, value] of fields) {
95 | const f = page.locator(`input[name="${name}"], textarea[name="${name}"]`);
96 | if (await f.count() > 0) { await f.fill(value); await page.waitForTimeout(200); }
97 | }
98 | const relField = page.locator('select[name="relation_to_patient"]');
99 | if (await relField.count() > 0) await relField.selectOption('patient');
100 | const dateField = page.locator('input[name="incident_date"]');
101 | if (await dateField.count() > 0) {
102 | const now = new Date();
103 | const p = (n: number) => String(n).padStart(2, '0');
104 | await dateField.fill(`${now.getFullYear()}-${p(now.getMonth()+1)}-${p(now.getDate())}`);
105 | }
106 |
107 | await submitContentForm(page);
108 | expect(page.url()).not.toContain('/complaints/new');
109 | await page.waitForTimeout(800);
110 | });
111 |
112 | test('source user creates inquiry', async ({ page }) => {
113 | const auth = new RoleAuthHelper(page);
114 | await auth.login('source_user');
115 | await page.waitForTimeout(800);
116 |
117 | await page.goto('/px-sources/inquiries/new/');
118 | await page.waitForLoadState('domcontentloaded');
119 | await page.waitForTimeout(2500);
120 |
121 | const subjectField = page.locator('input[name="subject"]');
122 | if (await subjectField.count() > 0) await subjectField.fill(`E2E Source Inquiry ${Date.now()}`);
123 | const msgField = page.locator('textarea[name="message"]');
124 | if (await msgField.count() > 0) await msgField.fill(`E2E source inquiry test ${Date.now()}. Please ignore.`);
125 |
126 | await submitContentForm(page);
127 | expect(page.url()).not.toContain('/inquiries/new');
128 | await page.waitForTimeout(800);
129 | });
130 |
131 | test('source user creates observation', async ({ page }) => {
132 | const auth = new RoleAuthHelper(page);
133 | await auth.login('source_user');
134 | await page.waitForTimeout(800);
135 |
136 | await page.goto('/px-sources/observations/new/');
137 | await page.waitForLoadState('domcontentloaded');
138 | await page.waitForTimeout(2500);
139 |
140 | const descField = page.locator('textarea[name="description"]');
141 | if (await descField.count() > 0) await descField.fill(`E2E source observation test ${Date.now()}. Please ignore.`);
142 |
143 | await submitContentForm(page);
144 | expect(page.url()).not.toContain('/observations/new');
145 | await page.waitForTimeout(800);
146 | });
147 |
148 | test('source user creates suggestion', async ({ page }) => {
149 | const auth = new RoleAuthHelper(page);
150 | await auth.login('source_user');
151 | await page.waitForTimeout(800);
152 |
153 | await page.goto('/px-sources/suggestions/new/');