Problem
CSS selectors and locator strings are hardcoded directly in step files (tests/e2e/steps/ui/) and even inside page object methods instead of being defined as module-level constants. This causes:
- Duplication -- same selector repeated across files (
#web-content appears in session.ts AND public.ts)
- Brittleness -- a UI change requires hunting down every inline usage
- Inconsistency -- some page objects define selectors at the top, others embed them inside methods
- Magic strings -- literal values like
'download', 'move', 'Incorrect password' used in assertions without named constants
Occurrences Found
A. Hardcoded Selectors in Step Files (bypass page objects entirely)
| No. |
File |
Line |
Current Code |
| 1 |
tests/e2e/steps/ui/session.ts |
59 |
page.locator('#web-content').waitFor() |
| 2 |
tests/e2e/steps/ui/session.ts |
77 |
page.locator('#input-error-otp') |
| 3 |
tests/e2e/steps/ui/session.ts |
106 |
page.locator('#_userMenuButton').count() |
| 4 |
tests/e2e/steps/ui/session.ts |
156 |
page.locator('#oc-login-error-message') |
The Session page object (tests/e2e/support/objects/runtime/session.ts) already encapsulates most login/logout logic. Step functions should call page object methods instead of using these selectors directly.
B. Inline Selectors Inside Page Object Methods (not using module-level constants)
Several page objects define selectors inline inside method bodies rather than as module-level constants:
| No. |
File |
Line(s) |
Selectors Used Inline |
| 5 |
runtime/session.ts |
22, 28-30, 34-42 |
'button[type="submit"]', '#username', '#password', '#kc-login', '#otp' |
| 6 |
app-admin-settings/general/actions.ts |
17, 20, 52, 68, 73-75 |
'#logo-upload-input', '.oc-notification-message', '#kc-totp-secret-qr-code', '#totp', '#userLabel', '#saveTOTPBtn' |
| 7 |
app-admin-settings/page/general.ts |
12-13 |
'//a[@data-nav-name="admin-settings-general"]', '#app-loading-spinner' |
| 8 |
app-files/utils/sidebar.ts |
153-154 |
'.sidebar-panel.is-active', '.header__back' |
| 9 |
app-files/page/public.ts |
76, 114 |
'#web-content', 'body' |
| 10 |
url-navigation/actions.ts |
94 |
'.page-not-found' |
C. Magic Strings in Step Files
| No. |
File |
Line |
Magic String |
Should Be |
| 11 |
steps/ui/resources.ts |
600 |
'download' |
Named constant for expected filename |
| 12 |
steps/ui/resources.ts |
616 |
'download' |
Named constant |
| 13 |
steps/ui/resources.ts |
1249 |
'move' |
fileAction constant |
| 14 |
steps/ui/spaces.ts |
185 |
'download.zip' |
Named constant |
| 15 |
steps/ui/public.ts |
160 |
'Incorrect password' |
Named constant for error message |
Recommended Solution
-
Items 1-4 -- Move selectors out of step files into page objects. Expose helper methods like sessionObject.waitForContent() instead of page.locator('#web-content').waitFor().
-
Items 5-10 -- Extract inline selectors from page object method bodies to module-level const declarations. See runtime/application.ts for the pattern.
-
Items 11-15 -- Replace magic strings with named constants in environment/constants.ts or near the relevant object.
Good Examples to Follow
Already well-structured page objects with module-level selectors:
tests/e2e/support/objects/runtime/application.ts -- all 9 selectors defined as const at the top
tests/e2e/support/objects/app-files/resource/actions.ts -- 50+ selectors as module-level constants
tests/e2e/support/objects/app-files/link/actions.ts -- all selectors as module-level constants
tests/e2e/environment/constants.ts -- shared constants for fileAction, application, searchScope, etc.
Impact of Fixing
| Metric |
Improvement |
| Selector duplication |
Eliminated -- single source of truth per selector |
| UI change resilience |
Update one constant, all tests update |
| Code clarity |
Step files focus on what to do, not how to find elements |
| Onboarding |
New team members find selectors in predictable locations |
Problem
CSS selectors and locator strings are hardcoded directly in step files (
tests/e2e/steps/ui/) and even inside page object methods instead of being defined as module-level constants. This causes:#web-contentappears insession.tsANDpublic.ts)'download','move','Incorrect password'used in assertions without named constantsOccurrences Found
A. Hardcoded Selectors in Step Files (bypass page objects entirely)
tests/e2e/steps/ui/session.tspage.locator('#web-content').waitFor()tests/e2e/steps/ui/session.tspage.locator('#input-error-otp')tests/e2e/steps/ui/session.tspage.locator('#_userMenuButton').count()tests/e2e/steps/ui/session.tspage.locator('#oc-login-error-message')The
Sessionpage object (tests/e2e/support/objects/runtime/session.ts) already encapsulates most login/logout logic. Step functions should call page object methods instead of using these selectors directly.B. Inline Selectors Inside Page Object Methods (not using module-level constants)
Several page objects define selectors inline inside method bodies rather than as module-level constants:
runtime/session.ts'button[type="submit"]','#username','#password','#kc-login','#otp'app-admin-settings/general/actions.ts'#logo-upload-input','.oc-notification-message','#kc-totp-secret-qr-code','#totp','#userLabel','#saveTOTPBtn'app-admin-settings/page/general.ts'//a[@data-nav-name="admin-settings-general"]','#app-loading-spinner'app-files/utils/sidebar.ts'.sidebar-panel.is-active','.header__back'app-files/page/public.ts'#web-content','body'url-navigation/actions.ts'.page-not-found'C. Magic Strings in Step Files
steps/ui/resources.ts'download'steps/ui/resources.ts'download'steps/ui/resources.ts'move'fileActionconstantsteps/ui/spaces.ts'download.zip'steps/ui/public.ts'Incorrect password'Recommended Solution
Items 1-4 -- Move selectors out of step files into page objects. Expose helper methods like
sessionObject.waitForContent()instead ofpage.locator('#web-content').waitFor().Items 5-10 -- Extract inline selectors from page object method bodies to module-level
constdeclarations. Seeruntime/application.tsfor the pattern.Items 11-15 -- Replace magic strings with named constants in
environment/constants.tsor near the relevant object.Good Examples to Follow
Already well-structured page objects with module-level selectors:
tests/e2e/support/objects/runtime/application.ts-- all 9 selectors defined asconstat the toptests/e2e/support/objects/app-files/resource/actions.ts-- 50+ selectors as module-level constantstests/e2e/support/objects/app-files/link/actions.ts-- all selectors as module-level constantstests/e2e/environment/constants.ts-- shared constants forfileAction,application,searchScope, etc.Impact of Fixing