mirror of
https://github.com/logos-messaging/lab.waku.org.git
synced 2026-01-03 14:23:14 +00:00
dogfooding light push v3
This commit is contained in:
parent
a1b991b1ed
commit
a7710da542
5
.github/workflows/ci.yml
vendored
5
.github/workflows/ci.yml
vendored
@ -50,6 +50,11 @@ jobs:
|
||||
fi
|
||||
working-directory: "examples/${{ matrix.example }}"
|
||||
|
||||
- name: Install Playwright browsers
|
||||
run: npx playwright install --with-deps
|
||||
working-directory: "examples/${{ matrix.example }}"
|
||||
if: matrix.example == 'dogfooding'
|
||||
|
||||
- name: test
|
||||
run: npm run test --if-present
|
||||
working-directory: "examples/${{ matrix.example }}"
|
||||
|
||||
13
examples/dogfooding/.gitignore
vendored
Normal file
13
examples/dogfooding/.gitignore
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
# Playwright
|
||||
playwright-report/
|
||||
test-results/
|
||||
playwright/.cache/
|
||||
|
||||
# Build output
|
||||
build/
|
||||
|
||||
# Dependencies
|
||||
node_modules/
|
||||
|
||||
# OS files
|
||||
.DS_Store
|
||||
161
examples/dogfooding/package-lock.json
generated
161
examples/dogfooding/package-lock.json
generated
@ -10,18 +10,20 @@
|
||||
"dependencies": {
|
||||
"@libp2p/crypto": "^5.0.5",
|
||||
"@multiformats/multiaddr": "^12.3.1",
|
||||
"@waku/sdk": "0.0.32-4997440.0",
|
||||
"@waku/sdk": "0.0.32-b0a2e39.0",
|
||||
"libp2p": "^2.1.10",
|
||||
"protobufjs": "^7.3.0",
|
||||
"uint8arrays": "^5.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@libp2p/interface": "^2.1.3",
|
||||
"@playwright/test": "^1.53.1",
|
||||
"@types/node": "^20.12.11",
|
||||
"copy-webpack-plugin": "^11.0.0",
|
||||
"eslint": "^8",
|
||||
"eslint-config-next": "13.5.6",
|
||||
"html-webpack-plugin": "^5.6.3",
|
||||
"playwright": "^1.53.1",
|
||||
"ts-loader": "^9.5.1",
|
||||
"typescript": "^5.4.5",
|
||||
"webpack": "^5.74.0",
|
||||
@ -783,6 +785,22 @@
|
||||
"node": ">=12.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@playwright/test": {
|
||||
"version": "1.53.1",
|
||||
"resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.53.1.tgz",
|
||||
"integrity": "sha512-Z4c23LHV0muZ8hfv4jw6HngPJkbbtZxTkxPNIg7cJcTc9C28N/p2q7g3JZS2SiKBBHJ3uM1dgDye66bB7LEk5w==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"playwright": "1.53.1"
|
||||
},
|
||||
"bin": {
|
||||
"playwright": "cli.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@protobufjs/aspromise": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz",
|
||||
@ -1315,16 +1333,16 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@waku/discovery": {
|
||||
"version": "0.0.9-4997440.0",
|
||||
"resolved": "https://registry.npmjs.org/@waku/discovery/-/discovery-0.0.9-4997440.0.tgz",
|
||||
"integrity": "sha512-cNJking/6FgHdl0e9x3MC/j7P7jBRn7rF1qU3PPvJ5EiugPcLyrxFRVZocZj4EQzYar7wY909MqNnlA+tGwCaQ==",
|
||||
"version": "0.0.9-b0a2e39.0",
|
||||
"resolved": "https://registry.npmjs.org/@waku/discovery/-/discovery-0.0.9-b0a2e39.0.tgz",
|
||||
"integrity": "sha512-4dmWAWX16fWecn7xI2WtbuQgoiuHiExF8ch7puv1pTrlLlbrtLm2miWbvgyraacBLUpn12UXUQOuZaM7lMGzGQ==",
|
||||
"license": "MIT OR Apache-2.0",
|
||||
"dependencies": {
|
||||
"@waku/core": "0.0.36-4997440.0",
|
||||
"@waku/enr": "0.0.30-4997440.0",
|
||||
"@waku/interfaces": "0.0.31-4997440.0",
|
||||
"@waku/proto": "0.0.11-4997440.0",
|
||||
"@waku/utils": "0.0.24-4997440.0",
|
||||
"@waku/core": "0.0.36-b0a2e39.0",
|
||||
"@waku/enr": "0.0.30-b0a2e39.0",
|
||||
"@waku/interfaces": "0.0.31-b0a2e39.0",
|
||||
"@waku/proto": "0.0.11-b0a2e39.0",
|
||||
"@waku/utils": "0.0.24-b0a2e39.0",
|
||||
"debug": "^4.3.4",
|
||||
"dns-over-http-resolver": "^3.0.8",
|
||||
"hi-base32": "^0.5.1",
|
||||
@ -1335,17 +1353,17 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@waku/discovery/node_modules/@waku/core": {
|
||||
"version": "0.0.36-4997440.0",
|
||||
"resolved": "https://registry.npmjs.org/@waku/core/-/core-0.0.36-4997440.0.tgz",
|
||||
"integrity": "sha512-1Z8bKLL8fFU7DeeAw+7iDazeNOayudnOSHIT4sP0pxnEe2kpLAaF5C5E0TeRj4Jk43f8xzTKmCMXXwN8/IbFgw==",
|
||||
"version": "0.0.36-b0a2e39.0",
|
||||
"resolved": "https://registry.npmjs.org/@waku/core/-/core-0.0.36-b0a2e39.0.tgz",
|
||||
"integrity": "sha512-c3cXUE45Q5SdwJ9RZXKGhl0cQwu8zkK3GMAfhNoRqMl/qLhRo+Y1u5m45KbG8HasH4Pjpibw8DkMmEjSd0OdRA==",
|
||||
"license": "MIT OR Apache-2.0",
|
||||
"dependencies": {
|
||||
"@libp2p/ping": "2.0.1",
|
||||
"@noble/hashes": "^1.3.2",
|
||||
"@waku/enr": "0.0.30-4997440.0",
|
||||
"@waku/interfaces": "0.0.31-4997440.0",
|
||||
"@waku/proto": "0.0.11-4997440.0",
|
||||
"@waku/utils": "0.0.24-4997440.0",
|
||||
"@waku/enr": "0.0.30-b0a2e39.0",
|
||||
"@waku/interfaces": "0.0.31-b0a2e39.0",
|
||||
"@waku/proto": "0.0.11-b0a2e39.0",
|
||||
"@waku/utils": "0.0.24-b0a2e39.0",
|
||||
"debug": "^4.3.4",
|
||||
"it-all": "^3.0.4",
|
||||
"it-length-prefixed": "^9.0.4",
|
||||
@ -1419,9 +1437,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@waku/enr": {
|
||||
"version": "0.0.30-4997440.0",
|
||||
"resolved": "https://registry.npmjs.org/@waku/enr/-/enr-0.0.30-4997440.0.tgz",
|
||||
"integrity": "sha512-LHSJhCFCgEpHuoRWndUlE3JXXKUnHwokL+Av8zSvJPQTbpmSiH/RtFchk4w58muVGQNNzevGkXcNNEZ6/LhtZg==",
|
||||
"version": "0.0.30-b0a2e39.0",
|
||||
"resolved": "https://registry.npmjs.org/@waku/enr/-/enr-0.0.30-b0a2e39.0.tgz",
|
||||
"integrity": "sha512-6/Uij9zErjUXDUGvmpdMDCCTWngJXkagbGxvNoij0VOfCe6M5wul/VV6qmlepZTbkoTKcv91k3stdrqv1jXaiw==",
|
||||
"license": "MIT OR Apache-2.0",
|
||||
"dependencies": {
|
||||
"@ethersproject/rlp": "^5.7.0",
|
||||
@ -1429,7 +1447,7 @@
|
||||
"@libp2p/peer-id": "^5.0.1",
|
||||
"@multiformats/multiaddr": "^12.0.0",
|
||||
"@noble/secp256k1": "^1.7.1",
|
||||
"@waku/utils": "0.0.24-4997440.0",
|
||||
"@waku/utils": "0.0.24-b0a2e39.0",
|
||||
"debug": "^4.3.4",
|
||||
"js-sha3": "^0.9.2"
|
||||
},
|
||||
@ -1446,18 +1464,18 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@waku/interfaces": {
|
||||
"version": "0.0.31-4997440.0",
|
||||
"resolved": "https://registry.npmjs.org/@waku/interfaces/-/interfaces-0.0.31-4997440.0.tgz",
|
||||
"integrity": "sha512-dV0o08C+NDCPTV1xzw6nfikC+1GnBszcY3/Vf2qD6RiZZxNygt9de0N1/c1xgEdGx1eVSrk/XZg8ImNsSl5qLg==",
|
||||
"version": "0.0.31-b0a2e39.0",
|
||||
"resolved": "https://registry.npmjs.org/@waku/interfaces/-/interfaces-0.0.31-b0a2e39.0.tgz",
|
||||
"integrity": "sha512-VXTnq+NA5qLPbwS7nB8hRQjN6D4VY+SUc6eYx5SB2d1MpgBkAyHFD9tKM12yHiIm5N2XFouj5eYzngaMguHF1A==",
|
||||
"license": "MIT OR Apache-2.0",
|
||||
"engines": {
|
||||
"node": ">=20"
|
||||
}
|
||||
},
|
||||
"node_modules/@waku/proto": {
|
||||
"version": "0.0.11-4997440.0",
|
||||
"resolved": "https://registry.npmjs.org/@waku/proto/-/proto-0.0.11-4997440.0.tgz",
|
||||
"integrity": "sha512-DkFrWxzryt25mBmeRXwu/h3sR4yMGxRCujDc3fswUW8JssKdCu81QBcOaX6XBy6sda8D8lDdN0399MVY5g3Yyw==",
|
||||
"version": "0.0.11-b0a2e39.0",
|
||||
"resolved": "https://registry.npmjs.org/@waku/proto/-/proto-0.0.11-b0a2e39.0.tgz",
|
||||
"integrity": "sha512-SQcL5rjSpTUy+1xSjHtq0GLgPd9NGTwCpZRRVu5K7GeN5tVZ5lyVtdXnO7MPVaWW/LYzbc7Fb2QtNxroi8sJ7w==",
|
||||
"license": "MIT OR Apache-2.0",
|
||||
"dependencies": {
|
||||
"protons-runtime": "^5.4.0"
|
||||
@ -1467,9 +1485,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@waku/sdk": {
|
||||
"version": "0.0.32-4997440.0",
|
||||
"resolved": "https://registry.npmjs.org/@waku/sdk/-/sdk-0.0.32-4997440.0.tgz",
|
||||
"integrity": "sha512-3PMJYOUSj6PNL/JGqsRBvKxd4n8RltCKXJ13S97h4x3iGUR5CCYtN5vXa71ePUIL+wtXEhoGVpOZVsgKrZrXuw==",
|
||||
"version": "0.0.32-b0a2e39.0",
|
||||
"resolved": "https://registry.npmjs.org/@waku/sdk/-/sdk-0.0.32-b0a2e39.0.tgz",
|
||||
"integrity": "sha512-UFoWy9PqtsbUz30qfnvAjrM+uVgCm5NWuzXCl6jyHdgyxplmUFkAfCHLoMTG9SG/ORiC5z07Jru+kOJoNtY5Eg==",
|
||||
"license": "MIT OR Apache-2.0",
|
||||
"dependencies": {
|
||||
"@chainsafe/libp2p-noise": "16.0.0",
|
||||
@ -1479,11 +1497,11 @@
|
||||
"@libp2p/ping": "2.0.1",
|
||||
"@libp2p/websockets": "^9.0.1",
|
||||
"@noble/hashes": "^1.3.3",
|
||||
"@waku/core": "0.0.36-4997440.0",
|
||||
"@waku/discovery": "0.0.9-4997440.0",
|
||||
"@waku/interfaces": "0.0.31-4997440.0",
|
||||
"@waku/proto": "0.0.11-4997440.0",
|
||||
"@waku/utils": "0.0.24-4997440.0",
|
||||
"@waku/core": "0.0.36-b0a2e39.0",
|
||||
"@waku/discovery": "0.0.9-b0a2e39.0",
|
||||
"@waku/interfaces": "0.0.31-b0a2e39.0",
|
||||
"@waku/proto": "0.0.11-b0a2e39.0",
|
||||
"@waku/utils": "0.0.24-b0a2e39.0",
|
||||
"libp2p": "2.1.8"
|
||||
},
|
||||
"engines": {
|
||||
@ -1491,17 +1509,17 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@waku/sdk/node_modules/@waku/core": {
|
||||
"version": "0.0.36-4997440.0",
|
||||
"resolved": "https://registry.npmjs.org/@waku/core/-/core-0.0.36-4997440.0.tgz",
|
||||
"integrity": "sha512-1Z8bKLL8fFU7DeeAw+7iDazeNOayudnOSHIT4sP0pxnEe2kpLAaF5C5E0TeRj4Jk43f8xzTKmCMXXwN8/IbFgw==",
|
||||
"version": "0.0.36-b0a2e39.0",
|
||||
"resolved": "https://registry.npmjs.org/@waku/core/-/core-0.0.36-b0a2e39.0.tgz",
|
||||
"integrity": "sha512-c3cXUE45Q5SdwJ9RZXKGhl0cQwu8zkK3GMAfhNoRqMl/qLhRo+Y1u5m45KbG8HasH4Pjpibw8DkMmEjSd0OdRA==",
|
||||
"license": "MIT OR Apache-2.0",
|
||||
"dependencies": {
|
||||
"@libp2p/ping": "2.0.1",
|
||||
"@noble/hashes": "^1.3.2",
|
||||
"@waku/enr": "0.0.30-4997440.0",
|
||||
"@waku/interfaces": "0.0.31-4997440.0",
|
||||
"@waku/proto": "0.0.11-4997440.0",
|
||||
"@waku/utils": "0.0.24-4997440.0",
|
||||
"@waku/enr": "0.0.30-b0a2e39.0",
|
||||
"@waku/interfaces": "0.0.31-b0a2e39.0",
|
||||
"@waku/proto": "0.0.11-b0a2e39.0",
|
||||
"@waku/utils": "0.0.24-b0a2e39.0",
|
||||
"debug": "^4.3.4",
|
||||
"it-all": "^3.0.4",
|
||||
"it-length-prefixed": "^9.0.4",
|
||||
@ -1573,13 +1591,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@waku/utils": {
|
||||
"version": "0.0.24-4997440.0",
|
||||
"resolved": "https://registry.npmjs.org/@waku/utils/-/utils-0.0.24-4997440.0.tgz",
|
||||
"integrity": "sha512-abWy/tUpJLEEX9lbTIl/1TfDuODc5Og55T5n1vtzrb7xTPdaBxOlx0jbGcQdZO/ZfrunKJEY7Vdb/Ofh4XW/DQ==",
|
||||
"version": "0.0.24-b0a2e39.0",
|
||||
"resolved": "https://registry.npmjs.org/@waku/utils/-/utils-0.0.24-b0a2e39.0.tgz",
|
||||
"integrity": "sha512-p8ZvIhROTrUFX+T2CKgepIypkWcHEMdJaJsIrxTIRb8xC412FiWNGGzViAJZ43rckvUatooEER/dvZ55ANFAyw==",
|
||||
"license": "MIT OR Apache-2.0",
|
||||
"dependencies": {
|
||||
"@noble/hashes": "^1.3.2",
|
||||
"@waku/interfaces": "0.0.31-4997440.0",
|
||||
"@waku/interfaces": "0.0.31-b0a2e39.0",
|
||||
"chai": "^4.3.10",
|
||||
"debug": "^4.3.4",
|
||||
"uint8arrays": "^5.0.1"
|
||||
@ -3107,9 +3125,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/dns-over-http-resolver": {
|
||||
"version": "3.0.15",
|
||||
"resolved": "https://registry.npmjs.org/dns-over-http-resolver/-/dns-over-http-resolver-3.0.15.tgz",
|
||||
"integrity": "sha512-h2Ldu6b8LjW725Q5zjjv7T5s1K3dPjlU3DWvcEFqB3Ksb3QmqC4dHhPKlGlBS/1P47D4T5arZMiE4dD4OIfO6A==",
|
||||
"version": "3.0.16",
|
||||
"resolved": "https://registry.npmjs.org/dns-over-http-resolver/-/dns-over-http-resolver-3.0.16.tgz",
|
||||
"integrity": "sha512-Qnq8HhNRuMnA61pf1lVPlStCAv1BVrraCx0umPESWgYKf995tUMF5oNhW59PKdnf7E8d5yqwHlEoFywXjsNMCw==",
|
||||
"license": "Apache-2.0 OR MIT",
|
||||
"dependencies": {
|
||||
"quick-lru": "^7.0.0",
|
||||
@ -7167,6 +7185,53 @@
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/playwright": {
|
||||
"version": "1.53.1",
|
||||
"resolved": "https://registry.npmjs.org/playwright/-/playwright-1.53.1.tgz",
|
||||
"integrity": "sha512-LJ13YLr/ocweuwxyGf1XNFWIU4M2zUSo149Qbp+A4cpwDjsxRPj7k6H25LBrEHiEwxvRbD8HdwvQmRMSvquhYw==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"playwright-core": "1.53.1"
|
||||
},
|
||||
"bin": {
|
||||
"playwright": "cli.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"fsevents": "2.3.2"
|
||||
}
|
||||
},
|
||||
"node_modules/playwright-core": {
|
||||
"version": "1.53.1",
|
||||
"resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.53.1.tgz",
|
||||
"integrity": "sha512-Z46Oq7tLAyT0lGoFx4DOuB1IA9D1TPj0QkYxpPVUnGDqHHvDpCftu1J2hM2PiWsNMoZh8+LQaarAWcDfPBc6zg==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"bin": {
|
||||
"playwright-core": "cli.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/playwright/node_modules/fsevents": {
|
||||
"version": "2.3.2",
|
||||
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
|
||||
"integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
|
||||
"dev": true,
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/possible-typed-array-names": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz",
|
||||
|
||||
@ -4,23 +4,27 @@
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"build": "NODE_ENV=production webpack --config webpack.config.js --mode production",
|
||||
"start": "webpack-dev-server"
|
||||
"start": "webpack-dev-server",
|
||||
"test": "playwright test",
|
||||
"test:ui": "playwright test --ui"
|
||||
},
|
||||
"dependencies": {
|
||||
"@libp2p/crypto": "^5.0.5",
|
||||
"@multiformats/multiaddr": "^12.3.1",
|
||||
"@waku/sdk": "0.0.32-4997440.0",
|
||||
"@waku/sdk": "0.0.32-b0a2e39.0",
|
||||
"libp2p": "^2.1.10",
|
||||
"protobufjs": "^7.3.0",
|
||||
"uint8arrays": "^5.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@libp2p/interface": "^2.1.3",
|
||||
"@playwright/test": "^1.53.1",
|
||||
"@types/node": "^20.12.11",
|
||||
"copy-webpack-plugin": "^11.0.0",
|
||||
"eslint": "^8",
|
||||
"eslint-config-next": "13.5.6",
|
||||
"html-webpack-plugin": "^5.6.3",
|
||||
"playwright": "^1.53.1",
|
||||
"ts-loader": "^9.5.1",
|
||||
"typescript": "^5.4.5",
|
||||
"webpack": "^5.74.0",
|
||||
|
||||
81
examples/dogfooding/playwright-report/index.html
Normal file
81
examples/dogfooding/playwright-report/index.html
Normal file
File diff suppressed because one or more lines are too long
27
examples/dogfooding/playwright.config.ts
Normal file
27
examples/dogfooding/playwright.config.ts
Normal file
@ -0,0 +1,27 @@
|
||||
import { defineConfig, devices } from '@playwright/test';
|
||||
|
||||
export default defineConfig({
|
||||
testDir: './tests',
|
||||
fullyParallel: true,
|
||||
forbidOnly: !!process.env.CI,
|
||||
retries: process.env.CI ? 2 : 0,
|
||||
workers: process.env.CI ? 1 : undefined,
|
||||
reporter: 'html',
|
||||
use: {
|
||||
baseURL: 'http://localhost:8080',
|
||||
trace: 'on-first-retry',
|
||||
},
|
||||
|
||||
projects: [
|
||||
{
|
||||
name: 'chromium',
|
||||
use: { ...devices['Desktop Chrome'] },
|
||||
},
|
||||
],
|
||||
|
||||
webServer: {
|
||||
command: 'npm start',
|
||||
port: 8080,
|
||||
reuseExistingServer: !process.env.CI,
|
||||
},
|
||||
});
|
||||
17
examples/dogfooding/src/light-push-errors.ts
Normal file
17
examples/dogfooding/src/light-push-errors.ts
Normal file
@ -0,0 +1,17 @@
|
||||
// Light Push V3 Error Code Mapping
|
||||
export const LIGHT_PUSH_V3_ERRORS: Record<string, string> = {
|
||||
'not_published_to_any_peer': 'Message was not relayed to any peers. This can happen if the remote peer has no relay connections.',
|
||||
'rate_limited': 'Message rejected due to rate limiting. Please slow down message sending.',
|
||||
'bad_request': 'Invalid message format or parameters.',
|
||||
'internal_server_error': 'Remote peer encountered an internal error.',
|
||||
'no_peers_available': 'No suitable peers found for relaying the message.',
|
||||
'duplicate_message': 'Message already exists in the network.',
|
||||
'message_too_large': 'Message exceeds the maximum allowed size.',
|
||||
'invalid_topic': 'The pubsub topic or content topic is invalid.',
|
||||
'unauthorized': 'Not authorized to publish to this topic.',
|
||||
'service_unavailable': 'Light Push service temporarily unavailable.'
|
||||
};
|
||||
|
||||
export function getLightPushErrorMessage(error: string): string {
|
||||
return LIGHT_PUSH_V3_ERRORS[error] || `Unknown Light Push error: ${error}`;
|
||||
}
|
||||
84
examples/dogfooding/tests/app.spec.ts
Normal file
84
examples/dogfooding/tests/app.spec.ts
Normal file
@ -0,0 +1,84 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
|
||||
test.describe('Waku Dogfooding App', () => {
|
||||
test('should load the app and initialize Waku node', async ({ page }) => {
|
||||
// Navigate to the app
|
||||
await page.goto('/');
|
||||
|
||||
// Wait for the app to load
|
||||
await expect(page).toHaveTitle(/Waku/);
|
||||
|
||||
// Wait for Waku node initialization
|
||||
await page.waitForFunction(() => {
|
||||
return (window as any).waku !== undefined;
|
||||
}, { timeout: 30000 });
|
||||
|
||||
// Verify Waku node is available and has expected properties
|
||||
const wakuNodeInfo = await page.evaluate(() => {
|
||||
const waku = (window as any).waku;
|
||||
if (!waku) return null;
|
||||
|
||||
return {
|
||||
isStarted: typeof waku.isStarted === 'function' ? waku.isStarted() : false,
|
||||
peerId: waku.peerId?.toString() || null,
|
||||
hasLightPush: !!waku.lightPush,
|
||||
hasFilter: !!waku.filter,
|
||||
hasStore: !!waku.store,
|
||||
};
|
||||
});
|
||||
|
||||
// Assert Waku node is properly initialized
|
||||
expect(wakuNodeInfo).not.toBeNull();
|
||||
expect(wakuNodeInfo?.isStarted).toBe(true);
|
||||
expect(wakuNodeInfo?.peerId).toBeTruthy();
|
||||
expect(wakuNodeInfo?.hasLightPush).toBe(true);
|
||||
expect(wakuNodeInfo?.hasFilter).toBe(true);
|
||||
expect(wakuNodeInfo?.hasStore).toBe(true);
|
||||
|
||||
// Verify UI elements are present
|
||||
await expect(page.locator('#peerIdDisplay')).toBeVisible();
|
||||
await expect(page.locator('#peerIdDisplay')).not.toHaveText('Connecting...');
|
||||
// Peer IDs can start with either 16Uiu2 or 12D3KooW depending on the key type
|
||||
const peerIdText = await page.locator('#peerIdDisplay').textContent();
|
||||
expect(peerIdText).toMatch(/^(16Uiu2|12D3KooW)/);
|
||||
|
||||
// Verify send message button is present
|
||||
await expect(page.locator('#sendMessageButton')).toBeVisible();
|
||||
});
|
||||
|
||||
test('should display peer ID in the UI', async ({ page }) => {
|
||||
await page.goto('/');
|
||||
|
||||
// Wait for peer ID to be displayed
|
||||
await page.waitForSelector('#peerIdDisplay', { state: 'visible' });
|
||||
|
||||
// Wait for the actual peer ID to load (not "Connecting...")
|
||||
await page.waitForFunction(() => {
|
||||
const el = document.querySelector('#peerIdDisplay');
|
||||
return el && el.textContent !== 'Connecting...';
|
||||
}, { timeout: 30000 });
|
||||
|
||||
const peerIdText = await page.locator('#peerIdDisplay').textContent();
|
||||
expect(peerIdText).toBeTruthy();
|
||||
expect(peerIdText).toMatch(/^(16Uiu2|12D3KooW)/); // Peer IDs can start with either prefix
|
||||
});
|
||||
|
||||
test('should have functional message sending UI', async ({ page }) => {
|
||||
await page.goto('/');
|
||||
|
||||
// Wait for Waku node to be ready
|
||||
await page.waitForFunction(() => {
|
||||
return (window as any).waku !== undefined;
|
||||
}, { timeout: 30000 });
|
||||
|
||||
// Check counters are initialized
|
||||
await expect(page.locator('#sentByMeCount')).toHaveText('0');
|
||||
await expect(page.locator('#receivedMineCount')).toHaveText('0');
|
||||
await expect(page.locator('#receivedOthersCount')).toHaveText('0');
|
||||
await expect(page.locator('#failedToSendCount')).toHaveText('0');
|
||||
|
||||
// Verify send button is enabled
|
||||
const sendButton = page.locator('#sendMessageButton');
|
||||
await expect(sendButton).toBeEnabled();
|
||||
});
|
||||
});
|
||||
151
examples/dogfooding/tests/lightpush.spec.ts
Normal file
151
examples/dogfooding/tests/lightpush.spec.ts
Normal file
@ -0,0 +1,151 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
|
||||
test.describe('Light Push Messages', () => {
|
||||
test('should send 5 messages over 30 seconds with at least one success', async ({ page }) => {
|
||||
test.setTimeout(60000); // Set timeout to 60 seconds for this test
|
||||
|
||||
// Navigate to the app
|
||||
await page.goto('/');
|
||||
|
||||
// Wait for Waku node initialization
|
||||
await page.waitForFunction(() => {
|
||||
return (window as any).waku !== undefined;
|
||||
}, { timeout: 30000 });
|
||||
|
||||
// Wait for peer ID to be displayed (indicates node is ready)
|
||||
await page.waitForSelector('#peerIdDisplay', { state: 'visible' });
|
||||
await page.waitForFunction(() => {
|
||||
const el = document.querySelector('#peerIdDisplay');
|
||||
return el && el.textContent !== 'Connecting...';
|
||||
}, { timeout: 30000 });
|
||||
|
||||
// Remove webpack dev server overlay if it exists
|
||||
await page.evaluate(() => {
|
||||
const overlay = document.querySelector('#webpack-dev-server-client-overlay');
|
||||
if (overlay) {
|
||||
overlay.remove();
|
||||
}
|
||||
});
|
||||
|
||||
// Get initial counter values
|
||||
const getCounters = async () => {
|
||||
return await page.evaluate(() => {
|
||||
return {
|
||||
sent: parseInt(document.querySelector('#sentByMeCount')?.textContent || '0'),
|
||||
receivedMine: parseInt(document.querySelector('#receivedMineCount')?.textContent || '0'),
|
||||
receivedOthers: parseInt(document.querySelector('#receivedOthersCount')?.textContent || '0'),
|
||||
failed: parseInt(document.querySelector('#failedToSendCount')?.textContent || '0')
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
const initialCounters = await getCounters();
|
||||
console.log('Initial counters:', initialCounters);
|
||||
|
||||
// Send 5 messages over 30 seconds (one every 6 seconds)
|
||||
const sendButton = page.locator('#sendMessageButton');
|
||||
const messagesPerBatch = 5; // Based on NUM_MESSAGES_PER_BATCH in the app
|
||||
let totalMessagesSent = 0;
|
||||
|
||||
for (let i = 0; i < 5; i++) {
|
||||
console.log(`Sending batch ${i + 1} of 5...`);
|
||||
|
||||
// Click send button (use force if needed to bypass any overlays)
|
||||
await sendButton.click({ force: true });
|
||||
totalMessagesSent += messagesPerBatch;
|
||||
|
||||
// Wait 6 seconds before next batch (except for the last one)
|
||||
if (i < 4) {
|
||||
await page.waitForTimeout(6000);
|
||||
}
|
||||
}
|
||||
|
||||
// Wait a bit for the last messages to be processed
|
||||
await page.waitForTimeout(3000);
|
||||
|
||||
// Get final counter values
|
||||
const finalCounters = await getCounters();
|
||||
console.log('Final counters:', finalCounters);
|
||||
|
||||
// Calculate the changes
|
||||
const sentMessages = finalCounters.sent - initialCounters.sent;
|
||||
const receivedMine = finalCounters.receivedMine - initialCounters.receivedMine;
|
||||
const failedMessages = finalCounters.failed - initialCounters.failed;
|
||||
const totalProcessed = sentMessages + failedMessages;
|
||||
|
||||
console.log(`Messages sent successfully (according to lightPush): ${sentMessages}`);
|
||||
console.log(`Messages received back (mine): ${receivedMine}`);
|
||||
console.log(`Messages failed: ${failedMessages}`);
|
||||
console.log(`Total messages processed: ${totalProcessed}`);
|
||||
console.log(`Total messages expected: ${totalMessagesSent}`);
|
||||
|
||||
// Verify at least one message was successfully delivered
|
||||
// A message is considered successful if either:
|
||||
// 1. Light push reports success (sentMessages > 0), OR
|
||||
// 2. We received our own messages back via Filter (receivedMine > 0)
|
||||
const successfulDeliveries = sentMessages + receivedMine;
|
||||
expect(successfulDeliveries).toBeGreaterThan(0);
|
||||
|
||||
// Verify that at least 20 out of 25 messages were processed (either sent or failed)
|
||||
// Allowing for some messages to be lost due to timing or network issues
|
||||
expect(totalProcessed).toBeGreaterThanOrEqual(20);
|
||||
|
||||
// Additional verification: check message log
|
||||
const allMessageElements = await page.locator('.message-item').count();
|
||||
console.log(`Total messages in UI: ${allMessageElements}`);
|
||||
expect(allMessageElements).toBeGreaterThan(0);
|
||||
|
||||
// Log success rate based on actual delivery
|
||||
const effectiveSuccessRate = (receivedMine / totalMessagesSent) * 100;
|
||||
console.log(`Effective delivery rate: ${effectiveSuccessRate.toFixed(2)}%`);
|
||||
});
|
||||
|
||||
test('should handle message failures gracefully', async ({ page }) => {
|
||||
// Navigate to the app
|
||||
await page.goto('/');
|
||||
|
||||
// Wait for Waku node initialization
|
||||
await page.waitForFunction(() => {
|
||||
return (window as any).waku !== undefined;
|
||||
}, { timeout: 30000 });
|
||||
|
||||
// Remove webpack dev server overlay if it exists
|
||||
await page.evaluate(() => {
|
||||
const overlay = document.querySelector('#webpack-dev-server-client-overlay');
|
||||
if (overlay) {
|
||||
overlay.remove();
|
||||
}
|
||||
});
|
||||
|
||||
// Monitor console for error messages
|
||||
const consoleErrors: string[] = [];
|
||||
page.on('console', (msg) => {
|
||||
if (msg.type() === 'error' || msg.type() === 'warning') {
|
||||
consoleErrors.push(msg.text());
|
||||
}
|
||||
});
|
||||
|
||||
// Send a batch of messages
|
||||
const sendButton = page.locator('#sendMessageButton');
|
||||
await sendButton.click({ force: true });
|
||||
|
||||
// Wait for processing
|
||||
await page.waitForTimeout(3000);
|
||||
|
||||
// Check if failed counter is visible and functional
|
||||
const failedCount = await page.locator('#failedToSendCount').textContent();
|
||||
expect(failedCount).toBeDefined();
|
||||
|
||||
// If there were failures, verify they were logged properly
|
||||
const failedMessages = parseInt(failedCount || '0');
|
||||
if (failedMessages > 0) {
|
||||
// Check for failed messages in the UI
|
||||
const failedMessageElements = await page.locator('.message-item.failed').count();
|
||||
expect(failedMessageElements).toBe(failedMessages);
|
||||
|
||||
// Verify error details are displayed
|
||||
const firstFailedMessage = page.locator('.message-item.failed').first();
|
||||
await expect(firstFailedMessage).toContainText('Failed');
|
||||
}
|
||||
});
|
||||
});
|
||||
234
examples/dogfooding/tests/multi-node.spec.ts
Normal file
234
examples/dogfooding/tests/multi-node.spec.ts
Normal file
@ -0,0 +1,234 @@
|
||||
import { test, expect, Browser, BrowserContext, Page } from '@playwright/test';
|
||||
|
||||
test.describe('Multi-Node Light Push Messages', () => {
|
||||
test('should send messages between two nodes and track delivery', async ({ browser }) => {
|
||||
test.setTimeout(90000); // Set timeout to 90 seconds for this test
|
||||
|
||||
// Create two separate browser contexts (like incognito windows)
|
||||
const context1 = await browser.newContext();
|
||||
const context2 = await browser.newContext();
|
||||
|
||||
// Create pages in each context
|
||||
const page1 = await context1.newPage();
|
||||
const page2 = await context2.newPage();
|
||||
|
||||
// Helper function to initialize a node
|
||||
const initializeNode = async (page: Page, nodeName: string) => {
|
||||
await page.goto('/');
|
||||
|
||||
// Wait for Waku node initialization
|
||||
await page.waitForFunction(() => {
|
||||
return (window as any).waku !== undefined;
|
||||
}, { timeout: 30000 });
|
||||
|
||||
// Wait for peer ID to be displayed
|
||||
await page.waitForSelector('#peerIdDisplay', { state: 'visible' });
|
||||
await page.waitForFunction(() => {
|
||||
const el = document.querySelector('#peerIdDisplay');
|
||||
return el && el.textContent !== 'Connecting...';
|
||||
}, { timeout: 30000 });
|
||||
|
||||
// Remove webpack dev server overlay if it exists
|
||||
await page.evaluate(() => {
|
||||
const overlay = document.querySelector('#webpack-dev-server-client-overlay');
|
||||
if (overlay) {
|
||||
overlay.remove();
|
||||
}
|
||||
});
|
||||
|
||||
// Get peer ID
|
||||
const peerId = await page.locator('#peerIdDisplay').textContent();
|
||||
console.log(`${nodeName} initialized with Peer ID: ${peerId}`);
|
||||
|
||||
return peerId;
|
||||
};
|
||||
|
||||
// Initialize both nodes
|
||||
console.log('Initializing Node 1...');
|
||||
const peerId1 = await initializeNode(page1, 'Node 1');
|
||||
|
||||
console.log('Initializing Node 2...');
|
||||
const peerId2 = await initializeNode(page2, 'Node 2');
|
||||
|
||||
// Helper function to get counters
|
||||
const getCounters = async (page: Page) => {
|
||||
return await page.evaluate(() => {
|
||||
return {
|
||||
sent: parseInt(document.querySelector('#sentByMeCount')?.textContent || '0'),
|
||||
receivedMine: parseInt(document.querySelector('#receivedMineCount')?.textContent || '0'),
|
||||
receivedOthers: parseInt(document.querySelector('#receivedOthersCount')?.textContent || '0'),
|
||||
failed: parseInt(document.querySelector('#failedToSendCount')?.textContent || '0')
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
// Get initial counters for both nodes
|
||||
const initialCounters1 = await getCounters(page1);
|
||||
const initialCounters2 = await getCounters(page2);
|
||||
|
||||
console.log('Initial counters Node 1:', initialCounters1);
|
||||
console.log('Initial counters Node 2:', initialCounters2);
|
||||
|
||||
// Send 5 batches of messages from Node 1
|
||||
console.log('\n--- Starting message sending from Node 1 ---');
|
||||
const sendButton1 = page1.locator('#sendMessageButton');
|
||||
const messagesPerBatch = 5;
|
||||
const totalBatches = 5;
|
||||
|
||||
for (let i = 0; i < totalBatches; i++) {
|
||||
console.log(`Node 1: Sending batch ${i + 1} of ${totalBatches}...`);
|
||||
await sendButton1.click({ force: true });
|
||||
|
||||
// Wait between batches
|
||||
if (i < totalBatches - 1) {
|
||||
await page1.waitForTimeout(3000);
|
||||
}
|
||||
}
|
||||
|
||||
// Wait for messages to propagate
|
||||
console.log('Waiting for message propagation...');
|
||||
await page1.waitForTimeout(5000);
|
||||
|
||||
// Get final counters for both nodes
|
||||
const finalCounters1 = await getCounters(page1);
|
||||
const finalCounters2 = await getCounters(page2);
|
||||
|
||||
console.log('\n--- Final Results ---');
|
||||
console.log('Final counters Node 1:', finalCounters1);
|
||||
console.log('Final counters Node 2:', finalCounters2);
|
||||
|
||||
// Calculate results for Node 1 (sender)
|
||||
const node1Results = {
|
||||
sent: finalCounters1.sent - initialCounters1.sent,
|
||||
receivedMine: finalCounters1.receivedMine - initialCounters1.receivedMine,
|
||||
receivedOthers: finalCounters1.receivedOthers - initialCounters1.receivedOthers,
|
||||
failed: finalCounters1.failed - initialCounters1.failed
|
||||
};
|
||||
|
||||
// Calculate results for Node 2 (receiver)
|
||||
const node2Results = {
|
||||
sent: finalCounters2.sent - initialCounters2.sent,
|
||||
receivedMine: finalCounters2.receivedMine - initialCounters2.receivedMine,
|
||||
receivedOthers: finalCounters2.receivedOthers - initialCounters2.receivedOthers,
|
||||
failed: finalCounters2.failed - initialCounters2.failed
|
||||
};
|
||||
|
||||
// Generate report
|
||||
console.log('\n========== DELIVERY REPORT ==========');
|
||||
console.log(`Total messages sent: ${messagesPerBatch * totalBatches}`);
|
||||
console.log('\nNode 1 (Sender):');
|
||||
console.log(` - Peer ID: ${peerId1}`);
|
||||
console.log(` - Messages sent successfully: ${node1Results.sent}`);
|
||||
console.log(` - Messages failed: ${node1Results.failed}`);
|
||||
console.log(` - Own messages received back: ${node1Results.receivedMine}`);
|
||||
console.log(` - Messages from others: ${node1Results.receivedOthers}`);
|
||||
|
||||
console.log('\nNode 2 (Receiver):');
|
||||
console.log(` - Peer ID: ${peerId2}`);
|
||||
console.log(` - Messages received from Node 1: ${node2Results.receivedOthers}`);
|
||||
console.log(` - Own messages received: ${node2Results.receivedMine}`);
|
||||
|
||||
const totalExpected = messagesPerBatch * totalBatches;
|
||||
const node1DeliveryRate = (node1Results.receivedMine / totalExpected) * 100;
|
||||
const node2DeliveryRate = (node2Results.receivedOthers / totalExpected) * 100;
|
||||
|
||||
console.log('\nDelivery Rates:');
|
||||
console.log(` - Node 1 self-delivery rate: ${node1DeliveryRate.toFixed(2)}%`);
|
||||
console.log(` - Node 2 reception rate: ${node2DeliveryRate.toFixed(2)}%`);
|
||||
console.log('=====================================\n');
|
||||
|
||||
// Verify at least one message was delivered
|
||||
expect(node1Results.receivedMine + node2Results.receivedOthers).toBeGreaterThan(0);
|
||||
|
||||
// Verify Node 2 received at least some messages from Node 1
|
||||
expect(node2Results.receivedOthers).toBeGreaterThan(0);
|
||||
|
||||
// Check message elements in UI
|
||||
const messageCount1 = await page1.locator('.message-item').count();
|
||||
const messageCount2 = await page2.locator('.message-item').count();
|
||||
|
||||
console.log(`Messages in Node 1 UI: ${messageCount1}`);
|
||||
console.log(`Messages in Node 2 UI: ${messageCount2}`);
|
||||
|
||||
// Cleanup
|
||||
await context1.close();
|
||||
await context2.close();
|
||||
});
|
||||
|
||||
test('should handle bidirectional messaging between two nodes', async ({ browser }) => {
|
||||
test.setTimeout(90000);
|
||||
|
||||
const context1 = await browser.newContext();
|
||||
const context2 = await browser.newContext();
|
||||
const page1 = await context1.newPage();
|
||||
const page2 = await context2.newPage();
|
||||
|
||||
// Initialize both nodes
|
||||
const initializeNode = async (page: Page, nodeName: string) => {
|
||||
await page.goto('/');
|
||||
await page.waitForFunction(() => (window as any).waku !== undefined, { timeout: 30000 });
|
||||
await page.waitForSelector('#peerIdDisplay', { state: 'visible' });
|
||||
await page.waitForFunction(() => {
|
||||
const el = document.querySelector('#peerIdDisplay');
|
||||
return el && el.textContent !== 'Connecting...';
|
||||
}, { timeout: 30000 });
|
||||
await page.evaluate(() => {
|
||||
const overlay = document.querySelector('#webpack-dev-server-client-overlay');
|
||||
if (overlay) overlay.remove();
|
||||
});
|
||||
const peerId = await page.locator('#peerIdDisplay').textContent();
|
||||
console.log(`${nodeName} initialized with Peer ID: ${peerId}`);
|
||||
return peerId;
|
||||
};
|
||||
|
||||
await initializeNode(page1, 'Node 1');
|
||||
await initializeNode(page2, 'Node 2');
|
||||
|
||||
// Helper to get message counts
|
||||
const getMessageCounts = async (page: Page) => {
|
||||
return await page.evaluate(() => {
|
||||
return {
|
||||
receivedOthers: parseInt(document.querySelector('#receivedOthersCount')?.textContent || '0')
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
const initial1 = await getMessageCounts(page1);
|
||||
const initial2 = await getMessageCounts(page2);
|
||||
|
||||
// Send messages from both nodes alternately
|
||||
console.log('\n--- Bidirectional messaging test ---');
|
||||
const sendButton1 = page1.locator('#sendMessageButton');
|
||||
const sendButton2 = page2.locator('#sendMessageButton');
|
||||
|
||||
for (let i = 0; i < 3; i++) {
|
||||
console.log(`Round ${i + 1}: Node 1 sending...`);
|
||||
await sendButton1.click({ force: true });
|
||||
await page1.waitForTimeout(2000);
|
||||
|
||||
console.log(`Round ${i + 1}: Node 2 sending...`);
|
||||
await sendButton2.click({ force: true });
|
||||
await page2.waitForTimeout(2000);
|
||||
}
|
||||
|
||||
// Wait for final propagation
|
||||
await page1.waitForTimeout(3000);
|
||||
|
||||
const final1 = await getMessageCounts(page1);
|
||||
const final2 = await getMessageCounts(page2);
|
||||
|
||||
const node1ReceivedFromNode2 = final1.receivedOthers - initial1.receivedOthers;
|
||||
const node2ReceivedFromNode1 = final2.receivedOthers - initial2.receivedOthers;
|
||||
|
||||
console.log('\n--- Bidirectional Results ---');
|
||||
console.log(`Node 1 received ${node1ReceivedFromNode2} messages from Node 2`);
|
||||
console.log(`Node 2 received ${node2ReceivedFromNode1} messages from Node 1`);
|
||||
|
||||
// Verify bidirectional communication
|
||||
expect(node1ReceivedFromNode2).toBeGreaterThan(0);
|
||||
expect(node2ReceivedFromNode1).toBeGreaterThan(0);
|
||||
|
||||
await context1.close();
|
||||
await context2.close();
|
||||
});
|
||||
});
|
||||
Loading…
x
Reference in New Issue
Block a user