Skip to content

Comments

feat: add Playwright E2E test infrastructure#533

Open
DSanich wants to merge 10 commits intogetAlby:masterfrom
DSanich:feat/e2e-test-integration
Open

feat: add Playwright E2E test infrastructure#533
DSanich wants to merge 10 commits intogetAlby:masterfrom
DSanich:feat/e2e-test-integration

Conversation

@DSanich
Copy link
Contributor

@DSanich DSanich commented Feb 17, 2026

Summary

Adds Playwright-based E2E tests to verify SDK behavior in a real browser environment.

What's included

Infrastructure

  • Playwright — browser automation
  • serve — static file server for fixtures
  • playwright.config.ts — webServer (build + serve), Chromium by default
  • CI — E2E tests run in GitHub Actions after unit tests

Test coverage by module

Module Tests
lnclient/Amount SATS, resolveAmount (sync, async, number)
lnclient/FiatAmount USD, EUR with mocked rates API
oauth Client, OAuth2Bearer, accountBalance, accountInformation, signMessage, createInvoice, decodeInvoice, base_url
oauth error handling AlbyResponseError (4xx, 5xx), network error propagation
webln OauthWeblnProvider (enable, getInfo, sendPayment, keysend, makeInvoice)
nwc NWCClient (parseWalletConnectUrl, getAuthorizationUrl, constructor), NWAClient
lnclient/LNClient Constructor (string, NWCClient, options), close

Scripts

  • yarn test:e2e — run E2E tests (Chromium)
  • yarn test:e2e:install — install Playwright browsers
  • yarn test:e2e:ui — run with Playwright UI
  • yarn test:e2e:headed — run in headed mode

How to run

yarn install
yarn test:e2e:install # one-time
yarn test:e2e

Summary by CodeRabbit

  • Tests

    • Added end-to-end test suites for amounts, fiat conversions, Lightning client, NWC, OAuth, and WebLN functionality.
    • Configured Playwright for cross-browser testing.
  • Documentation

    • Added E2E testing setup and usage documentation.
  • Chores

    • Updated CI pipeline to execute automated tests.
    • Added Playwright testing framework and development dependencies.

@coderabbitai
Copy link

coderabbitai bot commented Feb 17, 2026

📝 Walkthrough

Walkthrough

This PR introduces comprehensive end-to-end testing infrastructure using Playwright. It adds test fixtures, test suites covering LNClient, NWC, OAuth, WebLN, and amount resolution modules, Playwright configuration, CI integration, and supporting documentation and dependencies.

Changes

Cohort / File(s) Summary
CI & Build Configuration
.github/workflows/ci.yml, playwright.config.ts
Adds Playwright browser installation and e2e test execution to CI pipeline; introduces Playwright config with parallel test execution across Chromium, Firefox, and WebKit, web server setup, and baseline test settings.
E2E Test Suites
e2e/amount.spec.ts, e2e/fiat-amount.spec.ts, e2e/lnclient.spec.ts, e2e/nwc.spec.ts, e2e/oauth.spec.ts, e2e/webln.spec.ts
Introduces six Playwright test suites validating amount resolution, fiat conversion, LNClient construction, NWC wallet connect workflows, OAuth client interactions, and WebLN provider functionality with mocked API responses.
E2E Test Fixtures
e2e/fixtures/amount.html, e2e/fixtures/fiat-amount.html, e2e/fixtures/lnclient.html, e2e/fixtures/nwc.html, e2e/fixtures/oauth.html, e2e/fixtures/webln.html
Adds six HTML fixture files that load ESM modules and expose global test runners for browser-based validation of amount calculations, fiat conversions, LNClient instantiation, NWC workflows, OAuth client flows, and WebLN provider operations.
Configuration & Documentation
.gitignore, e2e/README.md, package.json
Updates ignore patterns for test artifacts; adds e2e test documentation covering setup, commands, and limitations; introduces e2e test scripts and Playwright dependency.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 A warren of tests, so thorough and keen,
End-to-end checks in browsers pristine!
Playwright hops through each fixture with care,
Testing our modules from here to there. 🎭✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title 'feat: add Playwright E2E test infrastructure' accurately and clearly summarizes the main change—adding end-to-end testing infrastructure using Playwright, which is the primary focus of all files and changes in this PR.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Tip

Issue Planner is now in beta. Read the docs and try it out! Share your feedback on Discord.


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 and usage tips.

@socket-security
Copy link

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Addedserve@​14.2.5991009987100
Added@​playwright/​test@​1.58.210010010099100

View full report

@socket-security
Copy link

Warning

Review the following alerts detected in dependencies.

According to your organization's Security Policy, it is recommended to resolve "Warn" alerts. Learn more about Socket for GitHub.

Action Severity Alert  (click "▶" to expand/collapse)
Warn High
Obfuscated code: npm registry-auth-token is 94.0% likely obfuscated

Confidence: 0.94

Location: Package overview

From: ?npm/serve@14.2.5npm/registry-auth-token@3.3.2

ℹ Read more on: This package | This alert | What is obfuscated code?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: Packages should not obfuscate their code. Consider not using packages with obfuscated code.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/registry-auth-token@3.3.2. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

View full report

@DSanich
Copy link
Contributor Author

DSanich commented Feb 17, 2026

@rolznz @reneaaron Hello!

Following this discussion getAlby/sandbox#15 (comment), I started working on e2e tests at https://github.com/getAlby/js-sdk. I'm happy to share this pull request with you. The library's core modules are now covered with real e2e tests, ensuring greater security for business logic.

Copy link

@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 (13)
e2e/fixtures/lnclient.html (1)

10-10: Unused LN import.

LN is imported but never used in this fixture.

Proposed fix
-      import { LNClient, LN } from "/dist/esm/lnclient.js";
+      import { LNClient } from "/dist/esm/lnclient.js";
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@e2e/fixtures/lnclient.html` at line 10, The import brings in LN but it is
unused; remove the unused symbol by changing the import that currently lists
both LNClient and LN to import only LNClient (i.e., update the import statement
that references LNClient and LN so it no longer includes LN) to eliminate the
unused import and any linter warnings.
package.json (1)

91-92: devDependencies alphabetical ordering.

serve (line 91) is listed before qrcode-terminal (line 92), breaking the alphabetical sort of devDependencies.

Proposed fix
-    "serve": "^14.2.4",
     "qrcode-terminal": "^0.12.0",
+    "serve": "^14.2.4",
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@package.json` around lines 91 - 92, The devDependencies list is out of
alphabetical order: swap the positions of the "serve" and "qrcode-terminal"
entries so that "qrcode-terminal" comes before "serve" (maintain existing
version strings and trailing commas), ensuring the devDependencies array is
sorted alphabetically by package name.
e2e/fixtures/oauth.html (1)

10-10: Unused OAuth2Bearer import.

OAuth2Bearer is imported but never used in this fixture. Remove it to keep the fixture clean.

Proposed fix
-      import { Client, OAuth2Bearer } from "/dist/esm/oauth.js";
+      import { Client } from "/dist/esm/oauth.js";
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@e2e/fixtures/oauth.html` at line 10, The import statement currently brings in
an unused symbol — remove OAuth2Bearer from the import so only the used Client
is imported; update the import that reads something like import { Client,
OAuth2Bearer } ... to import { Client } ... and ensure no other references to
OAuth2Bearer remain in the file.
.github/workflows/ci.yml (1)

20-25: Remove redundant yarn build in CI, as E2E tests trigger it via Playwright's webServer.

Line 20 runs yarn build, then line 25 runs yarn test:e2e, which executes playwright test --project=chromium. Playwright's webServer configuration (line 20 of playwright.config.ts) runs yarn build && serve . -p 3000, so the build executes twice unnecessarily. Since the E2E tests depend on the built output being served, the explicit build at line 20 can be removed (if unit tests don't require it) or the webServer command can be optimized to skip the redundant build using an environment variable or a CI-specific script.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/ci.yml around lines 20 - 25, Remove the redundant
top-level "yarn build" CI step because Playwright's webServer (configured in
playwright.config.ts and invoked by the "yarn test:e2e" / "playwright test
--project=chromium") already runs "yarn build && serve . -p 3000"; update the CI
workflow by deleting the "yarn build" run step (or alternatively modify the
webServer command to skip the build when running in CI via an environment
variable or a CI-specific script) so the build is not executed twice.
e2e/webln.spec.ts (1)

60-68: Extract repeated mockAuth object to reduce duplication.

The identical mockAuth object is constructed in every test. Extract it to a shared constant or a helper inside the describe block:

♻️ Suggested refactor
 test.describe("webln", () => {
+  const mockAuth = {
+    token: { access_token: "x" },
+    getAuthHeader: () => ({ Authorization: "Bearer x" }),
+  };
+
   test.beforeEach(async ({ page }) => {

Then pass mockAuth into each page.evaluate via the second argument, or serialize it as needed.

Note: since getAuthHeader is a function, it can't be serialized by page.evaluate. You could instead inline it in a shared snippet string or keep the object literal inside evaluate but extract just the repeated structure into a helper that returns the evaluate callback.

Also applies to: 76-84, 90-98, 105-114, 120-132, 139-152

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@e2e/webln.spec.ts` around lines 60 - 68, Extract the repeated mockAuth
construction used inside multiple page.evaluate calls into a shared helper or
constant within the describe block to avoid duplication; for example, create a
getMockAuth() helper (or a stringified snippet) and use it when constructing the
provider in tests that reference OauthWeblnProvider, but remember functions like
getAuthHeader can't be serialized into page.evaluate so either pass a
serializable representation or use the helper to return the full evaluate
callback (or inline the function inside the evaluate body) and update all places
that construct mockAuth (lines creating mockAuth for OauthWeblnProvider) to use
that helper.
e2e/fiat-amount.spec.ts (2)

5-11: EUR test reuses USD mock data — not truly testing EUR-specific conversion.

The mockRatesResponse has code: "USD", but it's also served for the EUR rate request (the RATES_API regex matches all currency paths). The EUR test passes only because the mock rate is identical. Consider adding a separate EUR mock (e.g., with a different rate_float) and routing based on the URL path to verify the currency-specific calculation path.

Also applies to: 52-61

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@e2e/fiat-amount.spec.ts` around lines 5 - 11, The USD mock
(mockRatesResponse) is reused for the EUR test so the EUR-specific conversion
isn't actually validated; create a separate mock object (e.g.,
eurMockRatesResponse with code: "EUR" and a different rate_float/rate_cents) and
update the request stub that matches RATES_API to inspect the request
URL/pathname (or currency segment) and return mockRatesResponse for USD paths
and eurMockRatesResponse for EUR paths; update any stubs/expectations referenced
around the existing mock usage (including the handler logic used by the EUR
test) so each currency test receives its corresponding mock response.

27-50: The first two tests (USD converts… and FiatAmount is interoperable…) are near-duplicates.

Both create USD(1) and call resolveAmount. The first asserts > 0 and the millisat relationship; the second asserts the exact value 1000. These could be a single test asserting exact values + the millisat relationship, reducing redundancy.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@e2e/fiat-amount.spec.ts` around lines 27 - 50, Duplicate tests: both tests
create USD(1) and call resolveAmount; collapse them into one. Replace the two
tests ("USD converts to satoshis via resolveAmount" and "FiatAmount is
interoperable with Amount") with a single test that imports USD and
resolveAmount, calls const fiatAmount = USD(1); const resolved = await
resolveAmount(fiatAmount); then assert resolved matches the shape (satoshi and
millisat are Numbers), assert resolved.satoshi === 1000, and assert
resolved.millisat === resolved.satoshi * 1000; remove the redundant test to
avoid duplication.
e2e/oauth.spec.ts (1)

175-199: Minor: Double page navigation in custom base_url test.

The beforeEach already navigates to the fixture page (line 82-83), then this test navigates again (line 187-188) after adding the custom route. The first navigation is wasted work. Consider moving this test to its own describe block without the shared beforeEach, or skipping the redundant navigation.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@e2e/oauth.spec.ts` around lines 175 - 199, The test "Client uses custom
base_url" contains a redundant page.goto because the shared beforeEach already
navigates to the fixture; remove the extra navigation inside that test or move
the test into its own describe block without the shared beforeEach.
Specifically, in the test named Client uses custom base_url remove the await
page.goto("/e2e/fixtures/oauth.html") (or relocate the whole test into a new
describe that does not use the existing beforeEach) so the custom route is added
then the already-navigated page is used to evaluate the Client and call
accountBalance.
playwright.config.ts (2)

19-24: serve . exposes the entire project root.

The web server command serves the repository root, making all files (including source, configs, node_modules, etc.) accessible on port 3000. This is fine for local dev and CI isolation, but worth noting. If you'd prefer a tighter surface, you could serve only the dist and e2e directories (e.g., by creating a small serve config or symlinking into a dedicated folder).

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@playwright.config.ts` around lines 19 - 24, The webServer configuration in
playwright.config.ts currently uses the command string "yarn build && serve . -p
3000" which exposes the entire repo root; change the webServer.command to serve
only the built output (e.g., "yarn build && serve ./dist -p 3000" or a dedicated
test-serve folder containing dist and e2e assets) or create a small serve
config/symlink to a dedicated folder and point webServer.command at that folder,
keeping the existing webServer.url, reuseExistingServer, and timeout settings
unchanged; update any scripts that rely on the old path accordingly.

14-18: Three browser projects may significantly increase CI time with workers: 1.

Running Chromium, Firefox, and WebKit sequentially in CI could triple test execution time. Consider running only Chromium in CI (matching the PR description's "uses Chromium by default") and reserving cross-browser testing for periodic/nightly runs, or increase the worker count.

♻️ Example: CI-only single-browser config
-  projects: [
-    { name: "chromium", use: { ...devices["Desktop Chrome"] } },
-    { name: "firefox", use: { ...devices["Desktop Firefox"] } },
-    { name: "webkit", use: { ...devices["Desktop Safari"] } },
-  ],
+  projects: process.env.CI
+    ? [{ name: "chromium", use: { ...devices["Desktop Chrome"] } }]
+    : [
+        { name: "chromium", use: { ...devices["Desktop Chrome"] } },
+        { name: "firefox", use: { ...devices["Desktop Firefox"] } },
+        { name: "webkit", use: { ...devices["Desktop Safari"] } },
+      ],
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@playwright.config.ts` around lines 14 - 18, The Playwright config currently
runs three browser projects (projects array with names "chromium", "firefox",
"webkit") which will slow CI when workers: 1; update playwright.config.ts to
only include the "chromium" project for CI or make the projects list conditional
(e.g., check process.env.CI) so CI uses only Chromium while local/dev runs
include all three, or alternatively increase the global "workers" value for CI;
modify the projects array or add the CI-branch logic around it and ensure any
references to "projects" and "workers" are adjusted accordingly.
e2e/fixtures/nwc.html (1)

12-13: Test NWC URL is duplicated across multiple files.

The same exampleNwcUrl string is hardcoded here, in e2e/nwc.spec.ts (line 3-4), and in e2e/lnclient.spec.ts (line 3-4). Consider extracting it to a shared test constants file (e.g., e2e/fixtures/constants.ts) to keep it DRY and simplify future updates.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@e2e/fixtures/nwc.html` around lines 12 - 13, The string assigned to
exampleNwcUrl is duplicated across tests; extract it into a single exported
constant (e.g., export const EXAMPLE_NWC_URL) in a new shared test constants
module and replace the inline exampleNwcUrl declarations in the tests with
imports from that module so all tests reference the same EXAMPLE_NWC_URL; update
import statements in the files that currently declare exampleNwcUrl and remove
their local definitions.
e2e/README.md (2)

23-24: Consider clarifying which browsers are included.

The comment mentions "All browsers" but doesn't specify which browsers Playwright will run against. Consider adding clarity for users unfamiliar with Playwright's defaults.

📝 Suggested clarification
-# All browsers (requires: yarn test:e2e:install first)
+# All browsers - Chromium, Firefox, WebKit (requires: yarn test:e2e:install first)
 yarn playwright test
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@e2e/README.md` around lines 23 - 24, The "All browsers" note is ambiguous;
update the README entry around the "All browsers (requires: yarn
test:e2e:install first)" heading and the "yarn playwright test" command to
explicitly list Playwright's default browser targets (Chromium, Firefox, and
WebKit) and mention that running "yarn test:e2e:install" will install the
browser binaries; e.g., change the heading text to name the three browsers and
add a short sentence clarifying that Playwright runs tests against Chromium,
Firefox and WebKit by default and that the install step downloads those browser
binaries.

33-44: Consider adding context about the test execution model.

The structure documentation is comprehensive, but could benefit from a brief explanation of how tests execute (e.g., that Playwright starts a webServer automatically to build and serve fixtures, tests load modules from /dist/esm, etc.). This would help users understand the test infrastructure better.

📝 Suggested addition
 ## Structure
 
+Tests run against a local webServer (configured in `playwright.config.ts`) that automatically builds and serves fixtures. Tests load SDK modules from `/dist/esm` in a real browser environment.
+
 - `e2e/` — e2e test directory
 - `e2e/fixtures/` — HTML fixtures for browser tests
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@e2e/README.md` around lines 33 - 44, Add a short paragraph to the
e2e/README.md that explains the test execution model: state that Playwright (via
playwright.config.ts) automatically starts a webServer to build and serve files
from e2e/fixtures, that browser tests load built modules from /dist/esm, and
that some specs use mocked APIs (e.g., oauth.spec.ts, webln.spec.ts) while
others run without a relay (nwc.spec.ts); mention any required build step before
running tests and how tests are started (e.g., via the Playwright test runner).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@package.json`:
- Around line 54-55: The package.json npm script "format" has a glob mismatch
with "format:fix" for examples (format excludes .ts while format:fix includes
it); update the "format" script's examples glob to match "format:fix" (change
'examples/**/*.(js|jsx)' to 'examples/**/*.(js|jsx|ts)') so both "format" and
"format:fix" use the same file set, and verify both scripts' globs remain
consistent across other entries.

---

Nitpick comments:
In @.github/workflows/ci.yml:
- Around line 20-25: Remove the redundant top-level "yarn build" CI step because
Playwright's webServer (configured in playwright.config.ts and invoked by the
"yarn test:e2e" / "playwright test --project=chromium") already runs "yarn build
&& serve . -p 3000"; update the CI workflow by deleting the "yarn build" run
step (or alternatively modify the webServer command to skip the build when
running in CI via an environment variable or a CI-specific script) so the build
is not executed twice.

In `@e2e/fiat-amount.spec.ts`:
- Around line 5-11: The USD mock (mockRatesResponse) is reused for the EUR test
so the EUR-specific conversion isn't actually validated; create a separate mock
object (e.g., eurMockRatesResponse with code: "EUR" and a different
rate_float/rate_cents) and update the request stub that matches RATES_API to
inspect the request URL/pathname (or currency segment) and return
mockRatesResponse for USD paths and eurMockRatesResponse for EUR paths; update
any stubs/expectations referenced around the existing mock usage (including the
handler logic used by the EUR test) so each currency test receives its
corresponding mock response.
- Around line 27-50: Duplicate tests: both tests create USD(1) and call
resolveAmount; collapse them into one. Replace the two tests ("USD converts to
satoshis via resolveAmount" and "FiatAmount is interoperable with Amount") with
a single test that imports USD and resolveAmount, calls const fiatAmount =
USD(1); const resolved = await resolveAmount(fiatAmount); then assert resolved
matches the shape (satoshi and millisat are Numbers), assert resolved.satoshi
=== 1000, and assert resolved.millisat === resolved.satoshi * 1000; remove the
redundant test to avoid duplication.

In `@e2e/fixtures/lnclient.html`:
- Line 10: The import brings in LN but it is unused; remove the unused symbol by
changing the import that currently lists both LNClient and LN to import only
LNClient (i.e., update the import statement that references LNClient and LN so
it no longer includes LN) to eliminate the unused import and any linter
warnings.

In `@e2e/fixtures/nwc.html`:
- Around line 12-13: The string assigned to exampleNwcUrl is duplicated across
tests; extract it into a single exported constant (e.g., export const
EXAMPLE_NWC_URL) in a new shared test constants module and replace the inline
exampleNwcUrl declarations in the tests with imports from that module so all
tests reference the same EXAMPLE_NWC_URL; update import statements in the files
that currently declare exampleNwcUrl and remove their local definitions.

In `@e2e/fixtures/oauth.html`:
- Line 10: The import statement currently brings in an unused symbol — remove
OAuth2Bearer from the import so only the used Client is imported; update the
import that reads something like import { Client, OAuth2Bearer } ... to import {
Client } ... and ensure no other references to OAuth2Bearer remain in the file.

In `@e2e/oauth.spec.ts`:
- Around line 175-199: The test "Client uses custom base_url" contains a
redundant page.goto because the shared beforeEach already navigates to the
fixture; remove the extra navigation inside that test or move the test into its
own describe block without the shared beforeEach. Specifically, in the test
named Client uses custom base_url remove the await
page.goto("/e2e/fixtures/oauth.html") (or relocate the whole test into a new
describe that does not use the existing beforeEach) so the custom route is added
then the already-navigated page is used to evaluate the Client and call
accountBalance.

In `@e2e/README.md`:
- Around line 23-24: The "All browsers" note is ambiguous; update the README
entry around the "All browsers (requires: yarn test:e2e:install first)" heading
and the "yarn playwright test" command to explicitly list Playwright's default
browser targets (Chromium, Firefox, and WebKit) and mention that running "yarn
test:e2e:install" will install the browser binaries; e.g., change the heading
text to name the three browsers and add a short sentence clarifying that
Playwright runs tests against Chromium, Firefox and WebKit by default and that
the install step downloads those browser binaries.
- Around line 33-44: Add a short paragraph to the e2e/README.md that explains
the test execution model: state that Playwright (via playwright.config.ts)
automatically starts a webServer to build and serve files from e2e/fixtures,
that browser tests load built modules from /dist/esm, and that some specs use
mocked APIs (e.g., oauth.spec.ts, webln.spec.ts) while others run without a
relay (nwc.spec.ts); mention any required build step before running tests and
how tests are started (e.g., via the Playwright test runner).

In `@e2e/webln.spec.ts`:
- Around line 60-68: Extract the repeated mockAuth construction used inside
multiple page.evaluate calls into a shared helper or constant within the
describe block to avoid duplication; for example, create a getMockAuth() helper
(or a stringified snippet) and use it when constructing the provider in tests
that reference OauthWeblnProvider, but remember functions like getAuthHeader
can't be serialized into page.evaluate so either pass a serializable
representation or use the helper to return the full evaluate callback (or inline
the function inside the evaluate body) and update all places that construct
mockAuth (lines creating mockAuth for OauthWeblnProvider) to use that helper.

In `@package.json`:
- Around line 91-92: The devDependencies list is out of alphabetical order: swap
the positions of the "serve" and "qrcode-terminal" entries so that
"qrcode-terminal" comes before "serve" (maintain existing version strings and
trailing commas), ensuring the devDependencies array is sorted alphabetically by
package name.

In `@playwright.config.ts`:
- Around line 19-24: The webServer configuration in playwright.config.ts
currently uses the command string "yarn build && serve . -p 3000" which exposes
the entire repo root; change the webServer.command to serve only the built
output (e.g., "yarn build && serve ./dist -p 3000" or a dedicated test-serve
folder containing dist and e2e assets) or create a small serve config/symlink to
a dedicated folder and point webServer.command at that folder, keeping the
existing webServer.url, reuseExistingServer, and timeout settings unchanged;
update any scripts that rely on the old path accordingly.
- Around line 14-18: The Playwright config currently runs three browser projects
(projects array with names "chromium", "firefox", "webkit") which will slow CI
when workers: 1; update playwright.config.ts to only include the "chromium"
project for CI or make the projects list conditional (e.g., check
process.env.CI) so CI uses only Chromium while local/dev runs include all three,
or alternatively increase the global "workers" value for CI; modify the projects
array or add the CI-branch logic around it and ensure any references to
"projects" and "workers" are adjusted accordingly.

Comment on lines +54 to +55
"format": "prettier --check '**/*.(md|json)' 'src/**/*.(js|ts)' 'examples/**/*.(js|jsx)' 'e2e/**/*.(js|ts)' 'playwright.config.ts'",
"format:fix": "prettier --loglevel silent --write '**/*.(md|json)' 'src/**/*.(js|ts)' 'examples/**/*.(js|jsx|ts)' 'e2e/**/*.(js|ts)' 'playwright.config.ts'",
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Glob mismatch between format and format:fix for examples.

format uses 'examples/**/*.(js|jsx)' while format:fix uses 'examples/**/*.(js|jsx|ts)'. The format check will miss .ts files in examples that format:fix would rewrite, leading to silent drift.

Proposed fix
-    "format": "prettier --check '**/*.(md|json)' 'src/**/*.(js|ts)' 'examples/**/*.(js|jsx)' 'e2e/**/*.(js|ts)' 'playwright.config.ts'",
+    "format": "prettier --check '**/*.(md|json)' 'src/**/*.(js|ts)' 'examples/**/*.(js|jsx|ts)' 'e2e/**/*.(js|ts)' 'playwright.config.ts'",
📝 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
"format": "prettier --check '**/*.(md|json)' 'src/**/*.(js|ts)' 'examples/**/*.(js|jsx)' 'e2e/**/*.(js|ts)' 'playwright.config.ts'",
"format:fix": "prettier --loglevel silent --write '**/*.(md|json)' 'src/**/*.(js|ts)' 'examples/**/*.(js|jsx|ts)' 'e2e/**/*.(js|ts)' 'playwright.config.ts'",
"format": "prettier --check '**/*.(md|json)' 'src/**/*.(js|ts)' 'examples/**/*.(js|jsx|ts)' 'e2e/**/*.(js|ts)' 'playwright.config.ts'",
"format:fix": "prettier --loglevel silent --write '**/*.(md|json)' 'src/**/*.(js|ts)' 'examples/**/*.(js|jsx|ts)' 'e2e/**/*.(js|ts)' 'playwright.config.ts'",
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@package.json` around lines 54 - 55, The package.json npm script "format" has
a glob mismatch with "format:fix" for examples (format excludes .ts while
format:fix includes it); update the "format" script's examples glob to match
"format:fix" (change 'examples/**/*.(js|jsx)' to 'examples/**/*.(js|jsx|ts)') so
both "format" and "format:fix" use the same file set, and verify both scripts'
globs remain consistent across other entries.

@rolznz
Copy link
Contributor

rolznz commented Feb 17, 2026

Hi, thanks for your PR.

I don't think Playwright makes sense here, the JS SDK has no frontend files.

@DSanich
Copy link
Contributor Author

DSanich commented Feb 17, 2026

@rolznz Thanks for you answer 🙏

js-sdk is a library that runs in browser contexts (webln, OAuth flows, NWC). If we consider Jest as an example, it runs in Node.js and doesn't test that environment.

Playwright lets us verify that:

  • The bundled SDK loads and runs correctly in a real browser
  • Browser APIs (fetch, WebSocket) work as expected
  • Module resolution and imports work in the browser build

I created minimal HTML fixtures that load the SDK — they simulate how a real app would consume the library. This is a common pattern for testing JS libraries that target the browser.

The webln providers (OauthWeblnProvider, NostrWeblnProvider) are explicitly browser-based; E2E tests are the right way to validate them.

What do you think?

@rolznz
Copy link
Contributor

rolznz commented Feb 17, 2026

I think we need to do a plan here.

Some of your tests are mixing multiple things and is hard to follow.

For Playwright, what are the minimum tests that we can do that actually are needed?

I'd like most of the tests to be done for the JS SDK directly, not for the browser.

As it is right now it's very difficult for me to review.

@DSanich
Copy link
Contributor Author

DSanich commented Feb 17, 2026

@rolznz yes, sorry that PR has become so monstrous. As for minimizing Playwright, there is the following idea:

One test — load the bundled SDK in a browser and run a simple operation (e.g. SATS(10) or Client instantiation). This validates that the build works in a browser environment. Jest runs in Node and can't catch browser-specific bundle issues.

Everything else (Amount, FiatAmount, oauth Client, nwc parsing, LNClient constructor) can be moved to Jest with fetch/API mocks — they don't require browser APIs.

I can refactor it. For example, cancel this PR and share a new one with minimal Playwright usage, and the next PR will be porting my current implementation to Jest. I'm open to any advice regarding this plan 🙏

@rolznz
Copy link
Contributor

rolznz commented Feb 17, 2026

@DSanich that would be great, thanks.

Small PRs that do a single thing are best for us right now. For jest, please also check out the tests we already have and if you're ok to double check with me which ones are missing and are useful to add. We don't have e2e tests that use faucet.nwc.dev yet.

@DSanich
Copy link
Contributor Author

DSanich commented Feb 17, 2026

@rolznz Yes, I would be happy if you could point out which tests are missing so that we could add them selectively (for example, several tests in one PR within one module) to make your review more comfortable.

I am currently preparing a PR with the minimum required tests using Playwright.

@rolznz
Copy link
Contributor

rolznz commented Feb 18, 2026

@DSanich for inspiration you could look at the CLI tests: https://github.com/getAlby/cli/tree/master/src/test

Ideally if you could first make a PR with a single test so we can more easily review the test setup. E.g. A test that creates a wallet and then checks the balance, it should be 10_000 sats. Later we can add more tests.

@DSanich
Copy link
Contributor Author

DSanich commented Feb 18, 2026

@rolznz Hi! Yes, that's a great idea. I'll create such a test using Jest and publish a PR today.

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.

2 participants