diff --git a/packages/browser-tests/.eslintrc.cjs b/packages/browser-tests/.eslintrc.cjs index 5591af2222..5bbd70f5ff 100644 --- a/packages/browser-tests/.eslintrc.cjs +++ b/packages/browser-tests/.eslintrc.cjs @@ -12,7 +12,6 @@ module.exports = { plugins: ["import"], extends: ["eslint:recommended"], rules: { - "no-console": "off", "no-unused-vars": ["error", { "argsIgnorePattern": "^_", "ignoreRestSiblings": true }] }, globals: { diff --git a/packages/browser-tests/package.json b/packages/browser-tests/package.json index be9ef3bcf6..56e2e58a71 100644 --- a/packages/browser-tests/package.json +++ b/packages/browser-tests/package.json @@ -14,7 +14,7 @@ "build:server": "tsc -p tsconfig.json", "build:web": "esbuild web/index.ts --bundle --format=esm --platform=browser --outdir=dist/web && cp web/index.html dist/web/index.html", "build": "npm-run-all -s build:server build:web", - "docker:build": "docker build -t waku-browser-tests:local ." + "docker:build": "docker build -t waku-browser-tests:local . && docker tag waku-browser-tests:local waku-browser-tests:latest" }, "dependencies": { "@playwright/test": "^1.51.1", diff --git a/packages/browser-tests/playwright.config.ts b/packages/browser-tests/playwright.config.ts index da35e611c9..572b2268ec 100644 --- a/packages/browser-tests/playwright.config.ts +++ b/packages/browser-tests/playwright.config.ts @@ -13,7 +13,7 @@ if (!process.env.CI) { const EXAMPLE_PORT = process.env.EXAMPLE_PORT || "8080"; const BASE_URL = `http://127.0.0.1:${EXAMPLE_PORT}`; -const TEST_IGNORE = process.env.CI ? ["tests/docker-*.spec.ts"] : []; +const TEST_IGNORE = process.env.CI ? ["tests/e2e.spec.ts"] : []; export default defineConfig({ testDir: "./tests", diff --git a/packages/browser-tests/scripts/docker-entrypoint.sh b/packages/browser-tests/scripts/docker-entrypoint.sh index 90c80de862..7a09d78c1c 100644 --- a/packages/browser-tests/scripts/docker-entrypoint.sh +++ b/packages/browser-tests/scripts/docker-entrypoint.sh @@ -5,11 +5,14 @@ # Supports reading discovered addresses from /etc/addrs/addrs.env (10k sim pattern) echo "docker-entrypoint.sh" echo "Using address: $addrs1" -export WAKU_LIGHTPUSH_NODE="$addrs1" +# Only set WAKU_LIGHTPUSH_NODE if it's not already set and addrs1 is available +if [ -z "$WAKU_LIGHTPUSH_NODE" ] && [ -n "$addrs1" ]; then + export WAKU_LIGHTPUSH_NODE="$addrs1" +fi echo "Num Args: $#" echo "Args: $@" -echo "WAKU_LIGHTPUSH_NODE=$addrs1" +echo "WAKU_LIGHTPUSH_NODE=$WAKU_LIGHTPUSH_NODE" # Parse command line arguments while [[ $# -gt 0 ]]; do diff --git a/packages/browser-tests/tests/e2e.spec.ts b/packages/browser-tests/tests/e2e.spec.ts index 9254dda07b..5cf2c2505e 100644 --- a/packages/browser-tests/tests/e2e.spec.ts +++ b/packages/browser-tests/tests/e2e.spec.ts @@ -1,27 +1,27 @@ import { test, expect } from "@playwright/test"; import axios from "axios"; import { StartedTestContainer } from "testcontainers"; -import { ServiceNodesFleet } from "@waku/tests"; import { DefaultTestRoutingInfo } from "@waku/tests"; -import { - startBrowserTestsContainer, - stopContainer +import { + startBrowserTestsContainer, + stopContainer } from "./utils/container-helpers.js"; -import { - createTwoNodeNetwork, - getDockerAccessibleMultiaddr, - stopNwakuNodes +import { + createTwoNodeNetwork, + getDockerAccessibleMultiaddr, + stopNwakuNodes, + TwoNodeNetwork } from "./utils/nwaku-helpers.js"; -import { - ENV_BUILDERS, - TEST_CONFIG, - ASSERTIONS +import { + ENV_BUILDERS, + TEST_CONFIG, + ASSERTIONS } from "./utils/test-config.js"; test.describe.configure({ mode: "serial" }); let container: StartedTestContainer; -let nwakuNodes: ServiceNodesFleet; +let nwakuNodes: TwoNodeNetwork; let baseUrl: string; test.beforeAll(async () => { @@ -30,10 +30,14 @@ test.beforeAll(async () => { const lightPushPeerAddr = await getDockerAccessibleMultiaddr(nwakuNodes.nodes[0]); const result = await startBrowserTestsContainer({ - environment: ENV_BUILDERS.withLocalLightPush(lightPushPeerAddr), + environment: { + ...ENV_BUILDERS.withLocalLightPush(lightPushPeerAddr), + DEBUG: "waku:*", + WAKU_LIGHTPUSH_NODE: lightPushPeerAddr, + }, networkMode: "waku", }); - + container = result.container; baseUrl = result.baseUrl; }); @@ -67,14 +71,14 @@ test("WakuHeadless can discover nwaku peer and use it for light push", async () const peerInfoResponse = await axios.get(`${baseUrl}/waku/v1/peer-info`); ASSERTIONS.peerInfo(peerInfoResponse); - + const routingInfo = DefaultTestRoutingInfo; - + const subscriptionResults = await Promise.all([ nwakuNodes.nodes[0].ensureSubscriptions([routingInfo.pubsubTopic]), nwakuNodes.nodes[1].ensureSubscriptions([routingInfo.pubsubTopic]) ]); - + expect(subscriptionResults[0]).toBe(true); expect(subscriptionResults[1]).toBe(true); @@ -99,15 +103,15 @@ test("WakuHeadless can discover nwaku peer and use it for light push", async () nwakuNodes.nodes[0].messages(contentTopic), nwakuNodes.nodes[1].messages(contentTopic) ]); - + const totalMessages = node1Messages.length + node2Messages.length; expect(totalMessages).toBeGreaterThanOrEqual(1); const receivedMessages = [...node1Messages, ...node2Messages]; expect(receivedMessages.length).toBeGreaterThan(0); - + const receivedMessage = receivedMessages[0]; ASSERTIONS.messageContent(receivedMessage, testMessage, contentTopic); -}); \ No newline at end of file +}); diff --git a/packages/browser-tests/tests/integration.spec.ts b/packages/browser-tests/tests/integration.spec.ts index c5be3fcbf6..cb3686604e 100644 --- a/packages/browser-tests/tests/integration.spec.ts +++ b/packages/browser-tests/tests/integration.spec.ts @@ -19,9 +19,12 @@ let wakuNode: LightNode; test.beforeAll(async () => { const result = await startBrowserTestsContainer({ - environment: ENV_BUILDERS.withProductionEnr(), + environment: { + ...ENV_BUILDERS.withProductionEnr(), + DEBUG: "waku:*", + }, }); - + container = result.container; baseUrl = result.baseUrl; }); diff --git a/packages/browser-tests/tests/utils/container-helpers.ts b/packages/browser-tests/tests/utils/container-helpers.ts index d65686a544..a026dee446 100644 --- a/packages/browser-tests/tests/utils/container-helpers.ts +++ b/packages/browser-tests/tests/utils/container-helpers.ts @@ -43,12 +43,14 @@ export async function startBrowserTestsContainer( const container = await generic.start(); - // Set up container logging - await new Promise((r) => setTimeout(r, 5000)); - const logs = await container.logs({ tail: 100 }); + // Set up container logging - stream all output from the start + const logs = await container.logs(); logs.on("data", (b) => process.stdout.write("[container] " + b.toString())); logs.on("error", (err) => log.error("[container log error]", err)); + // Give container time to initialize + await new Promise((r) => setTimeout(r, 5000)); + const mappedPort = container.getMappedPort(8080); const baseUrl = `http://127.0.0.1:${mappedPort}`; diff --git a/packages/browser-tests/tests/utils/nwaku-helpers.ts b/packages/browser-tests/tests/utils/nwaku-helpers.ts index 8b7466b5f0..e51d56bcf0 100644 --- a/packages/browser-tests/tests/utils/nwaku-helpers.ts +++ b/packages/browser-tests/tests/utils/nwaku-helpers.ts @@ -1,17 +1,23 @@ -import { ServiceNode, ServiceNodesFleet } from "@waku/tests"; +import { ServiceNode } from "@waku/tests"; import { DefaultTestRoutingInfo } from "@waku/tests"; import { Logger } from "@waku/utils"; const log = new Logger("nwaku-helpers"); +export interface TwoNodeNetwork { + nodes: ServiceNode[]; +} + /** * Creates a two-node nwaku network following waku/tests patterns. * Node 1: Relay + Light Push (service provider) * Node 2: Relay only (network peer) */ -export async function createTwoNodeNetwork(): Promise { +export async function createTwoNodeNetwork(): Promise { log.info("Creating nwaku node 1 (Relay + Light Push)..."); - const lightPushNode = new ServiceNode("lightpush-node-" + Math.random().toString(36).substring(7)); + const lightPushNode = new ServiceNode( + "lightpush-node-" + Math.random().toString(36).substring(7), + ); const lightPushArgs = { relay: true, @@ -20,13 +26,15 @@ export async function createTwoNodeNetwork(): Promise { store: false, clusterId: DefaultTestRoutingInfo.clusterId, numShardsInNetwork: DefaultTestRoutingInfo.networkConfig.numShardsInCluster, - contentTopic: [DefaultTestRoutingInfo.contentTopic] + contentTopic: [DefaultTestRoutingInfo.contentTopic], }; await lightPushNode.start(lightPushArgs, { retries: 3 }); log.info("Creating nwaku node 2 (Relay only)..."); - const relayNode = new ServiceNode("relay-node-" + Math.random().toString(36).substring(7)); + const relayNode = new ServiceNode( + "relay-node-" + Math.random().toString(36).substring(7), + ); // Connect second node to first node (following ServiceNodesFleet pattern) const firstNodeAddr = await lightPushNode.getExternalMultiaddr(); @@ -38,7 +46,7 @@ export async function createTwoNodeNetwork(): Promise { staticnode: firstNodeAddr, clusterId: DefaultTestRoutingInfo.clusterId, numShardsInNetwork: DefaultTestRoutingInfo.networkConfig.numShardsInCluster, - contentTopic: [DefaultTestRoutingInfo.contentTopic] + contentTopic: [DefaultTestRoutingInfo.contentTopic], }; await relayNode.start(relayArgs, { retries: 3 }); @@ -50,12 +58,9 @@ export async function createTwoNodeNetwork(): Promise { // Verify connectivity (optional, for debugging) await verifyNetworkFormation([lightPushNode, relayNode]); - // Return ServiceNodesFleet-compatible object - // Note: We're returning a partial ServiceNodesFleet for testing purposes return { nodes: [lightPushNode, relayNode], - messageCollector: null - } as ServiceNodesFleet; + }; } /** @@ -69,10 +74,10 @@ async function verifyNetworkFormation(nodes: ServiceNode[]): Promise { const peers = await node.peers(); log.info(`Node ${index + 1} has ${peers.length} peer(s)`); return peers.length; - }) + }), ); - if (peerCounts.every(count => count === 0)) { + if (peerCounts.every((count) => count === 0)) { log.warn("⚠️ Nodes may not be properly connected yet"); } } catch (error) { @@ -84,7 +89,9 @@ async function verifyNetworkFormation(nodes: ServiceNode[]): Promise { * Extracts Docker-accessible multiaddr from nwaku node. * Returns multiaddr using container's internal IP for Docker network communication. */ -export async function getDockerAccessibleMultiaddr(node: ServiceNode): Promise { +export async function getDockerAccessibleMultiaddr( + node: ServiceNode, +): Promise { // Get multiaddr with localhost and extract components const localhostMultiaddr = await node.getMultiaddrWithId(); const peerId = await node.getPeerId(); @@ -100,7 +107,9 @@ export async function getDockerAccessibleMultiaddr(node: ServiceNode): Promise { log.info("Stopping nwaku nodes..."); try { - await Promise.all(nodes.map(node => node.stop())); + await Promise.all(nodes.map((node) => node.stop())); log.info("Nwaku nodes stopped successfully"); } catch (error) { const message = error instanceof Error ? error.message : String(error); diff --git a/packages/browser-tests/web/index.ts b/packages/browser-tests/web/index.ts index 7ed1dbe033..c292be99e5 100644 --- a/packages/browser-tests/web/index.ts +++ b/packages/browser-tests/web/index.ts @@ -334,14 +334,17 @@ export class WakuHeadless { private async dialPreferredLightpushNode() { if (!this.waku || !this.lightpushNode) { + log.info("Skipping dial: waku or lightpushNode not set"); return; } try { + log.info("Attempting to dial preferred lightpush node:", this.lightpushNode); await this.waku.dial(this.lightpushNode); + log.info("Successfully dialed preferred lightpush node:", this.lightpushNode); } catch (error) { const message = error instanceof Error ? error.message : String(error); - log.warn( + log.error( "Failed to dial preferred lightpush node:", this.lightpushNode, message @@ -388,6 +391,12 @@ export class WakuHeadless { const globalLightpushNode = testWindow.__WAKU_LIGHTPUSH_NODE; const globalEnrBootstrap = testWindow.__WAKU_ENR_BOOTSTRAP; + log.info("Global config from window:", { + networkConfig: globalNetworkConfig, + lightpushNode: globalLightpushNode, + enrBootstrap: globalEnrBootstrap + }); + const instance = new WakuHeadless( globalNetworkConfig, globalLightpushNode,