-
Notifications
You must be signed in to change notification settings - Fork 43
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
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
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" |
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" | ||
} | ||
} | ||
] | ||
}; | ||
|
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"] |
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 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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"] | ||
] | ||
}' | ||
``` |
Original file line number | Diff line number | Diff line change | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
@@ -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", | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: can we group similar commands, please?
Suggested change
|
||||||||||
"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", | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we should be able instead of 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" | ||||||||||
} | ||||||||||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if
browser-tests
depends onheadless-tests
- then they should be defined in different order in the arrayalso, 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.