Skip to content

feat: headless app and api for testing js-waku in browser #2371

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,13 @@
"project": ["./tsconfig.json"]
},
"env": { "es6": true },
"ignorePatterns": ["node_modules", "build", "coverage", "proto"],
"ignorePatterns": [
"node_modules",
"build",
"coverage",
"proto",
"**/webpack.config.js"
],
"plugins": ["import", "eslint-comments", "functional"],
"extends": [
"eslint:recommended",
Expand Down
10 changes: 5 additions & 5 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
with:
repository: waku-org/js-waku

- uses: actions/setup-node@v3
with:
node-version: ${{ env.NODE_JS }}
Expand All @@ -37,7 +37,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
with:
repository: waku-org/js-waku
- uses: actions/setup-node@v3
with:
Expand All @@ -62,7 +62,7 @@ jobs:
HOME: "/root"
steps:
- uses: actions/checkout@v3
with:
with:
repository: waku-org/js-waku
- uses: actions/setup-node@v3
with:
Expand Down Expand Up @@ -150,7 +150,7 @@ jobs:
token: ${{ secrets.CI_TOKEN }}

- uses: actions/checkout@v3
with:
with:
repository: waku-org/js-waku
if: ${{ steps.release.outputs.releases_created }}

Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/playwright.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ jobs:

- uses: ./.github/actions/npm

- name: Build browser test environment
run: npm run build --workspace=@waku/browser-tests

- name: Run Playwright tests
run: npm run test --workspace=@waku/browser-tests

Expand Down
2,142 changes: 1,977 additions & 165 deletions package-lock.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"packages/rln",
"packages/tests",
"packages/browser-tests",
Copy link
Collaborator

Choose a reason for hiding this comment

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

if browser-tests depends on headless-tests - then they should be defined in different order in the array

also, about the naming, maybe it is better to rename:

  • browser-tests -> browser-container;
  • headless-tests -> browser-tests;

That way we define that one is container and another is test cases.

"packages/headless-tests",
"packages/build-utils",
"packages/react-native-polyfills"
],
Expand Down
4 changes: 2 additions & 2 deletions packages/browser-tests/.env.local
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
EXAMPLE_TEMPLATE="web-chat"
EXAMPLE_NAME="example"
EXAMPLE_TEMPLATE="headless"
EXAMPLE_NAME="headless"
EXAMPLE_PORT="8080"
35 changes: 30 additions & 5 deletions packages/browser-tests/.eslintrc.cjs
Original file line number Diff line number Diff line change
@@ -1,14 +1,39 @@
module.exports = {
root: true,
parserOptions: {
tsconfigRootDir: __dirname,
project: "./tsconfig.dev.json"
ecmaVersion: 2022,
sourceType: "module"
},
env: {
node: true,
browser: true,
es2021: true
},
plugins: ["import"],
extends: ["eslint:recommended"],
rules: {
"no-console": "off"
},
rules: {},
globals: {
process: true
}
},
overrides: [
{
files: ["*.spec.ts", "**/test_utils/*.ts"],
rules: {
"@typescript-eslint/no-non-null-assertion": "off",
"@typescript-eslint/no-explicit-any": "off",
"no-console": "off",
"import/no-extraneous-dependencies": ["error", { "devDependencies": true }]
}
},
{
files: ["*.ts"],
parser: "@typescript-eslint/parser",
parserOptions: {
tsconfigRootDir: __dirname,
project: "./tsconfig.dev.json"
}
}
]
};

59 changes: 59 additions & 0 deletions packages/browser-tests/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
FROM node:18-slim

# Install dependencies for Playwright and Chrome
RUN apt-get update && apt-get install -y \
wget \
gnupg \
procps \
libglib2.0-0 \
libnss3 \
libnspr4 \
libatk1.0-0 \
libatk-bridge2.0-0 \
libcups2 \
libdrm2 \
libxkbcommon0 \
libxcomposite1 \
libxdamage1 \
libxfixes3 \
libxrandr2 \
libgbm1 \
libasound2 \
libpango-1.0-0 \
libcairo2 \
libfontconfig1 \
&& rm -rf /var/lib/apt/lists/*

# Set working directory
WORKDIR /app

# Copy package.json files
COPY package.json ./
COPY tsconfig.json ./
COPY headless/package.json ./headless/
COPY types/ ./types/

# Install dependencies
RUN npm install
RUN cd headless && npm install

# Make sure serve is installed globally to avoid import issues
RUN npm install -g serve

# Copy project files
COPY . .

# Build headless package
RUN cd headless && npm run build

# Install Playwright browsers
RUN npx playwright install chromium

# Build TypeScript server
RUN npm run build:server

# Expose port for the API server
EXPOSE 3000

# Start the API server
CMD ["npm", "run", "start:server"]
155 changes: 155 additions & 0 deletions packages/browser-tests/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
# Waku Browser Tests

This project provides a system for testing the Waku SDK in a browser environment.

## Architecture

The system consists of:

1. **Headless Web App**: A simple web application (in the `@waku/headless-tests` package) that loads the Waku SDK and exposes shared API functions.
2. **Express Server**: A server that communicates with the headless app using Playwright.
3. **Shared API**: TypeScript functions shared between the server and web app.

## Setup

1. Install dependencies:

```bash
# Install main dependencies
npm install

# Install headless app dependencies
cd ../headless-tests
npm install
cd ../browser-tests
```

2. Build the application:

```bash
npm run build
```

This will:
- Build the headless web app using webpack
- Compile the TypeScript server code

## Running

Start the server with:

```bash
npm run start:server
```

This will:
1. Serve the headless app on port 8080
2. Start a headless browser to load the app
3. Expose API endpoints to interact with Waku

## API Endpoints
Copy link
Collaborator

Choose a reason for hiding this comment

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

🔥


- `GET /info`: Get information about the Waku node
- `GET /debug/v1/info`: Get debug information from the Waku node
- `POST /push`: Push a message to the Waku network (legacy)
- `POST /lightpush/v1/message`: Push a message to the Waku network (Waku REST API compatible)
- `POST /admin/v1/peers`: Dial to specified peers (Waku REST API compatible)
- `GET /filter/v2/messages/:contentTopic`: Subscribe to messages on a specific content topic using Server-Sent Events (Waku REST API compatible)
- `GET /filter/v1/messages/:contentTopic`: Retrieve stored messages from a content topic (Waku REST API compatible)

### Example: Pushing a message with the legacy endpoint

```bash
curl -X POST http://localhost:3000/push \
-H "Content-Type: application/json" \
-d '{"contentTopic": "/toy-chat/2/huilong/proto", "payload": [1, 2, 3]}'
```

### Example: Pushing a message with the Waku REST API compatible endpoint

```bash
curl -X POST http://localhost:3000/lightpush/v1/message \
-H "Content-Type: application/json" \
-d '{
"pubsubTopic": "/waku/2/rs/0/0",
"message": {
"payload": "SGVsbG8sIFdha3Uh",
"contentTopic": "/toy-chat/2/huilong/proto",
"timestamp": 1712135330213797632
}
}'
```

### Example: Executing a function

```bash
curl -X POST http://localhost:3000/execute \
-H "Content-Type: application/json" \
-d '{"functionName": "getPeerInfo", "params": []}'
```

### Example: Dialing to specific peers with the Waku REST API compatible endpoint

```bash
curl -X POST http://localhost:3000/admin/v1/peers \
-H "Content-Type: application/json" \
-d '{
"peerMultiaddrs": [
"/ip4/127.0.0.1/tcp/8000/p2p/16Uiu2HAm4v8KuHUH6Cwz3upPeQbkyxQJsFGPdt7kHtkN8F79QiE6"]
]
}'
```

### Example: Dialing to specific peers with the execute endpoint

```bash
curl -X POST http://localhost:3000/execute \
-H "Content-Type: application/json" \
-d '{
"functionName": "dialPeers",
"params": [
["/ip4/127.0.0.1/tcp/8000/p2p/16Uiu2HAm4v8KuHUH6Cwz3upPeQbkyxQJsFGPdt7kHtkN8F79QiE6"]
]
}'
```

### Example: Subscribing to a content topic with the filter endpoint

```bash
# Open a persistent connection to receive messages as Server-Sent Events
curl -N http://localhost:3000/filter/v2/messages/%2Ftoy-chat%2F2%2Fhuilong%2Fproto

# You can also specify clustering options
curl -N "http://localhost:3000/filter/v2/messages/%2Ftoy-chat%2F2%2Fhuilong%2Fproto?clusterId=0&shard=0"
```

### Example: Retrieving stored messages from a content topic

```bash
# Get the most recent 20 messages
curl http://localhost:3000/filter/v1/messages/%2Ftoy-chat%2F2%2Fhuilong%2Fproto

# Get messages with pagination and time filtering
curl "http://localhost:3000/filter/v1/messages/%2Ftoy-chat%2F2%2Fhuilong%2Fproto?pageSize=10&startTime=1712000000000&endTime=1713000000000&ascending=true"
```

## Extending

To add new functionality:

1. Add your function to `src/api/shared.ts`
2. Add your function to the `API` object in `src/api/shared.ts`
3. Use it via the server endpoints

### Example: Dialing to specific peers

```bash
curl -X POST http://localhost:3000/execute \
-H "Content-Type: application/json" \
-d '{
"functionName": "dialPeers",
"params": [
["/ip4/127.0.0.1/tcp/8000/p2p/16Uiu2HAm4v8KuHUH6Cwz3upPeQbkyxQJsFGPdt7kHtkN8F79QiE6"]
]
}'
```
33 changes: 24 additions & 9 deletions packages/browser-tests/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,31 @@
"private": true,
"type": "module",
"scripts": {
"start": "run-s start:*",
"start:setup": "node ./src/setup-example.js",
"start:build": "node ./src/build-example.js",
"start:serve": "npx serve -p 8080 --no-port-switching ./example",
"test": "npx playwright test"
"start": "npm run start:server",
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit: can we group similar commands, please?

Suggested change
"start": "npm run start:server",
"start": "npm run start:server",
"start:serve": "cd ../headless-tests && npx serve -p 8080 --no-port-switching . -s",
"start:server": "node ./dist/server.js",

"start:serve": "cd ../headless-tests && npx serve -p 8080 --no-port-switching . -s",
"start:server": "node ./dist/server.js",
"test": "npx playwright test",
"build:headless": "cd ../headless-tests && npm run build",
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think we should be able instead of cd ../headless-tests && npm run build to do something like npm run build --workspace=headless-tests in this and similar places, removing cd ../headless-tests altogether

let me know if it works, I am not 100% sure

"build:server": "tsc -p tsconfig.json",
"build": "run-s build:*"
},
"devDependencies": {
"@playwright/test": "^1.50.0",
"@waku/create-app": "^0.1.1-504bcd4",
"dotenv-flow": "^4.1.0",
"serve": "^14.2.3"
"@types/cors": "^2.8.15",
"@types/express": "^4.17.21",
"@types/node": "^20.10.0",
"@waku/headless-tests": "*",
"axios": "^1.8.4",
"dotenv-flow": "^0.4.0",
"npm-run-all": "^4.1.5",
"serve": "^14.2.3",
"typescript": "^5.3.0",
"webpack-cli": "^6.0.1"
},
"dependencies": {
"@playwright/test": "^1.51.1",
"@waku/sdk": "^0.0.30",
"cors": "^2.8.5",
"express": "^4.21.2",
"node-polyfill-webpack-plugin": "^4.1.0"
}
}
Loading
Loading