From 939138d0cd8e9fee24fd6b22b990450c5918709e Mon Sep 17 00:00:00 2001 From: Sebastian Miasojed Date: Tue, 14 Jan 2025 22:29:02 +0100 Subject: [PATCH] Add the revive tests in the browsers (#158) --- .github/workflows/build-revive-wasm.yml | 12 +++-- .gitignore | 3 ++ js/e2e/web.test.js | 63 ++++++++++++++++++++++ js/examples/web/index.html | 72 +++++++++++++++---------- js/examples/web/worker.js | 22 +------- js/package.json | 5 +- js/playwright.config.js | 52 ++++++++++++++++++ 7 files changed, 174 insertions(+), 55 deletions(-) create mode 100644 js/e2e/web.test.js create mode 100644 js/playwright.config.js diff --git a/.github/workflows/build-revive-wasm.yml b/.github/workflows/build-revive-wasm.yml index 1567676..c0db734 100644 --- a/.github/workflows/build-revive-wasm.yml +++ b/.github/workflows/build-revive-wasm.yml @@ -106,6 +106,7 @@ jobs: Set-ExecutionPolicy RemoteSigned -Scope CurrentUser iex (new-object net.webclient).downloadstring('https://get.scoop.sh') scoop install bun@${{ env.BUN_VERSION }} + scoop install wget Join-Path (Resolve-Path ~).Path "scoop\shims" >> $Env:GITHUB_PATH - name: Install Bun on macOS and Linux @@ -114,13 +115,16 @@ jobs: curl -fsSL https://bun.sh/install | bash -s bun-v${{ env.BUN_VERSION }} echo "$HOME/.bun/bin" >> $GITHUB_PATH - - name: Confirm Installations + - name: Install packages + run: npm install + + - name: Run Playwright tests run: | - node --version - bun --version + cd js + npx playwright install --with-deps + npx playwright test - name: Test revive run: | echo "Running tests for ${{ matrix.os }}" - npm install npm run test:wasm diff --git a/.gitignore b/.gitignore index 87ea520..dc2bedc 100644 --- a/.gitignore +++ b/.gitignore @@ -15,4 +15,7 @@ package-lock.json /*.html /build soljson.js +test-results +playwright-report +.cache emsdk diff --git a/js/e2e/web.test.js b/js/e2e/web.test.js new file mode 100644 index 0000000..c74f2d1 --- /dev/null +++ b/js/e2e/web.test.js @@ -0,0 +1,63 @@ +const { test, expect } = require('@playwright/test'); + +const validCompilerInput = { + language: 'Solidity', + sources: { + 'MyContract.sol': { + content: ` + // SPDX-License-Identifier: UNLICENSED + pragma solidity ^0.8.0; + contract MyContract { + function greet() public pure returns (string memory) { + return "Hello"; + } + } + `, + }, + }, + settings: { + optimizer: { + enabled: true, + runs: 200, + }, + outputSelection: { + '*': { + '*': ['abi', 'evm.bytecode'], + }, + }, + }, +}; + +async function runWorker(page, input) { + return await page.evaluate((input) => { + return new Promise((resolve, reject) => { + const worker = new Worker('worker.js'); // Path to your worker.js file + worker.postMessage(JSON.stringify(input)); + + worker.onmessage = (event) => { + resolve(event.data.output); + worker.terminate(); // Clean up the worker + }; + + worker.onerror = (error) => { + reject(error.message || error); // Provide error message for clarity + worker.terminate(); // Clean up the worker + }; + }); + }, input); // Pass the input as an argument to the function +} + +test('Test browser', async ({ page }) => { + await page.goto("http://127.0.0.1:8080"); + await page.setContent(""); + + const result = await runWorker(page, validCompilerInput); + + expect(typeof result).toBe('string'); + let output = JSON.parse(result); + expect(output).toHaveProperty('contracts'); + expect(output.contracts['MyContract.sol']).toHaveProperty('MyContract'); + expect(output.contracts['MyContract.sol'].MyContract).toHaveProperty('abi'); + expect(output.contracts['MyContract.sol'].MyContract).toHaveProperty('evm'); + expect(output.contracts['MyContract.sol'].MyContract.evm).toHaveProperty('bytecode'); +}); diff --git a/js/examples/web/index.html b/js/examples/web/index.html index 3123a26..959a24d 100644 --- a/js/examples/web/index.html +++ b/js/examples/web/index.html @@ -1,35 +1,51 @@ - - - Web Worker Example - - + + + Web Worker Example + + - -

Revive Compilation Output

-

-    
-
+            worker.postMessage(JSON.stringify(standardJsonInput));
+        
+    
 
 
diff --git a/js/examples/web/worker.js b/js/examples/web/worker.js
index 5ed8dd1..d32206e 100644
--- a/js/examples/web/worker.js
+++ b/js/examples/web/worker.js
@@ -4,32 +4,12 @@ importScripts('./resolc.js');
 
 // Handle messages from the main thread
 onmessage = async function (e) {
-  const contractCode = e.data.contractCode
-  const sourceCode = {
-      language: 'Solidity',
-      sources: {
-          contract: {
-              content: contractCode,
-          }
-      },
-      settings: {
-          optimizer: {
-            enabled: true,
-            runs: 200,
-          },
-          outputSelection: {
-              '*': {
-                '*': ['abi'],
-            }
-          }
-      }
-  };
     const m = createRevive();
 
     m.soljson = Module;
 
     // Set input data for stdin
-    m.writeToStdin(JSON.stringify(sourceCode));
+    m.writeToStdin(e.data);
 
     // Compile the Solidity source code
     m.callMain(['--standard-json']);
diff --git a/js/package.json b/js/package.json
index a3a7b50..f5f547a 100644
--- a/js/package.json
+++ b/js/package.json
@@ -8,11 +8,12 @@
     "fetch:soljson": "wget https://binaries.soliditylang.org/wasm/soljson-v0.8.28+commit.7893614a.js -O ./examples/web/soljson.js",
     "example:web": "npm run fetch:soljson && http-server ./examples/web/",
     "example:node": "node ./examples/node/run_revive.js",
-    "test:node": "mocha --timeout 10000 ./tests",
-    "test:bun": "bun test",
+    "test:node": "mocha --timeout 20000 ./tests",
+    "test:bun": "bun test --timeout 20000 node.test",
     "test:all": "npm run test:node && npm run test:bun"
   },
   "devDependencies": {
+    "@playwright/test": "^1.49.1",
     "chai": "^5.1.2",
     "http-server": "^14.1.1",
     "mocha": "^11.0.1"
diff --git a/js/playwright.config.js b/js/playwright.config.js
new file mode 100644
index 0000000..b89d659
--- /dev/null
+++ b/js/playwright.config.js
@@ -0,0 +1,52 @@
+const { defineConfig, devices } = require('@playwright/test');
+
+/**
+ * @see https://playwright.dev/docs/test-configuration
+ */
+module.exports = defineConfig({
+  testDir: './e2e',
+  /* Run tests in files in parallel */
+  fullyParallel: true,
+  /* Fail the build on CI if you accidentally left test.only in the source code. */
+  forbidOnly: !!process.env.CI,
+  /* Retry on CI only */
+  retries: process.env.CI ? 2 : 0,
+  /* Opt out of parallel tests on CI. */
+  workers: process.env.CI ? 1 : undefined,
+  /* Reporter to use. See https://playwright.dev/docs/test-reporters */
+  reporter: 'list',
+  /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
+  use: {
+    /* Base URL to use in actions like `await page.goto('/')`. */
+    baseURL: 'http://127.0.0.1:8080',
+
+    /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
+    trace: 'on-first-retry',
+  },
+
+  /* Configure projects for major browsers */
+  projects: [
+    {
+      name: 'chromium',
+      use: { ...devices['Desktop Chrome'] },
+    },
+
+    {
+      name: 'firefox',
+      use: { ...devices['Desktop Firefox'] },
+    },
+
+    {
+      name: 'webkit',
+      use: { ...devices['Desktop Safari'] },
+    }
+  ],
+
+  /* Run your local dev server before starting the tests */
+  webServer: {
+    command: 'npm run example:web',
+    url: 'http://127.0.0.1:8080',
+    reuseExistingServer: !process.env.CI,
+  },
+});
+