Skip to content

Commit fe290fc

Browse files
committed
feat: enable nested RegExp options
1 parent 9ddbd4c commit fe290fc

File tree

3 files changed

+43
-8
lines changed

3 files changed

+43
-8
lines changed

lib/index.ts

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,40 @@ const domLibraryAsString = readFileSync(
1111
).replace(/process.env/g, '{}')
1212

1313
/* istanbul ignore next */
14-
function mapArgument(argument: any, index: number): any {
15-
return index === 0 && typeof argument === 'object' && argument.regex
16-
? new RegExp(argument.regex, argument.flags)
17-
: argument
14+
function mapArgument(o: any): any {
15+
return convertProxyToRegExp(o, 0)
16+
}
17+
18+
/* istanbul ignore next */
19+
function convertProxyToRegExp(o: any, depth: number): any {
20+
if (typeof o !== 'object' || !o || depth > 2) return o
21+
if (!o.__regex || typeof o.__flags !== 'string') {
22+
const copy = {...o}
23+
for (const key of Object.keys(copy)) {
24+
copy[key] = convertProxyToRegExp(copy[key], depth + 1)
25+
}
26+
return copy
27+
}
28+
29+
return new RegExp(o.__regex, o.__flags)
30+
}
31+
32+
function convertRegExpToProxy(o: any, depth: number): any {
33+
if (typeof o !== 'object' || !o || depth > 2) return o
34+
if (!(o instanceof RegExp)) {
35+
const copy = {...o}
36+
for (const key of Object.keys(copy)) {
37+
copy[key] = convertRegExpToProxy(copy[key], depth + 1)
38+
}
39+
return copy
40+
}
41+
42+
return {__regex: o.source, __flags: o.flags}
1843
}
1944

2045
const delegateFnBodyToExecuteInPageInitial = `
2146
${domLibraryAsString};
47+
${convertProxyToRegExp.toString()};
2248
2349
const mappedArgs = args.map(${mapArgument.toString()});
2450
const moduleWithFns = fnName in __dom_testing_library__ ?
@@ -94,8 +120,6 @@ function createDelegateFor<T = DOMReturnType>(
94120
// @ts-ignore
95121
processHandleFn = processHandleFn || processQuery
96122

97-
const convertRegExp = (regex: RegExp) => ({regex: regex.source, flags: regex.flags})
98-
99123
return async function(...args: any[]): Promise<T> {
100124
// @ts-ignore
101125
const containerHandle: ElementHandle = contextFn ? contextFn.apply(this, args) : this
@@ -105,13 +129,15 @@ function createDelegateFor<T = DOMReturnType>(
105129
delegateFnBodyToExecuteInPage,
106130
)
107131

108-
// Convert RegExp to a special format since they don't serialize well
109-
let argsToForward = args.map(arg => (arg instanceof RegExp ? convertRegExp(arg) : arg))
132+
let argsToForward = args
110133
// Remove the container from the argsToForward since it's always the first argument
111134
if (containerHandle === args[0]) {
112135
argsToForward = argsToForward.slice(1)
113136
}
114137

138+
// Convert RegExp to a special format since they don't serialize well
139+
argsToForward = argsToForward.map(convertRegExpToProxy)
140+
115141
return processHandleFn!({fnName, containerHandle, evaluateFn, argsToForward})
116142
}
117143
}

test/extend.test.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,14 @@ describe('lib/extend.ts', () => {
9999
expect(text).toEqual('Hello h2')
100100
})
101101

102+
it('should handle the getBy* methods with a regex name', async () => {
103+
const element = await document.getByRole('button', {name: /getBy.*Test/})
104+
105+
const text = await page.evaluate(el => el.textContent, element)
106+
107+
expect(text).toEqual('getByRole Test')
108+
})
109+
102110
it('should scope results to element', async () => {
103111
const scope = await document.$('#scoped')
104112
const element = await scope!.queryByText(/Hello/)

test/fixtures/page.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ <h2 data-id="second-level-header">Hello h2</h2>
99
<label for="label-text-input" data-testid="testid-label">Label A</label>
1010
<input id="label-text-input" type="text">
1111

12+
<button role="button">getByRole Test</button>
1213
<div id="scoped">
1314
<h3>Hello h3</h3>
1415
</div>

0 commit comments

Comments
 (0)