Skip to content

Commit 2104763

Browse files
committed
feat: add getNodeText method
1 parent 7e56327 commit 2104763

File tree

8 files changed

+53
-19
lines changed

8 files changed

+53
-19
lines changed

lib/extend.ts

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ declare module 'puppeteer' {
2121
}
2222

2323
interface ElementHandle {
24+
getNodeText(): Promise<string>
2425
queryByPlaceholderText(m: Matcher, opts?: MatcherOptions): Promise<ElementHandle | null>
2526
queryAllByPlaceholderText(m: Matcher, opts?: MatcherOptions): Promise<ElementHandle[]>
2627
getByPlaceholderText(m: Matcher, opts?: MatcherOptions): Promise<ElementHandle>

lib/index.ts

+40-15
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import {readFileSync} from 'fs'
22
import * as path from 'path'
33
import {ElementHandle, EvaluateFn, JSHandle, Page} from 'puppeteer'
44
import waitForExpect from 'wait-for-expect'
5-
import {ITestUtils} from './typedefs'
5+
import {IQueryUtils} from './typedefs'
66

77
const domLibraryAsString = readFileSync(
88
path.join(__dirname, '../dom-testing-library.js'),
@@ -53,33 +53,53 @@ async function covertToElementHandle(handle: JSHandle, asArray: boolean): Promis
5353
return asArray ? createElementHandleArray(handle) : createElementHandle(handle)
5454
}
5555

56-
function createDelegateFor(
57-
fnName: keyof ITestUtils,
56+
function processNodeText(handles: IHandleSet): Promise<string> {
57+
return handles.containerHandle
58+
.executionContext()
59+
.evaluate(handles.evaluateFn, handles.containerHandle, 'getNodeText')
60+
}
61+
62+
async function processQuery(handles: IHandleSet): Promise<DOMReturnType> {
63+
const {containerHandle, evaluateFn, fnName, argsToForward} = handles
64+
65+
const handle = await containerHandle
66+
.executionContext()
67+
.evaluateHandle(evaluateFn, containerHandle, fnName, ...argsToForward)
68+
return covertToElementHandle(handle, fnName.includes('All'))
69+
}
70+
71+
interface IHandleSet {
72+
containerHandle: ElementHandle
73+
evaluateFn: EvaluateFn
74+
fnName: string
75+
argsToForward: any[]
76+
}
77+
78+
function createDelegateFor<T = DOMReturnType>(
79+
fnName: keyof IQueryUtils,
5880
contextFn?: ContextFn,
59-
): (...args: any[]) => Promise<DOMReturnType> {
60-
return async function(...args: any[]): Promise<DOMReturnType> {
81+
processHandleFn?: (handles: IHandleSet) => Promise<T>,
82+
): (...args: any[]) => Promise<T> {
83+
// @ts-ignore
84+
processHandleFn = processHandleFn || processQuery
85+
86+
return async function(...args: any[]): Promise<T> {
6187
// @ts-ignore
6288
const containerHandle: ElementHandle = contextFn ? contextFn.apply(this, args) : this
6389
// @ts-ignore
6490
const evaluateFn: EvaluateFn = {toString: () => delegateFnToExecuteInPage}
6591

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

72-
const handle = await containerHandle
73-
.executionContext()
74-
.evaluateHandle(evaluateFn, containerHandle, fnName, ...argsToForward)
75-
return covertToElementHandle(handle, fnName.includes('All'))
99+
return processHandleFn!({fnName, containerHandle, evaluateFn, argsToForward})
76100
}
77101
}
78102

79-
export function wait(callback = () => {}, {timeout = 4500, interval = 50} = {}): Promise<{}> {
80-
return waitForExpect(callback, timeout, interval)
81-
}
82-
83103
export async function getDocument(_page?: Page): Promise<ElementHandle> {
84104
// @ts-ignore
85105
const page: Page = _page || this
@@ -89,7 +109,11 @@ export async function getDocument(_page?: Page): Promise<ElementHandle> {
89109
return document
90110
}
91111

92-
export function getQueriesForElement<T>(object: T, contextFn?: ContextFn): T & ITestUtils {
112+
export function wait(callback = () => {}, {timeout = 4500, interval = 50} = {}): Promise<{}> {
113+
return waitForExpect(callback, timeout, interval)
114+
}
115+
116+
export function getQueriesForElement<T>(object: T, contextFn?: ContextFn): T & IQueryUtils {
93117
const o = object as any
94118
o.queryByPlaceholderText = createDelegateFor('queryByPlaceholderText', contextFn)
95119
o.queryAllByPlaceholderText = createDelegateFor('queryAllByPlaceholderText', contextFn)
@@ -115,11 +139,12 @@ export function getQueriesForElement<T>(object: T, contextFn?: ContextFn): T & I
115139
o.queryAllByTitle = createDelegateFor('queryAllByTitle', contextFn)
116140
o.getByTitle = createDelegateFor('getByTitle', contextFn)
117141
o.getAllByTitle = createDelegateFor('getAllByTitle', contextFn)
142+
o.getNodeText = createDelegateFor<string>('getNodeText', contextFn, processNodeText)
118143
return o
119144
}
120145

121146
export const within = getQueriesForElement
122147

123148
// @ts-ignore
124-
export const queries: ITestUtils = {}
149+
export const queries: IQueryUtils = {}
125150
getQueriesForElement(queries, el => el)

lib/typedefs.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ import {ElementHandle} from 'puppeteer'
33

44
type Element = ElementHandle
55

6-
export interface ITestUtils {
6+
export interface IQueryUtils {
7+
getNodeText(el: Element): Promise<string>
78
queryByPlaceholderText(el: Element, m: Matcher, opts?: MatcherOptions): Promise<Element | null>
89
queryAllByPlaceholderText(el: Element, m: Matcher, opts?: MatcherOptions): Promise<Element[]>
910
getByPlaceholderText(el: Element, m: Matcher, opts?: MatcherOptions): Promise<Element>

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
"clean": "rm -fR dist/",
1212
"rebuild": "npm run clean && npm run build",
1313
"prepublishOnly": "npm run rebuild && generate-export-aliases",
14-
"build": "npm run build:ts",
14+
"build": "npm run build:ts && npm run build:rollup",
1515
"build:ts": "tsc",
1616
"build:rollup": "rollup -c rollup.config.js"
1717
},

rollup.config.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
const path = require('path')
22

33
module.exports = {
4-
input: path.join(__dirname, 'node_modules/dom-testing-library/dist/queries.js'),
4+
input: path.join(__dirname, 'rollup.input.js'),
55
output: {
66
file: 'dom-testing-library.js',
77
format: 'iife',

rollup.input.js

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export * from 'dom-testing-library/dist/queries'
2+
export {getNodeText} from 'dom-testing-library/dist/get-node-text'

test/__snapshots__/extend.test.ts.snap

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ exports[`lib/extend.ts should handle the get* method failures 1`] = `
2020
at getAllByTitle (<anonymous>:2827:12)
2121
at firstResultOrNull (<anonymous>:2638:31)
2222
at Object.getByTitle (<anonymous>:2837:29)
23-
at evaluateInPage (<anonymous>:3047:41)]
23+
at evaluateInPage (<anonymous>:3048:41)]
2424
`;
2525
2626
exports[`lib/extend.ts should handle the get* methods 1`] = `"<input type=\\"text\\" data-testid=\\"testid-text-input\\">"`;

test/extend.test.ts

+5
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,11 @@ describe('lib/extend.ts', () => {
7171
expect(await page.evaluate(el => el.textContent, element)).toEqual('Hello h3')
7272
})
7373

74+
it('should get text content', async () => {
75+
const $h3 = await document.$('#scoped h3')
76+
expect(await $h3.getNodeText()).toEqual('Hello h3')
77+
})
78+
7479
afterAll(async () => {
7580
await browser.close()
7681
})

0 commit comments

Comments
 (0)