-
Notifications
You must be signed in to change notification settings - Fork 274
feat: ...byRole type queries accepts second arg #875
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
ea68aa1
28a342c
0713c95
1360487
f1e2c68
30644cb
cf0726f
9c490c7
ae3d062
48c4e3b
949d559
0405619
29c2d6f
1f725c7
a5f168c
9ff3136
b6abc2f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
import type { ReactTestInstance } from 'react-test-renderer'; | ||
import type { AccessibilityRole, AccessibilityState } from 'react-native'; | ||
import type { AccessibilityState } from 'react-native'; | ||
import type { WaitForOptions } from '../waitFor'; | ||
import type { TextMatch } from '../matches'; | ||
import makeA11yQuery from './makeA11yQuery'; | ||
|
@@ -11,6 +11,34 @@ type A11yValue = { | |
now?: number; | ||
text?: string; | ||
}; | ||
type A11yRole = | ||
kiranjd marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| 'none' | ||
| 'button' | ||
| 'link' | ||
| 'search' | ||
| 'image' | ||
| 'keyboardkey' | ||
| 'text' | ||
| 'adjustable' | ||
| 'imagebutton' | ||
| 'header' | ||
| 'summary' | ||
| 'alert' | ||
| 'checkbox' | ||
| 'combobox' | ||
| 'menu' | ||
| 'menubar' | ||
| 'menuitem' | ||
| 'progressbar' | ||
| 'radio' | ||
| 'radiogroup' | ||
| 'scrollbar' | ||
| 'spinbutton' | ||
| 'switch' | ||
| 'tab' | ||
| 'tablist' | ||
| 'timer' | ||
| 'toolbar'; | ||
|
||
type GetReturn = ReactTestInstance; | ||
type GetAllReturn = Array<ReactTestInstance>; | ||
|
@@ -19,6 +47,10 @@ type QueryAllReturn = Array<ReactTestInstance>; | |
type FindReturn = Promise<GetReturn>; | ||
type FindAllReturn = Promise<GetAllReturn>; | ||
|
||
export type QueryOptions = { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This type should be renamed to |
||
name?: string | RegExp; | ||
}; | ||
|
||
export type A11yAPI = { | ||
// Label | ||
getByLabelText: (label: TextMatch) => GetReturn; | ||
|
@@ -61,16 +93,30 @@ export type A11yAPI = { | |
) => FindAllReturn; | ||
|
||
// Role | ||
getByRole: (role: AccessibilityRole | RegExp) => GetReturn; | ||
getAllByRole: (role: AccessibilityRole | RegExp) => GetAllReturn; | ||
queryByRole: (role: AccessibilityRole | RegExp) => QueryReturn; | ||
queryAllByRole: (role: AccessibilityRole | RegExp) => QueryAllReturn; | ||
getByRole: ( | ||
role: A11yRole | RegExp, | ||
queryOptions?: QueryOptions | ||
) => GetReturn; | ||
getAllByRole: ( | ||
role: A11yRole | RegExp, | ||
queryOptions?: QueryOptions | ||
) => GetAllReturn; | ||
queryByRole: ( | ||
role: A11yRole | RegExp, | ||
queryOptions?: QueryOptions | ||
) => QueryReturn; | ||
queryAllByRole: ( | ||
role: A11yRole | RegExp, | ||
queryOptions?: QueryOptions | ||
) => QueryAllReturn; | ||
findByRole: ( | ||
role: AccessibilityRole, | ||
role: A11yRole, | ||
queryOptions?: QueryOptions & WaitForOptions, | ||
waitForOptions?: WaitForOptions | ||
) => FindReturn; | ||
findAllByRole: ( | ||
role: AccessibilityRole, | ||
role: A11yRole, | ||
queryOptions?: QueryOptions & WaitForOptions, | ||
waitForOptions?: WaitForOptions | ||
) => FindAllReturn; | ||
|
||
|
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -1,5 +1,6 @@ | ||||||
import type { ReactTestInstance } from 'react-test-renderer'; | ||||||
import waitFor from '../waitFor'; | ||||||
import { getQueriesForElement } from '../within'; | ||||||
import type { WaitForOptions } from '../waitFor'; | ||||||
import { | ||||||
ErrorWithStack, | ||||||
|
@@ -17,6 +18,39 @@ function makeAliases(aliases: Array<string>, query: Function) { | |||||
.reduce((acc, query) => ({ ...acc, ...query }), {}); | ||||||
} | ||||||
|
||||||
// The WaitForOptions has been moved to the third param of findBy* methods with the addition of QueryOptions. | ||||||
// To make the migration easier and to avoid a breaking change, keep reading these options from second param | ||||||
// but warn. | ||||||
const deprecatedKeys: (keyof WaitForOptions)[] = [ | ||||||
'timeout', | ||||||
'interval', | ||||||
'stackTraceError', | ||||||
]; | ||||||
const warnDeprectedWaitForOptionsUsage = (queryOptions?: WaitForOptions) => { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also pls move it to |
||||||
if (queryOptions) { | ||||||
const waitForOptions: WaitForOptions = { | ||||||
timeout: queryOptions.timeout, | ||||||
interval: queryOptions.interval, | ||||||
stackTraceError: queryOptions.stackTraceError, | ||||||
}; | ||||||
deprecatedKeys.forEach((key) => { | ||||||
if (queryOptions[key]) { | ||||||
// eslint-disable-next-line no-console | ||||||
console.warn( | ||||||
`Use of option "${key}" in a findBy* query's second parameter, QueryOptions, is deprecated. Please pass this option in the third, WaitForOptions, parameter. | ||||||
Example: | ||||||
findByText(text, {}, { ${key}: ${queryOptions[key]} })` | ||||||
); | ||||||
} | ||||||
}); | ||||||
return waitForOptions; | ||||||
} | ||||||
}; | ||||||
|
||||||
type QueryOptions = { | ||||||
name: string | RegExp; | ||||||
}; | ||||||
|
||||||
type QueryNames = { | ||||||
getBy: Array<string>; | ||||||
getAllBy: Array<string>; | ||||||
|
@@ -31,8 +65,27 @@ const makeA11yQuery = <P extends unknown, M extends unknown>( | |||||
queryNames: QueryNames, | ||||||
matcherFn: (prop: P, value: M) => boolean | ||||||
) => (instance: ReactTestInstance) => { | ||||||
const getBy = (matcher: M) => { | ||||||
const filterWithName = ( | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Suggested name |
||||||
node: ReactTestInstance, | ||||||
options: QueryOptions, | ||||||
matcher: M | ||||||
) => { | ||||||
const matchesRole = | ||||||
isNodeValid(node) && matcherFn(node.props[name], matcher); | ||||||
|
||||||
return ( | ||||||
matchesRole && !!getQueriesForElement(node).queryByText(options.name) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. it looks like we should match for either |
||||||
); | ||||||
}; | ||||||
|
||||||
const getBy = (matcher: M, queryOptions?: QueryOptions) => { | ||||||
try { | ||||||
if (queryOptions?.name) { | ||||||
return instance.find((node) => | ||||||
filterWithName(node, queryOptions, matcher) | ||||||
); | ||||||
} | ||||||
|
||||||
return instance.find( | ||||||
(node) => isNodeValid(node) && matcherFn(node.props[name], matcher) | ||||||
); | ||||||
|
@@ -44,10 +97,18 @@ const makeA11yQuery = <P extends unknown, M extends unknown>( | |||||
} | ||||||
}; | ||||||
|
||||||
const getAllBy = (matcher: M) => { | ||||||
const results = instance.findAll( | ||||||
(node) => isNodeValid(node) && matcherFn(node.props[name], matcher) | ||||||
); | ||||||
const getAllBy = (matcher: M, options?: QueryOptions) => { | ||||||
let results = []; | ||||||
|
||||||
if (options?.name) { | ||||||
results = instance.findAll((node) => | ||||||
filterWithName(node, options, matcher) | ||||||
); | ||||||
} else { | ||||||
results = instance.findAll( | ||||||
(node) => isNodeValid(node) && matcherFn(node.props[name], matcher) | ||||||
); | ||||||
} | ||||||
|
||||||
if (results.length === 0) { | ||||||
throw new ErrorWithStack( | ||||||
|
@@ -59,28 +120,50 @@ const makeA11yQuery = <P extends unknown, M extends unknown>( | |||||
return results; | ||||||
}; | ||||||
|
||||||
const queryBy = (matcher: M) => { | ||||||
const queryBy = (matcher: M, options?: QueryOptions) => { | ||||||
try { | ||||||
return getBy(matcher); | ||||||
return getBy(matcher, options); | ||||||
} catch (error) { | ||||||
return createQueryByError(error, queryBy); | ||||||
} | ||||||
}; | ||||||
|
||||||
const queryAllBy = (matcher: M) => { | ||||||
const queryAllBy = (matcher: M, options?: QueryOptions) => { | ||||||
try { | ||||||
return getAllBy(matcher); | ||||||
return getAllBy(matcher, options); | ||||||
} catch (error) { | ||||||
return []; | ||||||
} | ||||||
}; | ||||||
|
||||||
const findBy = (matcher: M, waitForOptions?: WaitForOptions) => { | ||||||
return waitFor(() => getBy(matcher), waitForOptions); | ||||||
const findBy = ( | ||||||
matcher: M, | ||||||
queryOptions?: QueryOptions & WaitForOptions, | ||||||
waitForOptions?: WaitForOptions | ||||||
) => { | ||||||
const deprecatedWaitForOptions = warnDeprectedWaitForOptionsUsage( | ||||||
queryOptions | ||||||
); | ||||||
|
||||||
return waitFor(() => getBy(matcher, queryOptions), { | ||||||
...deprecatedWaitForOptions, | ||||||
...waitForOptions, | ||||||
}); | ||||||
}; | ||||||
|
||||||
const findAllBy = (matcher: M, waitForOptions?: WaitForOptions) => { | ||||||
return waitFor(() => getAllBy(matcher), waitForOptions); | ||||||
const findAllBy = ( | ||||||
matcher: M, | ||||||
queryOptions?: QueryOptions & WaitForOptions, | ||||||
waitForOptions?: WaitForOptions | ||||||
) => { | ||||||
const deprecatedWaitForOptions = warnDeprectedWaitForOptionsUsage( | ||||||
queryOptions | ||||||
); | ||||||
|
||||||
return waitFor(() => getAllBy(matcher, queryOptions), { | ||||||
...deprecatedWaitForOptions, | ||||||
...waitForOptions, | ||||||
}); | ||||||
}; | ||||||
|
||||||
return { | ||||||
|
Uh oh!
There was an error while loading. Please reload this page.