diff --git a/.github/workflows/e2e-tests.yml b/.github/workflows/e2e-tests.yml
index 2cd146d..df75c89 100644
--- a/.github/workflows/e2e-tests.yml
+++ b/.github/workflows/e2e-tests.yml
@@ -50,7 +50,7 @@ jobs:
- name: Build Next.js app
run: npm run build
env:
- NEXT_PUBLIC_API_URL: http://localhost:3000/api
+ NEXT_PUBLIC_API_URL: http://127.0.0.1:3000/api
NEXT_PUBLIC_CONTRACT_ID: Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
NEXT_PUBLIC_STELLAR_NETWORK: testnet
NEXT_PUBLIC_STELLAR_NETWORK_PASSPHRASE: "Test SDF Network ; September 2015"
@@ -58,7 +58,7 @@ jobs:
- name: Run Playwright tests
run: npm run test:e2e
env:
- NEXT_PUBLIC_API_URL: http://localhost:3000/api
+ NEXT_PUBLIC_API_URL: http://127.0.0.1:3000/api
NEXT_PUBLIC_CONTRACT_ID: Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
NEXT_PUBLIC_STELLAR_NETWORK: testnet
NEXT_PUBLIC_STELLAR_NETWORK_PASSPHRASE: "Test SDF Network ; September 2015"
diff --git a/app/__tests__/layout.test.tsx b/app/__tests__/layout.test.tsx
deleted file mode 100644
index dbf619b..0000000
--- a/app/__tests__/layout.test.tsx
+++ /dev/null
@@ -1,171 +0,0 @@
-import { useQuery } from "@tanstack/react-query";
-import { render, screen, waitFor } from "@testing-library/react";
-import userEvent from "@testing-library/user-event";
-import { useTheme } from "next-themes";
-import { toast } from "sonner";
-import { afterAll, beforeAll, describe, expect, it, type Mock,vi } from "vitest";
-
-import { AppProviders } from "@/components/providers/AppProviders";
-import { useWallet } from "@/components/providers/WalletProvider";
-
-import RootLayout from "../layout";
-
-// Mock matchMedia for tests
-Object.defineProperty(window, 'matchMedia', {
- writable: true,
- value: vi.fn().mockImplementation(query => ({
- matches: false,
- media: query,
- onchange: null,
- addListener: vi.fn(), // Deprecated
- removeListener: vi.fn(), // Deprecated
- addEventListener: vi.fn(),
- removeEventListener: vi.fn(),
- dispatchEvent: vi.fn(),
- })),
-});
-
-// Mock ResizeObserver
-global.ResizeObserver = class ResizeObserver {
- observe() {}
- unobserve() {}
- disconnect() {}
-};
-
-// Mock Next font
-vi.mock("next/font/google", () => ({
- Geist: () => ({ variable: "--font-geist-sans" }),
- Geist_Mono: () => ({ variable: "--font-geist-mono" }),
-}));
-
-// Mock Next.js router and other hooks if needed
-vi.mock("next/navigation", () => ({
- usePathname: () => "/",
- useSearchParams: () => new URLSearchParams(),
- useRouter: () => ({
- push: vi.fn(),
- replace: vi.fn(),
- prefetch: vi.fn(),
- }),
-}));
-
-vi.mock("@/components/providers/ServiceWorkerProvider", () => ({
- ServiceWorkerProvider: () =>
-}));
-
-// Components to test providers
-const WalletConsumer = () => {
- const wallet = useWallet();
- return {wallet ? "Wallet Ready" : "No Wallet"}
;
-};
-
-const ThemeConsumer = () => {
- const { theme } = useTheme();
- return {theme || "No Theme"}
;
-};
-
-const QueryConsumer = () => {
- const { data } = useQuery({ queryKey: ["test"], queryFn: () => "Query Ready", staleTime: 0 });
- return {data || "Loading"}
;
-};
-
-describe("RootLayout & AppProviders", () => {
-
- describe("Provider Dependencies (Success Cases)", () => {
- it("WalletProvider is mounted and useWallet does not throw", () => {
- render(
-
-
-
- );
- expect(screen.getByTestId("wallet-consumer")).toBeInTheDocument();
- });
-
- it("ThemeProvider is mounted and useTheme returns a theme", () => {
- render(
-
-
-
- );
- expect(screen.getByTestId("theme-consumer")).toHaveTextContent("dark");
- });
-
- it("QueryClientProvider is mounted and useQuery executes successfully", async () => {
- render(
-
-
-
- );
- await waitFor(() => {
- expect(screen.getByTestId("query-consumer")).toHaveTextContent("Query Ready");
- });
- });
-
- it("Toaster is mounted and renders toast when triggered", async () => {
- const ToastTrigger = () => (
-
- );
-
- render(
-
-
-
- );
-
- const user = userEvent.setup();
- await user.click(screen.getByTestId("toast-trigger"));
-
- await waitFor(() => {
- expect(screen.getByText("Toast Ready")).toBeInTheDocument();
- }, { timeout: 3000 });
- });
- });
-
- describe("Failure Verification Tests (Throws without providers)", () => {
- // Suppress console.error for expected errors during rendering
- let consoleError: Mock;
- beforeAll(() => {
- consoleError = vi.spyOn(console, "error").mockImplementation(() => {});
- });
- afterAll(() => {
- consoleError.mockRestore();
- });
-
- it("useWallet throws an error when WalletProvider is removed", () => {
- expect(() => render()).toThrow();
- });
-
- it("useQuery throws an error when QueryClientProvider is removed", () => {
- expect(() => render()).toThrow();
- });
-
- it("useTheme might not throw, but we verify it's missing the theme context", () => {
- // next-themes useTheme doesn't strictly throw if missing, it might just be undefined.
- // So we test that without ThemeProvider, it doesn't give 'dark'.
- const { getByTestId } = render();
- expect(getByTestId("theme-consumer")).toHaveTextContent("No Theme");
- });
- });
-
- describe("Layout Component Structure", () => {
- it("renders required layout components and children", () => {
- // Testing RootLayout directly in RTL can be tricky with html/body tags
- // We will render it and check for the main content block and components
- const { container } = render(
-
- Child Content
-
- );
-
- // Verify layout shell elements
- expect(screen.getByTestId("layout-child")).toBeInTheDocument();
- expect(screen.getByText("TrustLink")).toBeInTheDocument(); // Navbar
-
- // Verify main content landmark
- const mainElement = document.getElementById('main-content') || container.querySelector('main#main-content');
- expect(mainElement).toBeInTheDocument();
- });
- });
-});
diff --git a/app/__tests__/badge-visual-test/page.tsx b/app/badge-visual-test/page.tsx
similarity index 100%
rename from app/__tests__/badge-visual-test/page.tsx
rename to app/badge-visual-test/page.tsx
diff --git a/app/dispute/[id]/DisputeForm.tsx b/app/dispute/[id]/DisputeForm.tsx
index bbf8690..7f4b597 100644
--- a/app/dispute/[id]/DisputeForm.tsx
+++ b/app/dispute/[id]/DisputeForm.tsx
@@ -123,7 +123,6 @@ export default function DisputeForm({ escrowId }: DisputeFormProps) {