Skip to content

Commit

Permalink
Support multiple space-separated values within a single element's dat…
Browse files Browse the repository at this point in the history
…a-test-subj attribute (#1587)

* Add matcher argument to findTestSubject.
* Add tests.
  • Loading branch information
cjcenizal authored Mar 1, 2019
1 parent edf0b85 commit 7ce11d3
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 3 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
## [`master`](https://github.com/elastic/eui/tree/master)

No public interface changes since `9.0.1`.
- Added support to `findTestSubject` for an optional `matcher` argument, which defaults to `~=`, enabling it to identify an element based on one of multiple space-separated values within its `data-test-subj` attribute ([#1587](https://github.com/elastic/eui/pull/1587))

## [`9.0.1`](https://github.com/elastic/eui/tree/v9.0.1)

Expand Down
22 changes: 20 additions & 2 deletions src/test/find_test_subject.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,27 @@
* Find node which matches a specific test subject selector. Returns ReactWrappers around DOM element,
* https://github.com/airbnb/enzyme/tree/master/docs/api/ReactWrapper.
* Common use cases include calling simulate or getDOMNode on the returned ReactWrapper.
*
* The ~= matcher looks for the value in space-separated list, allowing support for multiple data-test-subj
* values on a single element. See https://www.w3.org/TR/selectors-3/#attribute-selectors for more
* info on the other possible matchers.
*/
export const findTestSubject = (mountedComponent, testSubjectSelector) => {
const testSubject = mountedComponent.find(`[data-test-subj="${testSubjectSelector}"]`);

const MATCHERS = [
'=', // Exact match
'~=', // Exists in a space-separated list
'|=', // Begins with substring, followed by '-'
'^=', // Begins with substring
'$=', // Ends with substring
'*=', // Contains substring
];

export const findTestSubject = (mountedComponent, testSubjectSelector, matcher = '~=') => {
if (!MATCHERS.includes(matcher)) {
throw new Error(`Matcher ${matcher} not found in list of allowed matchers: ${MATCHERS.join(' ')}`);
}

const testSubject = mountedComponent.find(`[data-test-subj${matcher}"${testSubjectSelector}"]`);

// Restores Enzyme 2's find behavior, which was to only return ReactWrappers around DOM elements.
// Enzyme 3 returns ReactWrappers around both DOM elements and React components.
Expand Down
56 changes: 56 additions & 0 deletions src/test/find_test_subject.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import React from 'react';
import { mount } from 'enzyme';

import { findTestSubject } from './find_test_subject';

describe('findTestSubject', () => {
test('finds the specified element in a mounted component', () => {
const TestComponent = () => <div data-test-subj="test" />;
const component = mount(<TestComponent />);
const element = findTestSubject(component, 'test');

expect(element.length).toBe(1);
});

test('finds the specified element even if it has multiple identifiers', () => {
const TestComponent = () => <div data-test-subj="test1 test2" />;
const component = mount(<TestComponent />);
const element = findTestSubject(component, 'test2');

expect(element.length).toBe(1);
});

test('finds multiple elements with the same identifier', () => {
const TestComponent = () => (
<div>
<div data-test-subj="test" />
<div data-test-subj="test" />
</div>
);
const component = mount(<TestComponent />);
const element = findTestSubject(component, 'test');

expect(element.length).toBe(2);
});

describe('matcher optional argument', () => {
test('finds multiple elements with identifiers beginning with the same string', () => {
const TestComponent = () => (
<div>
<div data-test-subj="test1" />
<div data-test-subj="test2" />
</div>
);
const component = mount(<TestComponent />);
const element = findTestSubject(component, 'test', '^=');

expect(element.length).toBe(2);
});

test('throws an error if unsupported matcher is provided', () => {
const TestComponent = () => <div data-test-subj="test" />;
const component = mount(<TestComponent />);
expect(() => findTestSubject(component, 'test', '===')).toThrow();
});
});
});

0 comments on commit 7ce11d3

Please sign in to comment.