Skip to content

Commit

Permalink
feat: enable nested RegExp options
Browse files Browse the repository at this point in the history
  • Loading branch information
patrickhulce committed Aug 18, 2020
1 parent 9ddbd4c commit fe290fc
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 8 deletions.
42 changes: 34 additions & 8 deletions lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,40 @@ const domLibraryAsString = readFileSync(
).replace(/process.env/g, '{}')

/* istanbul ignore next */
function mapArgument(argument: any, index: number): any {
return index === 0 && typeof argument === 'object' && argument.regex
? new RegExp(argument.regex, argument.flags)
: argument
function mapArgument(o: any): any {
return convertProxyToRegExp(o, 0)
}

/* istanbul ignore next */
function convertProxyToRegExp(o: any, depth: number): any {
if (typeof o !== 'object' || !o || depth > 2) return o
if (!o.__regex || typeof o.__flags !== 'string') {
const copy = {...o}
for (const key of Object.keys(copy)) {
copy[key] = convertProxyToRegExp(copy[key], depth + 1)
}
return copy
}

return new RegExp(o.__regex, o.__flags)
}

function convertRegExpToProxy(o: any, depth: number): any {
if (typeof o !== 'object' || !o || depth > 2) return o
if (!(o instanceof RegExp)) {
const copy = {...o}
for (const key of Object.keys(copy)) {
copy[key] = convertRegExpToProxy(copy[key], depth + 1)
}
return copy
}

return {__regex: o.source, __flags: o.flags}
}

const delegateFnBodyToExecuteInPageInitial = `
${domLibraryAsString};
${convertProxyToRegExp.toString()};
const mappedArgs = args.map(${mapArgument.toString()});
const moduleWithFns = fnName in __dom_testing_library__ ?
Expand Down Expand Up @@ -94,8 +120,6 @@ function createDelegateFor<T = DOMReturnType>(
// @ts-ignore
processHandleFn = processHandleFn || processQuery

const convertRegExp = (regex: RegExp) => ({regex: regex.source, flags: regex.flags})

return async function(...args: any[]): Promise<T> {
// @ts-ignore
const containerHandle: ElementHandle = contextFn ? contextFn.apply(this, args) : this
Expand All @@ -105,13 +129,15 @@ function createDelegateFor<T = DOMReturnType>(
delegateFnBodyToExecuteInPage,
)

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

// Convert RegExp to a special format since they don't serialize well
argsToForward = argsToForward.map(convertRegExpToProxy)

return processHandleFn!({fnName, containerHandle, evaluateFn, argsToForward})
}
}
Expand Down
8 changes: 8 additions & 0 deletions test/extend.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,14 @@ describe('lib/extend.ts', () => {
expect(text).toEqual('Hello h2')
})

it('should handle the getBy* methods with a regex name', async () => {
const element = await document.getByRole('button', {name: /getBy.*Test/})

const text = await page.evaluate(el => el.textContent, element)

expect(text).toEqual('getByRole Test')
})

it('should scope results to element', async () => {
const scope = await document.$('#scoped')
const element = await scope!.queryByText(/Hello/)
Expand Down
1 change: 1 addition & 0 deletions test/fixtures/page.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ <h2 data-id="second-level-header">Hello h2</h2>
<label for="label-text-input" data-testid="testid-label">Label A</label>
<input id="label-text-input" type="text">

<button role="button">getByRole Test</button>
<div id="scoped">
<h3>Hello h3</h3>
</div>
Expand Down

0 comments on commit fe290fc

Please sign in to comment.