Skip to content
This repository was archived by the owner on Aug 6, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ branches:
- master
- next
node_js:
- node
- v14
- v12
- v10
env:
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ All your favorite user-centric querying functions from **@testing-library/react*

```js
const {webkit} = require('playwright') // or 'firefox' or 'chromium'
const {getDocument, queries, wait} = require('playwright-testing-library')
const {getDocument, queries, waitFor} = require('playwright-testing-library')

const {getByTestId, getByLabelText} = queries

Expand All @@ -51,7 +51,7 @@ const $email = await getByLabelText($form, 'Email')
// interact with playwright like usual
await $email.type('playwright@example.com')
// waiting works too!
await wait(() => getByText($document, 'Loading...'))
await waitFor(() => getByText($document, 'Loading...'))
```

A little too un-playwright for you? We've got prototype-mucking covered too :)
Expand Down
6 changes: 3 additions & 3 deletions lib/__tests__/fixtures/page.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
<html>

<body>
<h1>Hello h1</h1>
<h2>Hello h2</h2>
<h1 data-new-id="first-level-header">Hello h1</h1>
<h2 data-id="second-level-header">Hello h2</h2>
<img alt="Image A" src="">
<input type="text" data-testid="testid-text-input">
<label for="label-text-input">Label A</label>
<label for="label-text-input" data-testid="testid-label">Label A</label>
<input id="label-text-input" type="text">

<div id="scoped">
Expand Down
32 changes: 30 additions & 2 deletions lib/__tests__/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as path from 'path'
import * as playwright from 'playwright'
import {getDocument, queries, getQueriesForElement, wait} from '..'
import {getDocument, queries, getQueriesForElement, waitFor, configure} from '..'

describe('lib/index.ts', () => {
let browser: playwright.Browser
Expand All @@ -18,6 +18,30 @@ describe('lib/index.ts', () => {
expect(await queries.getNodeText(element)).toEqual('Hello h1')
})

it('should support custom data-testid attribute name', async () => {
configure({testIdAttribute: 'data-id'})
const document = await getDocument(page)
const element = await queries.getByTestId(document, 'second-level-header')
expect(await queries.getNodeText(element)).toEqual('Hello h2')
})

it('should support subsequent changing the data-testid attribute names', async () => {
configure({testIdAttribute: 'data-id'})
configure({testIdAttribute: 'data-new-id'})
const document = await getDocument(page)
const element = await queries.getByTestId(document, 'first-level-header')
expect(await queries.getNodeText(element)).toEqual('Hello h1')
})

it('should keep the default data-testid when input passed is invalid', async () => {
;[{}, undefined, null, {testIdAttribute: ''}].forEach(async options => {
const document = await getDocument(page)
configure(options as any)
const element = await queries.getByTestId(document, 'testid-label')
expect(await queries.getNodeText(element)).toEqual('Label A')
})
})

it('should support regex on raw queries object', async () => {
const scope = await page.$('#scoped')
if (!scope) throw new Error('Should have scope')
Expand All @@ -38,10 +62,14 @@ describe('lib/index.ts', () => {
it('should use `wait` properly', async () => {
const {getByText} = getQueriesForElement(await getDocument(page))
// eslint-disable-next-line @typescript-eslint/no-misused-promises
await wait(() => getByText('Loaded!'), {timeout: 7000})
await waitFor(() => getByText('Loaded!'), {timeout: 7000})
expect(await getByText('Loaded!')).toBeTruthy()
}, 9000)

afterEach(() => {
configure({testIdAttribute: 'data-testid'}) // cleanup
})

afterAll(async () => {
await browser.close()
})
Expand Down
23 changes: 21 additions & 2 deletions lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import * as path from 'path'
import {JSHandle, Page} from 'playwright'
import waitForExpect from 'wait-for-expect'

import {ElementHandle, IQueryUtils, IScopedQueryUtils} from './typedefs'
import {ElementHandle, IConfigureOptions, IQueryUtils, IScopedQueryUtils} from './typedefs'

const domLibraryAsString = readFileSync(
path.join(__dirname, '../dom-testing-library.js'),
Expand All @@ -17,7 +17,7 @@ function mapArgument(argument: any, index: number): any {
: argument
}

const delegateFnBodyToExecuteInPage = `
const delegateFnBodyToExecuteInPageInitial = `
${domLibraryAsString};

const mappedArgs = args.map(${mapArgument.toString()});
Expand All @@ -27,6 +27,8 @@ const delegateFnBodyToExecuteInPage = `
return moduleWithFns[fnName](container, ...mappedArgs);
`

let delegateFnBodyToExecuteInPage = delegateFnBodyToExecuteInPageInitial

type DOMReturnType = ElementHandle | ElementHandle[] | null

type ContextFn = (...args: any[]) => ElementHandle
Expand Down Expand Up @@ -132,6 +134,23 @@ export function wait(
return waitForExpect(callback, timeout, interval)
}

export const waitFor = wait

export function configure(options: Partial<IConfigureOptions>): void {
if (!options) {
return
}

const {testIdAttribute} = options

if (testIdAttribute) {
delegateFnBodyToExecuteInPage = delegateFnBodyToExecuteInPageInitial.replace(
/testIdAttribute: (['|"])data-testid(['|"])/g,
`testIdAttribute: $1${testIdAttribute}$2`,
)
}
}

export function getQueriesForElement<T>(
object: T,
contextFn?: ContextFn,
Expand Down
4 changes: 4 additions & 0 deletions lib/typedefs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,7 @@ export interface IQueryUtils extends IQueryMethods {
getQueriesForElement(): IQueryUtils & IScopedQueryUtils
getNodeText(el: Element): Promise<string>
}

export interface IConfigureOptions {
testIdAttribute: string
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,6 @@
"playwright": "^1.1.0"
},
"engines": {
"node": "^10 || ^12 || ^13 || ^14"
"node": ">=10"
}
}