From 5d8072c00121061fd50a6bb87e7f64426a8ea28b Mon Sep 17 00:00:00 2001 From: Alex Panturu Date: Thu, 23 May 2024 17:28:21 +0300 Subject: [PATCH 1/3] explorer: add `AppAnchorButton` component --- .../__tests__/AppAnchorButton.spec.js | 66 ++++++++ .../AppAnchorButton.spec.js.snap | 17 ++ .../app-anchor-button/AppAnchorButton.svelte | 11 ++ explorer/src/lib/components/index.js | 3 +- .../components/__tests__/AnchorButton.spec.js | 88 ++++++++++ .../__snapshots__/AnchorButton.spec.js.snap | 156 ++++++++++++++++++ .../components/anchor-button/AnchorButton.css | 10 ++ .../anchor-button/AnchorButton.svelte | 69 ++++++++ explorer/src/lib/dusk/components/index.js | 1 + 9 files changed, 420 insertions(+), 1 deletion(-) create mode 100644 explorer/src/lib/components/__tests__/AppAnchorButton.spec.js create mode 100644 explorer/src/lib/components/__tests__/__snapshots__/AppAnchorButton.spec.js.snap create mode 100644 explorer/src/lib/components/app-anchor-button/AppAnchorButton.svelte create mode 100644 explorer/src/lib/dusk/components/__tests__/AnchorButton.spec.js create mode 100644 explorer/src/lib/dusk/components/__tests__/__snapshots__/AnchorButton.spec.js.snap create mode 100644 explorer/src/lib/dusk/components/anchor-button/AnchorButton.css create mode 100644 explorer/src/lib/dusk/components/anchor-button/AnchorButton.svelte diff --git a/explorer/src/lib/components/__tests__/AppAnchorButton.spec.js b/explorer/src/lib/components/__tests__/AppAnchorButton.spec.js new file mode 100644 index 0000000000..25e5255e88 --- /dev/null +++ b/explorer/src/lib/components/__tests__/AppAnchorButton.spec.js @@ -0,0 +1,66 @@ +import { afterEach, describe, expect, it, vi } from "vitest"; +import { cleanup, fireEvent, render } from "@testing-library/svelte"; +import { base } from "$app/paths"; + +import { AppAnchorButton } from ".."; + +describe("AppAnchorButton", () => { + const baseProps = { + className: "foo bar", + href: "/setup", + id: "some-id", + }; + + afterEach(cleanup); + + it("should render an `AnchorButton` with the base path prepended to the `href` attribute, if the `href` represents an absolute URL", () => { + const { container, getByRole, rerender } = render( + AppAnchorButton, + baseProps + ); + const anchorA = getByRole("link"); + + expect(container.firstChild).toMatchSnapshot(); + expect(anchorA).toHaveAttribute("href", `${base}${baseProps.href}`); + expect(anchorA).toHaveClass("foo bar"); + expect(anchorA).toHaveAttribute("id", baseProps.id); + + rerender({ ...baseProps, href: "/" }); + + const anchorB = getByRole("link"); + + expect(anchorB).toHaveAttribute("href", `${base}/`); + expect(anchorB).toHaveClass("foo bar"); + expect(anchorB).toHaveAttribute("id", baseProps.id); + }); + + it("should leave the `AnchorButton` as it is if the `href` points to a relative path", () => { + const { getByRole } = render(AppAnchorButton, { + ...baseProps, + href: "foo/bar", + }); + + expect(getByRole("link")).toHaveAttribute("href", "foo/bar"); + }); + + it("should leave the `AnchorButton` as it is if the `href` points to an external URL", () => { + const href = "http://example.com"; + const { getByRole } = render(AppAnchorButton, { ...baseProps, href }); + + expect(getByRole("link")).toHaveAttribute("href", href); + }); + + it("should forward the `onclick` event to the `AnchorButton`", async () => { + const handler = vi.fn(); + const { component, getByRole } = render(AppAnchorButton, { + ...baseProps, + href: "#", + }); + + component.$on("click", handler); + + await fireEvent.click(getByRole("link")); + + expect(handler).toHaveBeenCalledTimes(1); + }); +}); diff --git a/explorer/src/lib/components/__tests__/__snapshots__/AppAnchorButton.spec.js.snap b/explorer/src/lib/components/__tests__/__snapshots__/AppAnchorButton.spec.js.snap new file mode 100644 index 0000000000..0e9235d24e --- /dev/null +++ b/explorer/src/lib/components/__tests__/__snapshots__/AppAnchorButton.spec.js.snap @@ -0,0 +1,17 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`AppAnchorButton > should render an \`AnchorButton\` with the base path prepended to the \`href\` attribute, if the \`href\` represents an absolute URL 1`] = ` +
+ + + + + + +
+`; diff --git a/explorer/src/lib/components/app-anchor-button/AppAnchorButton.svelte b/explorer/src/lib/components/app-anchor-button/AppAnchorButton.svelte new file mode 100644 index 0000000000..72800f2284 --- /dev/null +++ b/explorer/src/lib/components/app-anchor-button/AppAnchorButton.svelte @@ -0,0 +1,11 @@ + + + + + diff --git a/explorer/src/lib/components/index.js b/explorer/src/lib/components/index.js index a231b8b92d..837c1189b9 100644 --- a/explorer/src/lib/components/index.js +++ b/explorer/src/lib/components/index.js @@ -1,10 +1,11 @@ -export { default as DataAlert } from "./data-alert/DataAlert.svelte"; export { default as AppAnchor } from "./app-anchor/AppAnchor.svelte"; +export { default as AppAnchorButton } from "./app-anchor-button/AppAnchorButton.svelte"; export { default as AppImage } from "./app-image/AppImage.svelte"; export { default as BlockDetails } from "./block-details/BlockDetails.svelte"; export { default as BlocksCard } from "./blocks-card/BlocksCard.svelte"; export { default as BlocksList } from "./blocks-list/BlocksList.svelte"; export { default as BlocksTable } from "./blocks-table/BlocksTable.svelte"; +export { default as DataAlert } from "./data-alert/DataAlert.svelte"; export { default as DataCard } from "./data-card/DataCard.svelte"; export { default as DataGuard } from "./data-guard/DataGuard.svelte"; export { default as DetailList } from "./detail-list/DetailList.svelte"; diff --git a/explorer/src/lib/dusk/components/__tests__/AnchorButton.spec.js b/explorer/src/lib/dusk/components/__tests__/AnchorButton.spec.js new file mode 100644 index 0000000000..98417aa383 --- /dev/null +++ b/explorer/src/lib/dusk/components/__tests__/AnchorButton.spec.js @@ -0,0 +1,88 @@ +// @ts-nocheck + +import { afterEach, describe, expect, it } from "vitest"; +import { cleanup, render } from "@testing-library/svelte"; +import { mdiFolderOutline } from "@mdi/js"; + +import { AnchorButton } from ".."; + +describe("AnchorButton", () => { + const baseProps = { + href: "/some-url", + text: "some text", + }; + const baseOptions = { + props: baseProps, + target: document.body, + }; + + afterEach(cleanup); + + it("should render the AnchorButton component", () => { + const { container } = render(AnchorButton, baseOptions); + + expect(container.firstChild).toMatchSnapshot(); + }); + + it("should add a disabled class if the related property is `true`", () => { + const props = { + ...baseProps, + disabled: true, + }; + const { container } = render(AnchorButton, { ...baseOptions, props }); + + expect(container.firstChild).toMatchSnapshot(); + }); + + it("should pass additional class names and attributes to the rendered element", () => { + const props = { + ...baseProps, + className: "foo bar", + id: "some-id", + }; + const { container } = render(AnchorButton, { ...baseOptions, props }); + + expect(container.firstChild).toMatchSnapshot(); + }); + + it("should render a AnchorButton without a text", () => { + const props = { + ...baseProps, + text: "", + }; + const { container } = render(AnchorButton, { ...baseOptions, props }); + + expect(container.firstChild).toMatchSnapshot(); + }); + + it("should be able to render a AnchorButton with an icon and text", () => { + ["after", "before"].forEach((position) => { + const props = { + ...baseProps, + icon: { + path: mdiFolderOutline, + position, + }, + }; + const { container } = render(AnchorButton, { ...baseOptions, props }); + + expect(container.firstChild).toMatchSnapshot(); + }); + }); + + it("should be able to render a AnchorButton with an icon only", () => { + ["after", "before"].forEach((position) => { + const props = { + ...baseProps, + icon: { + path: mdiFolderOutline, + position, + }, + text: "", + }; + const { container } = render(AnchorButton, { ...baseOptions, props }); + + expect(container.firstChild).toMatchSnapshot(); + }); + }); +}); diff --git a/explorer/src/lib/dusk/components/__tests__/__snapshots__/AnchorButton.spec.js.snap b/explorer/src/lib/dusk/components/__tests__/__snapshots__/AnchorButton.spec.js.snap new file mode 100644 index 0000000000..e64474dc92 --- /dev/null +++ b/explorer/src/lib/dusk/components/__tests__/__snapshots__/AnchorButton.spec.js.snap @@ -0,0 +1,156 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`AnchorButton > should add a disabled class if the related property is \`true\` 1`] = ` + + + some text + + + +`; + +exports[`AnchorButton > should be able to render a AnchorButton with an icon and text 1`] = ` + + + some text + + + + + + + + + +`; + +exports[`AnchorButton > should be able to render a AnchorButton with an icon and text 2`] = ` + + + some text + + + + + + + + + +`; + +exports[`AnchorButton > should be able to render a AnchorButton with an icon only 1`] = ` + + + + + + + + + +`; + +exports[`AnchorButton > should be able to render a AnchorButton with an icon only 2`] = ` + + + + + + + + + +`; + +exports[`AnchorButton > should pass additional class names and attributes to the rendered element 1`] = ` + + + some text + + + +`; + +exports[`AnchorButton > should render a AnchorButton without a text 1`] = ` + + + +`; + +exports[`AnchorButton > should render the AnchorButton component 1`] = ` + + + some text + + + +`; diff --git a/explorer/src/lib/dusk/components/anchor-button/AnchorButton.css b/explorer/src/lib/dusk/components/anchor-button/AnchorButton.css new file mode 100644 index 0000000000..0d98b9baaa --- /dev/null +++ b/explorer/src/lib/dusk/components/anchor-button/AnchorButton.css @@ -0,0 +1,10 @@ +.dusk-anchor-button { + appearance: button; + text-decoration: none; + text-align: center; +} + +.dusk-anchor-button.dusk-anchor-button--disabled { + cursor: default; + pointer-events: none; +} diff --git a/explorer/src/lib/dusk/components/anchor-button/AnchorButton.svelte b/explorer/src/lib/dusk/components/anchor-button/AnchorButton.svelte new file mode 100644 index 0000000000..1b40d993be --- /dev/null +++ b/explorer/src/lib/dusk/components/anchor-button/AnchorButton.svelte @@ -0,0 +1,69 @@ + + + + + + {#if icon?.position === "after"} + {#if text} + {text} + {/if} + + {:else if icon} + + {#if text} + {text} + {/if} + {:else if text} + {text} + {/if} + diff --git a/explorer/src/lib/dusk/components/index.js b/explorer/src/lib/dusk/components/index.js index 8984b0c0e5..0be65f3158 100644 --- a/explorer/src/lib/dusk/components/index.js +++ b/explorer/src/lib/dusk/components/index.js @@ -1,4 +1,5 @@ export { default as Anchor } from "./anchor/Anchor.svelte"; +export { default as AnchorButton } from "./anchor-button/AnchorButton.svelte"; export { default as Badge } from "./badge/Badge.svelte"; export { default as Button } from "./button/Button.svelte"; export { default as Card } from "./card/Card.svelte"; From 4809d19e5002ff429199a7f54b8e392acaa5456d Mon Sep 17 00:00:00 2001 From: Alex Panturu Date: Thu, 23 May 2024 17:28:44 +0300 Subject: [PATCH 2/3] explorer: disable block height navigation --- .../__snapshots__/BlockDetails.spec.js.snap | 22 ++++++++++++++----- .../block-details/BlockDetails.svelte | 20 ++++++++--------- .../__tests__/__snapshots__/page.spec.js.snap | 22 ++++++++++++++----- 3 files changed, 42 insertions(+), 22 deletions(-) diff --git a/explorer/src/lib/components/__tests__/__snapshots__/BlockDetails.spec.js.snap b/explorer/src/lib/components/__tests__/__snapshots__/BlockDetails.spec.js.snap index 65fd87bc42..61719f10fc 100644 --- a/explorer/src/lib/components/__tests__/__snapshots__/BlockDetails.spec.js.snap +++ b/explorer/src/lib/components/__tests__/__snapshots__/BlockDetails.spec.js.snap @@ -85,11 +85,12 @@ exports[`Block Details > renders the Block Details component 1`] = ` class="details-list__definition" > @@ -99,18 +100,23 @@ exports[`Block Details > renders the Block Details component 1`] = ` + + + - + + 495,868 @@ -120,9 +126,13 @@ exports[`Block Details > renders the Block Details component 1`] = ` + + + - + + diff --git a/explorer/src/lib/components/block-details/BlockDetails.svelte b/explorer/src/lib/components/block-details/BlockDetails.svelte index 965d635206..bff9635df7 100644 --- a/explorer/src/lib/components/block-details/BlockDetails.svelte +++ b/explorer/src/lib/components/block-details/BlockDetails.svelte @@ -2,8 +2,8 @@