Commit da1f6ae3 authored by Natalia Tepluhina's avatar Natalia Tepluhina

Merge branch 'ps-update-fe-testing-guide-dom-selectors' into 'master'

Simplify example for dom selectors in FE testing

See merge request gitlab-org/gitlab!46173
parents 654f971a e8eb4489
...@@ -198,47 +198,33 @@ Following you'll find some general common practices you will find as part of our ...@@ -198,47 +198,33 @@ Following you'll find some general common practices you will find as part of our
When it comes to querying DOM elements in your tests, it is best to uniquely and semantically target When it comes to querying DOM elements in your tests, it is best to uniquely and semantically target
the element. the element.
Preferentially, this is done by targeting text the user actually sees using [DOM Testing Library](https://testing-library.com/docs/dom-testing-library/intro). Preferentially, this is done by targeting what the user actually sees using [DOM Testing Library](https://testing-library.com/docs/dom-testing-library/intro).
When selecting by text it is best to use [`getByRole` or `findByRole`](https://testing-library.com/docs/dom-testing-library/api-queries#byrole) When selecting by text it is best to use [`getByRole` or `findByRole`](https://testing-library.com/docs/dom-testing-library/api-queries#byrole)
as these enforce accessibility best practices as well. The examples below demonstrate the order of preference. as these enforce accessibility best practices as well. The examples below demonstrate the order of preference.
Sometimes this cannot be done feasibly. In these cases, adding test attributes to simplify the When writing Vue component unit tests, it can be wise to query children by component, so that the unit test can focus on comprehensive value coverage
selectors might be the best option. rather than dealing with the complexity of a child component's behavior.
Sometimes, neither of the above are feasible. In these cases, adding test attributes to simplify the selectors might be the best option. A list of
possible selectors include:
- A semantic attribute like `name` (also verifies that `name` was setup properly) - A semantic attribute like `name` (also verifies that `name` was setup properly)
- A `data-testid` attribute ([recommended by maintainers of `@vue/test-utils`](https://github.com/vuejs/vue-test-utils/issues/1498#issuecomment-610133465)) - A `data-testid` attribute ([recommended by maintainers of `@vue/test-utils`](https://github.com/vuejs/vue-test-utils/issues/1498#issuecomment-610133465))
- a Vue `ref` (if using `@vue/test-utils`) - a Vue `ref` (if using `@vue/test-utils`)
```javascript ```javascript
import { mount, shallowMount } from '@vue/test-utils'
import { getByRole, getByText } from '@testing-library/dom' import { getByRole, getByText } from '@testing-library/dom'
let wrapper // In this example, `wrapper` is a `@vue/test-utils` wrapper returned from `mount` or `shallowMount`.
let el
const createComponent = (mountFn = shallowMount) => {
wrapper = mountFn(Component)
el = wrapper.vm.$el // reference to the container element
}
beforeEach(() => {
createComponent()
})
it('exists', () => { it('exists', () => {
// Best // Best (especially for integration tests)
getByRole(wrapper.element, 'link', { name: /Click Me/i })
// NOTE: both mount and shallowMount work as long as a DOM element is available getByRole(wrapper.element, 'link', { name: 'Click Me' })
// Finds a properly formatted link with an accessible name of "Click Me" getByText(wrapper.element, 'Click Me')
getByRole(el, 'link', { name: /Click Me/i }) getByText(wrapper.element, /Click Me/i)
getByRole(el, 'link', { name: 'Click Me' })
// Finds any element with the text "Click Me" // Good (especially for unit tests)
getByText(el, 'Click Me') wrapper.find(FooComponent);
// Regex is also available
getByText(el, /Click Me/i)
// Good
wrapper.find('input[name=foo]'); wrapper.find('input[name=foo]');
wrapper.find('[data-testid="foo"]'); wrapper.find('[data-testid="foo"]');
wrapper.find({ ref: 'foo'}); wrapper.find({ ref: 'foo'});
...@@ -249,14 +235,6 @@ it('exists', () => { ...@@ -249,14 +235,6 @@ it('exists', () => {
wrapper.find('.qa-foo-component'); wrapper.find('.qa-foo-component');
wrapper.find('[data-qa-selector="foo"]'); wrapper.find('[data-qa-selector="foo"]');
}); });
// Good
it('exists', () => {
wrapper.find(FooComponent);
wrapper.find('input[name=foo]');
wrapper.find('[data-testid="foo"]');
wrapper.find({ ref: 'foo'});
});
``` ```
It is not recommended that you add `.js-*` classes just for testing purposes. Only do this if there are no other feasible options available. It is not recommended that you add `.js-*` classes just for testing purposes. Only do this if there are no other feasible options available.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment