Skip to content

Feature Request: Expand Node.js Bindings to Match Python Coverage #196

Description

@canomogollon

Feature Request: Expand Node.js Bindings to Match Python Coverage

Summary

The Node.js bindings for rustwright currently expose only ~11 methods (launch, newPage, goto, click, fill, title, textContent, evaluate, screenshot, close), while the Python bindings have 96% coverage (515/536 methods). This makes rustwright unusable for TypeScript/Node.js test suites that require features like storage_state, BrowserContext, Locator, and @playwright/test fixtures.

Background

I'm evaluating rustwright as a potential replacement for Playwright in a production TypeScript/Node.js project using modern web frameworks. The Python bindings are production-grade at 96% parity, but the Node.js bindings are too limited for real-world E2E testing.

Project Context

  • Stack: TypeScript/Node.js, Astro 5, Vue 3, Better Auth, Docker PostgreSQL
  • Test suite: 29 Playwright spec files using @playwright/test runner
  • Current Playwright usage: storage_state for auth persistence, BrowserContext for test isolation, Locator for assertions, fixtures for setup/teardown
  • Goal: Replace Playwright driver with rustwright to reduce memory (70% less) and improve startup time (2.55x faster)

Current Node.js Bindings

Available methods (~11):

launch, newPage, goto, click, fill, title, textContent, evaluate, screenshot, close (×2 variants)

Missing features critical for production E2E testing:

Feature Node.js Status Python Status Impact
storage_state (save/restore) ❌ Not bridged ✅ Available Blocks auth persistence (session cookies/tokens)
BrowserContext ❌ Not bridged ✅ 30/30 methods Blocks test isolation (29 spec files require this)
Locator (first-class) ❌ Not bridged ✅ 60/62 methods Blocks assertions (page.locator(), expect().toBeVisible(), etc.)
@playwright/test fixtures ❌ Not supported ✅ pytest fixtures Blocks test runner (cannot use existing test infrastructure)
Event waiters (waitForResponse, etc.) ❌ Not bridged ✅ Available Blocks E2E flows (wait for API responses, network idle, etc.)
Route/network interception ❌ Not bridged ✅ Available Blocks API mocking (mock backend responses in tests)

Use Case

Authentication Flow (Session Management)

// This is what we need to do in production test suites:
test('user can access dashboard after login', async ({ page, context }) => {
  // Save auth state after login
  await context.storageState({ path: 'auth.json' });
  
  // Restore auth state in subsequent tests
  const context = await browser.newContext({ storageState: 'auth.json' });
  const page = await context.newPage();
  
  // Navigate to protected route
  await page.goto('/dashboard');
  
  // Assert authenticated state
  await expect(page.locator('[data-testid="user-menu"]')).toBeVisible();
});

Current Node.js limitation: Cannot save/restore storage_state, so every test would need to re-authenticate (slow, flaky).

Test Isolation

// Each test needs isolated context:
test.describe('User management', () => {
  test('create user', async ({ page }) => {
    // Independent context, cookies don't leak between tests
    await page.goto('/users');
    await page.click('[data-testid="create-user"]');
    // ...
  });
  
  test('delete user', async ({ page }) => {
    // Fresh context, no state from previous test
    await page.goto('/users');
    // ...
  });
});

Current Node.js limitation: No BrowserContext means no test isolation. Tests would share cookies/storage, causing flakiness.

Locator Assertions

// Modern Playwright tests use Locator extensively:
await expect(page.locator('.success-message')).toBeVisible();
await expect(page.getByTestId('user-table')).toHaveCount(10);
await page.locator('[data-testid="submit"]').click();

Current Node.js limitation: No Locator API, only basic click/fill with selectors. Cannot use expect() assertions.

Proposed Solution

Expand Node.js bindings to cover the same API surface as Python:

  1. Priority 1 (Critical for E2E testing):

    • BrowserContext (create, close, cookies, storageState)
    • Locator (query, click, fill, expect assertions)
    • storageState (save/restore)
  2. Priority 2 (Important for production use):

    • Event waiters (waitForResponse, waitForSelector, waitForLoadState)
    • Route/network interception (page.route(), request.continue())
    • @playwright/test integration (fixtures, reporters)
  3. Priority 3 (Nice to have):

    • Tracing/screenshots with full options
    • Frame/iframe support
    • Multi-tab support

Workaround

Currently, the only workaround is to use Python bindings (96% coverage), but this requires:

  • Separate test suite in Python (duplicating TypeScript tests)
  • Additional infrastructure (Python virtualenv, pytest, etc.)
  • More coordination (maintaining 2 test suites)

This defeats the purpose of rustwright as a drop-in replacement for TypeScript/Node.js projects.

Environment

  • rustwright version: 0.1.1 (npm)
  • Node.js version: 20.x
  • TypeScript version: 5.x
  • OS: Linux (Ubuntu 22.04)

Additional Context

The Python bindings are excellent (96% coverage, production-grade). The Node.js bindings appear to be an early alpha within an alpha. Expanding them would make rustwright viable for the large TypeScript/Node.js ecosystem, not just Python projects.

I'm willing to test early builds, provide feedback, and contribute documentation once the Node.js bindings expand.


Labels: enhancement, nodejs-bindings, api-parity
Milestone: Post-v1.0 (when behavioral parity stabilizes)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions