Skip to content

Commit aa88056

Browse files
committed
refactor(fixture): split query-related stuff out into separate module
1 parent 27f7227 commit aa88056

File tree

3 files changed

+105
-106
lines changed

3 files changed

+105
-106
lines changed

lib/fixture/locator/fixtures.ts

+2-7
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,8 @@ import type {
99
Within,
1010
} from '../types'
1111

12-
import {
13-
buildTestingLibraryScript,
14-
isAllQuery,
15-
queriesFor,
16-
queryToSelector,
17-
synchronousQueryNames,
18-
} from './helpers'
12+
import {buildTestingLibraryScript, queryToSelector} from './helpers'
13+
import {isAllQuery, queriesFor, synchronousQueryNames} from './queries'
1914

2015
type TestArguments = PlaywrightTestArgs & Config
2116

lib/fixture/locator/helpers.ts

+3-99
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,8 @@
11
import {promises as fs} from 'fs'
22

3-
import type {Locator, Page} from '@playwright/test'
4-
import {errors} from '@playwright/test'
5-
import {queries} from '@testing-library/dom'
6-
73
import {configureTestingLibraryScript} from '../../common'
8-
import {replacer, reviver} from '../helpers'
9-
import type {
10-
AllQuery,
11-
Config,
12-
FindQuery,
13-
GetQuery,
14-
LocatorQueries as Queries,
15-
Query,
16-
QueryQuery,
17-
Selector,
18-
SynchronousQuery,
19-
} from '../types'
20-
21-
const allQueryNames = Object.keys(queries) as Query[]
22-
23-
const isAllQuery = (query: Query): query is AllQuery => query.includes('All')
24-
25-
const isFindQuery = (query: Query): query is FindQuery => query.startsWith('find')
26-
const isNotFindQuery = (query: Query): query is Exclude<Query, FindQuery> =>
27-
!query.startsWith('find')
28-
29-
const findQueryToGetQuery = (query: FindQuery) => query.replace(/^find/, 'get') as GetQuery
30-
const findQueryToQueryQuery = (query: FindQuery) => query.replace(/^find/, 'query') as QueryQuery
4+
import {reviver} from '../helpers'
5+
import type {Config, Selector, SynchronousQuery} from '../types'
316

327
const queryToSelector = (query: SynchronousQuery) =>
338
query.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase() as Selector
@@ -47,75 +22,4 @@ const buildTestingLibraryScript = async ({config}: {config: Config}) => {
4722
`
4823
}
4924

50-
const synchronousQueryNames = allQueryNames.filter(isNotFindQuery)
51-
52-
const createFindQuery =
53-
(
54-
pageOrLocator: Page | Locator,
55-
query: FindQuery,
56-
{asyncUtilTimeout, asyncUtilExpectedState}: Partial<Config> = {},
57-
) =>
58-
async (...[id, options, waitForElementOptions]: Parameters<Queries[FindQuery]>) => {
59-
const synchronousOptions = ([id, options] as const).filter(Boolean)
60-
61-
const locator = pageOrLocator.locator(
62-
`${queryToSelector(findQueryToQueryQuery(query))}=${JSON.stringify(
63-
synchronousOptions,
64-
replacer,
65-
)}`,
66-
)
67-
68-
const {state = asyncUtilExpectedState, timeout = asyncUtilTimeout} = waitForElementOptions ?? {}
69-
70-
try {
71-
await locator.first().waitFor({state, timeout})
72-
} catch (error) {
73-
// In the case of a `waitFor` timeout from Playwright, we want to
74-
// surface the appropriate error from Testing Library, so run the
75-
// query one more time as `get*` knowing that it will fail with the
76-
// error that we want the user to see instead of the `TimeoutError`
77-
if (error instanceof errors.TimeoutError) {
78-
return pageOrLocator
79-
.locator(
80-
`${queryToSelector(findQueryToGetQuery(query))}=${JSON.stringify(
81-
synchronousOptions,
82-
replacer,
83-
)}`,
84-
)
85-
.first()
86-
.waitFor({state, timeout: 100})
87-
}
88-
89-
throw error
90-
}
91-
92-
return locator
93-
}
94-
95-
/**
96-
* Given a `Page` or `Locator` instance, return an object of Testing Library
97-
* query methods that return a `Locator` instance for the queried element
98-
*
99-
* @internal this API is not currently intended for public usage and may be
100-
* removed or changed outside of semantic release versioning. If possible, you
101-
* should use the `locatorFixtures` with **@playwright/test** instead.
102-
* @see {@link locatorFixtures}
103-
*
104-
* @param pageOrLocator `Page` or `Locator` instance to use as the query root
105-
* @param config Testing Library configuration to apply to queries
106-
*
107-
* @returns object containing scoped Testing Library query methods
108-
*/
109-
const queriesFor = (pageOrLocator: Page | Locator, config?: Partial<Config>) =>
110-
allQueryNames.reduce(
111-
(rest, query) => ({
112-
...rest,
113-
[query]: isFindQuery(query)
114-
? createFindQuery(pageOrLocator, query, config)
115-
: (...args: Parameters<Queries[SynchronousQuery]>) =>
116-
pageOrLocator.locator(`${queryToSelector(query)}=${JSON.stringify(args, replacer)}`),
117-
}),
118-
{} as Queries,
119-
)
120-
121-
export {buildTestingLibraryScript, isAllQuery, queriesFor, queryToSelector, synchronousQueryNames}
25+
export {buildTestingLibraryScript, queryToSelector}

lib/fixture/locator/queries.ts

+100
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
import type {Locator, Page} from '@playwright/test'
2+
import {errors} from '@playwright/test'
3+
import {queries} from '@testing-library/dom'
4+
5+
import {replacer} from '../helpers'
6+
import type {
7+
AllQuery,
8+
Config,
9+
FindQuery,
10+
GetQuery,
11+
LocatorQueries as Queries,
12+
Query,
13+
QueryQuery,
14+
SynchronousQuery,
15+
} from '../types'
16+
17+
import {queryToSelector} from './helpers'
18+
19+
const isAllQuery = (query: Query): query is AllQuery => query.includes('All')
20+
21+
const isFindQuery = (query: Query): query is FindQuery => query.startsWith('find')
22+
const isNotFindQuery = (query: Query): query is Exclude<Query, FindQuery> =>
23+
!query.startsWith('find')
24+
25+
const allQueryNames = Object.keys(queries) as Query[]
26+
const synchronousQueryNames = allQueryNames.filter(isNotFindQuery)
27+
28+
const findQueryToGetQuery = (query: FindQuery) => query.replace(/^find/, 'get') as GetQuery
29+
const findQueryToQueryQuery = (query: FindQuery) => query.replace(/^find/, 'query') as QueryQuery
30+
31+
const createFindQuery =
32+
(
33+
pageOrLocator: Page | Locator,
34+
query: FindQuery,
35+
{asyncUtilTimeout, asyncUtilExpectedState}: Partial<Config> = {},
36+
) =>
37+
async (...[id, options, waitForElementOptions]: Parameters<Queries[FindQuery]>) => {
38+
const synchronousOptions = ([id, options] as const).filter(Boolean)
39+
40+
const locator = pageOrLocator.locator(
41+
`${queryToSelector(findQueryToQueryQuery(query))}=${JSON.stringify(
42+
synchronousOptions,
43+
replacer,
44+
)}`,
45+
)
46+
47+
const {state = asyncUtilExpectedState, timeout = asyncUtilTimeout} = waitForElementOptions ?? {}
48+
49+
try {
50+
await locator.first().waitFor({state, timeout})
51+
} catch (error) {
52+
// In the case of a `waitFor` timeout from Playwright, we want to
53+
// surface the appropriate error from Testing Library, so run the
54+
// query one more time as `get*` knowing that it will fail with the
55+
// error that we want the user to see instead of the `TimeoutError`
56+
if (error instanceof errors.TimeoutError) {
57+
return pageOrLocator
58+
.locator(
59+
`${queryToSelector(findQueryToGetQuery(query))}=${JSON.stringify(
60+
synchronousOptions,
61+
replacer,
62+
)}`,
63+
)
64+
.first()
65+
.waitFor({state, timeout: 100})
66+
}
67+
68+
throw error
69+
}
70+
71+
return locator
72+
}
73+
74+
/**
75+
* Given a `Page` or `Locator` instance, return an object of Testing Library
76+
* query methods that return a `Locator` instance for the queried element
77+
*
78+
* @internal this API is not currently intended for public usage and may be
79+
* removed or changed outside of semantic release versioning. If possible, you
80+
* should use the `locatorFixtures` with **@playwright/test** instead.
81+
* @see {@link locatorFixtures}
82+
*
83+
* @param pageOrLocator `Page` or `Locator` instance to use as the query root
84+
* @param config Testing Library configuration to apply to queries
85+
*
86+
* @returns object containing scoped Testing Library query methods
87+
*/
88+
const queriesFor = (pageOrLocator: Page | Locator, config?: Partial<Config>) =>
89+
allQueryNames.reduce(
90+
(rest, query) => ({
91+
...rest,
92+
[query]: isFindQuery(query)
93+
? createFindQuery(pageOrLocator, query, config)
94+
: (...args: Parameters<Queries[SynchronousQuery]>) =>
95+
pageOrLocator.locator(`${queryToSelector(query)}=${JSON.stringify(args, replacer)}`),
96+
}),
97+
{} as Queries,
98+
)
99+
100+
export {allQueryNames, isAllQuery, isNotFindQuery, queriesFor, synchronousQueryNames}

0 commit comments

Comments
 (0)