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’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(queryByCurrentValue) #169

Merged
merged 16 commits into from
Dec 12, 2018

Conversation

eunjae-lee
Copy link
Contributor

@eunjae-lee eunjae-lee commented Dec 7, 2018

What: It adds queryByCurrentValue, getByCurrentValue, queryAllByCurrentValue and getAllByCurrentValue.

Why: getByValue cannot get elements with value property (it only checks DOM value attributes)
(Discussed at #166)

How: Added a set of (get|query)(All)?ByCurrentValue methods.

Checklist:

  • Documentation
  • Tests
  • Ready to be merged
  • Added myself to contributors table

Feel free to give any feedbacks.


Closes #158

Copy link
Member

@kentcdodds kentcdodds left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! Here are a few comments :)

src/queries.js Outdated
@@ -356,8 +387,12 @@ export {
getAllByTitle,
queryByValue,
queryAllByValue,
queryByCurrentValue,
queryAllByCurrentValue,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you move both of these down two lines. I kinda like to group things together.

src/queries.js Outdated
const matcher = exact ? matches : fuzzyMatches
const matchOpts = {collapseWhitespace, trim}
return Array.from(container.querySelectorAll(`input,textarea,select`)).filter(
node => matcher(node.value, node, value, matchOpts),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This wont work for selects. Please look at (and maybe just use) the logic in queryAllBySelectText for selects.

@@ -565,4 +565,19 @@ test('getByText ignores script tags by default', () => {
expect(getAllByText(/hello/i, {ignore: false})).toHaveLength(3)
})

test('get element by its dynamically assigned value', () => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we also have a test for a textarea and a select. Can be in this test or in a new one I don't care which.

@eunjae-lee
Copy link
Contributor Author

Thanks for the review. I made changes regarding your three comments.

@alexkrolick
Copy link
Collaborator

Looks good! Just need docs and a test to execute line 358 (the error state for queryAllBy...) to keep coverage at 100%.

Also it might be nice to add an integration test for fireEvent.change() with getCurrentValue.

Copy link
Member

@kentcdodds kentcdodds left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking good, but I do have a question.

expect(queryByCurrentValue('Alaska').id).toEqual('state-select')

getByTestId('state').value = 'AL'
expect(getByCurrentValue('Alabama').id).toEqual('state-select')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if it's at all confusing that we are expected to set the value to AL but when we use the query we search for Alabama.

I realize that's just how things work (the value for a select has a display value), but I feel like this could be a point of confusion for people. My guess is they'd prefer to select by AL instead which isn't what is shown to the user but feels more intuitive here. I'm not sure of the best solution to this... Maybe allow for either the display value or the actual value?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That makes sense. To end-users Alabama is a value, but AL is the actual value.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

However, selectElem.value could be either 1, AL, or whatever user cannot know. In a perspective of writing tests as user would use it, I'd rather choose to restrict it to display value.
What do you think?

Copy link
Collaborator

@alexkrolick alexkrolick Dec 10, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm. To really avoid confusion, this could be called getByDisplayValue().

Technically an aria-menu is also compliant with this API: https://w3c.github.io/aria/#menu, https://w3c.github.io/aria/#aria-selected. In the ARIA case there doesn't seem to be any way to have a different "secret form value" vs "display value". EDIT: out of scope

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I think displayValue is probably a better mental model, though it may be a tiny confusing for input and textarea where the display value is actually the actual value but I think that's alright. Besides, people should normally be getting these elements by their label anyway, so I'm not too concerned about this slightly less-awesome API.

Let's go with getByDisplayValue 👍

@eunjae-lee
Copy link
Contributor Author

@alexkrolick I've added a test to check if it throws.

@kentcdodds I've renamed and updates the README.md. I didn't know how to edit it, so it's kind of a draft. Where do you want to put the section in the document? And how do you want to explain it to users? Take a look at the doc and let me know. Besides, I'm not a native English speaker, so pretty much worried about it 😅

Copy link
Member

@kentcdodds kentcdodds left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is great, just a few small docs changes. Thanks!

README.md Outdated
@@ -86,6 +86,7 @@ when a real user uses it.
- [`getByAltText`](#getbyalttext)
- [`getByTitle`](#getbytitle)
- [`getByValue`](#getbyvalue)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's remove the docs for getByValue and getBySelectText because we want to encourage people to use the getByDisplayValue instead.

README.md Outdated
}): HTMLElement
```

Returns the element that has the matching display value.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Returns the input, textarea, or select element that has the matching display value.

README.md Outdated
// <input type="text" id="lastName" />
// document.getElementById('lastName').value = 'Norris'

const lastNameInput = getByDisplayValue('Norris')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const lastNameInput = getByDisplayValue(document.body, 'Norris')

README.md Outdated
// <textarea id="messageTextArea"></textarea>
// document.getElementById('messageTextArea').value = 'Hello World'

const messageTextArea = getByDisplayValue('Hello World')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const messageTextArea = getByDisplayValue(document.body, 'Hello World')

README.md Outdated
// </select>

const selectElement = getByDisplayName('Alaska')
console.log(selectElement.id)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove the console.log here (it's not necessary and it's nice to be consistent with the others). Then fix it to be:

const selectElement = getByDisplayName(document.body, 'Alaska')

@eunjae-lee
Copy link
Contributor Author

@kentcdodds done! I've used container instead of document.body since I found out other parts of the doc used container.

@kentcdodds
Copy link
Member

Looks like we're missing some coverage. You can open the coverage report in the browser in coverage/lcov-report to see what's missing.

@eunjae-lee
Copy link
Contributor Author

@kentcdodds coverage 100% done

README.md Outdated
@@ -337,77 +335,54 @@ content is in an inline script file, then the script tag could be returned.

If you'd rather disable this behavior, set `ignore` to `false`.

### `getByAltText`
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are these doc sections being deleted?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh my, ..

image

When I saw that, I somehow thought it was sort of a diff, so I ended up deleting getByAltText, getByTitle, getByValue sections. Let me restore them and get rid of getByValue, getBySelectText sections.

@eunjae-lee
Copy link
Contributor Author

Updated the doc. Thanks for pointing it out @alexkrolick

Copy link
Member

@kentcdodds kentcdodds left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sweet! Thanks!

@kentcdodds kentcdodds merged commit 9a19474 into testing-library:master Dec 12, 2018
@kentcdodds
Copy link
Member

🎉 This PR is included in version 3.14.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

@eunjae-lee
Copy link
Contributor Author

Awesome! Thank you :) This merge made my day!!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

getByValue cannot get element by dynamically assigned value
3 participants