Skip to content

Establish test suite (Vitest/Playwright/CI) + native Stellar & Aztec wallet integration - #191

Open
Dannyorji wants to merge 2 commits into
BuidlZone-Labs:mainfrom
Dannyorji:feat/establish-test-suite
Open

Establish test suite (Vitest/Playwright/CI) + native Stellar & Aztec wallet integration#191
Dannyorji wants to merge 2 commits into
BuidlZone-Labs:mainfrom
Dannyorji:feat/establish-test-suite

Conversation

@Dannyorji

@Dannyorji Dannyorji commented Aug 4, 2026

Copy link
Copy Markdown

Summary

Testing infrastructure

  • Added Vitest + React Testing Library, with npm run test, test:watch, and test:coverage scripts.
  • Unit tests for the checkout flow (TicketInfo.test.tsx: ticket selection, quantity stepper, sold-out state, wallet-connect purchase flow, anonymous free-event flow, wallet error banner) and the search/filter flow (MainContent.test.tsx: price/location filtering, empty state, deep-link initial query).
  • Added aria-labels to the previously unlabeled quantity stepper buttons (accessibility gap + needed for reliable test queries).
  • Added Playwright for E2E, with npm run test:e2e. e2e/ticket-purchase.spec.ts covers ticket/quantity selection through the wallet connection modal, plus a full purchase run against a stubbed Freighter provider.
  • Added .github/workflows/ci.yml: lint, type-check, unit tests (with coverage upload), and Playwright E2E on every PR to main.

Native Stellar & Aztec wallet integration

  • Replaced the mock_tx_... random-string wallet SDK in lib/walletSdk.ts with a chain-agnostic facade backed by real adapters in lib/wallet/.
  • lib/wallet/stellarAdapter.ts: connects Freighter, Lobstr, WalletConnect, and xBull via @creit.tech/stellar-wallets-kit; signs and submits real transactions to Horizon; returns genuine on-chain tx hashes.
  • lib/wallet/aztecAdapter.ts: Azguard-compatible injected-provider adapter for Aztec, scaffolded against @aztec/aztec.js — flagged in comments since Aztec's wallet-connection RPC surface is still evolving.
  • app/api/transactions/[txHash]/status/route.ts now looks up real Stellar transaction hashes on Horizon, falling back to the existing simulated status only for non-Stellar-shaped (demo/free-flow) hashes.
  • ConnectWalletPrompt.tsx gets a Stellar/Aztec chain selector and shows the connected wallet's name/address; WalletConnectionIndicator.tsx now surfaces the real wallet name + shortened address instead of just "Connected".
  • Extended lib/user-session-sync.ts to persist walletAddress / walletName / walletChain alongside the existing connected flag.

Notes for reviewers

  • Dependencies were added to package.json but npm install was not run — no lockfile update yet.
  • No organizer payout address exists in the data model yet, so the default (no-argument) signTransaction() call signs a minimal real self-payment (1 stroop, memo zicket-ticket) purely to produce a verifiable on-chain transaction. Once ticket purchases have a real destination (organizer wallet + priced asset), build that XDR and pass it into signTransaction(xdr).
  • Aztec/Azguard method names in lib/wallet/aztecAdapter.ts are a best-effort based on the injected-provider convention other wallets use — verify against current Azguard/@aztec/aztec.js docs before shipping.
  • NEXT_PUBLIC_STELLAR_NETWORK, NEXT_PUBLIC_STELLAR_HORIZON_URL, and NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID are documented in .env.example.

Closes #186
Closes #187

Summary by CodeRabbit

  • New Features

    • Added support for Stellar and Aztec wallet connections.
    • Wallet indicators now show the connected wallet name and shortened address.
    • Added wallet and network configuration options.
    • Stellar transactions now report confirmed, failed, or pending status from the network.
    • Added improved wallet selection and transaction signing flows.
  • Bug Fixes

    • Improved sold-out ticket handling, accessibility labels, and wallet loading behavior.
  • Tests

    • Added automated coverage for event filtering, ticket checkout, wallet flows, and end-to-end purchases.

Adds Vitest + React Testing Library for component/unit coverage of the
checkout (TicketInfo) and search/filter (MainContent) flows, a Playwright
E2E spec covering the ticket purchase journey, and a GitHub Actions workflow
that runs lint, type-check, unit tests, and E2E on every PR. Also adds
missing aria-labels to the quantity stepper buttons in TicketInfo so they're
addressable by both assistive tech and tests.
Replaces the mock_tx_... random-string wallet SDK with real chain-specific
adapters. Stellar wallets (Freighter, Lobstr, WalletConnect, xBull) connect
through @creit.tech/stellar-wallets-kit, sign real transactions, and submit
them to Horizon; the transaction status API now looks up genuine Stellar tx
hashes on Horizon instead of only simulating confirmation. Aztec support is
scaffolded via an Azguard-compatible injected-provider adapter, clearly
flagged where Aztec's wallet-connection RPC surface is still unstable.

lib/walletSdk.ts stays the stable facade both checkout (TicketInfo) and the
organizer payout prompt (ConnectWalletPrompt) already depended on, now
lazy-loading the right chain adapter and exposing the connected account so
the UI can show a real wallet name/address instead of "Connected".
@netlify

netlify Bot commented Aug 4, 2026

Copy link
Copy Markdown

Deploy Preview for zicket failed.

Name Link
🔨 Latest commit dfccd53
🔍 Latest deploy log https://app.netlify.com/projects/zicket/deploys/6a7198c152724500085d1ac2

@drips-wave

drips-wave Bot commented Aug 4, 2026

Copy link
Copy Markdown

@Dannyorji Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@coderabbitai

coderabbitai Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

The PR adds Stellar and Aztec wallet adapters, chain-aware wallet session state, on-chain Stellar transaction status checks, checkout updates, component tests, Playwright tests, and GitHub Actions CI jobs.

Changes

Wallet integration and testing

Layer / File(s) Summary
Wallet contracts, adapters, and SDK loading
lib/wallet/types.ts, lib/wallet/*Adapter.ts, lib/walletSdk.ts, .env.example, package.json
Adds shared wallet contracts, Stellar and Aztec adapters, chain-aware lazy loading, transaction signing, and environment configuration.
Wallet selection and session metadata
lib/user-session-sync.ts, app/components/organizer/ConnectWalletPrompt.tsx, app/components/WalletConnectionIndicator.tsx
Adds Stellar/Aztec selection and persists wallet address, name, and chain for connection displays.
Checkout signing and transaction status
app/components/explore/EventCheckout/TicketInfo.tsx, app/api/transactions/[txHash]/status/route.ts
Stores the connected account after paid signing and queries Horizon for valid Stellar transaction hashes.
Component and checkout test coverage
app/components/explore/EventCheckout/TicketInfo.test.tsx, app/components/explore/MainContent.test.tsx, vitest.config.ts, vitest.setup.ts
Adds checkout and event-filter tests with Vitest and jsdom browser API mocks.
End-to-end tests and CI execution
e2e/ticket-purchase.spec.ts, playwright.config.ts, .github/workflows/ci.yml, .gitignore, package.json
Adds Playwright ticket-purchase tests and CI jobs for linting, type checks, unit tests, coverage, and E2E reports.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Attendee
  participant TicketInfo
  participant walletSdk
  participant StellarWallet
  participant Horizon
  Attendee->>TicketInfo: Select tickets and confirm privacy
  TicketInfo->>walletSdk: Sign transaction
  walletSdk->>StellarWallet: Request wallet signature
  StellarWallet-->>walletSdk: Return transaction hash
  walletSdk-->>TicketInfo: Return signed transaction result
  TicketInfo->>Horizon: Request transaction status
  Horizon-->>TicketInfo: Return confirmed, failed, or pending status
Loading

Possibly related PRs

Suggested reviewers: diochuks

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 62.50% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes both primary workstreams: automated testing infrastructure and native Stellar/Aztec wallet integration.
Linked Issues check ✅ Passed The changes satisfy the testing, CI, wallet adapter, transaction signing, and on-chain status objectives in issues #186 and #187.
Out of Scope Changes check ✅ Passed The configuration, tests, wallet UI, session metadata, and transaction-status changes directly support the linked issue objectives.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

🧹 Nitpick comments (8)
lib/walletSdk.ts (2)

101-106: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Remove the duplicated failure cleanup.

getOrLoadAdapter already deletes the cache entry on rejection at lines 55-57. The block here repeats that logic. Keep only the catch that swallows the rejection so no unhandled rejection is reported.

♻️ Proposed simplification
 export function preloadWalletSDK(chain: WalletChain = DEFAULT_CHAIN): void {
-  const current = getOrLoadAdapter(chain);
-  current.catch(() => {
-    if (adapterLoadPromises.get(chain) === current) adapterLoadPromises.delete(chain);
-  });
+  // getOrLoadAdapter already resets the cache entry on failure.
+  void getOrLoadAdapter(chain).catch(() => {});
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/walletSdk.ts` around lines 101 - 106, Remove the duplicated cache cleanup
from preloadWalletSDK. In the current.catch handler, retain only rejection
swallowing and rely on getOrLoadAdapter for deleting the adapterLoadPromises
entry; preserve the preload behavior and avoid introducing additional error
handling.

71-77: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

De-duplicate concurrent connect calls.

Two concurrent loadWalletSDK calls for the same chain both observe isConnected() === false, so both call adapter.connect(). For Stellar this opens the wallet picker twice. Cache the in-flight connect promise per chain, in the same way the module load is cached.

♻️ Proposed in-flight connect cache
+const connectPromises = new Map<WalletChain, Promise<unknown>>();
+
 export async function loadWalletSDK(chain: WalletChain = DEFAULT_CHAIN): Promise<WalletAdapter> {
   const adapter = await getOrLoadAdapter(chain);
-  if (!adapter.isConnected()) {
-    await adapter.connect();
-  }
+  if (!adapter.isConnected()) {
+    const pending =
+      connectPromises.get(chain) ??
+      adapter.connect().finally(() => connectPromises.delete(chain));
+    connectPromises.set(chain, pending);
+    await pending;
+  }
   return adapter;
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/walletSdk.ts` around lines 71 - 77, Update loadWalletSDK to cache
in-flight adapter.connect() promises keyed by chain, reusing the existing
module-load caching pattern. Before connecting, check the per-chain cache; store
the promise when starting a connection and clear it after completion so later
calls observe the connected adapter without duplicate wallet prompts.
lib/wallet/stellarAdapter.ts (2)

38-42: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Validate NEXT_PUBLIC_STELLAR_NETWORK instead of casting it.

The cast accepts any value. A typo such as mainnet silently selects the testnet passphrase and testnet Horizon URL, so a production deployment would submit to testnet without any signal. Normalize the value and fail fast on unknown input.

♻️ Proposed validation
-const NETWORK = (process.env.NEXT_PUBLIC_STELLAR_NETWORK ?? "testnet") as "testnet" | "public";
+const RAW_NETWORK = process.env.NEXT_PUBLIC_STELLAR_NETWORK ?? "testnet";
+if (RAW_NETWORK !== "testnet" && RAW_NETWORK !== "public") {
+  throw new Error(
+    `Invalid NEXT_PUBLIC_STELLAR_NETWORK "${RAW_NETWORK}". Use "testnet" or "public".`
+  );
+}
+const NETWORK: "testnet" | "public" = RAW_NETWORK;
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/wallet/stellarAdapter.ts` around lines 38 - 42, Replace the unsafe cast
in the NETWORK configuration with explicit normalization and validation of
NEXT_PUBLIC_STELLAR_NETWORK. Accept only the supported testnet/public values,
preserve their existing passphrase and Horizon URL mappings, and fail fast with
a clear error for unknown values so invalid configuration cannot default to
testnet.

135-147: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Map Horizon submission failures to actionable messages.

server.submitTransaction and server.loadAccount have no timeout and no error translation. Two consequences:

  1. A missing or unfunded account makes loadAccount reject with a 404 error. The user sees a generic message instead of a funding hint.
  2. Horizon answers 504 when a submission is still pending. The current code treats that as a failure, although the transaction may still confirm.

Wrap the Horizon calls and surface the extras.result_codes detail, and add an explicit request timeout.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/wallet/stellarAdapter.ts` around lines 135 - 147, Update the Horizon
interactions in the adapter’s account-loading and transaction-submission flows
to use an explicit request timeout and catch failures. Translate 404
account-load errors into an actionable funding message, treat submission HTTP
504 responses as potentially pending rather than a definitive failure, and
include Horizon’s extras.result_codes details in other surfaced errors.
lib/user-session-sync.ts (1)

46-48: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

Validate the restored wallet fields.

parseState trusts the persisted JSON. Any value passes as walletChain, so the declared WalletChain type can be wrong at runtime. A non-string walletAddress also reaches shortenAddress in app/components/WalletConnectionIndicator.tsx, where .length and .slice would throw during render.

Narrow the values while parsing.

♻️ Proposed validation
+const WALLET_CHAINS: WalletChain[] = ['stellar', 'aztec'];
+const asString = (value: unknown): string | null =>
+  typeof value === 'string' && value.length > 0 ? value : null;
+
 const parseState = (value: string | null): SessionState | null => {
-      walletAddress: parsed.walletAddress ?? null,
-      walletName: parsed.walletName ?? null,
-      walletChain: parsed.walletChain ?? null,
+      walletAddress: asString(parsed.walletAddress),
+      walletName: asString(parsed.walletName),
+      walletChain: WALLET_CHAINS.includes(parsed.walletChain as WalletChain)
+        ? (parsed.walletChain as WalletChain)
+        : null,
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/user-session-sync.ts` around lines 46 - 48, Update parseState to validate
restored walletAddress, walletName, and walletChain values before assigning
them: retain only strings, and for walletChain additionally restrict values to
the supported WalletChain members; otherwise use null. Ensure walletAddress
cannot pass a non-string value to shortenAddress while preserving valid
persisted wallet data.
lib/wallet/aztecAdapter.ts (1)

14-14: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Import AztecAddress and Wallet from the narrower Aztec JS entry points.

At lib/wallet/aztecAdapter.ts:14 and lib/wallet/aztecAdapter.ts:49, importing from the package root pulls in the large @aztec/aztec.js entrypoint just for address validation and wallet provider access. Use @aztec/aztec.js/addresses for AztecAddress.fromString, and import Wallet from its specific entrypoint if available for your installed Aztec version.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/wallet/aztecAdapter.ts` at line 14, Update the imports in aztecAdapter.ts
to use narrower Aztec JS entry points: import AztecAddress from
`@aztec/aztec.js/addresses` for address validation, and import Wallet from its
version-appropriate specific entrypoint instead of the `@aztec/aztec.js` package
root. Preserve the existing AztecAddress.fromString and Wallet usage.
e2e/ticket-purchase.spec.ts (1)

49-55: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Cover the chain-specific wallet pickers.

This test stays on Stellar and only checks Freighter/Lobstr/WalletConnect. Add coverage for the other supported wallets: xBull on Stellar, and Azguard on Aztec. If chain selection gates the picker contents, switch to Aztec and assert the Aztec wallet option is available.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@e2e/ticket-purchase.spec.ts` around lines 49 - 55, Extend the wallet picker
coverage in the test around the existing walletModal assertions: verify xBull is
available for Stellar, then switch the selected chain to Aztec when picker
contents are chain-specific, reopen or inspect the picker, and assert that
Azguard is available there. Preserve the existing Freighter, Lobstr, and
WalletConnect checks.
app/api/transactions/[txHash]/status/route.ts (1)

33-43: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Cover the transaction-status handler in CI.

The component test replaces useTransactionStatus, so it does not execute the Horizon and simulation split. The V8 include list also omits app/api, so CI cannot expose zero coverage for this route.

  • app/api/transactions/[txHash]/status/route.ts#L33-L43: Add isolated handler tests for successful records, unsuccessful records, lookup errors, and non-Stellar hashes.
  • vitest.config.ts#L17-L21: Add app/api/**/*.{ts,tsx} to the V8 coverage include list.
Proposed coverage include
       include: [
         "app/components/explore/**/*.{ts,tsx}",
+        "app/api/**/*.{ts,tsx}",
         "lib/**/*.{ts,tsx}",
         "hooks/**/*.{ts,tsx}",
       ],
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/api/transactions/`[txHash]/status/route.ts around lines 33 - 43, Add
isolated handler tests for app/api/transactions/[txHash]/status/route.ts
covering successful records, unsuccessful records, Horizon lookup errors, and
non-Stellar hashes; update vitest.config.ts coverage includes to add
app/api/**/*.{ts,tsx} so the route is measured in CI.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/ci.yml:
- Line 14: Update both actions/checkout steps in .github/workflows/ci.yml at
lines 14-14 and 46-46 to set persist-credentials to false, preserving the
existing checkout behavior and avoiding credential persistence in PR-triggered
jobs.

In `@app/api/transactions/`[txHash]/status/route.ts:
- Around line 35-42: Update getRealTxStatus to use an explicit timeout for
Horizon reads, configuring Horizon.Config.setTimeout or reusing a shared
Horizon.Server backed by an HTTP-client timeout before
transactions().transaction(hash).call(). Preserve the existing confirmed,
failed, and pending status handling.

In `@app/components/organizer/ConnectWalletPrompt.tsx`:
- Around line 80-100: Complete the radiogroup keyboard interaction in the
CHAIN_OPTIONS map within ConnectWalletPrompt: implement roving tabIndex with
only the selected option at 0 and all others at -1, and handle ArrowLeft,
ArrowRight, ArrowUp, and ArrowDown to move selection and focus between options
with wraparound. Preserve the existing click selection and loading-state
behavior.

In `@e2e/ticket-purchase.spec.ts`:
- Around line 20-23: Update the wallet mock’s signTransaction flow in the e2e
ticket purchase setup so it bypasses or mocks the getKit().signTransaction(),
TransactionBuilder.fromXDR(), and Horizon submission boundary. Return a valid
synthetic signedPayload/txHash combination, ensuring the purchase reaches the
/api/transactions/*/status route without attempting to parse the placeholder
XDR.

In `@lib/wallet/aztecAdapter.ts`:
- Around line 71-76: Validate the result from provider.request in the
transaction flow before returning from the adapter method containing
send_transaction. Reject the response when txHash is missing or not a valid
string, ensuring the malformed response throws a wallet error instead of
returning undefined; preserve the existing successful return shape for valid
responses.

In `@lib/wallet/stellarAdapter.ts`:
- Around line 1-14: Update the documentation comment above the Stellar wallet
adapter to list only the wallet modules registered by buildModules(): Freighter,
Lobstr, xBull, and WalletConnect. Remove Albedo, Rabet, and Hana from the
comment unless buildModules() is also updated to register them.

In `@playwright.config.ts`:
- Line 12: Update the reporter configuration in Playwright’s config so CI runs
both the GitHub reporter and the HTML reporter, preserving the existing
HTML-only behavior outside CI and ensuring the playwright-report directory is
generated during CI runs.

---

Nitpick comments:
In `@app/api/transactions/`[txHash]/status/route.ts:
- Around line 33-43: Add isolated handler tests for
app/api/transactions/[txHash]/status/route.ts covering successful records,
unsuccessful records, Horizon lookup errors, and non-Stellar hashes; update
vitest.config.ts coverage includes to add app/api/**/*.{ts,tsx} so the route is
measured in CI.

In `@e2e/ticket-purchase.spec.ts`:
- Around line 49-55: Extend the wallet picker coverage in the test around the
existing walletModal assertions: verify xBull is available for Stellar, then
switch the selected chain to Aztec when picker contents are chain-specific,
reopen or inspect the picker, and assert that Azguard is available there.
Preserve the existing Freighter, Lobstr, and WalletConnect checks.

In `@lib/user-session-sync.ts`:
- Around line 46-48: Update parseState to validate restored walletAddress,
walletName, and walletChain values before assigning them: retain only strings,
and for walletChain additionally restrict values to the supported WalletChain
members; otherwise use null. Ensure walletAddress cannot pass a non-string value
to shortenAddress while preserving valid persisted wallet data.

In `@lib/wallet/aztecAdapter.ts`:
- Line 14: Update the imports in aztecAdapter.ts to use narrower Aztec JS entry
points: import AztecAddress from `@aztec/aztec.js/addresses` for address
validation, and import Wallet from its version-appropriate specific entrypoint
instead of the `@aztec/aztec.js` package root. Preserve the existing
AztecAddress.fromString and Wallet usage.

In `@lib/wallet/stellarAdapter.ts`:
- Around line 38-42: Replace the unsafe cast in the NETWORK configuration with
explicit normalization and validation of NEXT_PUBLIC_STELLAR_NETWORK. Accept
only the supported testnet/public values, preserve their existing passphrase and
Horizon URL mappings, and fail fast with a clear error for unknown values so
invalid configuration cannot default to testnet.
- Around line 135-147: Update the Horizon interactions in the adapter’s
account-loading and transaction-submission flows to use an explicit request
timeout and catch failures. Translate 404 account-load errors into an actionable
funding message, treat submission HTTP 504 responses as potentially pending
rather than a definitive failure, and include Horizon’s extras.result_codes
details in other surfaced errors.

In `@lib/walletSdk.ts`:
- Around line 101-106: Remove the duplicated cache cleanup from
preloadWalletSDK. In the current.catch handler, retain only rejection swallowing
and rely on getOrLoadAdapter for deleting the adapterLoadPromises entry;
preserve the preload behavior and avoid introducing additional error handling.
- Around line 71-77: Update loadWalletSDK to cache in-flight adapter.connect()
promises keyed by chain, reusing the existing module-load caching pattern.
Before connecting, check the per-chain cache; store the promise when starting a
connection and clear it after completion so later calls observe the connected
adapter without duplicate wallet prompts.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: e713612a-d44e-4c02-a772-3a9d9721b16d

📥 Commits

Reviewing files that changed from the base of the PR and between a612e82 and dfccd53.

📒 Files selected for processing (19)
  • .env.example
  • .github/workflows/ci.yml
  • .gitignore
  • app/api/transactions/[txHash]/status/route.ts
  • app/components/WalletConnectionIndicator.tsx
  • app/components/explore/EventCheckout/TicketInfo.test.tsx
  • app/components/explore/EventCheckout/TicketInfo.tsx
  • app/components/explore/MainContent.test.tsx
  • app/components/organizer/ConnectWalletPrompt.tsx
  • e2e/ticket-purchase.spec.ts
  • lib/user-session-sync.ts
  • lib/wallet/aztecAdapter.ts
  • lib/wallet/stellarAdapter.ts
  • lib/wallet/types.ts
  • lib/walletSdk.ts
  • package.json
  • playwright.config.ts
  • vitest.config.ts
  • vitest.setup.ts

Comment thread .github/workflows/ci.yml
name: Lint & unit tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

rg -n -C 3 'actions/checkout@v4|persist-credentials|run: npm' .github/workflows/ci.yml
jq '.scripts' package.json

Repository: BuidlZone-Labs/zicket-web

Length of output: 1402


🌐 Web query:

actions/checkout v4 README default persist-credentials true README.md

💡 Result:

In the actions/checkout action version 4 (v4), the default value for the persist-credentials input is true [1][2][3]. When set to true (the default), the action configures the authentication token or SSH key in the local git configuration [1][2]. This allows subsequent steps in the same GitHub Actions job to execute authenticated git commands [1][4]. The token is automatically removed during the post-job cleanup [1]. To opt out of this behavior and prevent the credentials from being persisted in the local git configuration, you must explicitly set persist-credentials to false in your workflow file [1][4][5]: - name: Checkout code uses: actions/checkout@v4 with: persist-credentials: false While there has been ongoing community discussion and requests to change this default to false to improve security posture [6][5][7], as of August 2026, the default remains true [2][3].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

cat -n .github/workflows/ci.yml | sed -n '1,80p'

Repository: BuidlZone-Labs/zicket-web

Length of output: 2062


🌐 Web query:

GitHub Actions pull_request token contents permissions default read contents

💡 Result:

In GitHub Actions, the GITHUB_TOKEN used in workflows is subject to specific permission rules depending on the workflow trigger and the repository configuration [1][2]. When a workflow is triggered by a pull request from a forked repository, the GITHUB_TOKEN is automatically restricted to read-only access for all scopes [1][2]. This is a security measure to prevent unauthorized write operations from external contributors [2]. This restriction applies to all pull request-related events (such as pull_request or pull_request_review), except for the pull_request_target event [3]. Beyond this automatic restriction, the default permissions for the GITHUB_TOKEN in your repository are determined by your organization or repository settings [1]. Administrators can configure these to be either: - Permissive: Grants read/write access to most scopes [1][2]. - Restricted: Limits permissions (typically defaulting to read access for contents) [1][2]. You can explicitly override these defaults by using the permissions key within your workflow file or at the job level [1][4]. If you do not define specific permissions, the token will inherit the default settings configured for the repository or organization [1]. Even if you specify higher permissions, they will still be downgraded to read-only when the workflow is triggered by a pull request from a fork, unless the pull_request_target event is used [2][3].

Citations:


Sensitive Data Exposure (CWE-522): Insufficiently Protected Credentials

Reachability: External

Do not persist checkout credentials in PR-triggered CI.

actions/checkout@v4 defaults persist-credentials to true, leaving the workflow token available to npm scripts in the current job. These PR workflows install and execute PR-controlled code, so set persist-credentials: false unless authenticated Git operations are needed afterward.

Proposed fix
       - uses: actions/checkout@v4
+        with:
+          persist-credentials: false
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- uses: actions/checkout@v4
- uses: actions/checkout@v4
with:
persist-credentials: false
🧰 Tools
🪛 zizmor (1.28.0)

[warning] 14-14: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false

(artipacked)

📍 Affects 1 file
  • .github/workflows/ci.yml#L14-L14 (this comment)
  • .github/workflows/ci.yml#L46-L46
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/ci.yml at line 14, Update both actions/checkout steps in
.github/workflows/ci.yml at lines 14-14 and 46-46 to set persist-credentials to
false, preserving the existing checkout behavior and avoiding credential
persistence in PR-triggered jobs.

Source: Linters/SAST tools

Comment on lines +35 to +42
const record = await getHorizonServer().transactions().transaction(hash).call();
return record.successful
? { status: "confirmed" }
: { status: "failed", error: "Transaction failed on-chain." };
} catch (err) {
// Horizon 404s until the transaction lands in a ledger — treat that (and
// any transient network error) as still pending rather than failed.
return { status: "pending", error: err instanceof Error ? err.message : undefined };

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Expect a finite timeout that reaches the SDK HTTP client before Horizon calls.
rg -nP -C 4 --glob '*.{ts,tsx,js,mjs,cjs}' \
  '(?:Horizon\.AxiosClient|AxiosClient\.defaults\.timeout|\.defaults\.timeout\s*=|new\s+Horizon\.Server|\.transactions\(\)\.transaction\([^)]*\)\.call\(\))' .

Repository: BuidlZone-Labs/zicket-web

Length of output: 2192


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== package files =="
git ls-files | rg '(^|/)(package(-lock)?\.json|pnpm-lock\.yaml|yarn\.lock)$' || true

echo
echo "== stellar-sdk versions =="
python3 - <<'PY'
import json, pathlib
for p in pathlib.Path('.').glob('**/package-lock.json'):
    if '.next' in p.parts or 'node_modules' in p.parts:
        continue
    data=json.loads(p.read_text())
    deps=data.get('packages',{})
    for name in ['stellar-sdk','`@stellar/stellar-sdk`']:
        if name in deps:
            print(p)
            print(deps[name].get('version'))

for p in pathlib.Path('.').glob('**/package.json'):
    if '.next' in p.parts or 'node_modules' in p.parts:
        continue
    data=json.loads(p.read_text())
    for key in ('dependencies','devDependencies','peerDependencies'):
        deps=data.get(key,{})
        for name in ["stellar-sdk","`@stellar/stellar-sdk`","axios"]:
            if name in deps:
                print(f"{p}:{key}:{name}={deps[name]}")
PY

echo
echo "== stellar adapter relevant section =="
cat -n lib/wallet/stellarAdapter.ts | sed -n '1,120p'

echo
echo "== api status route relevant section =="
cat -n 'app/api/transactions/[txHash]/status/route.ts' | sed -n '1,120p'

echo
echo "== timeout / axios / Horizon imports/usages broad =="
rg -n --glob '*.{ts,tsx,js,mjs,cjs}' 'axios|AxiosClient|new Horizon\.Server|Horizon\.Server|\.call\(\)|timeout|AbortController|fetch\(' .

Repository: BuidlZone-Labs/zicket-web

Length of output: 9967


🌐 Web query:

@stellar/stellar-sdk 13.1.0 horizon CallBuilder call request options timeout source

💡 Result:

In @stellar/stellar-sdk 13.1.0, the CallBuilder does not support passing a per-request timeout directly through the call() method [1][2]. Instead, request timeouts are managed globally through the Config object [3][4]. You can set a global timeout (in milliseconds) that applies to all HTTP requests made by the SDK [3][4]. To set this globally: import { Config } from '@stellar/stellar-sdk'; Config.setTimeout(5000); // Sets the global timeout to 5000ms (5 seconds) If you are using the stream() method, there is a specific reconnectTimeout option available within the options object, which defaults to 15 seconds [5][1][2]. This is distinct from the HTTP request timeout and applies specifically to the EventSource stream connection [1][2]. Note that for transaction-specific operations, the SDK may handle retries and time bounds independently [6]. As of version 13.1.0, the default timeout for transaction calls was increased to 300 seconds [6].

Citations:


Set an explicit horizon read timeout.

getRealTxStatus calls Horizon without a deadline; this route has no local timeout and @stellar/stellar-sdk v13.1.0 does not pass per-request options through CallBuilder.call(). Call Horizon.Config.setTimeout(...) or create a shared Horizon.Server with an HTTP-client timeout so stalled Horizon reads do not keep the API request open indefinitely.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/api/transactions/`[txHash]/status/route.ts around lines 35 - 42, Update
getRealTxStatus to use an explicit timeout for Horizon reads, configuring
Horizon.Config.setTimeout or reusing a shared Horizon.Server backed by an
HTTP-client timeout before transactions().transaction(hash).call(). Preserve the
existing confirmed, failed, and pending status handling.

Comment on lines +80 to +100
{!walletConnected && (
<div className="flex gap-2" role="radiogroup" aria-label="Wallet network">
{CHAIN_OPTIONS.map((option) => (
<button
key={option.id}
type="button"
role="radio"
aria-checked={chain === option.id}
onClick={() => setChain(option.id)}
disabled={walletState.isLoading}
className={`px-4 py-1.5 rounded-full text-sm font-medium border transition disabled:opacity-60 disabled:cursor-not-allowed ${
chain === option.id
? "bg-[#6917AF] text-white border-[#6917AF]"
: "bg-white text-[#475467] border-[#E3E3E3] hover:border-[#6917AF]"
}`}
>
{option.label}
</button>
))}
</div>
)}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Complete the radiogroup keyboard pattern.

The buttons declare role="radio" inside a role="radiogroup", but the group has no arrow-key navigation and every option stays in the tab order. Assistive-technology users are told this is a radio group, then get button-style keyboard behavior.

Choose one of two options:

  1. Add a roving tabIndex (0 for the selected option, -1 for the others) and handle ArrowLeft/ArrowRight/ArrowUp/ArrowDown.
  2. Drop the ARIA roles and use native <input type="radio"> elements inside a <fieldset> with a <legend>.
♻️ Option 1: roving tabindex and arrow keys
             {CHAIN_OPTIONS.map((option) => (
               <button
                 key={option.id}
                 type="button"
                 role="radio"
                 aria-checked={chain === option.id}
+                tabIndex={chain === option.id ? 0 : -1}
                 onClick={() => setChain(option.id)}
+                onKeyDown={(event) => {
+                  if (!["ArrowLeft", "ArrowUp", "ArrowRight", "ArrowDown"].includes(event.key))
+                    return;
+                  event.preventDefault();
+                  const step = event.key === "ArrowLeft" || event.key === "ArrowUp" ? -1 : 1;
+                  const index = CHAIN_OPTIONS.findIndex((o) => o.id === chain);
+                  const next =
+                    CHAIN_OPTIONS[(index + step + CHAIN_OPTIONS.length) % CHAIN_OPTIONS.length];
+                  setChain(next.id);
+                }}
                 disabled={walletState.isLoading}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/components/organizer/ConnectWalletPrompt.tsx` around lines 80 - 100,
Complete the radiogroup keyboard interaction in the CHAIN_OPTIONS map within
ConnectWalletPrompt: implement roving tabIndex with only the selected option at
0 and all others at -1, and handle ArrowLeft, ArrowRight, ArrowUp, and ArrowDown
to move selection and focus between options with wraparound. Preserve the
existing click selection and loading-state behavior.

Comment on lines +20 to +23
requestAccess: async () => ({ address: "GATESTPUBLICKEYFORE2ETESTINGXXXXXXXXXXXXXXXXXXXXXXXXXX" }),
getAddress: async () => ({ address: "GATESTPUBLICKEYFORE2ETESTINGXXXXXXXXXXXXXXXXXXXXXXXXXX" }),
getNetwork: async () => ({ network: "TESTNET", networkPassphrase: "Test SDF Network ; September 2015" }),
signTransaction: async () => ({ signedTxXdr: "AAAAAgAAAABE2ETESTSIGNEDXDR", signerAddress: "GATESTPUBLICKEYFORE2ETESTINGXXXXXXXXXXXXXXXXXXXXXXXXXX" }),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

ast-grep outline lib/wallet/stellarAdapter.ts --items all
rg -n -C 5 --glob '*.ts' --glob '*.tsx' \
  'signedTxXdr|submitTransaction|/transactions|fromXDR|TransactionEnvelope' \
  lib/wallet app e2e

Repository: BuidlZone-Labs/zicket-web

Length of output: 4379


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '--- stellarAdapter outline ---\n'
ast-grep outline lib/wallet/stellarAdapter.ts --view expanded || true

printf '\n--- stellarAdapter relevant sections ---\n'
cat -n lib/wallet/stellarAdapter.ts | sed -n '1,220p'

printf '\n--- ticket purchase spec relevant sections ---\n'
cat -n e2e/ticket-purchase.spec.ts | sed -n '1,120p'

printf '\n--- stellar transaction status/fetch usages ---\n'
rg -n -C 4 'status|fetch|transactions' e2e lib app --glob '*.ts' --glob '*.tsx' | head -n 240

printf '\n--- package deps stellar-sdk/axios/fetch ---\n'
if [ -f package.json ]; then jq '.dependencies, .devDependencies' package.json; fi

Repository: BuidlZone-Labs/zicket-web

Length of output: 254


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '--- stellarAdapter outline ---'
ast-grep outline lib/wallet/stellarAdapter.ts --view expanded || true

echo
echo '--- stellarAdapter relevant sections ---'
cat -n lib/wallet/stellarAdapter.ts | sed -n '1,220p'

echo
echo '--- ticket purchase spec relevant sections ---'
cat -n e2e/ticket-purchase.spec.ts | sed -n '1,120p'

echo
echo '--- stellar transaction status/fetch usages ---'
rg -n -C 4 'status|fetch|transactions' e2e lib app --glob '*.ts' --glob '*.tsx' | head -n 240

echo
echo '--- package deps stellar-sdk/axios/fetch ---'
if [ -f package.json ]; then jq '.dependencies, .devDependencies' package.json; fi

Repository: BuidlZone-Labs/zicket-web

Length of output: 30284


Mock the end-to-end Stellar submission boundary.

signTransaction() now calls getKit().signTransaction(), then parses the returned XDR with TransactionBuilder.fromXDR(), then sends it through Horizon. Returning "AAAAAgAAAABE2ETESTSIGNEDXDR" cannot parse as a signed TransactionEnvelope, so the purchase can fail before the /api/transactions/*/status route is reached. Mock the adapter or Horizon submission path, and return a valid synthetic signedPayload/txHash.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@e2e/ticket-purchase.spec.ts` around lines 20 - 23, Update the wallet mock’s
signTransaction flow in the e2e ticket purchase setup so it bypasses or mocks
the getKit().signTransaction(), TransactionBuilder.fromXDR(), and Horizon
submission boundary. Return a valid synthetic signedPayload/txHash combination,
ensuring the purchase reaches the /api/transactions/*/status route without
attempting to parse the placeholder XDR.

Comment on lines +71 to +76
const result = await provider.request<{ txHash: string }>({
method: "send_transaction",
params: [payload ?? { memo: "zicket-ticket" }],
});

return { txHash: result.txHash, signedPayload: payload ?? "" };

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Validate the provider response before returning txHash.

provider.request is typed as { txHash: string }, but the injected provider returns unchecked data. If the response omits txHash, this adapter returns undefined as the hash. lib/walletSdk.ts then resolves successfully, and TicketInfo.runPurchase calls startTracking(undefined). The purchase UI stays in a pending state and the catch branch never runs.

Reject a malformed response here so the failure surfaces as a wallet error.

🐛 Proposed fix to validate the response
-    const result = await provider.request<{ txHash: string }>({
+    const result = await provider.request<{ txHash?: unknown }>({
       method: "send_transaction",
       params: [payload ?? { memo: "zicket-ticket" }],
     });
 
-    return { txHash: result.txHash, signedPayload: payload ?? "" };
+    if (typeof result?.txHash !== "string" || result.txHash.length === 0) {
+      throw new Error("Azguard did not return a transaction hash.");
+    }
+
+    return { txHash: result.txHash, signedPayload: payload ?? "" };
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const result = await provider.request<{ txHash: string }>({
method: "send_transaction",
params: [payload ?? { memo: "zicket-ticket" }],
});
return { txHash: result.txHash, signedPayload: payload ?? "" };
const result = await provider.request<{ txHash?: unknown }>({
method: "send_transaction",
params: [payload ?? { memo: "zicket-ticket" }],
});
if (typeof result?.txHash !== "string" || result.txHash.length === 0) {
throw new Error("Azguard did not return a transaction hash.");
}
return { txHash: result.txHash, signedPayload: payload ?? "" };
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/wallet/aztecAdapter.ts` around lines 71 - 76, Validate the result from
provider.request in the transaction flow before returning from the adapter
method containing send_transaction. Reject the response when txHash is missing
or not a valid string, ensuring the malformed response throws a wallet error
instead of returning undefined; preserve the existing successful return shape
for valid responses.

Comment on lines +1 to +14
/**
* Stellar wallet adapter — connects real browser wallets (Freighter, Lobstr,
* WalletConnect, xBull, Albedo, Rabet, Hana) through `@creit.tech/stellar-wallets-kit`,
* which owns wallet discovery/selection and delegates signing to whichever
* wallet the user picks. This replaces the old `mock_tx_...` random string
* generator with a real signed transaction submitted to Horizon.
*
* NOTE: There is no organizer payout address in the data model yet, so the
* default (no-argument) `signTransaction()` call signs a minimal self-payment
* (1 stroop, memo "zicket-ticket") purely to produce a real, verifiable
* on-chain transaction for the checkout flow. Once ticket purchases have a
* real destination (organizer wallet + priced asset), build that XDR
* server-side and pass it into `signTransaction(xdr)` instead.
*/

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Correct the wallet list in the doc comment.

The comment names Albedo, Rabet, and Hana. buildModules() registers only Freighter, Lobstr, xBull, and WalletConnect. Either register the extra modules or remove them from the comment.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/wallet/stellarAdapter.ts` around lines 1 - 14, Update the documentation
comment above the Stellar wallet adapter to list only the wallet modules
registered by buildModules(): Freighter, Lobstr, xBull, and WalletConnect.
Remove Albedo, Rabet, and Hana from the comment unless buildModules() is also
updated to register them.

Comment thread playwright.config.ts
forbidOnly: !!process.env.CI,
retries: process.env.CI ? 2 : 0,
workers: process.env.CI ? 1 : undefined,
reporter: process.env.CI ? "github" : "html",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🌐 Web query:

For @playwright/testversion 1.49.1, verify that a reporter array containinggithubandhtmlpreserves GitHub annotations and creates the defaultplaywright-report folder.

💡 Result:

In @playwright/test version 1.49.1, using a reporter array containing both 'github' and 'html' is fully supported and does not interfere with the functionality of either reporter [1][2]. 1. GitHub Annotations: Including 'github' in the reporter array ensures that Playwright generates automatic failure annotations when running in GitHub Actions [3][1]. This functionality operates independently of other reporters, meaning the 'html' reporter will continue to generate its report alongside these annotations [1][4]. 2. Default HTML Folder: The 'html' reporter will continue to create the default 'playwright-report' folder during the test run [5][1]. By default, Playwright overwrites the contents of this directory on each run [6]. If you need to change this behavior, you can specify a custom directory using the outputFolder option in the reporter configuration: reporter: [ ['github'], ['html', { outputFolder: 'playwright-report' }] ] Note that when using TypeScript, you may need to explicitly type the reporter array as ReporterDescription[] to avoid validation errors, as shown below [7]: import { ReporterDescription } from '@playwright/test'; export default { reporter: [ ['github'], ['html'] ] as ReporterDescription[] };

Citations:


Emit the CI-uploaded reporter alongside GitHub annotations.

In CI, only the GitHub reporter runs, so the uploaded playwright-report directory is not generated by the configured Playwright run. Keep the GitHub reporter and add the HTML reporter for CI output.

Proposed fix
-  reporter: process.env.CI ? "github" : "html",
+  reporter: process.env.CI
+    ? [["github"], ["html", { open: "never" }]]
+    : "html",
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
reporter: process.env.CI ? "github" : "html",
reporter: process.env.CI
? [["github"], ["html", { open: "never" }]]
: "html",
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@playwright.config.ts` at line 12, Update the reporter configuration in
Playwright’s config so CI runs both the GitHub reporter and the HTML reporter,
preserving the existing HTML-only behavior outside CI and ensuring the
playwright-report directory is generated during CI runs.

@DioChuks
DioChuks self-requested a review August 4, 2026 17:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Native Stellar & Aztec Web3 Wallet Adapter Integration Establish Comprehensive Test Suite (Jest / Vitest & Cypress / Playwright)

1 participant