Merge pull request #55 from vegaprotocol/test/Cypress-BDD-integration
Test/cypress bdd integration
This commit is contained in:
commit
c1c12d8c70
6
apps/explorer-e2e/src/integration/asset-page.feature
Normal file
6
apps/explorer-e2e/src/integration/asset-page.feature
Normal file
@ -0,0 +1,6 @@
|
||||
Feature: Asset Page
|
||||
|
||||
Scenario: Navigate to Asset Page
|
||||
Given I am on the homepage
|
||||
When I navigate to the asset page
|
||||
Then asset page is correctly displayed
|
6
apps/explorer-e2e/src/integration/blocks-page.feature
Normal file
6
apps/explorer-e2e/src/integration/blocks-page.feature
Normal file
@ -0,0 +1,6 @@
|
||||
Feature: Blocks Page
|
||||
|
||||
Scenario: Navigate to blocks page
|
||||
Given I am on the homepage
|
||||
When I navigate to the blocks page
|
||||
Then blocks page is correctly displayed
|
@ -1,4 +1,4 @@
|
||||
Feature: Home page
|
||||
|
||||
Scenario: Visit Home page
|
||||
Given I go to the homepage
|
||||
Given I am on the homepage
|
||||
|
6
apps/explorer-e2e/src/integration/markets-page.feature
Normal file
6
apps/explorer-e2e/src/integration/markets-page.feature
Normal file
@ -0,0 +1,6 @@
|
||||
Feature: Markets Page
|
||||
|
||||
Scenario: Navigate to markets page
|
||||
Given I am on the homepage
|
||||
When I navigate to the markets page
|
||||
Then markets page is correctly displayed
|
6
apps/explorer-e2e/src/integration/network-page.feature
Normal file
6
apps/explorer-e2e/src/integration/network-page.feature
Normal file
@ -0,0 +1,6 @@
|
||||
Feature: Network parameters Page
|
||||
|
||||
Scenario: Navigate to network parameters page
|
||||
Given I am on the homepage
|
||||
When I navigate to the transactions page
|
||||
Then transactions page is correctly displayed
|
@ -0,0 +1,6 @@
|
||||
Feature: Transactions Page
|
||||
|
||||
Scenario: Navigate to transactions page
|
||||
Given I am on the homepage
|
||||
When I navigate to the transactions page
|
||||
Then transactions page is correctly displayed
|
@ -0,0 +1,6 @@
|
||||
Feature: Validators Page
|
||||
|
||||
Scenario: Navigate to validators page
|
||||
Given I am on the homepage
|
||||
When I navigate to the validators page
|
||||
Then validators page is correctly displayed
|
@ -13,6 +13,7 @@ declare namespace Cypress {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
interface Chainable<Subject> {
|
||||
login(email: string, password: string): void;
|
||||
getByTestId(selector: string): Chainable<JQuery<HTMLElement>>;
|
||||
}
|
||||
}
|
||||
//
|
||||
@ -31,3 +32,6 @@ Cypress.Commands.add('login', (email, password) => {
|
||||
//
|
||||
// -- This will overwrite an existing command --
|
||||
// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... })
|
||||
Cypress.Commands.add('getByTestId', (selector, ...args) => {
|
||||
return cy.get(`[data-testid=${selector}]`, ...args);
|
||||
});
|
||||
|
9
apps/explorer-e2e/src/support/pages/assets-page.js
Normal file
9
apps/explorer-e2e/src/support/pages/assets-page.js
Normal file
@ -0,0 +1,9 @@
|
||||
import BasePage from './base-page';
|
||||
|
||||
export default class AssetsPage extends BasePage {
|
||||
assetHeader = 'asset-header';
|
||||
|
||||
validateAssetsDisplayed() {
|
||||
this.validateBlockDataDisplayed(this.assetHeader);
|
||||
}
|
||||
}
|
79
apps/explorer-e2e/src/support/pages/base-page.js
Normal file
79
apps/explorer-e2e/src/support/pages/base-page.js
Normal file
@ -0,0 +1,79 @@
|
||||
export default class BasePage {
|
||||
transactionsUrl = '/txs';
|
||||
blocksUrl = '/blocks';
|
||||
partiesUrl = '/parties';
|
||||
assetsUrl = '/assets';
|
||||
genesisUrl = '/genesis';
|
||||
governanceUrl = '/governance';
|
||||
marketsUrl = '/markets';
|
||||
networkParametersUrl = '/network-parameters';
|
||||
validatorsUrl = '/validators';
|
||||
blockExplorerHeader = 'explorer-header';
|
||||
searchField = 'search-input';
|
||||
|
||||
navigateToTxs() {
|
||||
cy.get(`a[href='${this.transactionsUrl}']`).click();
|
||||
}
|
||||
|
||||
navigateToBlocks() {
|
||||
cy.get(`a[href='${this.blocksUrl}']`).click();
|
||||
}
|
||||
|
||||
navigateToParties() {
|
||||
cy.get(`a[href='${this.partiesUrl}']`).click();
|
||||
}
|
||||
|
||||
navigateToAssets() {
|
||||
cy.get(`a[href*='${this.assetsUrl}']`).click();
|
||||
}
|
||||
|
||||
navigateToGenesis() {
|
||||
cy.get(`a[href='${this.genesisUrl}']`).click();
|
||||
}
|
||||
|
||||
navigateToGovernance() {
|
||||
cy.get(`a[href='${this.governanceUrl}']`).click();
|
||||
}
|
||||
|
||||
navigateToMarkets() {
|
||||
cy.get(`a[href='${this.marketsUrl}']`).click();
|
||||
}
|
||||
|
||||
navigateToNetworkParameters() {
|
||||
cy.get(`a[href='${this.networkParametersUrl}']`).click();
|
||||
}
|
||||
|
||||
navigateToValidators() {
|
||||
cy.get(`a[href='${this.validatorsUrl}']`).click();
|
||||
}
|
||||
|
||||
search(searchText) {
|
||||
cy.getByTestId(this.searchField).type(searchText);
|
||||
}
|
||||
|
||||
validateSearchDisplayed() {
|
||||
cy.getByTestId(this.blockExplorerHeader).should(
|
||||
'have.text',
|
||||
'Vega Block Explorer'
|
||||
);
|
||||
cy.getByTestId(this.searchField).should('be.visible');
|
||||
}
|
||||
|
||||
validateBlockDataDisplayed(headerTestId) {
|
||||
cy.getByTestId(headerTestId).then(($assetHeaders) => {
|
||||
const headersAmount = parseInt($assetHeaders.length);
|
||||
|
||||
cy.wrap($assetHeaders).each(($header) => {
|
||||
expect($header).to.not.be.empty;
|
||||
});
|
||||
|
||||
cy.get('.language-json')
|
||||
.each(($asset, index, $list) => {
|
||||
expect($asset).to.not.be.empty;
|
||||
})
|
||||
.then(($list) => {
|
||||
expect($list).to.have.length(headersAmount);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
9
apps/explorer-e2e/src/support/pages/genesis-page.js
Normal file
9
apps/explorer-e2e/src/support/pages/genesis-page.js
Normal file
@ -0,0 +1,9 @@
|
||||
import BasePage from './base-page';
|
||||
|
||||
export default class GenesisPage extends BasePage {
|
||||
GenesisHeader = 'genesis-header';
|
||||
|
||||
genesisFieldsDisplayed() {
|
||||
this.validateBlockDataDisplayed(this.GenesisHeader);
|
||||
}
|
||||
}
|
3
apps/explorer-e2e/src/support/pages/home-page.js
Normal file
3
apps/explorer-e2e/src/support/pages/home-page.js
Normal file
@ -0,0 +1,3 @@
|
||||
import BasePage from './base-page';
|
||||
|
||||
export default class HomePage extends BasePage {}
|
9
apps/explorer-e2e/src/support/pages/markets-page.js
Normal file
9
apps/explorer-e2e/src/support/pages/markets-page.js
Normal file
@ -0,0 +1,9 @@
|
||||
import BasePage from './base-page';
|
||||
|
||||
export default class MarketsPage extends BasePage {
|
||||
marketHeaders = 'markets-header';
|
||||
|
||||
validateMarketDataDisplayed() {
|
||||
this.validateBlockDataDisplayed(this.marketHeaders);
|
||||
}
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
import BasePage from './base-page';
|
||||
|
||||
export default class NetworkParametersPage extends BasePage {
|
||||
networkParametersHeader = 'network-param-header';
|
||||
parameters = 'parameters';
|
||||
|
||||
verifyNetworkParametersDisplayed() {
|
||||
cy.getByTestId(this.networkParametersHeader).should(
|
||||
'have.text',
|
||||
'NetworkParameters'
|
||||
);
|
||||
cy.getByTestId(this.parameters).should('not.be.empty');
|
||||
}
|
||||
}
|
37
apps/explorer-e2e/src/support/pages/transactions-page.js
Normal file
37
apps/explorer-e2e/src/support/pages/transactions-page.js
Normal file
@ -0,0 +1,37 @@
|
||||
import BasePage from './base-page';
|
||||
|
||||
export default class TransactionsPage extends BasePage {
|
||||
blockRow = 'block-row';
|
||||
blockHeight = 'block-height';
|
||||
numberOfTransactions = 'num-txs';
|
||||
validatorLink = 'validator-link';
|
||||
blockTime = 'block-time';
|
||||
refreshBtn = 'refresh';
|
||||
|
||||
validateTransactionsPagedisplayed() {
|
||||
cy.getByTestId(this.blockRow).should('have.length.above', 1);
|
||||
cy.getByTestId(this.blockHeight).first().should('not.be.empty');
|
||||
cy.getByTestId(this.numberOfTransactions).first().should('not.be.empty');
|
||||
cy.getByTestId(this.validatorLink).first().should('not.be.empty');
|
||||
cy.getByTestId(this.blockTime).first().should('not.be.empty');
|
||||
}
|
||||
|
||||
validateRefreshBtn() {
|
||||
cy.getByTestId(this.blockHeight)
|
||||
.first()
|
||||
.invoke('text')
|
||||
.then((blockHeightTxt) => {
|
||||
cy.wait(1000); // eslint-disable-line cypress/no-unnecessary-waiting
|
||||
//Wait needed to allow blocks to change
|
||||
cy.getByTestId(this.refreshBtn).click();
|
||||
|
||||
cy.getByTestId(this.blockHeight)
|
||||
.first()
|
||||
.invoke('text')
|
||||
.should((newBlockHeightText) => {
|
||||
expect(blockHeightTxt).not.to.eq(newBlockHeightText);
|
||||
});
|
||||
});
|
||||
cy.getByTestId(this.blockTime).first();
|
||||
}
|
||||
}
|
18
apps/explorer-e2e/src/support/pages/validators-page.js
Normal file
18
apps/explorer-e2e/src/support/pages/validators-page.js
Normal file
@ -0,0 +1,18 @@
|
||||
import BasePage from './base-page';
|
||||
|
||||
export default class ValidatorPage extends BasePage {
|
||||
tendermintHeader = 'tendermint-header';
|
||||
vegaHeader = 'vega-header';
|
||||
tendermintData = 'tendermint-data';
|
||||
vegaData = 'vega-data';
|
||||
|
||||
validateValidatorsDisplayed() {
|
||||
cy.getByTestId(this.tendermintHeader).should(
|
||||
'have.text',
|
||||
'Tendermint data'
|
||||
);
|
||||
cy.getByTestId(this.tendermintData).should('not.be.empty');
|
||||
cy.getByTestId(this.vegaHeader).should('have.text', 'Vega data');
|
||||
cy.getByTestId(this.vegaData).should('not.be.empty');
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
import { Given, Then, When } from 'cypress-cucumber-preprocessor/steps';
|
||||
|
||||
import AssetsPage from '../pages/assets-page';
|
||||
const assetPage = new AssetsPage();
|
||||
|
||||
When('I navigate to the asset page', () => {
|
||||
assetPage.navigateToAssets();
|
||||
});
|
||||
|
||||
Then('asset page is correctly displayed', () => {
|
||||
assetPage.validateAssetsDisplayed();
|
||||
});
|
@ -0,0 +1,5 @@
|
||||
import { Given, Then, When } from 'cypress-cucumber-preprocessor/steps';
|
||||
|
||||
Given('I am on the homepage', () => {
|
||||
cy.visit('/');
|
||||
});
|
@ -1,5 +1 @@
|
||||
import { Given, Then, When } from 'cypress-cucumber-preprocessor/steps';
|
||||
|
||||
Given('I go to the homepage', () => {
|
||||
cy.visit('/');
|
||||
});
|
||||
|
@ -0,0 +1,12 @@
|
||||
import { Given, Then, When } from 'cypress-cucumber-preprocessor/steps';
|
||||
|
||||
import MarketsPage from '../pages/markets-page';
|
||||
const marketsPage = new MarketsPage();
|
||||
|
||||
When('I navigate to the markets page', () => {
|
||||
marketsPage.navigateToMarkets();
|
||||
});
|
||||
|
||||
Then('markets page is correctly displayed', () => {
|
||||
marketsPage.validateMarketDataDisplayed();
|
||||
});
|
@ -0,0 +1,22 @@
|
||||
import { Then, When } from 'cypress-cucumber-preprocessor/steps';
|
||||
|
||||
import TransactionsPage from '../pages/transactions-page';
|
||||
const transactionsPage = new TransactionsPage();
|
||||
|
||||
When('I navigate to the transactions page', () => {
|
||||
transactionsPage.navigateToTxs();
|
||||
});
|
||||
|
||||
When('I navigate to the blocks page', () => {
|
||||
transactionsPage.navigateToBlocks();
|
||||
});
|
||||
|
||||
Then('transactions page is correctly displayed', () => {
|
||||
transactionsPage.validateTransactionsPagedisplayed();
|
||||
transactionsPage.validateRefreshBtn();
|
||||
});
|
||||
|
||||
Then('blocks page is correctly displayed', () => {
|
||||
transactionsPage.validateTransactionsPagedisplayed();
|
||||
transactionsPage.validateRefreshBtn();
|
||||
});
|
@ -0,0 +1,12 @@
|
||||
import { Then, When } from 'cypress-cucumber-preprocessor/steps';
|
||||
|
||||
import ValidatorPage from '../pages/validators-page';
|
||||
const validatorsPage = new ValidatorPage();
|
||||
|
||||
When('I navigate to the validators page', () => {
|
||||
validatorsPage.navigateToValidators();
|
||||
});
|
||||
|
||||
Then('validators page is correctly displayed', () => {
|
||||
validatorsPage.validateValidatorsDisplayed();
|
||||
});
|
@ -20,23 +20,23 @@ export const BlocksTable = ({ data, showTransactions }: BlocksProps) => {
|
||||
{data.result?.block_metas?.map((block, index) => {
|
||||
return (
|
||||
<React.Fragment key={index}>
|
||||
<tr>
|
||||
<td>
|
||||
<tr data-testid="block-row">
|
||||
<td data-testid="block-height">
|
||||
<Link to={`/blocks/${block.header?.height}`}>
|
||||
{block.header?.height}
|
||||
</Link>
|
||||
</td>
|
||||
<td>
|
||||
<td data-testid="num-txs">
|
||||
{block.num_txs === '1'
|
||||
? '1 transaction'
|
||||
: `${block.num_txs} transactions`}
|
||||
</td>
|
||||
<td>
|
||||
<td data-testid="validator-link">
|
||||
<Link to={`/validators/${block.header?.proposer_address}`}>
|
||||
{block.header.proposer_address}
|
||||
</Link>
|
||||
</td>
|
||||
<td>
|
||||
<td data-testid="block-time">
|
||||
<SecondsAgo date={block.header?.time} />
|
||||
</td>
|
||||
</tr>
|
||||
|
@ -91,10 +91,15 @@ const Search = () => {
|
||||
const { search, onChange } = useGuess();
|
||||
return (
|
||||
<section>
|
||||
<h1>Vega Block Explorer</h1>
|
||||
<h1 data-testid="explorer-header">Vega Block Explorer</h1>
|
||||
<fieldset>
|
||||
<label htmlFor="search">Search: </label>
|
||||
<input name="search" value={search} onChange={(e) => onChange(e)} />
|
||||
<input
|
||||
data-testid="search-field"
|
||||
name="search"
|
||||
value={search}
|
||||
onChange={(e) => onChange(e)}
|
||||
/>
|
||||
</fieldset>
|
||||
</section>
|
||||
);
|
||||
|
@ -17,12 +17,12 @@ export const TxDetails = ({ txData, pubKey }: TxDetailsProps) => {
|
||||
<Table>
|
||||
<tr>
|
||||
<td>Hash</td>
|
||||
<td>{txData.hash}</td>
|
||||
<td data-testid="hash">{txData.hash}</td>
|
||||
</tr>
|
||||
{pubKey ? (
|
||||
<tr>
|
||||
<td>Submitted by</td>
|
||||
<td>
|
||||
<td data-testid="submitted-by">
|
||||
<Link to={`/${Routes.PARTIES}/${pubKey}`}>{pubKey}</Link>
|
||||
</td>
|
||||
</tr>
|
||||
@ -35,14 +35,14 @@ export const TxDetails = ({ txData, pubKey }: TxDetailsProps) => {
|
||||
{txData.height ? (
|
||||
<tr>
|
||||
<td>Block</td>
|
||||
<td>
|
||||
<td data-testid="block">
|
||||
<Link to={`/blocks/${txData.height}`}>{txData.height}</Link>
|
||||
</td>
|
||||
</tr>
|
||||
) : null}
|
||||
<tr>
|
||||
<td>Encoded tnx</td>
|
||||
<td>{txData.tx}</td>
|
||||
<td data-testid="encoded-tnx">{txData.tx}</td>
|
||||
</tr>
|
||||
</Table>
|
||||
);
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React from "react";
|
||||
import { WebSocketHook } from "react-use-websocket/dist/lib/types";
|
||||
import React from 'react';
|
||||
import { WebSocketHook } from 'react-use-websocket/dist/lib/types';
|
||||
|
||||
export type WebsocketContextShape = WebSocketHook;
|
||||
|
||||
@ -9,7 +9,7 @@ export const TendermintWebsocketContext =
|
||||
export function useTendermintWebsocketContext() {
|
||||
const context = React.useContext(TendermintWebsocketContext);
|
||||
if (context === null) {
|
||||
throw new Error("useWebsocket must be used within WebsocketContext");
|
||||
throw new Error('useWebsocket must be used within WebsocketContext');
|
||||
}
|
||||
return context;
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ const Assets = () => {
|
||||
<h1>Assets</h1>
|
||||
{data?.assets.map((a) => (
|
||||
<React.Fragment key={a.id}>
|
||||
<h2>
|
||||
<h2 data-testid="asset-header">
|
||||
{a.name} ({a.symbol})
|
||||
</h2>
|
||||
<SyntaxHighlighter data={a} />
|
||||
|
@ -16,7 +16,9 @@ const Blocks = () => {
|
||||
<>
|
||||
<section>
|
||||
<h1>Blocks</h1>
|
||||
<button onClick={() => refetch()}>Refresh to see latest blocks</button>
|
||||
<button data-testid="refresh" onClick={() => refetch()}>
|
||||
Refresh to see latest blocks
|
||||
</button>
|
||||
<BlocksTable data={data} />
|
||||
</section>
|
||||
|
||||
|
@ -12,7 +12,7 @@ const Genesis = () => {
|
||||
if (!genesis?.result.genesis) return null;
|
||||
return (
|
||||
<section>
|
||||
<h1>Genesis</h1>
|
||||
<h1 data-testid="genesis-header">Genesis</h1>
|
||||
<SyntaxHighlighter data={genesis?.result.genesis} />
|
||||
</section>
|
||||
);
|
||||
|
@ -153,7 +153,7 @@ const Markets = () => {
|
||||
<h1>Markets</h1>
|
||||
{data.markets.map((m) => (
|
||||
<React.Fragment key={m.id}>
|
||||
<h2>{m.name}</h2>
|
||||
<h2 data-testid="markets-header">{m.name}</h2>
|
||||
<SyntaxHighlighter data={m} />
|
||||
</React.Fragment>
|
||||
))}
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { gql, useQuery } from "@apollo/client";
|
||||
import { NetworkParametersQuery } from "./__generated__/NetworkParametersQuery";
|
||||
import { gql, useQuery } from '@apollo/client';
|
||||
import { NetworkParametersQuery } from './__generated__/NetworkParametersQuery';
|
||||
|
||||
export const NETWORK_PARAMETERS_QUERY = gql`
|
||||
query NetworkParametersQuery {
|
||||
@ -14,8 +14,8 @@ const NetworkParameters = () => {
|
||||
const { data } = useQuery<NetworkParametersQuery>(NETWORK_PARAMETERS_QUERY);
|
||||
return (
|
||||
<section>
|
||||
<h1>NetworkParameters</h1>
|
||||
<pre>{JSON.stringify(data, null, " ")}</pre>
|
||||
<h1 data-testid="network-param-header">NetworkParameters</h1>
|
||||
<pre data-testid="parameters">{JSON.stringify(data, null, ' ')}</pre>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
@ -16,7 +16,9 @@ const Txs = () => {
|
||||
<>
|
||||
<section>
|
||||
<h1>Transactions</h1>
|
||||
<button onClick={() => refetch()}>Refresh to see latest blocks</button>
|
||||
<button data-testid="refresh" onClick={() => refetch()}>
|
||||
Refresh to see latest blocks
|
||||
</button>
|
||||
<BlocksTable data={data} showTransactions={true} />
|
||||
</section>
|
||||
|
||||
|
@ -44,10 +44,12 @@ const Validators = () => {
|
||||
return (
|
||||
<section>
|
||||
<h1>Validators</h1>
|
||||
<h2>Tendermint data</h2>
|
||||
<pre>{JSON.stringify(validators, null, ' ')}</pre>
|
||||
<h2>Vega data</h2>
|
||||
<pre>{JSON.stringify(data, null, ' ')}</pre>
|
||||
<h2 data-testid="tendermint-header">Tendermint data</h2>
|
||||
<pre data-testid="tendermint-data">
|
||||
{JSON.stringify(validators, null, ' ')}
|
||||
</pre>
|
||||
<h2 data-testid="vega-header">Vega data</h2>
|
||||
<pre data-testid="vega-data">{JSON.stringify(data, null, ' ')}</pre>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user