Skip to content

Commit c9c0493

Browse files
Add alias to hidden in query options (#1220)
Co-authored-by: Maciej Jastrzebski <[email protected]>
1 parent a178c55 commit c9c0493

19 files changed

+213
-58
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
node_modules
2+
coverage
23
*.log
34
.eslintcache
45
build

src/__tests__/config.test.ts

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ beforeEach(() => {
66

77
test('getConfig() returns existing configuration', () => {
88
expect(getConfig().asyncUtilTimeout).toEqual(1000);
9+
expect(getConfig().defaultIncludeHiddenElements).toEqual(true);
910
});
1011

1112
test('configure() overrides existing config values', () => {
@@ -14,14 +15,26 @@ test('configure() overrides existing config values', () => {
1415
expect(getConfig()).toEqual({
1516
asyncUtilTimeout: 5000,
1617
defaultDebugOptions: { message: 'debug message' },
17-
defaultHidden: true,
18+
defaultIncludeHiddenElements: true,
1819
});
1920
});
2021

2122
test('resetToDefaults() resets config to defaults', () => {
22-
configure({ asyncUtilTimeout: 5000 });
23+
configure({
24+
asyncUtilTimeout: 5000,
25+
defaultIncludeHiddenElements: false,
26+
});
2327
expect(getConfig().asyncUtilTimeout).toEqual(5000);
28+
expect(getConfig().defaultIncludeHiddenElements).toEqual(false);
2429

2530
resetToDefaults();
2631
expect(getConfig().asyncUtilTimeout).toEqual(1000);
32+
expect(getConfig().defaultIncludeHiddenElements).toEqual(true);
33+
});
34+
35+
test('configure handles alias option defaultHidden', () => {
36+
expect(getConfig().defaultIncludeHiddenElements).toEqual(true);
37+
38+
configure({ defaultHidden: false });
39+
expect(getConfig().defaultIncludeHiddenElements).toEqual(false);
2740
});

src/config.ts

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,24 +4,37 @@ export type Config = {
44
/** Default timeout, in ms, for `waitFor` and `findBy*` queries. */
55
asyncUtilTimeout: number;
66

7-
/** Default hidden value for all queries */
8-
defaultHidden: boolean;
7+
/** Default value for `includeHiddenElements` query option. */
8+
defaultIncludeHiddenElements: boolean;
99

1010
/** Default options for `debug` helper. */
1111
defaultDebugOptions?: Partial<DebugOptions>;
1212
};
1313

14+
export type ConfigAliasOptions = {
15+
/** RTL-compatibility alias to `defaultIncludeHiddenElements` */
16+
defaultHidden: boolean;
17+
};
18+
1419
const defaultConfig: Config = {
1520
asyncUtilTimeout: 1000,
16-
defaultHidden: true,
21+
defaultIncludeHiddenElements: true,
1722
};
1823

1924
let config = { ...defaultConfig };
2025

21-
export function configure(options: Partial<Config>) {
26+
export function configure(options: Partial<Config & ConfigAliasOptions>) {
27+
const { defaultHidden, ...restOptions } = options;
28+
29+
const defaultIncludeHiddenElements =
30+
restOptions.defaultIncludeHiddenElements ??
31+
defaultHidden ??
32+
config.defaultIncludeHiddenElements;
33+
2234
config = {
2335
...config,
24-
...options,
36+
...restOptions,
37+
defaultIncludeHiddenElements,
2538
};
2639
}
2740

src/helpers/__tests__/component-tree.test.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ describe('getHostParent()', () => {
4545
expect(getHostParent(hostGrandparent)).toBe(null);
4646
});
4747

48+
it('returns host parent for null', () => {
49+
expect(getHostParent(null)).toBe(null);
50+
});
51+
4852
it('returns host parent for composite component', () => {
4953
const view = render(
5054
<View testID="parent">
@@ -65,7 +69,7 @@ describe('getHostChildren()', () => {
6569
<View testID="grandparent">
6670
<View testID="parent">
6771
<View testID="subject" />
68-
<View testID="sibling" />
72+
<Text testID="sibling">Hello</Text>
6973
</View>
7074
</View>
7175
);
@@ -74,6 +78,8 @@ describe('getHostChildren()', () => {
7478
expect(getHostChildren(hostSubject)).toEqual([]);
7579

7680
const hostSibling = view.getByTestId('sibling');
81+
expect(getHostChildren(hostSibling)).toEqual([]);
82+
7783
const hostParent = view.getByTestId('parent');
7884
expect(getHostChildren(hostParent)).toEqual([hostSubject, hostSibling]);
7985

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import React from 'react';
2+
import { View } from 'react-native';
3+
import { configure, render, screen } from '../..';
4+
5+
test('includeHiddenElements query option takes priority over hidden option and global config', () => {
6+
configure({ defaultHidden: true, defaultIncludeHiddenElements: true });
7+
render(<View testID="view" style={{ display: 'none' }} />);
8+
expect(
9+
screen.queryByTestId('view', { includeHiddenElements: false, hidden: true })
10+
).toBeFalsy();
11+
});
12+
13+
test('hidden option takes priority over global config when includeHiddenElements is not defined', () => {
14+
configure({ defaultHidden: true, defaultIncludeHiddenElements: true });
15+
render(<View testID="view" style={{ display: 'none' }} />);
16+
expect(screen.queryByTestId('view', { hidden: false })).toBeFalsy();
17+
});
18+
19+
test('global config defaultIncludeElements option takes priority over defaultHidden when set at the same time', () => {
20+
configure({ defaultHidden: false, defaultIncludeHiddenElements: true });
21+
render(<View testID="view" style={{ display: 'none' }} />);
22+
expect(screen.getByTestId('view')).toBeTruthy();
23+
});
24+
25+
test('defaultHidden takes priority when it was set last', () => {
26+
// also simulates the case when defaultIncludeHiddenElements is true by default in the config
27+
configure({ defaultIncludeHiddenElements: true });
28+
configure({ defaultHidden: false });
29+
render(<View testID="view" style={{ display: 'none' }} />);
30+
expect(screen.queryByTestId('view')).toBeFalsy();
31+
});
32+
33+
test('defaultIncludeHiddenElements takes priority when it was set last', () => {
34+
// also simulates the case when defaultHidden is true by default in the config
35+
configure({ defaultHidden: true });
36+
configure({ defaultIncludeHiddenElements: false });
37+
render(<View testID="view" style={{ display: 'none' }} />);
38+
expect(screen.queryByTestId('view')).toBeFalsy();
39+
});

src/helpers/findAll.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import { getConfig } from '../config';
33
import { isHiddenFromAccessibility } from './accessiblity';
44

55
interface FindAllOptions {
6+
includeHiddenElements?: boolean;
7+
/** RTL-compatible alias to `includeHiddenElements` */
68
hidden?: boolean;
79
}
810

@@ -13,8 +15,12 @@ export function findAll(
1315
) {
1416
const results = root.findAll(predicate);
1517

16-
const hidden = options?.hidden ?? getConfig().defaultHidden;
17-
if (hidden) {
18+
const includeHiddenElements =
19+
options?.includeHiddenElements ??
20+
options?.hidden ??
21+
getConfig()?.defaultIncludeHiddenElements;
22+
23+
if (includeHiddenElements) {
1824
return results;
1925
}
2026

src/queries/__tests__/a11yState.test.tsx

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -238,10 +238,16 @@ test('byA11yState queries support hidden option', () => {
238238
);
239239

240240
expect(getByA11yState({ expanded: false })).toBeTruthy();
241-
expect(getByA11yState({ expanded: false }, { hidden: true })).toBeTruthy();
241+
expect(
242+
getByA11yState({ expanded: false }, { includeHiddenElements: true })
243+
).toBeTruthy();
242244

243-
expect(queryByA11yState({ expanded: false }, { hidden: false })).toBeFalsy();
245+
expect(
246+
queryByA11yState({ expanded: false }, { includeHiddenElements: false })
247+
).toBeFalsy();
244248
expect(() =>
245-
getByA11yState({ expanded: false }, { hidden: false })
246-
).toThrow();
249+
getByA11yState({ expanded: false }, { includeHiddenElements: false })
250+
).toThrowErrorMatchingInlineSnapshot(
251+
`"Unable to find an element with expanded state: false"`
252+
);
247253
});

src/queries/__tests__/a11yValue.test.tsx

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,16 @@ test('byA11yValue queries support hidden option', () => {
101101
);
102102

103103
expect(getByA11yValue({ max: 10 })).toBeTruthy();
104-
expect(getByA11yValue({ max: 10 }, { hidden: true })).toBeTruthy();
105-
106-
expect(queryByA11yValue({ max: 10 }, { hidden: false })).toBeFalsy();
107-
expect(() => getByA11yValue({ max: 10 }, { hidden: false })).toThrow();
104+
expect(
105+
getByA11yValue({ max: 10 }, { includeHiddenElements: true })
106+
).toBeTruthy();
107+
108+
expect(
109+
queryByA11yValue({ max: 10 }, { includeHiddenElements: false })
110+
).toBeFalsy();
111+
expect(() =>
112+
getByA11yValue({ max: 10 }, { includeHiddenElements: false })
113+
).toThrowErrorMatchingInlineSnapshot(
114+
`"Unable to find an element with accessibilityValue: {"max":10}"`
115+
);
108116
});

src/queries/__tests__/displayValue.test.tsx

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -106,8 +106,16 @@ test('byDisplayValue queries support hidden option', () => {
106106
);
107107

108108
expect(getByDisplayValue('hidden')).toBeTruthy();
109-
expect(getByDisplayValue('hidden', { hidden: true })).toBeTruthy();
110-
111-
expect(queryByDisplayValue('hidden', { hidden: false })).toBeFalsy();
112-
expect(() => getByDisplayValue('hidden', { hidden: false })).toThrow();
109+
expect(
110+
getByDisplayValue('hidden', { includeHiddenElements: true })
111+
).toBeTruthy();
112+
113+
expect(
114+
queryByDisplayValue('hidden', { includeHiddenElements: false })
115+
).toBeFalsy();
116+
expect(() =>
117+
getByDisplayValue('hidden', { includeHiddenElements: false })
118+
).toThrowErrorMatchingInlineSnapshot(
119+
`"Unable to find an element with displayValue: hidden"`
120+
);
113121
});

src/queries/__tests__/hintText.test.tsx

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -115,8 +115,14 @@ test('byHintText queries support hidden option', () => {
115115
);
116116

117117
expect(getByHintText('hidden')).toBeTruthy();
118-
expect(getByHintText('hidden', { hidden: true })).toBeTruthy();
119-
120-
expect(queryByHintText('hidden', { hidden: false })).toBeFalsy();
121-
expect(() => getByHintText('hidden', { hidden: false })).toThrow();
118+
expect(getByHintText('hidden', { includeHiddenElements: true })).toBeTruthy();
119+
120+
expect(
121+
queryByHintText('hidden', { includeHiddenElements: false })
122+
).toBeFalsy();
123+
expect(() =>
124+
getByHintText('hidden', { includeHiddenElements: false })
125+
).toThrowErrorMatchingInlineSnapshot(
126+
`"Unable to find an element with accessibilityHint: hidden"`
127+
);
122128
});

src/queries/__tests__/labelText.test.tsx

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -152,8 +152,16 @@ test('byLabelText queries support hidden option', () => {
152152
);
153153

154154
expect(getByLabelText('hidden')).toBeTruthy();
155-
expect(getByLabelText('hidden', { hidden: true })).toBeTruthy();
156-
157-
expect(queryByLabelText('hidden', { hidden: false })).toBeFalsy();
158-
expect(() => getByLabelText('hidden', { hidden: false })).toThrow();
155+
expect(
156+
getByLabelText('hidden', { includeHiddenElements: true })
157+
).toBeTruthy();
158+
159+
expect(
160+
queryByLabelText('hidden', { includeHiddenElements: false })
161+
).toBeFalsy();
162+
expect(() =>
163+
getByLabelText('hidden', { includeHiddenElements: false })
164+
).toThrowErrorMatchingInlineSnapshot(
165+
`"Unable to find an element with accessibilityLabel: hidden"`
166+
);
159167
});

src/queries/__tests__/placeholderText.test.tsx

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,16 @@ test('byPlaceholderText queries support hidden option', () => {
6565
);
6666

6767
expect(getByPlaceholderText('hidden')).toBeTruthy();
68-
expect(getByPlaceholderText('hidden', { hidden: true })).toBeTruthy();
68+
expect(
69+
getByPlaceholderText('hidden', { includeHiddenElements: true })
70+
).toBeTruthy();
6971

70-
expect(queryByPlaceholderText('hidden', { hidden: false })).toBeFalsy();
71-
expect(() => getByPlaceholderText('hidden', { hidden: false })).toThrow();
72+
expect(
73+
queryByPlaceholderText('hidden', { includeHiddenElements: false })
74+
).toBeFalsy();
75+
expect(() =>
76+
getByPlaceholderText('hidden', { includeHiddenElements: false })
77+
).toThrowErrorMatchingInlineSnapshot(
78+
`"Unable to find an element with placeholder: hidden"`
79+
);
7280
});

src/queries/__tests__/role.test.tsx

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -706,8 +706,12 @@ test('byRole queries support hidden option', () => {
706706
);
707707

708708
expect(getByRole('button')).toBeTruthy();
709-
expect(getByRole('button', { hidden: true })).toBeTruthy();
709+
expect(getByRole('button', { includeHiddenElements: true })).toBeTruthy();
710710

711-
expect(queryByRole('button', { hidden: false })).toBeFalsy();
712-
expect(() => getByRole('button', { hidden: false })).toThrow();
711+
expect(queryByRole('button', { includeHiddenElements: false })).toBeFalsy();
712+
expect(() =>
713+
getByRole('button', { includeHiddenElements: false })
714+
).toThrowErrorMatchingInlineSnapshot(
715+
`"Unable to find an element with role: "button""`
716+
);
713717
});

src/queries/__tests__/testId.test.tsx

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -141,8 +141,12 @@ test('byTestId queries support hidden option', () => {
141141
);
142142

143143
expect(getByTestId('hidden')).toBeTruthy();
144-
expect(getByTestId('hidden', { hidden: true })).toBeTruthy();
144+
expect(getByTestId('hidden', { includeHiddenElements: true })).toBeTruthy();
145145

146-
expect(queryByTestId('hidden', { hidden: false })).toBeFalsy();
147-
expect(() => getByTestId('hidden', { hidden: false })).toThrow();
146+
expect(queryByTestId('hidden', { includeHiddenElements: false })).toBeFalsy();
147+
expect(() =>
148+
getByTestId('hidden', { includeHiddenElements: false })
149+
).toThrowErrorMatchingInlineSnapshot(
150+
`"Unable to find an element with testID: hidden"`
151+
);
148152
});

src/queries/__tests__/text.test.tsx

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -473,8 +473,12 @@ test('byText support hidden option', () => {
473473
);
474474

475475
expect(getByText(/hidden/i)).toBeTruthy();
476-
expect(getByText(/hidden/i, { hidden: true })).toBeTruthy();
476+
expect(getByText(/hidden/i, { includeHiddenElements: true })).toBeTruthy();
477477

478-
expect(queryByText(/hidden/i, { hidden: false })).toBeFalsy();
479-
expect(() => getByText(/hidden/i, { hidden: false })).toThrow();
478+
expect(queryByText(/hidden/i, { includeHiddenElements: false })).toBeFalsy();
479+
expect(() =>
480+
getByText(/hidden/i, { includeHiddenElements: false })
481+
).toThrowErrorMatchingInlineSnapshot(
482+
`"Unable to find an element with text: /hidden/i"`
483+
);
480484
});

src/queries/options.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
import { NormalizerFn } from '../matches';
22

3-
export type CommonQueryOptions = { hidden?: boolean };
3+
export type CommonQueryOptions = {
4+
/** Should query include elements hidden from accessibility. */
5+
includeHiddenElements?: boolean;
6+
7+
/** RTL-compatibile alias to `includeHiddenElements`. */
8+
hidden?: boolean;
9+
};
410

511
export type TextMatchOptions = {
612
exact?: boolean;

typings/index.flow.js

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,10 @@ type QueryAllReturn = Array<ReactTestInstance> | [];
88
type FindReturn = Promise<ReactTestInstance>;
99
type FindAllReturn = Promise<ReactTestInstance[]>;
1010

11-
type CommonQueryOptions = { hidden?: boolean };
11+
type CommonQueryOptions = {
12+
includeHiddenElements?: boolean,
13+
hidden?: boolean,
14+
};
1215
type TextMatch = string | RegExp;
1316

1417
declare type NormalizerFn = (textToNormalize: string) => string;
@@ -463,10 +466,18 @@ declare module '@testing-library/react-native' {
463466

464467
declare interface Config {
465468
asyncUtilTimeout: number;
469+
defaultIncludeHiddenElements: boolean;
466470
defaultDebugOptions?: $Shape<DebugOptions>;
467471
}
468472

469-
declare export var configure: (options: $Shape<Config>) => void;
473+
declare interface ConfigAliasOptions {
474+
/** Alias to `defaultIncludeHiddenElements` for RTL compatibility */
475+
defaultHidden: boolean;
476+
}
477+
478+
declare export var configure: (
479+
options: $Shape<Config & ConfigAliasOptions>
480+
) => void;
470481
declare export var resetToDefaults: () => void;
471482

472483
declare export var act: (callback: () => void) => Thenable;

0 commit comments

Comments
 (0)