Skip to content

Conversation

@akaladarshi
Copy link
Contributor

@akaladarshi akaladarshi commented Oct 1, 2025

Summary of changes

Changes introduced in this pull request:

  • Add k6 script to test the claim_token API

Reference issue to close (if applicable)

Closes #319

Other information and links

Change checklist

  • I have performed a self-review of my own code,
  • I have made corresponding changes to the documentation. All new code
    adheres to the team's
    documentation standards,
  • I have added tests that prove my fix is effective or that my feature works
    (if possible),
  • I have made sure the CHANGELOG is up-to-date. All user-facing changes
    should be reflected in this document.

Summary by CodeRabbit

  • Tests
    • Added new E2E API suite covering input validation, rate-limiting, wallet-cap scenarios, transaction-hash validation, connectivity checks, and environment-configurable API target.
    • Added new E2E CORS suite validating preflight, cross-origin and same-origin GETs, multiple origins, security headers, and CORS presence on error responses.
  • Chores
    • CI E2E rebuilt as a matrix (Browser/API/CORS) with caching, improved tooling, per-run isolated local servers, and readiness checks.
  • Documentation
    • Added comprehensive E2E API testing guide and CORS testing guide with scenarios and run instructions.

@akaladarshi akaladarshi requested a review from a team as a code owner October 1, 2025 10:43
@akaladarshi akaladarshi requested review from Copilot, elmattic and sudo-shashank and removed request for Copilot October 1, 2025 10:43
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 1, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

Adds a matrix-driven GitHub Actions E2E workflow that launches isolated Durable Object servers per matrix entry, adds k6 API and CORS E2E tests with configs, makes E2E BASE_URL configurable via env, and introduces documentation for API and CORS E2E testing.

Changes

Cohort / File(s) Summary
Workflow: matrix-driven e2e & cache/tooling changes
.github/workflows/e2e.yml
Adds a matrix strategy (Browser / API / CORS) with per-entry script, port, state_dir, k6_browser_enabled; restores Cargo/npm caches; installs wasm-opt; updates worker-build flags; launches per-entry wrangler dev with isolated state dirs; performs port and HTTP readiness checks; runs k6 with API_URL bound to matrix port.
E2E test: claim_token API tests (k6)
e2e/test_claim_token_api.js
New k6 test module exporting options and default function; adds helpers (validateTransactionHash, makeClaimRequest, runTestScenarios); implements connectivity, input-validation, rate-limiting (cooldown), and wallet-cap test suites with assertions and pacing.
E2E config: claim_token test constants & scenarios
e2e/test_claim_token_api_config.js
New config module exporting API_CONFIG, TEST_ADDRESSES, FaucetTypes, STATUS_CODES, and TEST_SCENARIOS (invalid requests, cooldown/rate-limit cases, wallet-cap scenarios, invalid addresses).
E2E test: CORS validation (k6)
e2e/test_cors.js
New k6 CORS test exporting options and default function; verifies preflight OPTIONS and cross-origin GET behavior, multiple-origin scenarios, same-origin checks, security/edge-case checks, and asserts Access-Control-* headers (including on error responses).
E2E runtime: configurable base URL
e2e/script.js
Replaces fixed BASE_URL with environment-driven __ENV.API_URL fallback (http://127.0.0.1:8787) so CI can target per-matrix ports.
Docs: E2E API testing guide
docs/e2e_api_testing_guide.md
New guide describing Durable Objects, address types, Browser vs API tests, matrix isolation, API test flow (connectivity, input validation, cooldowns, wallet-cap), helper functions, and references to test config.
Docs: CORS testing guide
docs/cors_testing_guide.md
New guide covering CORS concepts, CI matrix approach, preflight & actual-request checks, multiple-origin scenarios, expected results, troubleshooting, and local run instructions for /api/claim_token.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor GH as GitHub Actions
  participant Runner as Job Runner
  participant Cache as Cache Restore
  participant Tools as Tooling Install
  participant Wrangler as wrangler dev (DO)
  participant Readiness as Port/HTTP Checks
  participant K6 as k6 Runner
  participant API as /api/claim_token

  GH->>Runner: start matrix entry (Browser / API / CORS)
  Runner->>Cache: restore cargo/npm caches
  Runner->>Tools: install wasm-opt & toolchain
  Runner->>Wrangler: wrangler dev --port matrix.port --state-dir matrix.state_dir
  Wrangler->>Readiness: bind/listen on matrix.port
  Readiness-->>Runner: port + HTTP ready
  Runner->>K6: run matrix.script (API_URL=http://127.0.0.1:matrix.port)
  K6->>API: OPTIONS/GET /api/claim_token?... (connectivity / CORS / validation)
  alt success (200)
    API-->>K6: 200 + tx hash
  else limited / mainnet / error
    API-->>K6: 429 / 418 / 4xx/5xx (with CORS headers)
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • elmattic
  • hanabi1224
  • LesnyRumcajs

Poem

I nibble logs and hop around the tree,
matrix jobs sprout states for me.
k6 flutters tests through day and night,
CORS and tx hashes twinkle bright.
🐇 Hop, run, assert — CI passes light.

Pre-merge checks and finishing touches

❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Linked Issues Check ⚠️ Warning Issue #319 explicitly requires comprehensive automated tests including unit tests for functions like parse_and_validate_address, handle_native_claim, and handle_erc20_claim in the Rust codebase (src/faucet/server_api.rs), along with integration/endpoint tests for specific scenarios (Mainnet branch, rate limiting, CalibnetFIL/USDC success paths). The PR provides E2E tests using k6 that validate API endpoint behavior (invalid addresses, rate limiting, wallet caps), but does not include the Rust unit tests for internal functions that were explicitly required. While the E2E tests partially address some requirements by validating endpoint behavior, they do not fulfill the specific unit test requirements outlined in the issue for internal logic validation. To fully satisfy issue #319, the PR should include Rust unit tests in src/faucet/server_api.rs for the functions mentioned in the issue: parse_and_validate_address, handle_native_claim, and handle_erc20_claim. These tests should validate the specific scenarios outlined (invalid address formats returning 400, valid addresses across networks, success paths with proper transaction IDs). The existing E2E tests provide valuable endpoint-level validation but do not substitute for unit tests of internal business logic.
Out of Scope Changes Check ⚠️ Warning Consider moving the CORS testing components (e2e/test_cors.js and docs/cors_testing_guide.md) to a separate PR or clarify their necessity as part of the claim token API testing scope. Alternatively, if CORS testing is intended as part of this work, update the PR description and linked issue to reflect this expanded scope so reviewers understand the intentional inclusion of these supplementary tests.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The pull request title "tests(api) add script to test the claim token api" is clear, concise, and directly related to the primary objective of the changeset. It accurately summarizes the main contribution: adding E2E test scripts for the claim token API. The title uses conventional commit formatting and communicates the key change without unnecessary verbosity or vague language.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch akaladarshi/claim-token-api-tests

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 01bf0d8 and 836fb69.

📒 Files selected for processing (1)
  • .github/workflows/e2e.yml (5 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: codedov
  • GitHub Check: lint
  • GitHub Check: E2E API Tests
  • GitHub Check: E2E Claim Token API CORS Tests
  • GitHub Check: E2E Browser Tests
  • GitHub Check: deploy
🔇 Additional comments (7)
.github/workflows/e2e.yml (7)

27-46: Matrix strategy is well-structured for multi-variant E2E testing.

The matrix-driven approach enables parallel execution of distinct test suites (browser, API, CORS) with isolated configurations. Using unique state_dir entries with github.run_id ensures proper Durable Object storage isolation.


58-71: Cache configuration provides good dependency isolation.

Caching Cargo and npm artifacts keyed by lockfiles is a sound practice. The restoration of multiple cache directories minimizes redundant builds across matrix variants.


83-83: Verify necessity of --force flag for worker-build installation.

The --force flag on Line 83 forces reinstallation even if worker-build is already cached. Confirm whether this is intentional—it may bypass cache benefits and increase CI runtime. If the intent is to guarantee a fresh build per matrix variant, consider documenting this rationale.


88-88: k6 browser enablement is correctly controlled per variant.

Using matrix.k6_browser_enabled appropriately disables browser automation for non-browser test variants (API and CORS tests), reducing overhead and startup time.


97-116: Wrangler dev orchestration includes robust readiness checks.

The two-stage readiness strategy—TCP port check followed by HTTP server validation—ensures the server is fully initialized before tests begin. The 120-second timeout and 5-second retry cadence are reasonable for account for cold starts and slow builds.

One minor observation: the background process (&) will persist for the job lifetime. Ensure cleanup happens implicitly via job teardown, or consider explicit termination before job completion.


118-123: ✓ Test execution is parameterized correctly.

All referenced test scripts (e2e/test_claim_token_api.js, e2e/test_cors.js, e2e/script.js) are present and correctly consume the API_URL environment variable. The parameterization works as intended:

  • test_claim_token_api.js and script.js reference __ENV.API_URL with appropriate fallback values
  • test_cors.js also properly consumes __ENV.API_URL
  • All scripts include sensible defaults, ensuring connectivity is handled appropriately

1-123: Test coverage for issue #319 requirements is comprehensive.

The workflow correctly implements all required test scenarios:

  • Input validation tests verify proper 400 BAD_REQUEST rejection for invalid addresses
  • Rate limiting tests verify 429 TOO_MANY_REQUESTS response with retry timing validation
  • Mainnet routing rejection is tested via "MainnetFIL request (should be blocked)" scenario returning 418 IM_A_TEAPOT
  • CalibnetFIL and CalibnetUSDFC success paths are tested in the API test script
  • CORS tests validate proper header handling across origins and error responses

All required test coverage is in place.


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

@akaladarshi akaladarshi marked this pull request as draft October 1, 2025 10:43
@codecov-commenter
Copy link

codecov-commenter commented Oct 1, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 38.75%. Comparing base (f092eaa) to head (836fb69).

Additional details and impacted files
@@           Coverage Diff           @@
##             main     #320   +/-   ##
=======================================
  Coverage   38.75%   38.75%           
=======================================
  Files          40       40           
  Lines        2578     2578           
=======================================
  Hits          999      999           
  Misses       1579     1579           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (2)
e2e/test_claim_token_api.js (2)

12-21: Consider adding threshold for error rate metric.

The errorRate metric is tracked but has no threshold defined. Consider adding a threshold like 'errors': ['rate<0.1'] to fail the test if error rate exceeds 10%.

Apply this diff:

 export const options = {
   vus: 1,
   iterations: 1,
   thresholds: {
     'http_req_duration': ['p(95)<5000'],
+    'errors': ['rate<0.1'],
   },
 };

23-30: Enhance Filecoin transaction hash validation.

The Filecoin validation only checks length (46-70 characters) but doesn't verify the format. Filecoin CIDs typically start with bafy for base32-encoded multihash. Consider adding a prefix check for stronger validation.

Apply this diff:

 function validateTransactionHash(txHash, expectedFormat) {
   if (expectedFormat === 'ethereum') {
     return txHash.startsWith('0x') && txHash.length === 66;
   } else if (expectedFormat === 'filecoin') {
-    return txHash.length >= 46 && txHash.length <= 70;
+    return txHash.startsWith('bafy') && txHash.length >= 46 && txHash.length <= 70;
   }
   return false;
 }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2c81243 and 08faae4.

📒 Files selected for processing (3)
  • .github/workflows/e2e.yml (1 hunks)
  • e2e/test_claim_token_api.js (1 hunks)
  • e2e/test_claim_token_api_config.js (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
e2e/test_claim_token_api.js (1)
e2e/test_claim_token_api_config.js (10)
  • API_CONFIG (2-10)
  • API_CONFIG (2-10)
  • FaucetTypes (34-39)
  • FaucetTypes (34-39)
  • TEST_ADDRESSES (12-32)
  • TEST_ADDRESSES (12-32)
  • STATUS_CODES (41-47)
  • STATUS_CODES (41-47)
  • TEST_SCENARIOS (50-194)
  • TEST_SCENARIOS (50-194)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: codedov
  • GitHub Check: lint
  • GitHub Check: e2e
  • GitHub Check: deploy
🔇 Additional comments (9)
.github/workflows/e2e.yml (1)

81-84: LGTM!

The new workflow step correctly integrates the claim_token API tests into the CI pipeline using the same pattern as the existing k6 step.

e2e/test_claim_token_api_config.js (4)

34-47: LGTM!

Faucet types and status codes are well-defined and align with the API requirements from issue #319.


99-193: Excellent rate-limiting test coverage.

The test scenarios comprehensively cover rate limiting across different faucet types, address formats, and address equivalence (ETH ↔ t410). This aligns well with the requirements in issue #319.


54-74: Tests are correct: missing parameters yield 500 The GetUrl extractor fails on absent query fields and surfaces them as INTERNAL_SERVER_ERROR, so keeping the tests’ expectations at 500 is accurate.


15-16: ETH_FORMAT_ADDRESS and T410_ADDRESS correctly correspond. No change required.

e2e/test_claim_token_api.js (4)

32-52: LGTM!

The request helper properly handles optional parameters, applies URL encoding, and configures timeouts and tags appropriately.


54-85: LGTM!

Input validation tests comprehensively cover invalid addresses and malformed requests, addressing the requirements from issue #319 for testing parse_and_validate_address behavior.


87-114: LGTM!

Rate limiting tests thoroughly validate the 429 response requirement from issue #319, including transaction hash format verification for successful claims and proper handling of address equivalence.


116-119: LGTM!

Test orchestration is clean and runs validation tests before rate limiting tests in a logical sequence.

@akaladarshi akaladarshi force-pushed the akaladarshi/claim-token-api-tests branch from 08faae4 to a98ce34 Compare October 1, 2025 10:59
@akaladarshi akaladarshi force-pushed the akaladarshi/claim-token-api-tests branch from a98ce34 to 68b4178 Compare October 1, 2025 13:06
@akaladarshi akaladarshi force-pushed the akaladarshi/claim-token-api-tests branch 2 times, most recently from 7604d27 to 54d2c5f Compare October 1, 2025 14:08
@akaladarshi akaladarshi force-pushed the akaladarshi/claim-token-api-tests branch from 54d2c5f to bb16e24 Compare October 1, 2025 14:54
@akaladarshi akaladarshi force-pushed the akaladarshi/claim-token-api-tests branch from bad61b9 to 2fb3d4c Compare October 1, 2025 15:32
@akaladarshi akaladarshi marked this pull request as ready for review October 2, 2025 09:26
Copilot AI review requested due to automatic review settings October 2, 2025 09:26
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR adds comprehensive end-to-end testing for the claim token API using k6. The testing suite validates API behavior including input validation, rate limiting mechanisms, and response format verification across different faucet types and address formats.

  • Implements k6 test script with configurable test scenarios for claim token API validation
  • Adds comprehensive test cases covering invalid inputs, rate limiting behavior, and transaction hash validation
  • Integrates new test suite into existing CI/E2E workflow for automated verification

Reviewed Changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
e2e/test_claim_token_api_config.js Configuration file defining test addresses, faucet types, status codes, and test scenarios
e2e/test_claim_token_api.js Main test script implementing validation logic and test execution
.github/workflows/e2e.yml CI workflow update to include the new claim token API test suite

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
e2e/test_claim_token_api.js (1)

95-108: Assert Retry-After on rate-limited responses.

Issue #319 asks us to verify the retry-after messaging when rate limiting kicks in. We only assert the 429 status today, so the header/message could regress unnoticed. Please add a check that inspects response.headers['Retry-After'] (or the equivalent body field if that’s how the API surfaces it).

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 08faae4 and 2fb3d4c.

📒 Files selected for processing (3)
  • .github/workflows/e2e.yml (1 hunks)
  • e2e/test_claim_token_api.js (1 hunks)
  • e2e/test_claim_token_api_config.js (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
e2e/test_claim_token_api.js (1)
e2e/test_claim_token_api_config.js (10)
  • API_CONFIG (2-10)
  • API_CONFIG (2-10)
  • FaucetTypes (34-39)
  • FaucetTypes (34-39)
  • TEST_ADDRESSES (12-32)
  • TEST_ADDRESSES (12-32)
  • STATUS_CODES (41-47)
  • STATUS_CODES (41-47)
  • TEST_SCENARIOS (50-165)
  • TEST_SCENARIOS (50-165)

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (3)
e2e/test_claim_token_api.js (3)

22-28: Redundant quote stripping suggests uncertainty about response format.

The logic strips quotes twice (lines 22-24, then 26-28), which would only be necessary for triple-quoted strings like """hash""". This redundancy suggests uncertainty about the actual response format.

Investigate the actual format returned by the API and simplify to a single stripping operation:

 function validateTransactionHash(txHash) {
-  // Remove outer quotes if present
   if (txHash.startsWith('"') && txHash.endsWith('"')) {
     txHash = txHash.slice(1, -1);
   }
-  // Remove inner quotes if present
-  if (txHash.startsWith('"') && txHash.endsWith('"')) {
-    txHash = txHash.slice(1, -1);
-  }
-
-  // Both CalibnetFIL and CalibnetUSDFC now return Ethereum format: 0x + 64 hex chars = 66 total
   return txHash.startsWith('0x') && txHash.length === 66;
 }

Alternatively, if the API genuinely returns nested quotes, add a comment explaining why.


66-71: Consider extracting check name construction.

The inline check name construction on line 67 works but reduces readability. Consider extracting it:

+      const checkName = `${faucetType} - Invalid address "${invalidAddress}" properly rejected (400 and error)`;
       check(response, {
-        [checkName]: (r) =>
+        [checkName]: (r) =>
           r.status === STATUS_CODES.BAD_REQUEST &&
           r.body &&
           r.body.toLowerCase().includes("invalid")
       });

This makes the check assertion more readable while maintaining the same functionality.


120-121: Clarify the 5-second buffer in cooldown wait.

The wait uses FAUCET_COOLDOWN_BUFFER_SECONDS (65s) but doesn't explain the 5-second buffer beyond the 60-second cooldown. Consider improving the comment:

-  console.log(`⏰ Waiting ${API_CONFIG.FAUCET_COOLDOWN_BUFFER_SECONDS} seconds to ensure previous global faucet cooldowns have expired...`);
+  console.log(`⏰ Waiting ${API_CONFIG.FAUCET_COOLDOWN_BUFFER_SECONDS} seconds (60s cooldown + 5s buffer) to ensure previous faucet cooldowns have expired...`);

This makes the buffer explicit in the log message, helping future maintainers understand why it's not exactly 60 seconds.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2fb3d4c and 21d42c1.

📒 Files selected for processing (2)
  • e2e/test_claim_token_api.js (1 hunks)
  • e2e/test_claim_token_api_config.js (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • e2e/test_claim_token_api_config.js
🧰 Additional context used
🧬 Code graph analysis (1)
e2e/test_claim_token_api.js (1)
e2e/test_claim_token_api_config.js (10)
  • API_CONFIG (2-12)
  • API_CONFIG (2-12)
  • FaucetTypes (36-41)
  • FaucetTypes (36-41)
  • TEST_ADDRESSES (14-34)
  • TEST_ADDRESSES (14-34)
  • STATUS_CODES (43-49)
  • STATUS_CODES (43-49)
  • TEST_SCENARIOS (52-167)
  • TEST_SCENARIOS (52-167)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: deploy
  • GitHub Check: lint
  • GitHub Check: codedov
  • GitHub Check: e2e
🔇 Additional comments (3)
e2e/test_claim_token_api.js (3)

1-18: LGTM! Clean test setup.

The k6 imports and options configuration are well-structured. Single VU and iteration ensure deterministic sequential execution, which is appropriate for testing rate-limiting behavior that depends on order.


34-53: LGTM! Proper URL construction and request handling.

The function correctly handles optional parameters, applies URL encoding, and configures appropriate timeout and tags for the HTTP request.


90-116: LGTM! Thorough rate-limiting test coverage.

The test suite properly validates both successful claims and rate-limited rejections, validates transaction hashes on success, and includes helpful debug logging. The 0.5-second sleep between requests is appropriate pacing.

@akaladarshi akaladarshi marked this pull request as draft October 6, 2025 04:17
@akaladarshi akaladarshi marked this pull request as ready for review October 6, 2025 05:27
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (2)
e2e/test_claim_token_api.js (2)

20-32: Clarify or fix duplicate quote-removal logic.

Lines 22-23 and 26-27 contain identical logic for removing quotes. If this is intentional to handle doubly-nested quotes, add a comment explaining why. Otherwise, this appears to be a copy-paste error. Typically, you'd only need to remove quotes once.

Apply this diff to simplify the function:

 function validateTransactionHash(txHash) {
   // Remove outer quotes if present
   if (txHash.startsWith('"') && txHash.endsWith('"')) {
     txHash = txHash.slice(1, -1);
   }
-  // Remove inner quotes if present
-  if (txHash.startsWith('"') && txHash.endsWith('"')) {
-    txHash = txHash.slice(1, -1);
-  }
 
   // Both CalibnetFIL and CalibnetUSDFC now return Ethereum format: 0x + 64 hex chars = 66 total
   return txHash.startsWith('0x') && txHash.length === 66;
 }

162-162: Add semicolon for consistency.

Line 162 is missing a semicolon after testWalletCap(). While JavaScript doesn't strictly require it, adding one would maintain consistency with the rest of the codebase.

   testRateLimiting();
-  testWalletCap()
+  testWalletCap();
   console.log('\n✅ All tests passed successfully!');
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 21d42c1 and b481a55.

📒 Files selected for processing (2)
  • e2e/test_claim_token_api.js (1 hunks)
  • e2e/test_claim_token_api_config.js (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
e2e/test_claim_token_api.js (1)
e2e/test_claim_token_api_config.js (10)
  • API_CONFIG (2-12)
  • API_CONFIG (2-12)
  • FaucetTypes (36-41)
  • FaucetTypes (36-41)
  • TEST_ADDRESSES (14-34)
  • TEST_ADDRESSES (14-34)
  • STATUS_CODES (43-49)
  • STATUS_CODES (43-49)
  • TEST_SCENARIOS (52-305)
  • TEST_SCENARIOS (52-305)

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

♻️ Duplicate comments (1)
e2e/test_claim_token_api.js (1)

20-25: Transaction hash validation still accepts non-hex characters.

This issue was previously flagged: the current check only validates prefix and length, allowing malformed hashes like 0xZZZZ... to pass validation. The suggested regex-based approach ensures all 64 characters after 0x are valid hexadecimal.

Apply the previously suggested fix:

-  return txHash.startsWith('0x') && txHash.length === 66;
+  return /^0x[0-9a-fA-F]{64}$/.test(txHash);
🧹 Nitpick comments (1)
e2e/test_claim_token_api.js (1)

148-156: Consider more robust retry-time parsing.

The regex /(\d+)/ captures the first digit sequence in the response body, which could break if the API response format evolves to include other numbers (e.g., "You've claimed 2 times. Retry in 3600 seconds"). Either use a more specific pattern that anchors to expected text (e.g., /retry.*?(\d+)\s*seconds?/i) or document the assumed response format to help future maintainers catch regressions.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3cab8fc and d5a9084.

📒 Files selected for processing (1)
  • e2e/test_claim_token_api.js (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
e2e/test_claim_token_api.js (1)
e2e/test_claim_token_api_config.js (10)
  • STATUS_CODES (72-78)
  • STATUS_CODES (72-78)
  • API_CONFIG (2-13)
  • API_CONFIG (2-13)
  • FaucetTypes (65-70)
  • FaucetTypes (65-70)
  • TEST_ADDRESSES (15-63)
  • TEST_ADDRESSES (15-63)
  • TEST_SCENARIOS (81-334)
  • TEST_SCENARIOS (81-334)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: codedov
  • GitHub Check: deploy
  • GitHub Check: E2E Browser Tests
  • GitHub Check: E2E API Tests
🔇 Additional comments (2)
e2e/test_claim_token_api.js (2)

27-69: Well-structured helper with clear fail-fast logic.

The refactored runTestScenarios consolidates common test execution patterns effectively:

  • Configurable waiting and sleep intervals
  • Primary status check before additional validations prevents cascading false positives
  • Extensible via additionalChecks callback for test-specific assertions
  • Clear debug logging when checks fail

This addresses the previous feedback to extract shared logic between rate-limiting and wallet-cap tests.


164-188: Robust connectivity check with appropriate retry logic.

The server health check provides a good safety net before test execution:

  • Three retry attempts with clear logging at each step
  • 5-second intervals give the server time to become ready
  • Boolean return allows the main test runner to abort gracefully
  • Explicit timeout prevents hanging on unresponsive servers

@akaladarshi akaladarshi enabled auto-merge October 14, 2025 11:23
elmattic
elmattic previously approved these changes Oct 14, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
.github/workflows/e2e.yml (1)

3-5: Fix boolean expression quoting in concurrency.

cancel-in-progress expects a boolean/expression, not a quoted string. Unquote to ensure proper behavior.

Apply this diff:

 concurrency:
   group: "${{ github.workflow }}-${{ github.ref }}"
-  cancel-in-progress: "${{ github.ref != 'refs/heads/main' }}"
+  cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
🧹 Nitpick comments (10)
e2e/test_claim_token_api_config.js (2)

212-213: DRY up cooldown waits.

Use the existing FAUCET_COOLDOWN_BUFFER_SECONDS constant instead of hardcoded 65s to keep tests in sync if the buffer changes.

Apply this diff:

-      waitBefore: 65, // Wait for cooldown from the main rate-limit tests to expire
+      waitBefore: API_CONFIG.FAUCET_COOLDOWN_BUFFER_SECONDS, // Wait for cooldown from the main rate-limit tests to expire
@@
-      waitBefore: 65, // Wait for cooldown from its own 2nd transaction
+      waitBefore: API_CONFIG.FAUCET_COOLDOWN_BUFFER_SECONDS, // Wait for cooldown from its own 2nd transaction
@@
-      waitBefore: 65, // Wait for cooldown from the previous test group
+      waitBefore: API_CONFIG.FAUCET_COOLDOWN_BUFFER_SECONDS, // Wait for cooldown from the previous test group
@@
-      waitBefore: 65, // Wait for its own cooldown
+      waitBefore: API_CONFIG.FAUCET_COOLDOWN_BUFFER_SECONDS, // Wait for its own cooldown
@@
-      waitBefore: 65, // Wait for its own cooldown
+      waitBefore: API_CONFIG.FAUCET_COOLDOWN_BUFFER_SECONDS, // Wait for its own cooldown
@@
-      waitBefore: 65, // Wait for cooldown from the previous test group to expire
+      waitBefore: API_CONFIG.FAUCET_COOLDOWN_BUFFER_SECONDS, // Wait for cooldown from the previous test group to expire
@@
-      waitBefore: 65, // Wait for cooldown from its own 2nd transaction
+      waitBefore: API_CONFIG.FAUCET_COOLDOWN_BUFFER_SECONDS, // Wait for cooldown from its own 2nd transaction

Also applies to: 220-221, 230-231, 238-239, 246-247, 280-281, 288-289


80-142: Make error matching resilient.

Error strings (“missing”, “unknown variant”, “invalid address”, “teapot”) can vary with framework/serde versions. Ensure the assertion is case-insensitive and trims noise (or assert status only in k6 and leave exact error matching to Rust unit/integration tests).

.github/workflows/e2e.yml (2)

112-116: Remove nc dependency; rely on curl-only readiness checks.

Ubuntu runners may lack nc; using curl-only simplifies and avoids a missing-binary failure.

Apply this diff:

-          echo "waiting for server on port ${{ matrix.port }}"
-          timeout 120 sh -c 'until nc -z $0 $1; do sleep 1; done' 127.0.0.1 ${{ matrix.port }}
-          echo "TCP port check passed, now waiting for HTTP server to be ready..."
-          timeout 120 sh -c 'until curl -s --max-time 30 http://127.0.0.1:${{ matrix.port }} > /dev/null; do echo "Waiting for HTTP server (first request may take 60-90s)..."; sleep 5; done'
+          echo "Waiting for HTTP server to be ready..."
+          timeout 180 sh -c 'until curl -fsS --max-time 10 http://127.0.0.1:${{ matrix.port }} >/dev/null; do echo "Waiting for HTTP server (first request may take 60-90s)..."; sleep 5; done'
           echo "Server is ready!"

90-96: Avoid echoing secrets directly in logs.

GitHub masks values, but it’s safer to prevent any accidental leakage. Prefer a here-doc to avoid repeating secrets in shell history/log lines.

Apply this diff:

-          echo "SECRET_WALLET=${{ secrets.TEST_CALIBNET_PRIVATE_KEY_HEX }}" > .dev.vars
-          echo "SECRET_MAINNET_WALLET=${{ secrets.TEST_MAINNET_PRIVATE_KEY_HEX }}" >> .dev.vars
-          echo "SECRET_CALIBNET_USDFC_WALLET=${{ secrets.TEST_CALIBNET_USDFC_PRIVATE_KEY_HEX }}" >> .dev.vars
+          cat > .dev.vars <<'EOF'
+SECRET_WALLET=${{ secrets.TEST_CALIBNET_PRIVATE_KEY_HEX }}
+SECRET_MAINNET_WALLET=${{ secrets.TEST_MAINNET_PRIVATE_KEY_HEX }}
+SECRET_CALIBNET_USDFC_WALLET=${{ secrets.TEST_CALIBNET_USDFC_PRIVATE_KEY_HEX }}
+EOF
e2e/test_cors.js (2)

100-111: Also assert Retry-After is exposed on 429 responses.

Frontends often need Retry-After for backoff. Verify both the header’s presence and that CORS exposes it.

Apply this diff:

   check(securityResponse, {
     'Security: Has Access-Control-Allow-Origin': (r) =>
       r.headers['Access-Control-Allow-Origin'] !== undefined,
     'Security: Access-Control-Allow-Credentials is not set (safer for public APIs)': (r) =>
       r.headers['Access-Control-Allow-Credentials'] === undefined ||
       r.headers['Access-Control-Allow-Credentials'] === 'false',
   });
 
+  // Test 6.1: If rate-limited, ensure Retry-After is present and exposed via CORS
+  const rateLimitProbe1 = http.get(url, { headers: { 'Origin': 'https://external-example.com' } });
+  const rateLimitProbe2 = http.get(url, { headers: { 'Origin': 'https://external-example.com' } });
+  check(rateLimitProbe2, {
+    '429: Has Retry-After header when rate limited (if applicable)': (r) =>
+      r.status !== 429 || r.headers['Retry-After'] !== undefined,
+    '429: Access-Control-Expose-Headers includes Retry-After (or is *)': (r) => {
+      if (r.status !== 429) return true;
+      const expose = (r.headers['Access-Control-Expose-Headers'] || '').toLowerCase();
+      return expose === '*' || expose.includes('retry-after');
+    },
+  });

73-76: Consider relaxing same-origin CORS header expectation.

Some servers omit CORS headers for same-origin. If portability matters, allow header absence for same-origin. Optional.

docs/cors_testing_guide.md (4)

51-57: Sync port with the workflow (uses 8787).

Either update docs to 8787 or set the CORS matrix to 8788. Keep them consistent to avoid confusion.

Apply this diff:

-  port: 8788 # Separate port from Browser/API tests
+  port: 8787 # Same port as CI workflow configuration

147-147: Use a heading instead of emphasis (markdownlint MD036).

Change bold emphasis to a proper heading.

Apply this diff:

-**Total: 23 checks covering full CORS compliance**
+### Total: 23 checks covering full CORS compliance

163-189: Add fenced code languages (markdownlint MD040).

Mark blocks as text for expected output to improve readability and linting.

Apply this diff:

-```
+```text
 checks_succeeded...: 100.00% 23 out of 23
@@
 ✓ Error Response: CORS headers present even on errors

---

`135-145`: **Document exposing Retry-After for browsers.**

Mention Access-Control-Expose-Headers so UIs can read Retry-After on 429.


Apply this diff:

```diff
 ### 5. Security & Edge Cases (3 checks)
@@
-✓ CORS headers present even on 500/400 errors (critical for browser error handling)
+✓ CORS headers present even on 500/400 errors (critical for browser error handling)
+✓ On 429, Retry-After is present and exposed via `Access-Control-Expose-Headers` (or wildcard `*`)
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d5a9084 and e83b66a.

📒 Files selected for processing (4)
  • .github/workflows/e2e.yml (4 hunks)
  • docs/cors_testing_guide.md (1 hunks)
  • e2e/test_claim_token_api_config.js (1 hunks)
  • e2e/test_cors.js (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
e2e/test_cors.js (1)
e2e/test_claim_token_api_config.js (4)
  • FaucetTypes (65-70)
  • FaucetTypes (65-70)
  • TEST_ADDRESSES (15-63)
  • TEST_ADDRESSES (15-63)
🪛 markdownlint-cli2 (0.18.1)
docs/cors_testing_guide.md

147-147: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


163-163: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: E2E Claim Token API CORS Tests
  • GitHub Check: E2E Browser Tests
  • GitHub Check: E2E API Tests
  • GitHub Check: deploy
  • GitHub Check: codedov
🔇 Additional comments (2)
e2e/test_cors.js (1)

32-49: Preflight coverage looks good.

Validating status, A-C-A-Origin, methods, and requested headers is sufficient here.

e2e/test_claim_token_api_config.js (1)

144-205: Now I need to check the e2e test file to understand how it currently handles the 60+ second waits:

I need to examine the actual e2e test file to understand how the 60+ second waits are being used:Now I have comprehensive information. The review comment is suggesting that the e2e tests use environment variables to override rate-limit settings. Based on my verification:

Key Findings:

  1. The Rust backend rate-limit constants (MAINNET_COOLDOWN_SECONDS=600, CALIBNET_COOLDOWN_SECONDS=60) are hardcoded - NOT environment-configurable
  2. Only RATE_LIMITER_DISABLED env var exists, which disables the entire rate limiter (not suitable for testing the behavior itself)
  3. The codebase would need refactoring to make cooldown and wallet-cap configurable via environment variables
  4. The review suggests a solution that is NOT currently feasible without code changes to the Rust backend

The review comment is requesting a feature that doesn't exist in the codebase. The suggestion to "override cooldown and wallet-cap via test-only env" requires implementation work that hasn't been done.


Shorten CI duration by configuring test-only rate-limit settings.

The 60+ second waits will inflate runtime significantly. To implement this suggestion, the backend rate-limit constants (MAINNET_COOLDOWN_SECONDS, CALIBNET_COOLDOWN_SECONDS, wallet-cap multipliers in src/faucet/constants.rs) must be made configurable via environment variables with fallback defaults. Currently, only RATE_LIMITER_DISABLED exists (which disables all rate limiting entirely).

Suggested approach:

  • Refactor FaucetInfo::rate_limit_seconds() and FaucetInfo::wallet_cap() methods to read from environment variables (e.g., TEST_COOLDOWN_SECONDS, TEST_WALLET_CAP_MULTIPLIER) before falling back to hardcoded constants
  • Update wrangler.toml to allow setting these vars for test environment
  • Then e2e tests can set short test intervals (2–3s cooldown, cap=2) while keeping the same test scenario logic intact

@akaladarshi akaladarshi force-pushed the akaladarshi/claim-token-api-tests branch from e83b66a to 9a346fe Compare October 17, 2025 14:36
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (4)
e2e/test_claim_token_api_config.js (2)

12-12: Good buffer choice; consider documenting the rationale.

The 65-second buffer (5 seconds over the 60-second cooldown) is a sensible safety margin for timing-sensitive tests, but the reason for the extra 5 seconds isn't immediately obvious. Consider adding an inline comment explaining that this provides a buffer to account for timing variations in test execution.

-  FAUCET_COOLDOWN_BUFFER_SECONDS: 65,
+  FAUCET_COOLDOWN_BUFFER_SECONDS: 65, // 60s cooldown + 5s buffer for timing variations

300-334: Track the commented ID wallet tests.

The commented-out test cases for CalibnetUSDFC ID wallet are reasonable given the uncertainty about token recovery, but this represents a gap in test coverage.

Would you like me to create a tracking issue for implementing these tests once the token recovery mechanism is clarified? This would ensure comprehensive wallet cap testing across all address formats.

docs/cors_testing_guide.md (2)

148-148: Use heading instead of emphasis.

For better document structure, convert the bold text to a proper heading.

-**Total: 22 checks covering full CORS compliance**
+### Total: 22 checks covering full CORS compliance

164-189: Add language identifier to code block.

The fenced code block should specify a language for proper syntax highlighting.

-```
+```text
 checks_succeeded...: 100.00% 22 out of 22
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e83b66a and 9a346fe.

📒 Files selected for processing (4)
  • .github/workflows/e2e.yml (4 hunks)
  • docs/cors_testing_guide.md (1 hunks)
  • e2e/test_claim_token_api_config.js (1 hunks)
  • e2e/test_cors.js (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • e2e/test_cors.js
🧰 Additional context used
🪛 markdownlint-cli2 (0.18.1)
docs/cors_testing_guide.md

148-148: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


164-164: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: deploy
  • GitHub Check: codedov
  • GitHub Check: E2E API Tests
  • GitHub Check: E2E Claim Token API CORS Tests
  • GitHub Check: E2E Browser Tests
🔇 Additional comments (5)
e2e/test_claim_token_api_config.js (1)

15-63: Excellent address coverage!

The test addresses cover all major formats (F1, T1, T410, ETH, T0, ID) and the invalid address list includes comprehensive edge cases (malformed ETH addresses, invalid checksums, unsupported protocols). This addresses the previous review feedback thoroughly.

.github/workflows/e2e.yml (3)

27-46: Matrix strategy looks solid!

The fail-fast: false configuration ensures all test suites run to completion even if one fails, providing comprehensive test results. Each matrix entry correctly uses the same port (8787) since they run on separate GitHub-hosted runners, avoiding conflicts.


110-111: Good state isolation strategy.

Using per-matrix and per-run state directories (--persist-to .wrangler-state-${{ matrix.state_dir }}-${{ github.run_id }}) provides excellent isolation between parallel test runs. In CI, these are ephemeral since each workflow run gets a fresh checkout. For local development, developers should be aware that these directories will accumulate and may need periodic cleanup.


112-116: Excellent readiness checks.

The two-phase readiness validation (TCP port check followed by HTTP availability check) with clear progress messages and appropriate timeouts (120s total) is a robust approach for handling the 60-90s first-request warm-up time.

docs/cors_testing_guide.md (1)

1-258: Comprehensive and well-structured guide.

The CORS testing documentation provides excellent coverage of terminology, configuration, test flow, and troubleshooting. The examples are practical and the explanations are clear. Once the port inconsistency is corrected, this will be a valuable resource for understanding and running the CORS tests.

sudo-shashank
sudo-shashank previously approved these changes Oct 17, 2025
Copy link
Contributor

@sudo-shashank sudo-shashank left a comment

Choose a reason for hiding this comment

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

LGTM, we can create an issue for commented test cases and add a TODO

sudo-shashank
sudo-shashank previously approved these changes Oct 22, 2025
@akaladarshi akaladarshi force-pushed the akaladarshi/claim-token-api-tests branch from 01bf0d8 to 836fb69 Compare October 22, 2025 12:53
@akaladarshi akaladarshi added this pull request to the merge queue Oct 22, 2025
Merged via the queue into main with commit 1020831 Oct 22, 2025
7 checks passed
@akaladarshi akaladarshi deleted the akaladarshi/claim-token-api-tests branch October 22, 2025 14:07
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.

Add automated tests for claim_token endpoint

5 participants