Skip to content

Commit 92cceaa

Browse files
fix: using regular expressions in options argument
Options are not being serialized correctly, their values are passed to execute unmodified. This means passing a regular expression as the byRole name option does not work.
1 parent 993f019 commit 92cceaa

File tree

3 files changed

+53
-21
lines changed

3 files changed

+53
-21
lines changed

.eslintrc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@
1919
"overrides": [
2020
{
2121
"files": ["wdio.conf.js", "*/**/*.e2e.*"],
22+
"rules": {
23+
"max-lines-per-function": "off"
24+
},
2225
"globals": {
2326
"browser": "readonly"
2427
}

src/index.ts

Lines changed: 38 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -36,31 +36,51 @@ async function injectDOMTestingLibrary(container: Element) {
3636
}
3737
}
3838

39-
function serializeArgs(args: any[]) {
40-
return args.map((arg) => {
41-
if (arg instanceof RegExp) {
42-
return {RegExp: arg.toString()}
43-
}
44-
if (typeof arg === 'undefined') {
45-
return {Undefined: true}
46-
}
47-
return arg
48-
})
39+
function serializeObject(object: Object): Object {
40+
return Object.entries(object)
41+
.map(([key, value]) => [key, serializeArg(value)])
42+
.reduce((acc, [key, value]) => ({...acc, [key]: value}), {})
43+
}
44+
45+
function serializeArg(arg: any) {
46+
if (arg instanceof RegExp) {
47+
return {RegExp: arg.toString()}
48+
}
49+
if (typeof arg === 'undefined') {
50+
return {Undefined: true}
51+
}
52+
if (arg && typeof arg === 'object') {
53+
return serializeObject(arg)
54+
}
55+
return arg
4956
}
5057

5158
function executeQuery(
5259
[query, container, ...args]: [QueryName, HTMLElement, ...any[]],
5360
done: (result: any) => void,
5461
) {
55-
const [matcher, options, waitForOptions] = args.map((arg) => {
62+
// @ts-ignore
63+
function deserializeObject(object) {
64+
return Object.entries(object)
65+
.map(([key, value]) => [key, deserializeArg(value)])
66+
.reduce((acc, [key, value]) => ({...acc, [key]: value}), {})
67+
}
68+
69+
// @ts-ignore
70+
function deserializeArg(arg) {
5671
if (arg && arg.RegExp) {
5772
return eval(arg.RegExp)
5873
}
5974
if (arg && arg.Undefined) {
6075
return undefined
6176
}
77+
if (arg && typeof arg === 'object') {
78+
return deserializeObject(arg)
79+
}
6280
return arg
63-
})
81+
}
82+
83+
const [matcher, options, waitForOptions] = args.map(deserializeArg)
6484

6585
Promise.resolve(
6686
window.TestingLibraryDom[query](
@@ -96,7 +116,7 @@ function createQuery(element: Element, queryName: string) {
96116
const result = await element.executeAsync<any[], any[]>(executeQuery, [
97117
queryName,
98118
element,
99-
...serializeArgs(args),
119+
...args.map(serializeArg),
100120
])
101121

102122
if (typeof result === 'string') {
@@ -126,18 +146,18 @@ function within(element: Element) {
126146
}
127147

128148
function setupBrowser(browser: BrowserObject | MultiRemoteBrowserObject) {
129-
const queries: { [key: string]: any } = {};
149+
const queries: {[key: string]: any} = {}
130150

131151
Object.keys(baseQueries).forEach((key) => {
132-
const queryName = key as keyof typeof baseQueries;
152+
const queryName = key as keyof typeof baseQueries
133153

134154
const query = async (...args: any[]) => {
135-
const body = await browser.$('body');
136-
return within(body)[queryName](...args);
155+
const body = await browser.$('body')
156+
return within(body)[queryName](...args)
137157
}
138158

139159
// add query to response queries
140-
queries[queryName] = query;
160+
queries[queryName] = query
141161

142162
// add query to BrowserObject
143163
browser.addCommand(queryName, query)

test/queries.e2e.ts

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import {setupBrowser} from '../src';
1+
import {setupBrowser} from '../src'
22

33
describe('queries', () => {
44
it('queryBy resolves with matching element', async () => {
@@ -108,10 +108,10 @@ describe('queries', () => {
108108
expect(await buttons[1].getText()).toEqual('Button Clicked')
109109
})
110110

111-
it('support Regular Expressions', async () => {
111+
it('support Regular Expressions as matchers', async () => {
112112
const {getAllByText} = setupBrowser(browser)
113113

114-
const chans = await getAllByText(/Jackie Chan/)
114+
const chans = await getAllByText(/jackie chan/i)
115115
expect(chans).toHaveLength(2)
116116
})
117117

@@ -122,6 +122,15 @@ describe('queries', () => {
122122
expect(chans).toHaveLength(2)
123123
})
124124

125+
it('support Regular Expressions in options', async () => {
126+
const {getAllByRole} = setupBrowser(browser)
127+
128+
const chans = await getAllByRole('button', {
129+
name: /jackie chan/i,
130+
})
131+
expect(chans).toHaveLength(2)
132+
})
133+
125134
it('support waitFor options', async () => {
126135
const {findByText} = setupBrowser(browser)
127136

0 commit comments

Comments
 (0)