Skip to content

Commit

Permalink
feat(react): added new react component for ic-skip-link
Browse files Browse the repository at this point in the history
added new component definition to react package for ic-skip-link. Also added stories and cypress
tests
  • Loading branch information
GCHQ-Developer-741 committed Feb 19, 2025
1 parent 07e67dd commit 6267bf2
Show file tree
Hide file tree
Showing 12 changed files with 477 additions and 0 deletions.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
268 changes: 268 additions & 0 deletions packages/react/src/component-tests/IcSkipLink/IcSkipLink.cy.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,268 @@
/// <reference types="cypress" />

import { mount } from "cypress/react";
import React from "react";
import { setThresholdBasedOnEnv } from "../../../cypress/utils/helpers";
import { IcButton, IcSkipLink, IcTopNavigation } from "../../components";
import { SlottedSVG } from "../../react-component-lib/slottedSVG";
import { HAVE_FOCUS } from "../utils/constants";

const SKIP_LINK_SELECTOR = "ic-skip-link";
const LINK_SELECTOR = "ic-link";
const DEFAULT_TEST_THRESHOLD = 0.01;

describe("IcSkipLink e2e, visual regression and a11y tests", () => {
beforeEach(() => {
cy.injectAxe();
});

afterEach(() => {
cy.task("generateReport");
});

it("should render IcSkipLink", () => {
mount(
<>
<IcSkipLink target="#page-content" />
<a id="page-content" tabIndex={-1}>
{" "}
</a>
</>
);

cy.checkHydrated(SKIP_LINK_SELECTOR);

cy.findShadowEl(SKIP_LINK_SELECTOR, LINK_SELECTOR)
.shadow()
.find("a")
.focus();

cy.checkA11yWithWait();
cy.compareSnapshot({
name: "/default",
testThreshold: setThresholdBasedOnEnv(DEFAULT_TEST_THRESHOLD + 0.006),
});
});

it("should render IcSkipLink with a custom label", () => {
mount(
<>
<IcSkipLink target="#page-content" label="Custom skip label" />
<a id="page-content" tabIndex={-1}>
{" "}
</a>
</>
);

cy.checkHydrated(SKIP_LINK_SELECTOR);

cy.findShadowEl(SKIP_LINK_SELECTOR, LINK_SELECTOR)
.shadow()
.find("a")
.focus();

cy.checkA11yWithWait();
cy.compareSnapshot({
name: "/custom-label",
testThreshold: setThresholdBasedOnEnv(DEFAULT_TEST_THRESHOLD + 0.005),
});
});

it("should render IcSkipLink with a transparent background", () => {
mount(
<div
style={{
backgroundColor: "var(--ic-architectural-100)",
paddingBottom: "100px",
}}
>
<IcSkipLink target="#page-content" transparentBackground />
<a id="page-content" tabIndex={-1}>
{" "}
</a>
</div>
);

cy.checkHydrated(SKIP_LINK_SELECTOR);

cy.findShadowEl(SKIP_LINK_SELECTOR, LINK_SELECTOR)
.shadow()
.find("a")
.focus();

cy.checkA11yWithWait();
cy.compareSnapshot({
name: "/transparent-background",
testThreshold: setThresholdBasedOnEnv(DEFAULT_TEST_THRESHOLD + 0.003),
});
});

it("should render IcSkipLink at the full width of the page", () => {
mount(
<>
<IcSkipLink target="#page-content" fullWidth />
<a id="page-content" tabIndex={-1}>
{" "}
</a>
</>
);

cy.checkHydrated(SKIP_LINK_SELECTOR);

cy.findShadowEl(SKIP_LINK_SELECTOR, LINK_SELECTOR)
.shadow()
.find("a")
.focus();

cy.checkA11yWithWait();
cy.compareSnapshot({
name: "/full-width",
testThreshold: setThresholdBasedOnEnv(DEFAULT_TEST_THRESHOLD + 0.006),
});
});

it("should render IcSkipLink inline with other page content", () => {
mount(
<>
<IcTopNavigation app-title="Application Name">
<SlottedSVG
slot="app-icon"
xmlns="http://www.w3.org/2000/svg"
height="24px"
viewBox="0 0 24 24"
width="24px"
fill="#000000"
>
<path d="M0 0h24v24H0V0z" fill="none" />
<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zm-5.5-2.5l7.51-3.49L17.5 6.5 9.99 9.99 6.5 17.5zm5.5-6.6c.61 0 1.1.49 1.1 1.1s-.49 1.1-1.1 1.1-1.1-.49-1.1-1.1.49-1.1 1.1-1.1z" />
</SlottedSVG>
</IcTopNavigation>
<IcSkipLink target="#page-content" inline />
<a id="page-content" tabIndex={-1}>
{" "}
</a>
</>
);

cy.checkHydrated(SKIP_LINK_SELECTOR);

cy.findShadowEl(SKIP_LINK_SELECTOR, LINK_SELECTOR)
.shadow()
.find("a")
.focus();

cy.checkA11yWithWait();
cy.compareSnapshot({
name: "/inline",
testThreshold: setThresholdBasedOnEnv(DEFAULT_TEST_THRESHOLD + 0.022),
});
});

it("should render IcSkipLink in dark theme", () => {
mount(
<>
<IcSkipLink target="#page-content" theme="dark" />
<a id="page-content" tabIndex={-1}>
{" "}
</a>
</>
);

cy.checkHydrated(SKIP_LINK_SELECTOR);

cy.findShadowEl(SKIP_LINK_SELECTOR, LINK_SELECTOR)
.shadow()
.find("a")
.focus();

cy.checkA11yWithWait();
cy.compareSnapshot({
name: "/dark-theme",
testThreshold: setThresholdBasedOnEnv(DEFAULT_TEST_THRESHOLD),
});
});

it("should render IcSkipLink in monochrome", () => {
mount(
<>
<IcSkipLink target="#page-content" monochrome />
<a id="page-content" tabIndex={-1}>
{" "}
</a>
</>
);

cy.checkHydrated(SKIP_LINK_SELECTOR);

cy.findShadowEl(SKIP_LINK_SELECTOR, LINK_SELECTOR)
.shadow()
.find("a")
.focus();

cy.checkA11yWithWait();
cy.compareSnapshot({
name: "/monochrome",
testThreshold: setThresholdBasedOnEnv(DEFAULT_TEST_THRESHOLD + 0.012),
});
});

it("should move focus to the target element when the link is clicked", () => {
mount(
<>
<IcSkipLink target="#page-content" />
<main id="page-content">Target element</main>
<IcButton>Should receive next focus</IcButton>
</>
);

cy.checkHydrated(SKIP_LINK_SELECTOR);

cy.findShadowEl(SKIP_LINK_SELECTOR, LINK_SELECTOR)
.shadow()
.find("a")
.focus()
.click();

cy.realPress("Tab");

cy.get("ic-button").should(HAVE_FOCUS);
});
});

describe("IcSkipLink visual regression high-contrast", () => {
before(() => {
cy.enableForcedColors();
});

afterEach(() => {
cy.task("generateReport");
});

after(() => {
cy.disableForcedColors();
});

it("should render IcSkipLink with a custom label", () => {
mount(
<>
<IcSkipLink target="#page-content" label="Custom skip label" />
<a id="page-content" tabIndex={-1}>
{" "}
</a>
</>
);

cy.checkHydrated(SKIP_LINK_SELECTOR);

cy.findShadowEl(SKIP_LINK_SELECTOR, LINK_SELECTOR)
.shadow()
.find("a")
.focus();

cy.checkA11yWithWait();
cy.compareSnapshot({
name: "/custom-label-hc",
testThreshold: setThresholdBasedOnEnv(DEFAULT_TEST_THRESHOLD + 0.013),
});
});
});
1 change: 1 addition & 0 deletions packages/react/src/components.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ export const IcSectionContainer = /*@__PURE__*/createReactComponent<JSX.IcSectio
export const IcSelect = /*@__PURE__*/createReactComponent<JSX.IcSelect, HTMLIcSelectElement>('ic-select');
export const IcSideNavigation = /*@__PURE__*/createReactComponent<JSX.IcSideNavigation, HTMLIcSideNavigationElement>('ic-side-navigation');
export const IcSkeleton = /*@__PURE__*/createReactComponent<JSX.IcSkeleton, HTMLIcSkeletonElement>('ic-skeleton');
export const IcSkipLink = /*@__PURE__*/createReactComponent<JSX.IcSkipLink, HTMLIcSkipLinkElement>('ic-skip-link');
export const IcStatusTag = /*@__PURE__*/createReactComponent<JSX.IcStatusTag, HTMLIcStatusTagElement>('ic-status-tag');
export const IcStep = /*@__PURE__*/createReactComponent<JSX.IcStep, HTMLIcStepElement>('ic-step');
export const IcStepper = /*@__PURE__*/createReactComponent<JSX.IcStepper, HTMLIcStepperElement>('ic-stepper');
Expand Down
37 changes: 37 additions & 0 deletions packages/react/src/stories/ic-skip-link.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { Canvas, Markdown, Meta, Story } from "@storybook/blocks";
import * as IcSkipLinkStories from './ic-skip-link.stories';
import readme from "../../../web-components/src/components/ic-skip-link/readme.md";

<Meta of={IcSkipLinkStories} />

<Markdown>{readme}</Markdown>

### Default

<Canvas>
<Story of={IcSkipLinkStories.Default} />
</Canvas>

### Full width

<Canvas>
<Story of={IcSkipLinkStories.FullWidth} />
</Canvas>

### Inline

<Canvas>
<Story of={IcSkipLinkStories.Inline} />
</Canvas>

### Hide background

<Canvas>
<Story of={IcSkipLinkStories.HideBackground} />
</Canvas>

### Playground

<Canvas>
<Story of={IcSkipLinkStories.Playground} />
</Canvas>
Loading

0 comments on commit 6267bf2

Please sign in to comment.