From 4c0615394e26c9c941c673ded652f8aa4d2d34da Mon Sep 17 00:00:00 2001 From: Jordan Gensler Date: Wed, 14 Sep 2022 16:07:21 -0700 Subject: [PATCH] [explorer] Convert some tests to localnet tests (#4580) --- .../client/cypress/e2e/localnet/address.cy.ts | 13 ++++ .../client/cypress/e2e/localnet/objects.cy.ts | 41 +++++++++++ .../client/cypress/e2e/localnet/search.cy.ts | 11 +++ explorer/client/cypress/e2e/static/e2e.cy.ts | 72 ------------------- explorer/client/cypress/localnet.ts | 31 +++++++- explorer/client/cypress/support/commands.d.ts | 6 ++ 6 files changed, 101 insertions(+), 73 deletions(-) create mode 100644 explorer/client/cypress/e2e/localnet/address.cy.ts create mode 100644 explorer/client/cypress/e2e/localnet/objects.cy.ts diff --git a/explorer/client/cypress/e2e/localnet/address.cy.ts b/explorer/client/cypress/e2e/localnet/address.cy.ts new file mode 100644 index 0000000000000..904689f090d07 --- /dev/null +++ b/explorer/client/cypress/e2e/localnet/address.cy.ts @@ -0,0 +1,13 @@ +// Copyright (c) 2022, Mysten Labs, Inc. +// SPDX-License-Identifier: Apache-2.0 + +Cypress.config('baseUrl', 'http://localhost:3000'); + +describe('Address', () => { + it('can be directly visted', () => { + cy.task('faucet').then((address) => { + cy.visit(`/addresses/${address}`); + cy.get('#addressID').contains(address); + }); + }); +}); diff --git a/explorer/client/cypress/e2e/localnet/objects.cy.ts b/explorer/client/cypress/e2e/localnet/objects.cy.ts new file mode 100644 index 0000000000000..b47d40dc2c820 --- /dev/null +++ b/explorer/client/cypress/e2e/localnet/objects.cy.ts @@ -0,0 +1,41 @@ +// Copyright (c) 2022, Mysten Labs, Inc. +// SPDX-License-Identifier: Apache-2.0 + +Cypress.config('baseUrl', 'http://localhost:3000'); + +describe('Objects', () => { + it('can be reached through URL', () => { + cy.task('faucet') + .then((address) => cy.task('mint', address)) + .then(({ effects }) => { + const { objectId } = effects.created![0].reference; + cy.visit(`/objects/${objectId}`); + cy.get('#objectID').contains(objectId); + }); + }); + + it('displays an error when no objects', () => { + cy.visit(`/objects/fakeAddress`); + cy.get('#errorResult'); + }); + + describe('Owned Objects', () => { + it('link going from address to object and back', () => { + cy.task('faucet') + .then((address) => cy.task('mint', address)) + .then(({ certificate, effects }) => { + const address = certificate.data.sender; + const [nft] = effects.created!; + cy.visit(`/addresses/${address}`); + + // Find a reference to the NFT: + cy.contains(nft.reference.objectId.slice(0, 4)).click(); + cy.get('#objectID').contains(nft.reference.objectId); + + // Find a reference to the owning address: + cy.contains(address).click(); + cy.get('#addressID').contains(address); + }); + }); + }); +}); diff --git a/explorer/client/cypress/e2e/localnet/search.cy.ts b/explorer/client/cypress/e2e/localnet/search.cy.ts index 645be42d526e3..83606d371b8af 100644 --- a/explorer/client/cypress/e2e/localnet/search.cy.ts +++ b/explorer/client/cypress/e2e/localnet/search.cy.ts @@ -11,4 +11,15 @@ describe('search', () => { cy.url().should('include', `/addresses/${address}`); }); }); + + it('can search for objects', () => { + cy.task('faucet') + .then((address) => cy.task('mint', address)) + .then(({ effects }) => { + const { objectId } = effects.created![0].reference; + cy.visit('/'); + cy.get('[data-testid=search]').type(objectId).type('{enter}'); + cy.url().should('include', `/objects/${objectId}`); + }); + }); }); diff --git a/explorer/client/cypress/e2e/static/e2e.cy.ts b/explorer/client/cypress/e2e/static/e2e.cy.ts index 794e20aeee710..8b489a054c946 100644 --- a/explorer/client/cypress/e2e/static/e2e.cy.ts +++ b/explorer/client/cypress/e2e/static/e2e.cy.ts @@ -9,10 +9,6 @@ const nftObject = (num: number) => `div#ownedObjects > div:nth-child(${num}) a`; const ownerButton = 'td#owner > div > div'; // Standardized expectations: -const expectHome = () => { - cy.get(mainBodyCSS).invoke('attr', 'data-testid').should('eq', 'home-page'); -}; - const expectErrorResult = () => { cy.get(mainBodyCSS).invoke('attr', 'id').should('eq', 'errorResult'); }; @@ -23,24 +19,6 @@ const searchText = (text: string) => { }; describe('End-to-end Tests', () => { - describe('The Home Page', () => { - it('is the landing page', () => { - cy.visit('/'); - expectHome(); - }); - - it('is the redirect page', () => { - cy.visit('/apples'); - expectHome(); - }); - - it('has a go home button', () => { - cy.visit('/objects/CollectionObject'); - cy.get('#homeBtn').click(); - expectHome(); - }); - }); - describe('Wrong Search', () => { it('leads to error page', () => { cy.visit('/'); @@ -49,48 +27,6 @@ describe('End-to-end Tests', () => { }); }); - describe('Object Results', () => { - const successObjectID = 'CollectionObject'; - const problemObjectID = 'ProblemObject'; - - it('can be searched', () => { - cy.visit('/'); - searchText(successObjectID); - cy.get('#objectID').contains(successObjectID); - }); - - it('can be reached through URL', () => { - cy.visit(`/objects/${successObjectID}`); - cy.get('#objectID').contains(successObjectID); - }); - - it('can have missing data', () => { - cy.visit(`/objects/${problemObjectID}`); - expectErrorResult(); - }); - }); - - describe('Address Results', () => { - const successAddressID = 'receiverAddress'; - const noObjectsAddressID = 'senderAddress'; - - it('can be searched', () => { - cy.visit('/'); - searchText(successAddressID); - cy.get('#addressID').contains(successAddressID); - }); - - it('can be reached through URL', () => { - cy.visit(`/addresses/${successAddressID}`); - cy.get('#addressID').contains(successAddressID); - }); - - it('displays error when no objects', () => { - cy.visit(`/objects/${noObjectsAddressID}`); - expectErrorResult(); - }); - }); - describe('Transaction Results', () => { const successID = 'Da4vHc9IwbvOYblE8LnrVsqXwryt2Kmms+xnJ7Zx5E4='; it('can be searched', () => { @@ -113,14 +49,6 @@ describe('End-to-end Tests', () => { }); describe('Owned Objects have links that enable', () => { - it('going from address to object and back', () => { - cy.visit('/addresses/receiverAddress'); - cy.get(nftObject(1)).click(); - cy.get('#objectID').contains('player1'); - cy.get(ownerButton).click(); - cy.get('#addressID').contains('receiverAddress'); - }); - it('going from object to child object and back', () => { cy.visit('/objects/player2'); cy.get(nftObject(1)).click(); diff --git a/explorer/client/cypress/localnet.ts b/explorer/client/cypress/localnet.ts index 491b9ce049a02..474b256874edc 100644 --- a/explorer/client/cypress/localnet.ts +++ b/explorer/client/cypress/localnet.ts @@ -5,12 +5,41 @@ import axios from 'axios'; // NOTE: We import out of the source directory here to work around an issue with Cypress not // respecting tsconfig paths in the config file. -import { Ed25519Keypair, type Keypair } from '../../../sdk/typescript/src'; +import { + Ed25519Keypair, + JsonRpcProvider, + RawSigner, + type Keypair, +} from '../../../sdk/typescript/src'; export async function createLocalnetTasks() { const addressToKeypair = new Map(); return { + async mint(address: string) { + const keypair = addressToKeypair.get(address); + if (!keypair) { + throw new Error('missing keypair'); + } + const provider = new JsonRpcProvider('http://localhost:5001'); + const signer = new RawSigner(keypair, provider); + + const tx = await signer.executeMoveCall({ + packageObjectId: '0x2', + module: 'devnet_nft', + function: 'mint', + typeArguments: [], + arguments: [ + 'Example NFT', + 'An example NFT.', + 'ipfs://bafkreibngqhl3gaa7daob4i2vccziay2jjlp435cf66vhono7nrvww53ty', + ], + gasBudget: 30000, + }); + + return tx; + }, + async faucet() { const keypair = Ed25519Keypair.generate(); const address = keypair.getPublicKey().toSuiAddress(); diff --git a/explorer/client/cypress/support/commands.d.ts b/explorer/client/cypress/support/commands.d.ts index dc35884bc18b1..a13024452045c 100644 --- a/explorer/client/cypress/support/commands.d.ts +++ b/explorer/client/cypress/support/commands.d.ts @@ -1,10 +1,16 @@ // Copyright (c) 2022, Mysten Labs, Inc. // SPDX-License-Identifier: Apache-2.0 +/* eslint-disable @typescript-eslint/consistent-type-imports */ + /// declare namespace Cypress { interface Chainable { task(name: 'faucet', arg?: unknown): Chainable; + task( + name: 'mint', + address?: string + ): Chainable; } }