Skip to content
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鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: use regex based TextMatch for suggestions #617

Merged
merged 3 commits into from Jun 11, 2020
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
40 changes: 22 additions & 18 deletions src/__tests__/suggestions.js
Expand Up @@ -72,7 +72,9 @@ test(`should not suggest if the suggestion would give different results`, () =>
test('should suggest by label over title', () => {
renderIntoDocument(`<label><span>bar</span><input title="foo" /></label>`)

expect(() => screen.getByTitle('foo')).toThrowError(/getByLabelText\('bar'\)/)
expect(() => screen.getByTitle('foo')).toThrowError(
/getByLabelText\(\/bar\/i\)/,
)
})

test('should not suggest if there would be mixed suggestions', () => {
Expand Down Expand Up @@ -178,7 +180,7 @@ test('should suggest getByLabelText when no role available', () => {
`<label for="foo">Username</label><input data-testid="foo" id="foo" />`,
)
expect(() => screen.getByTestId('foo')).toThrowError(
/getByLabelText\('Username'\)/,
/getByLabelText\(\/username\/i\)/,
)
})

Expand All @@ -191,7 +193,7 @@ test(`should suggest getByLabel on non form elements`, () => {
`)

expect(() => screen.getByTestId('foo')).toThrowError(
/getByLabelText\('Section One'\)/,
/getByLabelText\(\/section one\/i\)/,
)
})

Expand Down Expand Up @@ -230,23 +232,23 @@ test(`should suggest label over placeholder text`, () => {
)

expect(() => screen.getByPlaceholderText('Username')).toThrowError(
/getByLabelText\('Username'\)/,
/getByLabelText\(\/username\/i\)/,
)
})

test(`should suggest getByPlaceholderText`, () => {
renderIntoDocument(`<input data-testid="foo" placeholder="Username" />`)

expect(() => screen.getByTestId('foo')).toThrowError(
/getByPlaceholderText\('Username'\)/,
/getByPlaceholderText\(\/username\/i\)/,
)
})

test(`should suggest getByText for simple elements`, () => {
renderIntoDocument(`<div data-testid="foo">hello there</div>`)

expect(() => screen.getByTestId('foo')).toThrowError(
/getByText\('hello there'\)/,
/getByText\(\/hello there\/i\)/,
)
})

Expand All @@ -256,7 +258,7 @@ test(`should suggest getByDisplayValue`, () => {
document.getElementById('lastName').value = 'Prine' // RIP John Prine

expect(() => screen.getByTestId('lastName')).toThrowError(
/getByDisplayValue\('Prine'\)/,
/getByDisplayValue\(\/prine\/i\)/,
)
})

Expand All @@ -269,10 +271,10 @@ test(`should suggest getByAltText`, () => {
`)

expect(() => screen.getByTestId('input')).toThrowError(
/getByAltText\('last name'\)/,
/getByAltText\(\/last name\/i\)/,
)
expect(() => screen.getByTestId('area')).toThrowError(
/getByAltText\('Computer'\)/,
/getByAltText\(\/computer\/i\)/,
)
})

Expand All @@ -285,27 +287,29 @@ test(`should suggest getByTitle`, () => {
</svg>`)

expect(() => screen.getByTestId('delete')).toThrowError(
/getByTitle\('Delete'\)/,
/getByTitle\(\/delete\/i\)/,
)
expect(() => screen.getAllByTestId('delete')).toThrowError(
/getAllByTitle\('Delete'\)/,
/getAllByTitle\(\/delete\/i\)/,
)
expect(() => screen.queryByTestId('delete')).toThrowError(
/queryByTitle\('Delete'\)/,
/queryByTitle\(\/delete\/i\)/,
)
expect(() => screen.queryAllByTestId('delete')).toThrowError(
/queryAllByTitle\('Delete'\)/,
/queryAllByTitle\(\/delete\/i\)/,
)
expect(() => screen.queryAllByTestId('delete')).toThrowError(
/queryAllByTitle\('Delete'\)/,
/queryAllByTitle\(\/delete\/i\)/,
)
expect(() => screen.queryAllByTestId('delete')).toThrowError(
/queryAllByTitle\('Delete'\)/,
/queryAllByTitle\(\/delete\/i\)/,
)

// Since `ByTitle` and `ByText` will both return the <title> element
// `getByText` will always be the suggested query as it is higher up the list.
expect(() => screen.getByTestId('svg')).toThrowError(/getByText\('Close'\)/)
expect(() => screen.getByTestId('svg')).toThrowError(
/getByText\(\/close\/i\)/,
)
})

test('getSuggestedQuery handles `variant` and defaults to `get`', () => {
Expand Down Expand Up @@ -343,9 +347,9 @@ test('getSuggestedQuery returns rich data for tooling', () => {
expect(getSuggestedQuery(div)).toMatchObject({
queryName: 'Text',
queryMethod: 'getByText',
queryArgs: ['cancel'],
queryArgs: [/cancel/i],
variant: 'get',
})

expect(getSuggestedQuery(div).toString()).toEqual(`getByText('cancel')`)
expect(getSuggestedQuery(div).toString()).toEqual(`getByText(/cancel/i)`)
})
17 changes: 13 additions & 4 deletions src/suggestions.js
Expand Up @@ -30,8 +30,12 @@ function escapeRegExp(string) {
return string.replace(/[.*+\-?^${}()|[\]\\]/g, '\\$&') // $& means the whole matched string
}

function getRegExpMatcher(string) {
return new RegExp(string.toLowerCase(), 'i')
}

function makeSuggestion(queryName, content, {variant = 'get', name}) {
const queryArgs = [content]
const queryArgs = [queryName === 'Role' ? content : getRegExpMatcher(content)]

if (name) {
queryArgs.push({name: new RegExp(escapeRegExp(name.toLowerCase()), 'i')})
Expand All @@ -45,12 +49,17 @@ function makeSuggestion(queryName, content, {variant = 'get', name}) {
queryArgs,
variant,
toString() {
const options = queryArgs[1]
? `, { ${Object.entries(queryArgs[1])
let [text, options] = queryArgs

text = typeof text === 'string' ? `'${text}'` : text

options = options
? `, { ${Object.entries(options)
.map(([k, v]) => `${k}: ${v}`)
.join(', ')} }`
: ''
return `${queryMethod}('${content}'${options})`

return `${queryMethod}(${text}${options})`
},
}
}
Expand Down