Skip to content

Commit

Permalink
add: storybook variations and tests
Browse files Browse the repository at this point in the history
  • Loading branch information
ChristianBusshoff committed Dec 20, 2024
1 parent 82f4225 commit 7227f96
Show file tree
Hide file tree
Showing 7 changed files with 185 additions and 8 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { DENSITIES } from "../../composables/density";
import { expect, test } from "../../playwright/a11y";
import { executeMatrixScreenshotTest } from "../../playwright/screenshots";
import OnyxAccordionItem from "../OnyxAccordionItem/OnyxAccordionItem.vue";
import OnyxAccordion from "./OnyxAccordion.vue";

test.describe("ScreenshotTest", () => {
executeMatrixScreenshotTest({
name: "Accordion",
columns: DENSITIES,
rows: ["default", "open", "hover", "focus-visible", "disabled", "skeleton"],
component: (column, row) => (
<OnyxAccordion
style="width: 200px;"
density={column}
skeleton={row === "skeleton"}
disabled={row === "disabled"}
>
<OnyxAccordionItem>
<template v-slot:header>Accordion Header 1</template>
<template v-slot:panel>Accordion Panel 1</template>
</OnyxAccordionItem>
<OnyxAccordionItem>
<template v-slot:header>Accordion Header 2</template>
<template v-slot:panel>Accordion Panel 2</template>
</OnyxAccordionItem>
</OnyxAccordion>
),
hooks: {
beforeEach: async (component, page, _column, row) => {
if (row == "open") await component.locator(".onyx-accordion-item__header").click();
if (row === "hover") await component.hover();
if (row === "focus-visible") await page.keyboard.press("Tab");
},
},
});
});

// Test for exclusive mode
test("should open only one item at a time in exclusive mode", async ({ mount, makeAxeBuilder }) => {
const component = await mount(
<OnyxAccordion exclusive>
<OnyxAccordionItem>
<template v-slot:header>Accordion Header 1</template>
<template v-slot:panel>Accordion Panel 1</template>
</OnyxAccordionItem>
<OnyxAccordionItem>
<template v-slot:header>Accordion Header 2</template>
<template v-slot:panel>Accordion Panel 2</template>
</OnyxAccordionItem>
</OnyxAccordion>,
);

const firstHeader = component.locator(".onyx-accordion-item__header").first();
const secondHeader = component.locator(".onyx-accordion-item__header").nth(1);

await firstHeader.click();
await expect(component.locator(".onyx-accordion-item__panel").first()).toBeVisible();
await expect(component.locator(".onyx-accordion-item__panel").nth(1)).toBeHidden();

await secondHeader.click();
await expect(component.locator(".onyx-accordion-item__panel").first()).toBeHidden();
await expect(component.locator(".onyx-accordion-item__panel").nth(1)).toBeVisible();

const accessibilityScanResults = await makeAxeBuilder().analyze();

expect(accessibilityScanResults.violations).toEqual([]);
});
Original file line number Diff line number Diff line change
Expand Up @@ -21,22 +21,40 @@ const meta: Meta<typeof OnyxAccordion> = {
export default meta;
type Story = StoryObj<typeof OnyxAccordion>;

/** Standard Accord */
export const Default = {
args: {
default: () => [
h(OnyxAccordionItem, null, {
header: () => h("span", "First Accordion Header"),
header: () => h("h4", "First Accordion Header"),
panel: () => h("p", "This is the content inside the first panel."),
}),
h(OnyxAccordionItem, null, {
header: () => h("span", "Second Accordion Header"),
header: () => h("h4", "Second Accordion Header"),
panel: () => h("p", "This is the content inside the second panel."),
}),
h(OnyxAccordionItem, null, {
header: () => h("span", "Third Accordion Header"),
header: () => h("h4", "Third Accordion Header"),
panel: () => h("p", "This is the content inside the third panel."),
}),
],
},
} satisfies Story;

export const Exclusive = {
args: {
...Default.args,
exclusive: true,
},
} satisfies Story;
export const Disabled = {
args: {
...Default.args,
disabled: true,
},
} satisfies Story;
export const Skeleton = {
args: {
...Default.args,
skeleton: true,
},
} satisfies Story;
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<script lang="ts" setup>
import { defineSlots, provide, ref, toRefs } from "vue";
import { useDensity } from "../../";
import { SKELETON_INJECTED_SYMBOL, useSkeletonContext } from "../../composables/useSkeletonState";
import {
ACCORDION_INJECTION_KEY,
Expand All @@ -14,6 +15,7 @@ const props = withDefaults(defineProps<OnyxAccordionProps>(), {
});
const { disabled } = toRefs(props);
const skeleton = useSkeletonContext(props);
const { densityClass } = useDensity(props);
const accordionRef = ref<HTMLElement>();
const openItems = ref<Set<string>>(new Set());
Expand Down Expand Up @@ -46,7 +48,7 @@ defineSlots<{
</script>

<template>
<div ref="accordionRef" class="onyx-component onyx-accordion">
<div ref="accordionRef" :class="['onyx-component', 'onyx-accordion', densityClass]">
<slot></slot>
</div>
</template>
Expand Down
3 changes: 2 additions & 1 deletion packages/sit-onyx/src/components/OnyxAccordion/types.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import type { SkeletonInjected } from "src/composables/useSkeletonState";
import type { InjectionKey, Ref } from "vue";
import type { DensityProp } from "../../composables/density";

export type OnyxAccordionProps = {
export type OnyxAccordionProps = DensityProp & {
/** Whether only one AccordionItem can be open at the same time */
exclusive?: boolean;
/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { DENSITIES } from "../../composables/density";
import { expect, test } from "../../playwright/a11y";
import { executeMatrixScreenshotTest } from "../../playwright/screenshots";
import OnyxAccordionItem from "./OnyxAccordionItem.vue";

test.describe("ScreenshotTest", () => {
executeMatrixScreenshotTest({
name: "AccordionItem",
columns: DENSITIES,
rows: ["default", "open", "hover", "focus-visible", "disabled", "skeleton"],
component: (column, row) => (
<OnyxAccordionItem
style="width: 200px;"
density={column}
skeleton={row === "skeleton"}
disabled={row === "disabled"}
>
<template v-slot:header>Accordion Header</template>
<template v-slot:panel>Accordion Panel</template>
</OnyxAccordionItem>
),
hooks: {
beforeEach: async (component, page, _column, row) => {
if (row == "open") await component.locator(".onyx-accordion-item__header").click();
if (row === "hover") await component.hover();
if (row === "focus-visible") await page.keyboard.press("Tab");
},
},
});
});

test("should toggle open state on click", async ({ mount, makeAxeBuilder }) => {
// ARRANGE
const component = await mount(
<OnyxAccordionItem>
<template v-slot:header>Accordion Header</template>
<template v-slot:panel>Accordion Panel</template>
</OnyxAccordionItem>,
);

// Locators
const header = component.locator(".onyx-accordion-item__header");
const panel = component.locator(".onyx-accordion-item__panel");

await expect(panel).toBeHidden();
await header.click();
await expect(panel).toBeVisible();
await header.click();
await expect(panel).toBeHidden();

// ACT
const accessibilityScanResults = await makeAxeBuilder().analyze();

// ASSERT
expect(accessibilityScanResults.violations).toEqual([]);
});
test("should apply the disabled state", async ({ mount, makeAxeBuilder }) => {
const component = await mount(
<OnyxAccordionItem disabled>
<template v-slot:header>Accordion Header</template>
<template v-slot:panel>Accordion Panel</template>
</OnyxAccordionItem>,
);

// Locators
const header = component.locator(".onyx-accordion-item__header");
await expect(header).toHaveAttribute("tabindex", "-1");

const accessibilityScanResults = await makeAxeBuilder().analyze();

expect(accessibilityScanResults.violations).toEqual([]);
});
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,20 @@ type Story = StoryObj<typeof OnyxAccordionItem>;
/** Standard AccordionItem*/
export const Default = {
args: {
header: () => h("header", "Title"),
panel: () => h("panel", "Hidden Content"),
header: () => h("h4", "Title"),
panel: () => h("p", "Hidden Content"),
},
} satisfies Story;

export const Disabled = {
args: {
...Default.args,
disabled: true,
},
} satisfies Story;
export const Skeleton = {
args: {
...Default.args,
skeleton: true,
},
} satisfies Story;
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const props = withDefaults(defineProps<OnyxAccordionItemProps>(), {
disabled: false,
skeleton: SKELETON_INJECTED_SYMBOL,
});
const itemId = useId();
defineSlots<{
Expand Down Expand Up @@ -90,6 +91,8 @@ const { densityClass } = useDensity(props);
display: flex;
align-items: center;
padding: var(--onyx-density-md);
padding-right: calc(3 * var(--onyx-density-md));
cursor: pointer;
&:hover,
&:focus-visible {
Expand Down

0 comments on commit 7227f96

Please sign in to comment.