Skip to content

Commit

Permalink
LG-4250: tabs test harnesses (#2334)
Browse files Browse the repository at this point in the history
* Tabs changeset and README

* Add tabs test harnesses

* Refactor tabs specs with test harnesses

* Address test feedback

* Fix imports in readme
  • Loading branch information
stephl3 authored May 9, 2024
1 parent a149857 commit 4cfd6dd
Show file tree
Hide file tree
Showing 12 changed files with 550 additions and 129 deletions.
7 changes: 7 additions & 0 deletions .changeset/curvy-deers-swim.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@leafygreen-ui/tabs': minor
---

[LG-4250](https://jira.mongodb.org/browse/LG-4250)

- Exports `getTestUtils`, a util to reliably interact with `LG Tabs` in a product test suite. For more details, check out the [README](https://github.com/mongodb/leafygreen-ui/tree/main/packages/tabs#test-harnesses)
174 changes: 127 additions & 47 deletions packages/tabs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,53 +32,6 @@ const [selected, setSelected] = useState(0)
</Tabs>
```

## Output HTML

```html
<div>
<div class="leafygreen-ui-4furr2" role="tablist">
<button
class="leafygreen-ui-17lvitv"
role="tab"
aria-controls="tab-0"
aria-selected="true"
tabindex="0"
>
Tab One
</button>
<button
class="leafygreen-ui-6uqhxy"
role="tab"
aria-controls="tab-1"
aria-selected="false"
tabindex="-1"
>
Tab Two
</button>
<button
class="leafygreen-ui-6uqhxy"
role="tab"
aria-controls="tab-2"
aria-selected="false"
tabindex="-1"
>
Tab Three
</button>
</div>
<div class="leafygreen-ui-xh3r7y">
<div class="leafygreen-ui-11283ir"></div>
</div>
<div
aria-disabled="false"
aria-selected="true"
aria-controls="tab-0"
role="tabpanel"
>
Tab Content One
</div>
</div>
```

## Properties

| Prop | Type | Description | Default |
Expand Down Expand Up @@ -108,6 +61,133 @@ _Any other properties supplied will be spread on the root element._
| `children` | `node` | Content that appears inside the `<Tab />` component | |
| ... | native attributes of component passed to `as` prop | Any other props will be spread on the root element | |

# Test Harnesses

## getTestUtils()

`getTestUtils()` is a util that allows consumers to reliably interact with `LG Tabs` in a product test suite. If the `Tabs` component cannot be found, an error will be thrown.

### Usage

```tsx
import { getTestUtils } from '@leafygreen-ui/tabs';

const utils = getTestUtils(lgId?: string); // lgId refers to the custom `data-lgid` attribute passed to `Tabs`. It defaults to 'lg-tabs' if left empty.
```

#### Single `Tabs` component

```tsx
import { render } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { Tabs, Tab, getTestUtils } from '@leafygreen-ui/tabs';

...

test('tabs', () => {
render(
<Tabs aria-label="Label">
<Tab name="First" default>
Content 1
</Tab>
<Tab name="Second">
Content 2
</Tab>
<Tab name="Third">
Content 3
</Tab>
</Tabs>
);

const { getAllTabsInTabList, getTabUtilsByName, getSelectedPanel } = getTestUtils();

expect(getAllTabsInTabList()).toHaveLength(3);

const firstTabUtils = getTabUtilsByName('First');
expect(firstTabUtils.isSelected()).toBeTruthy();

expect(getSelectedPanel()).toHaveTextContent('Content 1');

const secondTabUtils = getTabUtilsByName('Second');

// click to second tab
if (secondTabUtils) {
userEvent.click(secondTabUtils.getTab());
}
// selected panel text content is updated
expect(getSelectedPanel()).toHaveTextContent('Content 2');
});
```

#### Multiple `Tabs` components

When testing multiple `Tabs` components, it is recommended to add the custom `data-lgid` attribute to each `Tabs`.

```tsx
import { render } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { Tabs, Tab, getTestUtils } from '@leafygreen-ui/tabs';

...

test('tabs', () => {
render(
<>
<Tabs aria-label="Label ABC" data-lgid="tabs-abc">
<Tab name="A" default>
Content A
</Tab>
<Tab name="B">
Content B
</Tab>
<Tab name="C">
Content C
</Tab>
</Tabs>
<Tabs aria-label="Label XY" data-lgid="tabs-xy">
<Tab name="X">
Content X
</Tab>
<Tab name="Y" default>
Content Y
</Tab>
</Tabs>
</>
);

const testUtils1 = getTestUtils('tabs-abc'); // data-lgid
const testUtils2 = getTestUtils('tabs-xy'); // data-lgid

// First tabs
expect(testUtils1.getAllTabsInTabList()).toHaveLength(3);
expect(testUtils1.getSelectedPanel()).toHaveTextContent('Content A');

// Second tabs
expect(testUtils1.getAllTabsInTabList()).toHaveLength(2);
expect(testUtils1.getSelectedPanel()).toHaveTextContent('Content Y');
});
```

### Test Utils

```tsx
const {
getAllTabsInTabList,
getTabUtilsByName: { getTab, isSelected, isDisabled },
getSelectedPanel,
} = getTestUtils();
```

| Util | Description | Returns |
| ----------------------- | ---------------------------------------------------- | ----------------------- |
| `getAllTabsInTabList()` | Returns an array of tabs | `Array<HTMLElement>` |
| `getSelectedPanel()` | Returns the selected tab panel | `HTMLElement` \| `null` |
| `getTabUtilsByName()` | Returns tab utils if tab with matching name is found | `TabUtils` \| `null` |
| TabUtils | | |
| `getTab()` | Returns the tab | `HTMLElement` |
| `isSelected()` | Returns whether the tab is selected | `boolean` |
| `isDisabled()` | Returns whether the tab is disabled | `boolean` |

## Reference

### Usage with NextJS Link components
Expand Down
3 changes: 2 additions & 1 deletion packages/tabs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@
"@leafygreen-ui/palette": "^4.0.9",
"@leafygreen-ui/portal": "^5.1.1",
"@leafygreen-ui/tokens": "^2.5.2",
"@leafygreen-ui/typography": "^19.0.0"
"@leafygreen-ui/typography": "^19.0.0",
"@lg-tools/test-harnesses": "0.1.2"
},
"peerDependencies": {
"@leafygreen-ui/leafygreen-provider": "^3.1.12"
Expand Down
Loading

0 comments on commit 4cfd6dd

Please sign in to comment.