Skip to content

Add Playwright integration tests for River UI with Freenet backend #46

@sanity

Description

@sanity

Problem

River's existing integration tests (cli/tests/) test state logic directly via API calls but don't exercise the full web UI stack. This gap allowed a critical bug to go undetected:

  • Room creation works via web UI
  • Room joining via invitation hangs indefinitely in network mode
  • Local mode works perfectly (tested Nov 2025)

The bug exists somewhere in the contract request/response flow when running against a real Freenet network, but passes all existing tests because:

  1. CLI tests use direct API calls, bypassing the web UI sync layer
  2. freenet-test-network tests don't exercise the browser-based invitation flow

Proposed Solution

Add Playwright-based integration tests that exercise the River web UI against:

  1. Freenet local mode - Fast, deterministic, good for CI
  2. Freenet network mode (optional) - Slower, tests real p2p behavior

Test Scenarios

P0 - Critical Path

  • Create room via UI
  • Generate invitation URL
  • Second browser context joins via invitation URL
  • Verify both users see the room and each other

P1 - Core Functionality

  • Send/receive messages
  • Member list updates propagate to all participants
  • Room persists after page reload

P2 - Edge Cases

  • Decline invitation
  • Multiple concurrent joiners
  • Network disconnection/reconnection

Implementation Notes

A working Playwright test already exists at /tmp/playwright-test-river-join4.js (used for debugging). Key patterns:

// Two browser contexts simulate two users
const context1 = await browser.newContext();
const context2 = await browser.newContext();

// User 1 creates room
await page1.click('button:has-text("Create Room")');
// ... fill form ...

// Get invitation code from invite modal
const inviteUrl = await page1.locator('input[readonly]').first().inputValue();
const inviteCode = inviteUrl.match(/invitation=([^&]+)/)[1];

// User 2 joins via invitation URL
await page2.goto(`${TARGET_URL}?invitation=${inviteCode}`);
// Accept invitation in modal
await page2.locator('.modal button:has-text("Accept")').click();

// Verify success
await expect(page2.locator('body')).toContainText('Room Name');

CI Integration

For CI, run against local mode:

# Start Freenet in local mode
freenet --data-dir /tmp/test-data --config-dir /tmp/test-config local &

# Start River dev server (proxies to :7509)
cd river/main && cargo make dev &

# Run Playwright tests
npx playwright test

Context

This issue originated from debugging session on Nov 2025 where room joining was found to hang in network mode but work perfectly in local mode. The existing test infrastructure didn't catch this because no tests exercise the web UI against a real Freenet backend.

Related

  • Room join debugging (identified Nov 2025 - network mode specific issue)
  • River web UI uses Dioxus (Rust WASM) with signal-based state management
  • Key files: room_synchronizer.rs, freenet_synchronizer.rs, receive_invitation_modal.rs

[AI-assisted - Claude]

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