diff --git a/src/app/(sidebar)/explore-endpoints/[[...pages]]/page.tsx b/src/app/(sidebar)/explore-endpoints/[[...pages]]/page.tsx index 1f41821a..a6912452 100644 --- a/src/app/(sidebar)/explore-endpoints/[[...pages]]/page.tsx +++ b/src/app/(sidebar)/explore-endpoints/[[...pages]]/page.tsx @@ -440,13 +440,17 @@ export default function ExploreEndpoints() { <>
+
{pageData.requestMethod}
} @@ -457,6 +461,7 @@ export default function ExploreEndpoints() { type="submit" disabled={!isSubmitEnabled()} isLoading={isLoading || isFetching} + data-testid="endpoints-submitBtn" > Submit @@ -486,7 +491,7 @@ export default function ExploreEndpoints() { return (
-
+
{renderPostPayload()} {allFields.map((f) => { @@ -616,7 +621,11 @@ export default function ExploreEndpoints() { {page.label} - }> + } + data-testid="endpoints-docsLink" + > {`View ${pageData.docsLabel ? `${pageData.docsLabel} ` : ""}documentation`}
@@ -751,7 +760,7 @@ const ExploreEndpointsLandingPage = () => { For Stellar docs, take a look at the{" "} - + Stellar developers site . diff --git a/src/app/page.tsx b/src/app/page.tsx index be4f8959..04d7da1a 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -1,6 +1,5 @@ "use client"; -import { useRouter } from "next/navigation"; import { Card, Link, Text, Icon } from "@stellar/design-system"; import { NextLink } from "@/components/NextLink"; @@ -10,8 +9,6 @@ import { SdsLink } from "@/components/SdsLink"; import { Routes } from "@/constants/routes"; export default function Introduction() { - const router = useRouter(); - const infoCards = [ { id: "stellar-quest", @@ -29,7 +26,8 @@ export default function Introduction() { "Tools, like the Stellar CLI, for reading and interacting with smart contracts on the Stellar Network", buttonLabel: "See tools", buttonIcon: undefined, - buttonAction: () => router.push(Routes.SOROBAN_CONTRACT_EXPLORER), + buttonAction: () => + window.open("https://developers.stellar.org/docs/tools/sdks", "_blank"), }, { id: "stellar-rpc", @@ -83,7 +81,7 @@ export default function Introduction() { For Stellar docs, take a look at the{" "} - + Stellar developers site . diff --git a/src/components/MainNav.tsx b/src/components/MainNav.tsx index 233b3abe..cbfa7189 100644 --- a/src/components/MainNav.tsx +++ b/src/components/MainNav.tsx @@ -37,7 +37,7 @@ const primaryNavLinks: NavLink[] = [ const secondaryNavLinks: NavLink[] = [ { - href: "https://developers.stellar.org/network", + href: "https://developers.stellar.org/", label: "View Documentation", }, ]; diff --git a/src/components/layout/LayoutSidebarContent.tsx b/src/components/layout/LayoutSidebarContent.tsx index c28bc802..b12fb568 100644 --- a/src/components/layout/LayoutSidebarContent.tsx +++ b/src/components/layout/LayoutSidebarContent.tsx @@ -45,9 +45,13 @@ export const LayoutSidebarContent = ({
{sidebar.instruction ? ( -
+
{sidebar.instruction}
) : null} @@ -95,12 +99,16 @@ const Link = ({ item, pathname }: { item: SidebarLink; pathname: string }) => { if (item.nestedItems?.length) { return ( -
+
{ setIsExpanded(!isExpanded); }} + data-testid="endpoints-sidebar-linkToggle" > {item.label}
@@ -109,6 +117,7 @@ const Link = ({ item, pathname }: { item: SidebarLink; pathname: string }) => {
{item.nestedItems.map((nested) => ( @@ -117,6 +126,7 @@ const Link = ({ item, pathname }: { item: SidebarLink; pathname: string }) => { href={nested.route} className="SidebarLink" data-is-active={pathname === nested.route} + data-testid="endpoints-sidebar-link" > {nested.label} diff --git a/src/constants/exploreEndpointsPages.ts b/src/constants/exploreEndpointsPages.ts index cd7c1d0b..5b6b6472 100644 --- a/src/constants/exploreEndpointsPages.ts +++ b/src/constants/exploreEndpointsPages.ts @@ -94,7 +94,7 @@ export const EXPLORE_ENDPOINTS_PAGES_HORIZON: ExploreEndpointsPagesProps = { form: { docsUrl: "https://developers.stellar.org/network/horizon/resources/list-all-claimable-balances", - docsLabel: "claimable balance", + docsLabel: "claimable balances", requestMethod: "GET", endpointUrlTemplate: "/claimable_balances/{?sponsor,asset,claimant,cursor,limit,order}", @@ -108,7 +108,7 @@ export const EXPLORE_ENDPOINTS_PAGES_HORIZON: ExploreEndpointsPagesProps = { form: { docsUrl: "https://developers.stellar.org/network/horizon/resources/retrieve-a-claimable-balance", - docsLabel: "claimable balances", + docsLabel: "claimable balance", requestMethod: "GET", endpointUrlTemplate: "/claimable_balances/{claimable_balance_id}", requiredParams: "claimable_balance_id", diff --git a/tests/endpointsPage.test.ts b/tests/endpointsPage.test.ts new file mode 100644 index 00000000..ac2aca15 --- /dev/null +++ b/tests/endpointsPage.test.ts @@ -0,0 +1,183 @@ +import { test, expect } from "@playwright/test"; + +test.describe("Endpoints page", () => { + test.beforeEach(async ({ page }) => { + await page.goto("http://localhost:3000/explore-endpoints"); + }); + + test("Loads", async ({ page }) => { + await expect(page.locator("h1")).toHaveText("Explore Endpoints"); + }); + + test("Renders info cards", async ({ page }) => { + await expect(page.locator("h2")).toHaveText([ + "Stellar RPC Endpoints", + "Horizon Endpoints", + ]); + }); + + test.describe("Sidebar", () => { + test("Renders Horizon endpoints", async ({ page }) => { + const sidebar = page.getByTestId("endpoints-sidebar-section").first(); + await expect( + sidebar.getByTestId("endpoints-sidebar-subtitle"), + ).toContainText("Horizon Endpoints"); + + const linkToggles = sidebar.getByTestId("endpoints-sidebar-linkToggle"); + + await expect(linkToggles).toHaveCount(15); + + await expect(linkToggles).toContainText([ + "Accounts", + "Assets", + "Claimable Balances", + "Effects", + "Fee Stats", + "Ledgers", + "Liquidity Pools", + "Offers", + "Operations", + "Order Book", + "Paths", + "Payments", + "Trade Aggregations", + "Trades", + "Transactions", + ]); + }); + + test("Expands dropdown on click with correct links", async ({ page }) => { + const sidebar = page.getByTestId("endpoints-sidebar-section").first(); + const accountsLink = sidebar + .getByTestId("endpoints-sidebar-linkToggle") + .filter({ hasText: "Accounts" }); + + const parent = sidebar.getByTestId( + "endpoints-sidebar/explore-endpoints/accounts", + ); + await expect(parent).toBeVisible(); + + const linksContainer = parent.getByTestId( + "endpoints-sidebar-linksContainer", + ); + + await expect(linksContainer).toBeHidden(); + await accountsLink.click(); + await expect(linksContainer).toBeVisible(); + + await expect( + linksContainer.getByTestId("endpoints-sidebar-link"), + ).toContainText(["All Accounts", "Single Account"]); + + await expect( + linksContainer + .getByTestId("endpoints-sidebar-link") + .filter({ hasText: "All Accounts" }), + ).toHaveAttribute("href", "/explore-endpoints/accounts"); + }); + }); + + test.describe("All Accounts", () => { + test.beforeEach(async ({ page }) => { + await page.goto("http://localhost:3000/explore-endpoints/accounts"); + }); + + test("Page loads with correct title and view docs link", async ({ + page, + }) => { + await expect(page.locator("h1")).toHaveText("All Accounts"); + + const docsLink = page.getByTestId("endpoints-docsLink"); + + await expect(docsLink).toContainText("View accounts documentation"); + await expect(docsLink).toHaveAttribute( + "href", + "https://developers.stellar.org/network/horizon/resources/list-all-accounts", + ); + }); + + test("URL and buttons have correct defaults", async ({ page }) => { + await expect(page.getByTestId("endpoints-url")).toHaveValue( + "https://horizon-testnet.stellar.org/accounts/", + ); + await expect(page.getByTestId("endpoints-url-method")).toContainText( + "GET", + ); + await expect(page.getByTestId("endpoints-submitBtn")).toBeEnabled(); + }); + + test("URL updates when inputs change", async ({ page }) => { + await page + .getByLabel("Sponsor(optional)") + .fill("GBV6DGKNXELF3TYU4V3NRCF57Q3477KLUBBINVG5GGR3LJYVQPKPDX4C"); + + await expect(page.getByTestId("endpoints-url")).toHaveValue( + "https://horizon-testnet.stellar.org/accounts/?sponsor=GBV6DGKNXELF3TYU4V3NRCF57Q3477KLUBBINVG5GGR3LJYVQPKPDX4C", + ); + + await page.getByLabel("Limit(optional)").fill("2"); + + await expect(page.getByTestId("endpoints-url")).toHaveValue( + "https://horizon-testnet.stellar.org/accounts/?sponsor=GBV6DGKNXELF3TYU4V3NRCF57Q3477KLUBBINVG5GGR3LJYVQPKPDX4C&limit=2", + ); + }); + }); + + test.describe("Effects for Account", () => { + test.beforeEach(async ({ page }) => { + await page.goto( + "http://localhost:3000/explore-endpoints/effects/account", + ); + }); + + test("Page loads with correct title and view docs link", async ({ + page, + }) => { + await expect(page.locator("h1")).toHaveText("Effects for Account"); + + const docsLink = page.getByTestId("endpoints-docsLink"); + + await expect(docsLink).toContainText( + "View effects for account documentation", + ); + await expect(docsLink).toHaveAttribute( + "href", + "https://developers.stellar.org/network/horizon/resources/get-effects-by-account-id", + ); + }); + + test("URL and buttons have correct defaults", async ({ page }) => { + await expect(page.getByTestId("endpoints-url")).toHaveValue( + "https://horizon-testnet.stellar.org/accounts//effects", + ); + await expect(page.getByTestId("endpoints-url-method")).toContainText( + "GET", + ); + await expect(page.getByTestId("endpoints-submitBtn")).toBeDisabled(); + }); + + test("Filling required field enables submit button", async ({ page }) => { + const accountInput = page.getByLabel("Account ID"); + await accountInput.fill( + "GAXELIT3WH4ALN66AYQAZILPSSZVIQV67R62FACYC6DHNZCLCN45CA2A", + ); + + await expect(accountInput).toHaveAttribute("aria-invalid", "false"); + await expect(page.getByTestId("endpoints-url")).toHaveValue( + "https://horizon-testnet.stellar.org/accounts/GAXELIT3WH4ALN66AYQAZILPSSZVIQV67R62FACYC6DHNZCLCN45CA2A/effects", + ); + await expect(page.getByTestId("endpoints-submitBtn")).toBeEnabled(); + }); + + test("Input with error disables submit button", async ({ page }) => { + const accountInput = page.getByLabel("Account ID"); + await accountInput.fill("abc"); + + await expect(accountInput).toHaveAttribute("aria-invalid", "true"); + await expect(page.getByTestId("endpoints-pageContent")).toContainText( + "Public key is invalid.", + ); + await expect(page.getByTestId("endpoints-submitBtn")).toBeDisabled(); + }); + }); +});