Skip to content

Commit

Permalink
Merge pull request #147 from matter-labs/QA-446-replacefixupdate2-api…
Browse files Browse the repository at this point in the history
…-tests

test: api integration tests for be
  • Loading branch information
abilevych authored Jan 18, 2024
2 parents 533b4ed + 610df0d commit 8a57793
Show file tree
Hide file tree
Showing 12 changed files with 462 additions and 45 deletions.
3 changes: 2 additions & 1 deletion .github/workflows/integration-tests-api.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ on: pull_request

jobs:
runTests:
name: Run API integration tests
timeout-minutes: 30
runs-on: ubuntu-latest
permissions:
Expand All @@ -14,6 +13,7 @@ jobs:
matrix:
node-version: ['lts/*'] # 18.17.1 or lts/*
test-pattern:
- accounts.test.ts
- addresses.test.ts
- batches.test.ts
- blocks.test.ts
Expand All @@ -22,6 +22,7 @@ jobs:
- stats.test.ts
- tokens.test.ts
- transactions.test.ts
name: 'API test set: ${{ matrix.test-pattern}} / Node: ${{ matrix.node-version}}'
steps:
- name: Checkout with Submodule
uses: actions/checkout@v3
Expand Down
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ cypress/videos/
cypress/screenshots/
tests/e2e/reports/
**/tests/e2e/artifacts/
**/playbook/artifacts-zk/
**/playbook/artifacts/
**/playbook/buffer/
**/playbook/cache-zk/
**/playbook/cache/

# Logs
logs
Expand Down
2 changes: 1 addition & 1 deletion packages/app/tests/e2e/features/copying.feature

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Feature: Redirection

Examples:
| Extra button name | url |
| Docs | https://era.zksync.io/docs/dev/ |
| Docs | https://docs.zksync.io/build/ |
| Terms | https://zksync.io/terms |
| Contact | https://zksync.io/contact |

Expand All @@ -32,7 +32,7 @@ Feature: Redirection
@id251
Scenario: Verify redirection for Documentation link
Given I click by text "Documentation"
Then New page have "https://era.zksync.io/docs/dev/" address
Then New page have "https://docs.zksync.io/build/" address

@id252
Scenario Outline: Verify redirection for "<Sub-Section>" in BE menu
Expand Down Expand Up @@ -80,12 +80,12 @@ Feature: Redirection
@id253:IV @featureEnv @mainnet
Scenario Outline: Verify redirection for "<Sub-Section>" in Tools menu
Given I click by text "Tools "
When I click by element with partial href "<url>" and text "<Sub-Section>"
When I click by element with partial href "<redirect_url>" and text "<Sub-Section>"
Then New page have "<url>" address

Examples:
| Sub-Section | url |
| Portal | https://staging-portal.zksync.dev/ |
| Sub-Section | url | redirect_url |
| Portal | https://staging-portal.zksync.dev/bridge/ | https://staging-portal.zksync.dev |


@id253:IV @productionEnv @mainnet
Expand Down
20 changes: 20 additions & 0 deletions packages/integration-tests/src/helper.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
import { execSync } from "child_process";
import { ethers } from "ethers";
import { promises as fs } from "fs";
import * as path from "path";
import { Provider } from "zksync-web3";

import { localConfig } from "./config";
import { Logger } from "./entities";

import type { BaseProvider } from "@ethersproject/providers/src.ts/base-provider";

export class Helper {
async txHashLogger(txType: string, txValue: string, tokenName?: string) {
const logMessage = `TxHash for ${txType} ${Logger.textSeparator} ${txValue}`;
Expand Down Expand Up @@ -35,4 +40,19 @@ export class Helper {
console.log(`There is no the expected file: ${fileName}`);
}
}

async getBalanceETH(walletAddress: string, layer: string) {
let network: string;
let provider: BaseProvider;
if (layer == "L1") {
network = localConfig.L1Network;
provider = ethers.getDefaultProvider(network);
} else if (layer == "L2") {
network = localConfig.L2Network;
provider = new Provider(network);
} else {
console.log(`Wrong layer: ${layer}`);
}
return ethers.utils.formatUnits(await provider.getBalance(walletAddress), "wei");
}
}
109 changes: 109 additions & 0 deletions packages/integration-tests/tests/api/accounts.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import * as request from "supertest";
import { setTimeout } from "timers/promises";

import { environment } from "../../src/config";
import { localConfig } from "../../src/config";
import { Token, Wallets } from "../../src/entities";
import { Helper } from "../../src/helper";

describe("API module: Account", () => {
jest.setTimeout(localConfig.standardTimeout);

const helper = new Helper();
//@id1704
it("Verify /api?module=account&action=balancemulti response", async () => {
const apiRoute = `/api?module=account&action=balancemulti&address=${Wallets.richWalletAddress},${Wallets.mainWalletAddress}`;
const richWalletBalance = await helper.getBalanceETH(Wallets.richWalletAddress, "L2");
const mainWalletBalance = await helper.getBalanceETH(Wallets.mainWalletAddress, "L2");
const richWalletLowerCase = Wallets.richWalletAddress.toLowerCase();
const mainWalletLowerCase = Wallets.mainWalletAddress.toLowerCase();
await setTimeout(localConfig.extendedPause); //works unstable without timeout

return request(environment.blockExplorerAPI)
.get(apiRoute)
.expect(200)
.expect((res) => expect(res.body.result.length).toBeGreaterThan(1))
.expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ status: "1" })))
.expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ message: "OK" })))
.expect((res) =>
expect(res.body.result[0]).toStrictEqual(
expect.objectContaining({ account: richWalletLowerCase, balance: richWalletBalance })
)
)
.expect((res) =>
expect(res.body.result[1]).toStrictEqual(
expect.objectContaining({ account: mainWalletLowerCase, balance: mainWalletBalance })
)
);
});

//@id1703
it("Verify /api?module=account&action=balance response", async () => {
const apiRoute = `/api?module=account&action=balance&address=${Wallets.richWalletAddress}`;
const balance = await helper.getBalanceETH(Wallets.richWalletAddress, "L2");
await setTimeout(localConfig.extendedPause); //works unstable without timeout

return request(environment.blockExplorerAPI)
.get(apiRoute)
.expect(200)
.expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ status: "1" })))
.expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ message: "OK" })))
.expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ result: balance })));
});

//@id1705
it("Verify /api?module=account&action=tokenbalance response", async () => {
const apiRoute = `/api?module=account&action=tokenbalance&contractaddress=${Token.ETHER_ERC20_Address}&address=${Wallets.richWalletAddress}`;
await setTimeout(localConfig.extendedPause); //works unstable without timeout

return request(environment.blockExplorerAPI)
.get(apiRoute)
.expect(200)
.expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ status: "1" })))
.expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ message: "OK" })))
.expect((res) => expect(typeof res.body.result).toStrictEqual("string"));
});

//@id1702
it("Verify /api?module=account&action=txlist response", async () => {
const blocks = await request(environment.blockExplorerAPI).get("/blocks");

const blockNumber = blocks.body.items[0].number;
const apiRoute = `/api?module=account&action=txlist&page=1&offset=10&sort=desc&endblock${blockNumber}&startblock=0&address=${Wallets.richWalletAddress}`;

await setTimeout(localConfig.extendedPause); //works unstable without timeout

return request(environment.blockExplorerAPI)
.get(apiRoute)
.expect(200)
.expect((res) => expect(res.body.result.length).toBeGreaterThan(1))
.expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ status: "1" })))
.expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ message: "OK" })))
.expect((res) => expect(typeof res.body.result[0].blockNumber).toStrictEqual("string"))
.expect((res) => expect(typeof res.body.result[0].timeStamp).toStrictEqual("string"))
.expect((res) => expect(typeof res.body.result[0].hash).toStrictEqual("string"))
.expect((res) => expect(typeof res.body.result[0].nonce).toStrictEqual("string"))
.expect((res) => expect(typeof res.body.result[0].blockHash).toStrictEqual("string"))
.expect((res) => expect(typeof res.body.result[0].transactionIndex).toStrictEqual("string"))
.expect((res) => expect(typeof res.body.result[0].from).toStrictEqual("string"))
.expect((res) => expect(typeof res.body.result[0].to).toStrictEqual("string"))
.expect((res) => expect(typeof res.body.result[0].value).toStrictEqual("string"))
.expect((res) => expect(typeof res.body.result[0].gas).toStrictEqual("string"))
.expect((res) => expect(typeof res.body.result[0].gasPrice).toStrictEqual("string"))
.expect((res) => expect(typeof res.body.result[0].isError).toStrictEqual("string"))
.expect((res) => expect(typeof res.body.result[0].txreceipt_status).toStrictEqual("string"))
.expect((res) => expect(typeof res.body.result[0].input).toStrictEqual("string"))
.expect((res) => expect(typeof res.body.result[0].contractAddress).toBeTruthy()) // can be null
.expect((res) => expect(typeof res.body.result[0].cumulativeGasUsed).toStrictEqual("string"))
.expect((res) => expect(typeof res.body.result[0].gasUsed).toStrictEqual("string"))
.expect((res) => expect(typeof res.body.result[0].confirmations).toStrictEqual("string"))
.expect((res) => expect(typeof res.body.result[0].fee).toStrictEqual("string"))
.expect((res) => expect(typeof res.body.result[0].commitTxHash).toStrictEqual("string"))
.expect((res) => expect(typeof res.body.result[0].proveTxHash).toStrictEqual("string"))
.expect((res) => expect(typeof res.body.result[0].executeTxHash).toStrictEqual("string"))
.expect((res) => expect(typeof res.body.result[0].isL1Originated).toStrictEqual("string"))
.expect((res) => expect(typeof res.body.result[0].l1BatchNumber).toStrictEqual("string"))
.expect((res) => expect(typeof res.body.result[0].methodId).toStrictEqual("string"))
.expect((res) => expect(typeof res.body.result[0].functionName).toStrictEqual("string"));
});
});
8 changes: 4 additions & 4 deletions packages/integration-tests/tests/api/batches.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { setTimeout } from "timers/promises";
import { environment } from "../../src/config";
import { localConfig } from "../../src/config";

describe("/batches", () => {
describe("Batches", () => {
jest.setTimeout(localConfig.standardTimeout);

//@id1513
Expand All @@ -30,8 +30,8 @@ describe("/batches", () => {
});

//@id1514
xit("Verify the response via /batches/{batchNumber}", async () => {
await setTimeout(localConfig.standardPause); //works unstable without timeout
it("Verify the response via /batches/{batchNumber}", async () => {
await setTimeout(localConfig.extendedPause); //works unstable without timeout

const batches = await request(environment.blockExplorerAPI).get("/batches");

Expand All @@ -56,6 +56,6 @@ describe("/batches", () => {
.expect((res) => expect(typeof res.body.l1GasPrice).toStrictEqual("string"))
.expect((res) => expect(typeof res.body.l2FairGasPrice).toStrictEqual("string"))
.expect((res) => expect(typeof res.body.size).toStrictEqual("number"))
.expect((res) => expect(res.body.status).toStrictEqual("string"));
.expect((res) => expect(typeof res.body.status).toStrictEqual("string"));
});
});
57 changes: 56 additions & 1 deletion packages/integration-tests/tests/api/blocks.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { setTimeout } from "timers/promises";
import { environment } from "../../src/config";
import { localConfig } from "../../src/config";

describe("/blocks", () => {
describe("Blocks", () => {
jest.setTimeout(localConfig.standardTimeout);

//@id1511
Expand Down Expand Up @@ -66,3 +66,58 @@ describe("/blocks", () => {
);
});
});

describe("/api?module=block", () => {
//@id1700
it("Verify /api?module=block&action=getblockcountdown&blockno={block_number} response", async () => {
const blocks = await request(environment.blockExplorerAPI).get("/blocks");

const blockNumber = blocks.body.items[0].number + 1;
const apiRoute = `/api?module=block&action=getblockcountdown&blockno=${blockNumber}`;
await setTimeout(localConfig.extendedPause); //works unstable without timeout

return request(environment.blockExplorerAPI)
.get(apiRoute)
.expect(200)
.expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ status: "1" })))
.expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ message: "OK" })))
.expect((res) => expect(typeof res.body.result.CurrentBlock).toStrictEqual("string"))
.expect((res) => expect(typeof res.body.result.CountdownBlock).toStrictEqual("string"))
.expect((res) => expect(typeof res.body.result.RemainingBlock).toStrictEqual("string"))
.expect((res) => expect(typeof res.body.result.EstimateTimeInSec).toStrictEqual("string"));
});

//@id1699
it("Verify /api?module=block&action=getblocknobytime&closest=before&timestamp={timestamp} response", async () => {
const apiRoute = `/api?module=block&action=getblocknobytime&closest=before&timestamp=1635934550`;
await setTimeout(localConfig.extendedPause); //works unstable without timeout

return request(environment.blockExplorerAPI)
.get(apiRoute)
.expect(200)
.expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ status: "1" })))
.expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ message: "OK" })))
.expect((res) => expect(typeof res.body.result).toStrictEqual("string"));
});

//@id1701
it("Verify /api?module=block&action=getblockreward&blockno={blockNumber} response", async () => {
const blocks = await request(environment.blockExplorerAPI).get("/blocks");

const blockNumber = blocks.body.items[0].number;
const apiRoute = `/api?module=block&action=getblockreward&blockno=${blockNumber}`;
await setTimeout(localConfig.extendedPause); //works unstable without timeout

return request(environment.blockExplorerAPI)
.get(apiRoute)
.expect(200)
.expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ status: "1" })))
.expect((res) => expect(res.body).toStrictEqual(expect.objectContaining({ message: "OK" })))
.expect((res) => expect(typeof res.body.result.blockNumber).toStrictEqual("string"))
.expect((res) => expect(typeof res.body.result.timeStamp).toStrictEqual("string"))
.expect((res) => expect(typeof res.body.result.blockMiner).toStrictEqual("string"))
.expect((res) => expect(typeof res.body.result.blockReward).toStrictEqual("string"))
.expect((res) => expect(typeof res.body.result.uncleInclusionReward).toStrictEqual("string"))
.expect((res) => expect(typeof res.body.result.uncles).toStrictEqual("object"));
});
});
6 changes: 4 additions & 2 deletions packages/integration-tests/tests/api/contracts.test.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import * as request from "supertest";
import { setTimeout } from "timers/promises";

import { environment } from "../../src/config";
import { localConfig } from "../../src/config";
import { Buffer, Wallets } from "../../src/entities";
import { Helper } from "../../src/helper";
import { Playbook } from "../../src/playbook/playbook";

describe("Contracts API", () => {
describe("API module: Contract", () => {
jest.setTimeout(localConfig.standardTimeout);

const helper = new Helper();
Expand All @@ -24,7 +25,8 @@ describe("Contracts API", () => {
});

//@id1696
xit("Verify the response via /api?module=contract&action=getcontractcreation&contractaddresses={address1},{address2}", async () => {
it("Verify /api?module=contract&action=getcontractcreation&contractaddresses={address1},{address2} response", async () => {
await setTimeout(localConfig.standardPause);
paymasterContract = await helper.getStringFromFile(bufferFile + Buffer.paymaster);
paymasterTx = await helper.getStringFromFile(bufferFile + Buffer.paymasterDeployTx);
multicallCallerContract = await helper.getStringFromFile(bufferFile + Buffer.addressMultiCallCaller);
Expand Down
8 changes: 5 additions & 3 deletions packages/integration-tests/tests/api/logs.test.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import * as request from "supertest";
import { setTimeout } from "timers/promises";

import { environment } from "../../src/config";
import { localConfig } from "../../src/config";
import { Buffer } from "../../src/entities";
import { Helper } from "../../src/helper";
import { Playbook } from "../../src/playbook/playbook";

xdescribe("Logs API", () => {
describe("API module: Logs", () => {
jest.setTimeout(localConfig.standardTimeout); //works unstable without timeout
const helper = new Helper();
const bufferFile = "src/playbook/";
Expand All @@ -21,7 +22,8 @@ xdescribe("Logs API", () => {
});

//@id1808
it("Verify the response via /api?module=logs&action=getLogs&page={page}&offset={offset}0&toBlock={toBlock}&fromBlock={fromBlock}&address={address}", async () => {
it("Verify /api?module=logs&action=getLogs&page={page}&offset={offset}0&toBlock={toBlock}&fromBlock={fromBlock}&address={address} response", async () => {
await setTimeout(localConfig.standardPause);
contractAddress = await helper.getStringFromFile(bufferFile + Buffer.greeterL2);
txHash = await helper.getStringFromFile(bufferFile + Buffer.executeGreeterTx);

Expand All @@ -42,7 +44,7 @@ xdescribe("Logs API", () => {
.expect((res) => expect(res.body.result[0].data.length).toBe(194))
.expect((res) => expect(typeof res.body.result[0].blockNumber).toStrictEqual("string"))
.expect((res) => expect(res.body.result[0].blockNumber.startsWith("0x")).toBe(true))
.expect((res) => expect(res.body.result[0].blockNumber.length).toBe(5))
.expect((res) => expect(typeof res.body.result[0].blockNumber.length).toStrictEqual("number"))
.expect((res) => expect(typeof res.body.result[0].timeStamp).toStrictEqual("string"))
.expect((res) => expect(res.body.result[0].timeStamp.startsWith("0x")).toBe(true))
.expect((res) => expect(res.body.result[0].timeStamp.length).toBe(10))
Expand Down
2 changes: 1 addition & 1 deletion packages/integration-tests/tests/api/stats.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { setTimeout } from "timers/promises";
import { environment } from "../../src/config";
import { localConfig } from "../../src/config";

describe("/stats", () => {
describe("Stats", () => {
jest.setTimeout(localConfig.standardTimeout); //works unstable without timeout

//@id1515
Expand Down
Loading

0 comments on commit 8a57793

Please sign in to comment.