Skip to content

Commit

Permalink
fix: add tooltip play test (#1854)
Browse files Browse the repository at this point in the history
* fix: add playwright tests for tabs, tooltip, banner, autocomplete
  • Loading branch information
ganeshsomasundaram-okta authored Jun 30, 2023
1 parent b96def7 commit 1306cbd
Show file tree
Hide file tree
Showing 10 changed files with 352 additions and 185 deletions.
16 changes: 7 additions & 9 deletions packages/odyssey-storybook/src/axe-util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,7 @@
// eslint-disable-next-line import/no-extraneous-dependencies
import axe from "axe-core";

export const sleep = (ms = 1000) => new Promise((r) => setTimeout(r, ms));

export const axeRun = async (interaction = "") => {
await sleep();

await axe
.run({
runOnly: {
Expand All @@ -34,14 +30,16 @@ export const axeRun = async (interaction = "") => {
})
.then((results) => {
if (results.violations.length) {
console.log("Accessibility issues found ==> ", results.violations);
throw new Error(`Accessibility issues found ${interaction}`);
throw new Error(
`Accessibility issues found in "${interaction}". ${JSON.stringify(
results.violations,
null,
2
)}`
);
}
})
.catch((e) => {
console.log(
e instanceof Error ? e.message : "Unknown Error in play-test"
);
throw new Error(
e instanceof Error ? e.message : "Unknown Error in play-test"
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,41 @@
import { Autocomplete, AutocompleteProps } from "@okta/odyssey-react-mui";
import { Meta, StoryObj } from "@storybook/react";

import { userEvent, waitFor, within, screen } from "@storybook/testing-library";
import { axeRun } from "../../../axe-util";
import { expect } from "@storybook/jest";
import { MuiThemeDecorator } from "../../../../.storybook/components";

type StationType = { label: string };

const stations: ReadonlyArray<StationType> = [
{ label: "Anderson Station" },
{ label: "Bara Gaon Complex" },
{ label: "Ceres" },
{ label: "Corley Station" },
{ label: "Deep Transfer Station Three" },
{ label: "Eros" },
{ label: "Free Navy Supply Depot" },
{ label: "Ganymede" },
{ label: "Gewitter Base" },
{ label: "Iapetus Station" },
{ label: "Kelso Station" },
{ label: "Laconian Transfer Station" },
{ label: "Mao Station" },
{ label: "Medina Station" },
{ label: "Nauvoo" },
{ label: "Oshima" },
{ label: "Osiris Station" },
{ label: "Pallas" },
{ label: "Phoebe Station" },
{ label: "Prospero Station" },
{ label: "Shirazi-Ma Complex" },
{ label: "Terryon Lock" },
{ label: "Thoth Station" },
{ label: "Tycho Station" },
{ label: "Vesta" },
];

const storybookMeta: Meta<typeof Autocomplete> = {
title: "MUI Components/Forms/Autocomplete",
component: Autocomplete,
Expand Down Expand Up @@ -44,85 +77,114 @@ const storybookMeta: Meta<typeof Autocomplete> = {
args: {
label: "Destination",
hint: "Select your destination in the Sol system.",
options: stations,
},
decorators: [MuiThemeDecorator],
};

export default storybookMeta;

type StationType = { label: string };

const stations: ReadonlyArray<StationType> = [
{ label: "Anderson Station" },
{ label: "Bara Gaon Complex" },
{ label: "Ceres" },
{ label: "Corley Station" },
{ label: "Deep Transfer Station Three" },
{ label: "Eros" },
{ label: "Free Navy Supply Depot" },
{ label: "Ganymede" },
{ label: "Gewitter Base" },
{ label: "Iapetus Station" },
{ label: "Kelso Station" },
{ label: "Laconian Transfer Station" },
{ label: "Mao Station" },
{ label: "Medina Station" },
{ label: "Nauvoo" },
{ label: "Oshima" },
{ label: "Osiris Station" },
{ label: "Pallas" },
{ label: "Phoebe Station" },
{ label: "Prospero Station" },
{ label: "Shirazi-Ma Complex" },
{ label: "Terryon Lock" },
{ label: "Thoth Station" },
{ label: "Tycho Station" },
{ label: "Vesta" },
];

type AutocompleteType = AutocompleteProps<
StationType | undefined,
boolean | undefined,
boolean | undefined
>;

export const Default: StoryObj<AutocompleteType> = {
render: function C(props) {
return <Autocomplete {...props} options={stations} />;
play: async ({ canvasElement, step }) => {
const canvas = within(canvasElement);
const comboBoxElement = canvas.getByRole("combobox") as HTMLInputElement;
await step("Filter and Select from listbox", async () => {
userEvent.click(comboBoxElement);
const listboxElement = screen.getByRole("listbox");
expect(listboxElement).toBeVisible();
});
await step("Check for 'No options' in the list", async () => {
await axeRun("Autocomplete Default");
waitFor(() => {
userEvent.type(comboBoxElement, "q");
const noOptionsElement = screen.getByText("No options");
expect(noOptionsElement).toBeVisible();
});
});
await step("Check for Filtered item from the list", async () => {
userEvent.clear(comboBoxElement);
userEvent.type(comboBoxElement, "z");
const listItem = screen.getByRole("listbox").firstChild as HTMLLIElement;
expect(listItem?.textContent).toBe("Shirazi-Ma Complex");
userEvent.click(listItem);
expect(comboBoxElement.value).toBe("Shirazi-Ma Complex");
});
await step("Clear the selected item", async () => {
const clearButton = canvas.getByTitle("Clear");
userEvent.click(clearButton);
expect(comboBoxElement.value).toBe("");
userEvent.tab();
});
},
};

export const Disabled: StoryObj<AutocompleteType> = {
...Default,
args: {
isDisabled: true,
value: { label: "Tycho Station" },
},
};

export const IsCustomValueAllowed: StoryObj<AutocompleteType> = {
...Default,
args: {
isCustomValueAllowed: true,
},
play: async ({ canvasElement, step }) => {
await step("Enter custom value", async () => {
const canvas = within(canvasElement);
const comboBoxElement = canvas.getByRole("combobox") as HTMLInputElement;
userEvent.click(comboBoxElement);
userEvent.type(comboBoxElement, "qwerty");
userEvent.tab();
expect(comboBoxElement.value).toBe("qwerty");
});
},
};

export const Loading: StoryObj<AutocompleteType> = {
...Default,
args: {
isLoading: true,
},
};

export const Multiple: StoryObj<AutocompleteType> = {
...Default,
args: {
hasMultipleChoices: true,
},
play: async ({ canvasElement, step }) => {
const canvas = within(canvasElement);
const comboBoxElement = canvas.getByRole("combobox") as HTMLInputElement;
await step("Check for list box to be visible", async () => {
userEvent.click(comboBoxElement);
const listboxElement = screen.getByRole("listbox");
expect(listboxElement).toBeVisible();
});
await step("Select multiple items", async () => {
userEvent.type(comboBoxElement, "z");
userEvent.click(screen.getByRole("listbox").firstChild as HTMLLIElement);
userEvent.clear(comboBoxElement);
userEvent.type(comboBoxElement, "w");
userEvent.click(screen.getByRole("listbox").firstChild as HTMLLIElement);
await axeRun("Autocomplete Multiple");
});
await step("Clear the selected items", async () => {
waitFor(() => {
const clearButton = canvas.getByTitle("Clear");
userEvent.click(clearButton);
expect(comboBoxElement.value).toBe("");
userEvent.tab();
});
});
},
};

export const MultipleDisabled: StoryObj<AutocompleteType> = {
...Default,
args: {
hasMultipleChoices: true,
isDisabled: true,
Expand All @@ -131,7 +193,6 @@ export const MultipleDisabled: StoryObj<AutocompleteType> = {
};

export const MultipleReadOnly: StoryObj<AutocompleteType> = {
...Default,
args: {
hasMultipleChoices: true,
isReadOnly: true,
Expand All @@ -140,7 +201,6 @@ export const MultipleReadOnly: StoryObj<AutocompleteType> = {
};

export const ReadOnly: StoryObj<AutocompleteType> = {
...Default,
args: {
isReadOnly: true,
value: { label: "Tycho Station" },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ import { Banner, BannerProps } from "@okta/odyssey-react-mui";
import { Meta, StoryObj } from "@storybook/react";

import { MuiThemeDecorator } from "../../../../.storybook/components";
import { userEvent, within } from "@storybook/testing-library";
import { expect, jest } from "@storybook/jest";
import { axeRun } from "../../../axe-util";

const storybookMeta: Meta<typeof Banner> = {
title: "MUI Components/Alerts/Banner",
Expand Down Expand Up @@ -83,12 +86,28 @@ export const BannerWithLink: StoryObj<BannerProps> = {
severity: "error",
text: "An unidentified flying object compromised Hangar 18.",
},
play: async ({ canvasElement, step }) => {
await step("check for the link text", async () => {
const canvas = within(canvasElement);
const link = canvas.getByText("View report") as HTMLAnchorElement;
expect(link?.tagName).toBe("A");
expect(link?.href).toBe(`${link?.baseURI}#anchor`);
});
},
};

export const DismissibleBanner: StoryObj<BannerProps> = {
args: {
onClose: function noRefCheck(event) {
event;
},
onClose: jest.fn(),
},
play: async ({ args, canvasElement, step }) => {
await step("dismiss the banner on click", async () => {
const canvas = within(canvasElement);
const button = canvas.getByTitle("Close");
userEvent.click(button);
userEvent.tab();
expect(args.onClose).toHaveBeenCalled();
await axeRun("Dismissible Banner");
});
},
};
Loading

0 comments on commit 1306cbd

Please sign in to comment.