Corda Automation Testing with Nightwatch.js and CircleCI

Chainstack
Chainstack
Published in
5 min readJan 7, 2020

Testing is an integral part of software development. In Chainstack, we do not only test the platform but also ensure all blockchain protocols work perfectly. In this post, I will share how we carry out end-to-end continuous Corda integration with Nightwatch.js and CircleCI.

The code in Corda is written using Kotlin, a programming language from JetBrains, and Nightwatch.js is a Node.js powered end-to-end testing framework. Our challenges are to connect to a node, initiate a flow, and have it signed by relevant parties using JavaScript.

We have a few ideas to do this:

  • Run a Corda web server in our Docker image, and write JavaScript to interact to the CorDapp.
  • Set up GraalVM (a high-performance polyglot VM) in our Docker image, write a Java function in Nightwatch.js.
  • Interact with Corda Standalone Shell client by executing a shell script in Node.js, then verify the output of the shell script.

The first two ideas seem possible, but we need to include CorDapp source code in the test, which is non-optimal and inconvenient. Eventually, the last one is better and simpler.

We use No ticket scalping CorDapp for our test. You may want to explore it before moving to details.

Technology stack

These are the details of programming languages, tools, and frameworks we used in the test:

I assume that you are familiar with the Nightwatch.js framework, so I won’t focus on the structure as well as the test case code.

Besides the Corda Standalone Shell client, Chainstack also provides Chainstack standalone shell, which is a containerized version of Corda Standalone Shell, and which helps you interact with the CorDapps. You can learn more about it in our official documentation.

You need to install OpenJDK-8 to run Corda Standalone Shell client; add the following lines into your Docker file.

# Install OpenJDK-8 RUN apt-get update && \ apt-get install -y openjdk-8-jdk && \ apt-get install -y ant && \ apt-get clean; # Fix certificate issues RUN apt-get update && \ apt-get install ca-certificates-java && \ apt-get clean && \ update-ca-certificates -f; # Setup JAVA_HOME -- useful for docker commandline ENV JAVA_HOME /usr/lib/jvm/java-8-openjdk-amd64/ RUN export JAVA_HOME

You may need to build your Docker image again.

docker build .

You can learn the prerequisites to run Corda Standalone Shell client at Chainstack Docs.

The below script will do the following things:

  • Connect to Corda Node 1.
  • Print out all flows in Node 1.
  • Start noScalpFlow flow to distribute 99 tickets of event Chainstack live concert from Node 1 to Node 2.
  • Verify the transaction by executing the vaultQuery command.
  • Exit the Corda Standalone Shell client.
# location of binary files CORDA_CLI="corda-tools-shell-cli-4.3-all.jar" CORDAPP_DIR="../my-cordapps/" # node 1 credentials NODE1_HOST="nd-255-728-694.rg-837-380.int.chainstack.com" NODE1_PORT="10201" NODE1_USER="vibrant_ptolemy" NODE1_PASS="*****" # node 2 legal name NODE2_LEGALNAME="OU=Chainstack-ND-026-270-261, O=Chainstack, L=Singapore, C=SG" # command to connect to Corda node 1 START_CORDAPP="java -jar $CORDA_CLI --host=$NODE1_HOST --port=$NODE1_PORT --user=$NODE1_USER --password=$NODE1_PASS --cordapp-directory=$CORDAPP_DIR" # launch the Corda Standalone Shell client and run flow commands { echo "flow list" echo "start noScalpFlow eventName: 'Chainstack live concert', ticketQuantity: 99, toDistributor: '$NODE2_LEGALNAME'" echo "run vaultQuery contractStateType: com.noScalpDapp.states.noScalpState" echo "bye" } | $START_CORDAPP

Save as a start_cordapp.sh file, and run it in the terminal.

Checking the output, there should be a transaction. You can use this information to verify whether the test passed or not.

Flow completed with result: SignedTransaction(id=C98A2B49358B9FC6C1C8EEBAA99DF36238E9E4F97CF492905C2A1EF25B1B9639)

In the below code, I write a function to start the noScalpFlow flow, print out, and verify its result. In Node.js, the child_process module provides the ability to spawn child processes.

Then, I combine child_process.exe() and util.promisify() to create an async function which returns a boolean Promise.

// Nodejs utils to execute the shell script asynchronously const { promisify } = require('util'); const exec = promisify(require('child_process').exec); /** * Run noScalpFlow flow and verify the result * @param {Object} node1 First node * @param {Object} node2 Second node */ async function verifyFlow(node1, node2) { const CORDA_CLI = 'corda-tools-shell-cli-4.3-all.jar'; const CORDAPP_DIR = '../my-cordapps/'; const START_CORDAPP = `java -jar ${CORDA_CLI} --host=${node1.host} --port=${node1.port} --user=${node1.user} --password=${node1.pass} --cordapp-directory=${CORDAPP_DIR}`; // launch the Corda Shell client and run flow commands const { stdout } = await exec(` START_CORDAPP="${START_CORDAPP}" { echo "flow list" echo "start noScalpFlow eventName: 'Chainstack live concert', ticketQuantity: 99, toDistributor: '${node2.legalName}'" echo "run vaultQuery contractStateType: com.noScalpDapp.states.noScalpState" echo "bye" } | $START_CORDAPP `); // Print out the output console.log(stdout); // Verify the output return stdout.includes('Flow completed with result: SignedTransaction'); }

After that, you need a test scenario using the Nightwatch.js framework.

// Node 1 credentials const node1 = { host: 'nd-255-728-694.rg-837-380.int.chainstack.com', port: '10201', user: 'vibrant_ptolemy', pass: '*****', }; // Node 2 legal name const node2 = { legalName: 'OU=Chainstack-ND-026-270-261, O=Chainstack, L=Singapore, C=SG', }; module.exports = { '@tags': ['runCorDappFlow'], 'Run CorDapp flow'(browser) { const { page } = browser; const corda = page.nodes.corda(); // Run flow and verify result browser.perform(async () => { await corda.verifyFlow(node1, node2); }); browser.end(); }, };

Commit your code and run the workflow in CircleCI; it will take a few minutes to complete. In my scenario, I get the credentials of Node 1 and Node 2, run the noScalpFlow flow, and verify the output. You can see the results in the below screenshot.

Before writing this post, I have done a lot of research to find the best solution for Corda automation testing as most of the resources from the Internet focus on building CorDapps. I believe this post will help your team to test, speed up, and secure your Corda applications like what the Chainstack team is doing.

You can try Chainstack for free at https://console.chainstack.com.

Originally published at https://chainstack.com on January 7, 2020.

--

--

Chainstack
Chainstack

Managed blockchain services making it simple to launch and scale decentralized networks and applications.