diff --git a/.github/workflows/haskell-wasm.yml b/.github/workflows/haskell-wasm.yml index 3222d398cc..dd2b82ed10 100644 --- a/.github/workflows/haskell-wasm.yml +++ b/.github/workflows/haskell-wasm.yml @@ -142,6 +142,21 @@ jobs: run: | wasm32-wasi-cabal build cardano-wasm --no-semaphore -j1 --ghc-options="-j1" + - name: Prepare example + run: | + cp $(env -u CABAL_CONFIG wasm32-wasi-cabal list-bin exe:cardano-wasm | tail -n1) cardano-wasm/example/ + $(wasm32-wasi-ghc --print-libdir)/post-link.mjs -i "$(env -u CABAL_CONFIG wasm32-wasi-cabal list-bin exe:cardano-wasm | tail -n1)" -o cardano-wasm/example/cardano-wasm.js + cp cardano-wasm/lib-wrapper/* cardano-wasm/example/ + + - uses: rrbutani/use-nix-shell-action@v1 + with: + devShell: .#playwright + + - name: Run playwright test in example + run: | + httpserver -h localhost -a 127.0.0.1 -p 8080 cardano-wasm/example & + playwright test cardano-wasm/js-test/basic-test.spec.ts + # - name: Run tests # env: # TMPDIR: ${{ runner.temp }} diff --git a/cardano-wasm/example/example.js b/cardano-wasm/example/example.js index 4c58158830..743c4195a4 100644 --- a/cardano-wasm/example/example.js +++ b/cardano-wasm/example/example.js @@ -9,30 +9,61 @@ async function get_protocol_params() { let protocolParams = await get_protocol_params(); +const output = document.createElement("code"); +output.innerText = ""; +output.id = "test-output"; +document.body.appendChild(output); + +function log(out) { + console.log(out); + if (typeof(out) == "object") { + output.innerText += "> [object] {\n"; + for (let [key, val] of Object.entries(out)) { + let text = val.toString(); + if (typeof(val) == "function") { + text = text.split("{")[0]; + } + output.innerText += "    " + key + ": " + text + "\n"; + } + output.innerText += "  }\n"; + } else { + output.innerText += "> " + JSON.stringify(out) + "\n"; + } +} + +function finish_test() { + let finishTag = document.createElement("p"); + finishTag.innerText = "Finished test!"; + finishTag.id = "finish-tag"; + document.body.appendChild(finishTag); +} + async function do_async_work() { let api = await promise; - console.log("Api object:"); - console.log(api); + log("Api object:"); + log(api); let emptyTx = await api.newConwayTx(); - console.log("UnsignedTx object:"); - console.log(emptyTx); + log("UnsignedTx object:"); + log(emptyTx); let tx = await emptyTx.addTxInput("be6efd42a3d7b9a00d09d77a5d41e55ceaf0bd093a8aa8a893ce70d9caafd978", 0) - .addSimpleTxOut("addr_test1vzpfxhjyjdlgk5c0xt8xw26avqxs52rtf69993j4tajehpcue4v2v", 10_000_000n) + .addSimpleTxOut("addr_test1vzpfxhjyjdlgk5c0xt8xw26avqxs52rtf69993j4tajehpcue4v2v", 10_000_000n) let feeEstimate = await tx.estimateMinFee(protocolParams, 1, 0, 0); - console.log("Estimated fee:"); - console.log(feeEstimate); + log("Estimated fee:"); + log(feeEstimate); let signedTx = await tx.setFee(feeEstimate) - .signWithPaymentKey("addr_sk1648253w4tf6fv5fk28dc7crsjsaw7d9ymhztd4favg3cwkhz7x8sl5u3ms"); - console.log("SignedTx object:"); - console.log(signedTx); + .signWithPaymentKey("addr_sk1648253w4tf6fv5fk28dc7crsjsaw7d9ymhztd4favg3cwkhz7x8sl5u3ms"); + log("SignedTx object:"); + log(signedTx); let txCbor = await signedTx.txToCbor(); - console.log("Tx CBOR:"); - console.log(txCbor); + log("Tx CBOR:"); + log(txCbor); + + finish_test(); } do_async_work().then(() => { }); diff --git a/cardano-wasm/example/index.html b/cardano-wasm/example/index.html index 2efd25a184..3c6107bd9a 100644 --- a/cardano-wasm/example/index.html +++ b/cardano-wasm/example/index.html @@ -1,7 +1,10 @@ + + cardano-wasm test + + + +

Test output

+ - - - - - \ No newline at end of file + diff --git a/cardano-wasm/js-test/basic-test.spec.ts b/cardano-wasm/js-test/basic-test.spec.ts new file mode 100644 index 0000000000..e05313fc21 --- /dev/null +++ b/cardano-wasm/js-test/basic-test.spec.ts @@ -0,0 +1,9 @@ +import { test, expect } from '@playwright/test'; + +test('test output matches', async ({ page }) => { + await page.goto('http://localhost:8080'); + await expect(page).toHaveTitle(/cardano-wasm test/); + await expect(page.locator('#finish-tag')).toHaveText("Finished test!"); + await expect(page.locator('#test-output')).toHaveText('> "Api object:"> [object] { objectType: cardano-api newConwayTx: async function (...args) }> "UnsignedTx object:"> [object] { objectType: UnsignedTx addTxInput: function(txId,txIx) addSimpleTxOut: function(destAddr,lovelaceAmount) setFee: function(lovelaceAmount) estimateMinFee: function(protocolParams,numKeyWitnesses,numByronKeyWitnesses,totalRefScriptSize) signWithPaymentKey: function(signingKey) }> "Estimated fee:"> 164005> "SignedTx object:"> [object] { objectType: SignedTx alsoSignWithPaymentKey: function(signingKey) txToCbor: function() }> "Tx CBOR:"> "84a300d9010281825820be6efd42a3d7b9a00d09d77a5d41e55ceaf0bd093a8aa8a893ce70d9caafd97800018182581d6082935e44937e8b530f32ce672b5d600d0a286b4e8a52c6555f659b871a00989680021a000280a5a100d9010281825820adfc1c30385916da87db1ba3328f0690a57ebb2a6ac9f6f86b2d97f943adae005840a49259b5977aea523b46f01261fbff93e0899e8700319e11f5ab96b67eb628fca1a233ce2d50ee3227b591b84f27237d920d63974d65728362382f751c4d9400f5f6"'); +}); + diff --git a/flake.nix b/flake.nix index 59567ac51e..4c87c68a59 100644 --- a/flake.nix +++ b/flake.nix @@ -207,19 +207,34 @@ ]; }; }; + playwrightShell = let + playwright-pkgs = inputs.nixpkgs.legacyPackages.${system}; + in { + playwright = playwright-pkgs.mkShell { + packages = [ + playwright-pkgs.playwright-test + playwright-pkgs.python313Packages.docopt + playwright-pkgs.python313Packages.httpserver + ]; + }; + }; flakeWithWasmShell = nixpkgs.lib.recursiveUpdate flake { devShells = wasmShell; hydraJobs = {devShells = wasmShell;}; }; + flakeWithPlaywrightShell = nixpkgs.lib.recursiveUpdate flakeWithWasmShell { + devShells = playwrightShell; + hydraJobs = {devShells = playwrightShell;}; + }; in - nixpkgs.lib.recursiveUpdate flakeWithWasmShell rec { + nixpkgs.lib.recursiveUpdate flakeWithPlaywrightShell rec { project = cabalProject; # add a required job, that's basically all hydraJobs. hydraJobs = nixpkgs.callPackages inputs.iohkNix.utils.ciJobsAggregates { ciJobs = - flakeWithWasmShell.hydraJobs + flakeWithPlaywrightShell.hydraJobs // { # This ensure hydra send a status for the required job (even if no change other than commit hash) revision = nixpkgs.writeText "revision" (inputs.self.rev or "dirty");