Skip to content

Commit 79da6b7

Browse files
committed
refactor: DRY role locator handling with helper functions
- Extract isRoleLocatorObject() helper to check for role locator objects - Extract handleRoleLocator() helper to convert role locators to Playwright getByRole API - Replace 4 duplicated code blocks with reusable helper functions - No functional changes - all 16 tests still passing
1 parent fc20104 commit 79da6b7

File tree

1 file changed

+36
-29
lines changed

1 file changed

+36
-29
lines changed

lib/helper/Playwright.js

Lines changed: 36 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -2822,14 +2822,14 @@ class Playwright extends Helper {
28222822
*/
28232823
async grabTextFrom(locator) {
28242824
// Handle role locators with text/exact options
2825-
if (locator && typeof locator === 'object' && locator.role && !locator.type) {
2826-
const options = {}
2827-
if (locator.text) options.name = locator.text
2828-
if (locator.exact !== undefined) options.exact = locator.exact
2829-
const text = await this.page.getByRole(locator.role, Object.keys(options).length > 0 ? options : undefined).first().textContent()
2830-
assertElementExists(text, JSON.stringify(locator))
2831-
this.debugSection('Text', text)
2832-
return text
2825+
if (isRoleLocatorObject(locator)) {
2826+
const elements = await handleRoleLocator(this.page, locator)
2827+
if (elements && elements.length > 0) {
2828+
const text = await elements[0].textContent()
2829+
assertElementExists(text, JSON.stringify(locator))
2830+
this.debugSection('Text', text)
2831+
return text
2832+
}
28332833
}
28342834

28352835
const locatorObj = new Locator(locator, 'css')
@@ -4340,6 +4340,27 @@ function buildLocatorString(locator) {
43404340
return locator.simplify()
43414341
}
43424342

4343+
/**
4344+
* Checks if a locator is a role locator object (e.g., {role: 'button', text: 'Submit', exact: true})
4345+
*/
4346+
function isRoleLocatorObject(locator) {
4347+
return locator && typeof locator === 'object' && locator.role && !locator.type
4348+
}
4349+
4350+
/**
4351+
* Handles role locator objects by converting them to Playwright's getByRole() API
4352+
* Returns elements array if role locator, null otherwise
4353+
*/
4354+
async function handleRoleLocator(context, locator) {
4355+
if (!isRoleLocatorObject(locator)) return null
4356+
4357+
const options = {}
4358+
if (locator.text) options.name = locator.text
4359+
if (locator.exact !== undefined) options.exact = locator.exact
4360+
4361+
return context.getByRole(locator.role, Object.keys(options).length > 0 ? options : undefined).all()
4362+
}
4363+
43434364
async function findElements(matcher, locator) {
43444365
// Check if locator is a Locator object with react/vue type, or a raw object with react/vue property
43454366
const isReactLocator = locator.type === 'react' || (locator.locator && locator.locator.react) || locator.react
@@ -4351,16 +4372,8 @@ async function findElements(matcher, locator) {
43514372
if (isPwLocator) return findByPlaywrightLocator.call(this, matcher, locator)
43524373

43534374
// Handle role locators with text/exact options (e.g., {role: 'button', text: 'Submit', exact: true})
4354-
if (locator && typeof locator === 'object' && locator.role && !locator.type) {
4355-
const options = {}
4356-
if (locator.text) {
4357-
options.name = locator.text
4358-
}
4359-
if (locator.exact !== undefined) {
4360-
options.exact = locator.exact
4361-
}
4362-
return matcher.getByRole(locator.role, Object.keys(options).length > 0 ? options : undefined).all()
4363-
}
4375+
const roleElements = await handleRoleLocator(matcher, locator)
4376+
if (roleElements) return roleElements
43644377

43654378
locator = new Locator(locator, 'css')
43664379

@@ -4610,12 +4623,8 @@ async function findCheckable(locator, context) {
46104623
}
46114624

46124625
// Handle role locators with text/exact options
4613-
if (locator && typeof locator === 'object' && locator.role && !locator.type) {
4614-
const options = {}
4615-
if (locator.text) options.name = locator.text
4616-
if (locator.exact !== undefined) options.exact = locator.exact
4617-
return contextEl.getByRole(locator.role, Object.keys(options).length > 0 ? options : undefined).all()
4618-
}
4626+
const roleElements = await handleRoleLocator(contextEl, locator)
4627+
if (roleElements) return roleElements
46194628

46204629
const matchedLocator = new Locator(locator)
46214630
if (!matchedLocator.isFuzzy()) {
@@ -4644,12 +4653,10 @@ async function proceedIsChecked(assertType, option) {
46444653

46454654
async function findFields(locator) {
46464655
// Handle role locators with text/exact options
4647-
if (locator && typeof locator === 'object' && locator.role && !locator.type) {
4648-
const options = {}
4649-
if (locator.text) options.name = locator.text
4650-
if (locator.exact !== undefined) options.exact = locator.exact
4656+
if (isRoleLocatorObject(locator)) {
46514657
const page = await this.page
4652-
return page.getByRole(locator.role, Object.keys(options).length > 0 ? options : undefined).all()
4658+
const roleElements = await handleRoleLocator(page, locator)
4659+
if (roleElements) return roleElements
46534660
}
46544661

46554662
const matchedLocator = new Locator(locator)

0 commit comments

Comments
 (0)