Skip to content

Commit

Permalink
Enable e2e test against devent and testnet branch (MystenLabs#7800)
Browse files Browse the repository at this point in the history
- Added CI workflow to verify that the TypeScript/Explorer/Rust changes
are compatible with TestNet and DevNet branch
- Edited the existing localnet e2e tests for Explorer and wallet:
previously we only run Explorer/Wallet test when there is a rust change
or an Explorer/Wallet change, now the test will also run when there's a
TypeScript change(since TS change can also break Explorer).
- Fixed some backward incompatibility on the SDK and Explorer side with
the testnet branch
  • Loading branch information
666lcz authored Feb 6, 2023
1 parent 8625246 commit c01ea7c
Show file tree
Hide file tree
Showing 9 changed files with 151 additions and 24 deletions.
128 changes: 120 additions & 8 deletions .github/workflows/e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ jobs:
diff:
runs-on: ubuntu-latest
outputs:
isWallet: ${{ (steps.turbo.outputs.packages && contains(fromJson(steps.turbo.outputs.packages), 'sui-wallet')) || steps.diff.outputs.isRust }}
isExplorer: ${{ (steps.turbo.outputs.packages && contains(fromJson(steps.turbo.outputs.packages), 'sui-explorer')) || steps.diff.outputs.isRust }}
isTypescriptSDK: ${{ (steps.turbo.outputs.packages && contains(fromJson(steps.turbo.outputs.packages), '@mysten/sui.js')) || steps.diff.outputs.isRust }}
isWallet: ${{ (steps.turbo.outputs.packages && contains(fromJson(steps.turbo.outputs.packages), 'sui-wallet')) }}
isExplorer: ${{ (steps.turbo.outputs.packages && contains(fromJson(steps.turbo.outputs.packages), 'sui-explorer')) }}
isTypescriptSDK: ${{ (steps.turbo.outputs.packages && contains(fromJson(steps.turbo.outputs.packages), '@mysten/sui.js')) }}
isRust: ${{ steps.diff.outputs.isRust }}
steps:
- uses: actions/checkout@7dd9e2a3dc350cf687eb1b2a4fadfee8c8e49675 # pin@v3
- name: Detect Changes (turbo)
Expand All @@ -16,10 +17,11 @@ jobs:
uses: "./.github/actions/diffs"
id: diff

# Run e2e test against localnet built on the main branch
localnet:
name: Localnet
needs: diff
if: needs.diff.outputs.isExplorer == 'true' || needs.diff.outputs.isTypescriptSDK == 'true' || needs.diff.outputs.isWallet == 'true'
if: needs.diff.outputs.isExplorer == 'true' || needs.diff.outputs.isTypescriptSDK == 'true' || needs.diff.outputs.isWallet == 'true' || needs.diff.outputs.isRust == 'true'
runs-on: ubuntu-ghcloud
steps:
- uses: actions/checkout@7dd9e2a3dc350cf687eb1b2a4fadfee8c8e49675 # pin@v3
Expand All @@ -40,11 +42,12 @@ jobs:
run: pnpm explorer playwright install --with-deps chromium

- name: Run TS SDK e2e tests
if: ${{ needs.diff.outputs.isTypescriptSDK == 'true' }}
if: ${{ needs.diff.outputs.isTypescriptSDK == 'true' || needs.diff.outputs.isRust == 'true'}}
run: pnpm dlx concurrently --kill-others --success command-1 'RUST_LOG="consensus=off" cargo run --bin sui-test-validator' 'pnpm sdk test:e2e'

- name: Run Explorer e2e tests
if: ${{ needs.diff.outputs.isExplorer == 'true' }}
# need to run Explorer e2e when its upstream(TS SDK and Rust) or itself is changed
if: ${{ needs.diff.outputs.isTypescriptSDK == 'true' || needs.diff.outputs.isExplorer == 'true' || needs.diff.outputs.isRust == 'true'}}
run: pnpm explorer playwright test
- uses: actions/upload-artifact@v3
if: always()
Expand All @@ -54,14 +57,123 @@ jobs:
retention-days: 30

- name: Build Wallet
if: ${{ needs.diff.outputs.isWallet == 'true' }}
# need to run Wallet e2e when its upstream(TS SDK and Rust) or itself is changed
if: ${{ needs.diff.outputs.isWallet == 'true' || needs.diff.outputs.isRust == 'true' || needs.diff.outputs.isTypescriptSDK == 'true'}}
run: pnpm wallet build
- name: Run Wallet e2e tests
if: ${{ needs.diff.outputs.isWallet == 'true' }}
if: ${{ needs.diff.outputs.isWallet == 'true' || needs.diff.outputs.isRust == 'true' || needs.diff.outputs.isTypescriptSDK == 'true'}}
run: xvfb-run --auto-servernum --server-args="-screen 0 1280x960x24" -- pnpm wallet playwright test
- uses: actions/upload-artifact@v3
if: always()
with:
name: playwright-report-wallet
path: apps/wallet/playwright-report/
retention-days: 30

# Run e2e test against localnet built on the devnet branch for backward compatibility check
local_devnet_branch:
name: Local Network Built on devnet branch
needs: diff
# TODO: add wallet e2e to the `if` condition when available
if: needs.diff.outputs.isExplorer == 'true' || needs.diff.outputs.isTypescriptSDK == 'true'
runs-on: ubuntu-ghcloud
steps:
# checkout the devnet branch
- uses: actions/checkout@7dd9e2a3dc350cf687eb1b2a4fadfee8c8e49675 # pin@v3
with:
ref: devnet
- uses: actions-rs/toolchain@16499b5e05bf2e26879000db0c1d13f7e13fa3af # pin@v1
- uses: bmwill/rust-cache@v1 # Fork of 'Swatinem/rust-cache' which allows caching additional paths
- uses: pnpm/action-setup@c3b53f6a16e57305370b4ae5a540c2077a1d50dd # [email protected]
with:
version: 7
- run: cargo build --bin sui-test-validator --bin sui --profile dev

# checkout the current branch
- uses: actions/checkout@7dd9e2a3dc350cf687eb1b2a4fadfee8c8e49675 # pin@v3
with:
clean: false

- name: Install Nodejs
uses: actions/setup-node@8c91899e586c5b171469028077307d293428b516 # pin@v3
with:
node-version: "18"
cache: "pnpm"
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Install Playwright Browsers
run: pnpm explorer playwright install --with-deps chromium

- name: Set env
run: echo "E2E_RUN_LOCAL_NET_CMD=(RUST_LOG=\"consensus=off\" $(echo $PWD/target/debug/sui-test-validator))" >> $GITHUB_ENV

- name: Run TS SDK e2e tests
if: ${{ needs.diff.outputs.isTypescriptSDK == 'true' }}
run: pnpm dlx concurrently --kill-others --success command-1 "$E2E_RUN_LOCAL_NET_CMD" 'pnpm sdk test:e2e'

- name: Run Explorer e2e tests
if: ${{ needs.diff.outputs.isExplorer == 'true' || needs.diff.outputs.isTypescriptSDK == 'true'}}
run: pnpm explorer playwright test

# TODO: add wallet e2e when available

- uses: actions/upload-artifact@v3
if: always()
with:
name: playwright-report-explorer
path: apps/explorer/playwright-report/
retention-days: 30

# Run e2e test against localnet built on the Testnet branch for backward compatibility check
local_testnet_branch:
name: Local Network Built on testnet branch
needs: diff
# TODO: add wallet e2e to the `if` condition when available
if: needs.diff.outputs.isExplorer == 'true' || needs.diff.outputs.isTypescriptSDK == 'true'
runs-on: ubuntu-ghcloud
steps:
# checkout the testnet branch
- uses: actions/checkout@7dd9e2a3dc350cf687eb1b2a4fadfee8c8e49675 # pin@v3
with:
ref: testnet
- uses: actions-rs/toolchain@16499b5e05bf2e26879000db0c1d13f7e13fa3af # pin@v1
- uses: bmwill/rust-cache@v1 # Fork of 'Swatinem/rust-cache' which allows caching additional paths
- uses: pnpm/action-setup@c3b53f6a16e57305370b4ae5a540c2077a1d50dd # [email protected]
with:
version: 7
- run: cargo build --bin sui-test-validator --bin sui --profile dev

# checkout the current branch
- uses: actions/checkout@7dd9e2a3dc350cf687eb1b2a4fadfee8c8e49675 # pin@v3
with:
clean: false

- name: Install Nodejs
uses: actions/setup-node@8c91899e586c5b171469028077307d293428b516 # pin@v3
with:
node-version: "18"
cache: "pnpm"
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Install Playwright Browsers
run: pnpm explorer playwright install --with-deps chromium

- name: Set env
run: echo "E2E_RUN_LOCAL_NET_CMD=(RUST_LOG="consensus=off "$(echo $PWD/target/debug/sui-test-validator))" >> $GITHUB_ENV

- name: Run TS SDK e2e tests
if: ${{ needs.diff.outputs.isTypescriptSDK == 'true' }}
run: pnpm dlx concurrently --kill-others --success command-1 "$E2E_RUN_LOCAL_NET_CMD" 'pnpm sdk test:e2e'

- name: Run Explorer e2e tests
if: ${{ needs.diff.outputs.isExplorer == 'true' || needs.diff.outputs.isTypescriptSDK == 'true'}}
run: pnpm explorer playwright test

# TODO: add wallet e2e when available

- uses: actions/upload-artifact@v3
if: always()
with:
name: playwright-report-explorer
path: apps/explorer/playwright-report/
retention-days: 30
1 change: 1 addition & 0 deletions apps/explorer/playwright.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ const config: PlaywrightTestConfig = {
// Localnet:
{
command:
process.env.E2E_RUN_LOCAL_NET_CMD ??
'RUST_LOG="consensus=off" cargo run --bin sui-test-validator',
port: 9123,
timeout: 120 * 1000,
Expand Down
5 changes: 3 additions & 2 deletions apps/explorer/tests/objects.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@

import { test, expect } from '@playwright/test';

import { getCreatedObjects } from '@mysten/sui.js';
import { faucet, mint } from './utils/localnet';

test('can be reached through URL', async ({ page }) => {
const address = await faucet();
const tx = await mint(address);

const { objectId } = tx.effects.effects.created![0].reference;
const { objectId } = getCreatedObjects(tx)![0].reference;
await page.goto(`/object/${objectId}`);
await expect(page.getByRole('heading', { name: objectId })).toBeVisible();
});
Expand All @@ -19,7 +20,7 @@ test.describe('Owned Objects', () => {
const address = await faucet();
const tx = await mint(address);

const [nft] = tx.effects.effects.created!;
const [nft] = getCreatedObjects(tx)!;
await page.goto(`/address/0x${address}`);

// Find a reference to the NFT:
Expand Down
5 changes: 3 additions & 2 deletions apps/explorer/tests/search.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import { expect, test, type Page } from '@playwright/test';

import { faucet, mint } from './utils/localnet';
import { getCreatedObjects, getTransactionDigest } from '@mysten/sui.js';

async function search(page: Page, text: string) {
const searchbar = page.getByRole('combobox');
Expand All @@ -23,7 +24,7 @@ test('can search for objects', async ({ page }) => {
const address = await faucet();
const tx = await mint(address);

const { objectId } = tx.effects.effects.created![0].reference;
const { objectId } = getCreatedObjects(tx)![0].reference;
await page.goto('/');
await search(page, objectId);
await expect(page).toHaveURL(`/object/${objectId}`);
Expand All @@ -33,7 +34,7 @@ test('can search for transaction', async ({ page }) => {
const address = await faucet();
const tx = await mint(address);

const txid = tx.effects.effects.transactionDigest;
const txid = getTransactionDigest(tx);
await page.goto('/');
await search(page, txid);
await expect(page).toHaveURL(`/transaction/${txid}`);
Expand Down
5 changes: 3 additions & 2 deletions apps/explorer/tests/transaction.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@
import { expect, test } from '@playwright/test';

import { faucet, mint } from './utils/localnet';
import { getTransactionDigest } from '@mysten/sui.js';

test('displays the transaction timestamp', async ({ page }) => {
const address = await faucet();
const tx = await mint(address);
const txid = tx.effects.effects.transactionDigest;
const txid = getTransactionDigest(tx);
await page.goto(`/transaction/${txid}`);
await expect(
page.getByTestId('transaction-timestamp').locator('div').nth(1)
Expand All @@ -17,7 +18,7 @@ test('displays the transaction timestamp', async ({ page }) => {
test('displays gas breakdown', async ({ page }) => {
const address = await faucet();
const tx = await mint(address);
const txid = tx.effects.effects.transactionDigest;
const txid = getTransactionDigest(tx);
await page.goto(`/transaction/${txid}`);
await expect(page.getByTestId('gas-breakdown')).toBeVisible();
});
10 changes: 3 additions & 7 deletions apps/explorer/tests/utils/localnet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import {
RawSigner,
LocalTxnDataSerializer,
type Keypair,
SuiExecuteTransactionResponse,
assert,
} from '@mysten/sui.js';

const addressToKeypair = new Map<string, Keypair>();
Expand Down Expand Up @@ -45,13 +47,7 @@ export async function mint(address: string) {
gasBudget: 30000,
});

if (!('certificate' in tx)) {
throw new Error('Missing certificate');
}
if (!('effects' in tx)) {
throw new Error('Missing effects');
}

assert(tx, SuiExecuteTransactionResponse);
return tx;
}

Expand Down
4 changes: 2 additions & 2 deletions sdk/typescript/src/types/transactions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -377,8 +377,8 @@ export function getTransactionDigest(
if ('transactionDigest' in tx) {
return tx.transactionDigest;
}
const ctxn = getCertifiedTransaction(tx)!;
return ctxn.transactionDigest;
const effects = getTransactionEffects(tx)!;
return effects.transactionDigest;
}

export function getTransactionSignature(tx: CertifiedTransaction): string {
Expand Down
3 changes: 2 additions & 1 deletion sdk/typescript/src/types/validator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,8 @@ export const MoveValidatorsFieldsClass = object({
export const MoveSuiSystemObjectFields = object({
chain_id: optional(number()),
epoch: string(),
epoch_start_timestamp_ms: string(),
// TODO(cleanup): remove optional after TestNet Wave 2(0.22.0)
epoch_start_timestamp_ms: optional(string()),
safe_mode: boolean(),
id: object({
id: string(),
Expand Down
14 changes: 14 additions & 0 deletions sdk/typescript/test/e2e/checkpoint.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,14 @@ import { setup, TestToolbox } from './utils/setup';

describe('Checkpoints Reading API', () => {
let toolbox: TestToolbox;
let shouldSkip: boolean;

beforeAll(async () => {
toolbox = await setup();
// TODO(cleanup): remove this after TestNet Wave 2(0.22.0) or backward compatibility
// is supported
const version = await toolbox.provider.getRpcApiVersion()!;
shouldSkip = version?.major === 0 && version?.minor < 23;
});

it('Get latest checkpoint sequence number', async () => {
Expand All @@ -28,6 +33,9 @@ describe('Checkpoints Reading API', () => {
});

it('get checkpoint summary by digest', async () => {
if (shouldSkip) {
return;
}
const checkpoint_resp = await toolbox.provider.getCheckpointSummary(1);
const digest = checkpoint_resp.previous_digest;
expect(digest).not.toBeNull();
Expand All @@ -41,11 +49,17 @@ describe('Checkpoints Reading API', () => {
});

it('get checkpoint contents', async () => {
if (shouldSkip) {
return;
}
const resp = await toolbox.provider.getCheckpointContents(0);
expect(resp.transactions.length).greaterThan(0);
});

it('get checkpoint contents by digest', async () => {
if (shouldSkip) {
return;
}
const checkpoint_resp = await toolbox.provider.getCheckpointSummary(0);
const digest = checkpoint_resp.content_digest;
const resp = await toolbox.provider.getCheckpointContentsByDigest(digest);
Expand Down

0 comments on commit c01ea7c

Please sign in to comment.