Skip to content

Commit

Permalink
test: improve tabs tests (#6898)
Browse files Browse the repository at this point in the history
  • Loading branch information
bvandercar-vt authored Jul 16, 2024
1 parent b38194b commit 1f3241d
Showing 1 changed file with 34 additions and 24 deletions.
58 changes: 34 additions & 24 deletions packages/core/test/tabs/tabsTests.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@ describe("<Tabs>", () => {
const TAB_IDS = ["first", "second", "third"];

// selectors using ARIA role
const TAB = "[role='tab']";
const TAB_LIST = "[role='tablist']";
const TAB_PANEL = "[role='tabpanel']";
const TAB_SELECTOR = "[role='tab']";
const TAB_LIST_SELECTOR = "[role='tablist']";
const TAB_PANEL_SELECTOR = "[role='tabpanel']";

let testsContainerElement: HTMLElement;

Expand Down Expand Up @@ -67,30 +67,32 @@ describe("<Tabs>", () => {
{getTabsContents()}
</Tabs>,
);
assert.lengthOf(wrapper.find(TAB), 3);
assert.lengthOf(wrapper.find(TAB_SELECTOR), 3);
assert.strictEqual(wrapper.state("selectedTabId"), TAB_IDS[0]);
});

it("renders one TabTitle for each Tab", () => {
it("renders one TabTitle and one TabPanel for each Tab, aria roles are correct", () => {
const wrapper = mount(<Tabs id={ID}>{getTabsContents()}</Tabs>);
assert.lengthOf(wrapper.find(TAB), 3);
assert.lengthOf(wrapper.find(TAB_SELECTOR), 3);
assert.lengthOf(wrapper.find(TAB_LIST_SELECTOR), 1);
assert.lengthOf(wrapper.find(TAB_PANEL_SELECTOR), 3);
});

it("renders all Tab children, but active is not aria-hidden", () => {
it("renders all Tab children, active is not aria-hidden", () => {
const activeIndex = 1;
const wrapper = mount(<Tabs id={ID}>{getTabsContents()}</Tabs>);
wrapper.setState({ selectedTabId: TAB_IDS[activeIndex] });
const tabs = wrapper.find(TAB_PANEL);
assert.lengthOf(tabs, 3);
const tabPanels = wrapper.find(TAB_PANEL_SELECTOR);
assert.lengthOf(tabPanels, 3);
for (let i = 0; i < TAB_IDS.length; i++) {
// hidden unless it is active
assert.equal(tabs.at(i).prop("aria-hidden"), i !== activeIndex);
assert.equal(tabPanels.at(i).prop("aria-hidden"), i !== activeIndex);
}
});

it(`renders without ${Classes.LARGE} when by default`, () => {
const wrapper = mount(<Tabs id={ID}>{getTabsContents()}</Tabs>);
assert.lengthOf(wrapper.find(`.${Classes.TAB_LIST}.${Classes.LARGE}`), 0);
assert.lengthOf(wrapper.find(`${TAB_LIST_SELECTOR}.${Classes.LARGE}`), 0);
});

it(`renders using ${Classes.LARGE} when large={true}`, () => {
Expand All @@ -99,7 +101,7 @@ describe("<Tabs>", () => {
{getTabsContents()}
</Tabs>,
);
assert.lengthOf(wrapper.find(`.${Classes.TAB_LIST}.${Classes.LARGE}`), 1);
assert.lengthOf(wrapper.find(`${TAB_LIST_SELECTOR}.${Classes.LARGE}`), 1);
});

it("attaches className to both tab and panel container if set", () => {
Expand All @@ -113,7 +115,10 @@ describe("<Tabs>", () => {
<Tab id="third" title="Third" className={tabClassName} panel={<Panel title="third" />} />,
</Tabs>,
);
assert.lengthOf(wrapper.find(`.${tabClassName}`), 9);
const NUM_TABS = 3;
assert.lengthOf(wrapper.find(TAB_SELECTOR), NUM_TABS);
assert.lengthOf(wrapper.find(TAB_PANEL_SELECTOR), NUM_TABS);
assert.lengthOf(wrapper.find(`.${tabClassName}`).hostNodes(), NUM_TABS * 2);
});

it("attaches panelClassName to panel container if set", () => {
Expand All @@ -126,6 +131,9 @@ describe("<Tabs>", () => {
<Tab id="third" title="Third" panel={<Panel title="third" />} />,
</Tabs>,
);
const NUM_TABS = 3;
assert.lengthOf(wrapper.find(TAB_SELECTOR), NUM_TABS);
assert.lengthOf(wrapper.find(TAB_PANEL_SELECTOR), NUM_TABS);
assert.lengthOf(wrapper.find(`.${panelClassName}`), 1);
});

Expand Down Expand Up @@ -158,12 +166,12 @@ describe("<Tabs>", () => {

it("sets aria-* attributes with matching IDs", () => {
const wrapper = mount(<Tabs id={ID}>{getTabsContents()}</Tabs>);
wrapper.find(TAB).forEach(title => {
wrapper.find(TAB_SELECTOR).forEach(title => {
// title "controls" tab element
const titleControls = title.prop("aria-controls");
const tab = wrapper.find(`#${titleControls}`);
// tab element "labelled by" title element
assert.isTrue(tab.is(TAB_PANEL), "aria-controls isn't TAB_PANEL");
assert.isTrue(tab.is(TAB_PANEL_SELECTOR), "aria-controls isn't TAB_PANEL");
assert.deepEqual(tab.prop("aria-labelledby"), title.prop("id"), "mismatched IDs");
});
});
Expand All @@ -173,7 +181,7 @@ describe("<Tabs>", () => {
<Tab id={id} key={id} panel={<Panel title={id} />} title={id} data-arbitrary-attr="foo" />
));
const wrapper = mount(<Tabs id={ID}>{tabs}</Tabs>);
wrapper.find(TAB).forEach(title => {
wrapper.find(TAB_SELECTOR).forEach(title => {
assert.strictEqual((title.getDOMNode() as HTMLElement).getAttribute("data-arbitrary-attr"), "foo");
});
});
Expand Down Expand Up @@ -204,7 +212,7 @@ describe("<Tabs>", () => {
);
assert.equal(wrapper.state("selectedTabId"), TAB_IDS[0]);
// last Tab is inside nested
wrapper.find(TAB).last().simulate("click");
wrapper.find(TAB_SELECTOR).last().simulate("click");
assert.equal(wrapper.state("selectedTabId"), TAB_IDS[0]);
assert.isTrue(changeSpy.notCalled, "onChange invoked");
});
Expand All @@ -219,8 +227,8 @@ describe("<Tabs>", () => {
{ attachTo: testsContainerElement },
);

const tabList = wrapper.find(TAB_LIST);
const tabElements = testsContainerElement.querySelectorAll<HTMLElement>(TAB);
const tabList = wrapper.find(TAB_LIST_SELECTOR);
const tabElements = testsContainerElement.querySelectorAll<HTMLElement>(TAB_SELECTOR);
tabElements[0].focus();

tabList.simulate("keydown", { key: "ArrowRight" });
Expand All @@ -241,8 +249,8 @@ describe("<Tabs>", () => {
</Tabs>,
{ attachTo: testsContainerElement },
);
const tabList = wrapper.find(TAB_LIST);
const tabElements = testsContainerElement.querySelectorAll<HTMLElement>(TAB);
const tabList = wrapper.find(TAB_LIST_SELECTOR);
const tabElements = testsContainerElement.querySelectorAll<HTMLElement>(TAB_SELECTOR);

// must target different elements each time as onChange is only called when id changes
tabList.simulate("keypress", { target: tabElements[1], key: "Enter" });
Expand All @@ -260,7 +268,7 @@ describe("<Tabs>", () => {
</Tabs>,
);
assert.isUndefined(wrapper.state().indicatorWrapperStyle);
assert.equal(wrapper.find("." + Classes.TAB_INDICATOR).length, 0);
assert.equal(wrapper.find(`.${Classes.TAB_INDICATOR}`).length, 0);
});

it("removes indicator element when selected tab is removed", () => {
Expand Down Expand Up @@ -408,14 +416,16 @@ describe("<Tabs>", () => {
function findTabById(wrapper: ReactWrapper<TabsProps>, id: string) {
// Need this to get the right overload signature
// eslint-disable-line @typescript-eslint/consistent-type-assertions
return wrapper.find(TAB).filter({ "data-tab-id": id } as React.HTMLAttributes<HTMLElement>);
return wrapper.find(TAB_SELECTOR).filter({ "data-tab-id": id } as React.HTMLAttributes<HTMLElement>);
}

function assertIndicatorPosition(wrapper: ReactWrapper<TabsProps, TabsState>, selectedTabId: string) {
const style = wrapper.state().indicatorWrapperStyle;
assert.isDefined(style, "Tabs should have a indicatorWrapperStyle prop set");
const node = wrapper.getDOMNode();
const expected = node.querySelector<HTMLLIElement>(`${TAB}[data-tab-id='${selectedTabId}']`)!.offsetLeft;
const expected = node.querySelector<HTMLLIElement>(
`${TAB_SELECTOR}[data-tab-id='${selectedTabId}']`,
)!.offsetLeft;
assert.isTrue(style?.transform?.indexOf(`${expected}px`) !== -1, "indicator has not moved correctly");
}

Expand Down

1 comment on commit 1f3241d

@svc-palantir-github
Copy link

Choose a reason for hiding this comment

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

test: improve tabs tests (#6898)

Build artifact links for this commit: documentation | landing | table | demo

This is an automated comment from the deploy-preview CircleCI job.

Please sign in to comment.