-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
test(explorer): add e2e tests for all routes
- Loading branch information
1 parent
d37289d
commit 868d062
Showing
16 changed files
with
449 additions
and
23 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import { Locator, Page } from 'playwright' | ||
import { SEARCHBAR } from './constants' | ||
|
||
export class ExplorerApp { | ||
private readonly searchBar: Locator | ||
|
||
constructor(public readonly page: Page) { | ||
this.searchBar = this.page.locator(SEARCHBAR) | ||
} | ||
|
||
async navigateBySearchBar(searchTerm: string) { | ||
await this.searchBar.click() | ||
await this.searchBar.fill(searchTerm) | ||
await this.page.keyboard.press('Enter') | ||
} | ||
|
||
async goTo(url: string) { | ||
await this.page.goto(url) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
// General/Shared | ||
export const SEARCHBAR = `input[name="query"]` | ||
export const APP_NAME = 'explorer-identity-appName' | ||
export const APP_NETWORK = 'explorer-identity-network' | ||
export const DATUM_VALUE = 'explorer-datum-value' | ||
|
||
// Home page | ||
export const METRICS_ITEM = 'explorer-metrics-item' | ||
export const LATEST_BLOCKS_ITEM = 'explorer-latestBlocks-item' | ||
export const TOP_HOSTS_ITEMS = 'explorer-topHosts-item' | ||
|
||
// Contract page | ||
export const RENEWED_FROM_BUTTON = 'explorer-contract-renewedFrom' | ||
export const RENEWED_TO_BUTTON = 'explorer-contract-renewedTo' | ||
|
||
// Host page | ||
export const HOST_PRICING = 'explorer-hostPricing' | ||
export const HOST_SETTINGS_PATTERNS = [ | ||
'\\b\\d+(?:\\.\\d{1,2})?\\s?(TB|GB|MB|KB|B)\\b', // 3.00 TB | ||
'(\\$\\d+(?:\\.\\d{1,3})?|\\d+(?:\\.\\d{1,3})?\\s?[A-Z]{2})\\/(TB|GB|MB|KB|B)\\/(month|year|day)', // $1.16/TB/month | ||
'(\\$\\d+(?:\\.\\d{1,3})?|\\d+(?:\\.\\d{1,3})?\\s?[A-Z]{2})\\/(TB|GB|MB|KB|B)', // $1.12/TB | ||
'\\b\\d+\\s?(days?|months?|years?)\\b', // 6 months | ||
'^\\$\\d+(?:\\.\\d+)?$', // $4.50 | ||
'(\\$\\d+(?:\\.\\d+)?|\\d+(?:\\.\\d+)?\\s?[A-Z]{2})\\/million', // $0.0045 SC/million | ||
'^\\d+(?:\\.\\d+)?\\s?(KS|mS)$', // 1.000 KS/mS | ||
'\\b\\d+\\s?blocks\\b', // 25920 blocks | ||
'^(6553[0-5]|(655[0-2][0-9]|64[0-9]{3}|6[0-3][0-9]{2}|[1-5]?[0-9]{0,4}))$', // 9883 | ||
'^\\d{1,16}$', // 2592000000000000 | ||
'\\b\\d+(?:\\.\\d{1,2})?\\s?(Mbps|Gbps|Kbps)\\b', // 998.64 Mbps | ||
] | ||
|
||
// Test data | ||
export const TEST_BLOCK_1 = { | ||
height: '25000', | ||
id: '0000000016920b69bfbe192005cfed7c9c5369bb83ff8406320f77f74f7b40cb', | ||
display: { | ||
title: 'Block 25,000', | ||
blockHash: '000000...7b40cb', | ||
minerPayoutAddress: '13caad1b4eea...', | ||
transactionHeader: '2 transactions', | ||
lastTransactionID: '8a03682f2285...', | ||
}, | ||
} | ||
|
||
export const TEST_TX_1 = { | ||
id: '8a03682f22857f306a95f55a28fa9edf111e1d11803f8b4a91bd01d2803a4eb6', | ||
display: { | ||
title: 'Transaction 8a03682f22857f3...', | ||
confirmationHeight: '25,000', | ||
numberOfConfirmations: '72+ confirmations', | ||
inputAddress: '83cc8e810db6...', | ||
outputAddress: 'e3ed23ed389f...', | ||
inputAmount: '+8.979 KS', | ||
outputAmount: '+107.674 SC', | ||
contractID: '25c94822bf7b...', | ||
}, | ||
} | ||
|
||
export const TEST_ADDRESS_1 = { | ||
id: '68bf48e81536f2221f3809aa9d1c89c1c869a17c6f186a088e49fd2605e4bfaaa24f26e4c42c', | ||
display: { | ||
title: 'Address 68bf48e81536f22...', | ||
transactionNumber: '500 transactions', | ||
amount: '1.262 MS', | ||
transactionID: '23e427949a63...', | ||
}, | ||
} | ||
|
||
export const TEST_CONTRACT_1 = { | ||
id: '25c94822bf7bd86a92d28a148d9d30151949f3599bf93af0df7b4f1e1b3c990d', | ||
renewedFromTitle: 'Contract 494d147a8028217...', | ||
renewedToTitle: 'Contract 43a81d1a21ebf6f...', | ||
display: { | ||
title: 'Contract 25c94822bf7bd86...', | ||
transactionID: 'a3a4a6808e33...', | ||
unlockHash: 'c50b70e7dd79...', | ||
revisionNumber: '18,446,744,0...', | ||
status: 'obligation succeeded', | ||
missedProofTitle: 'Missed proof outputs (2)', | ||
validProofTitle: 'Valid proof outputs (2)', | ||
}, | ||
} | ||
|
||
export const TEST_HOST_1 = { | ||
pubkey: | ||
'ed25519:3926a0434232bba9eaca2041303a1039d4f65bf54d7bd4e2a9164ea2d778b714', | ||
display: { | ||
pubkey: 'ed25519:3926a0434232bba9eaca20...', | ||
title: '51.81.242.140:9882', | ||
location: 'US', | ||
}, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
import { test, expect } from '@playwright/test' | ||
import { ExplorerApp } from '../fixtures/ExplorerApp' | ||
import { TEST_ADDRESS_1 } from '../fixtures/constants' | ||
|
||
let explorerApp: ExplorerApp | ||
|
||
test.beforeEach(async ({ page }) => { | ||
explorerApp = new ExplorerApp(page) | ||
}) | ||
|
||
test('address can be searched by id', async ({ page }) => { | ||
await explorerApp.goTo('/') | ||
await explorerApp.navigateBySearchBar(TEST_ADDRESS_1.id) | ||
|
||
await expect(page.getByText(TEST_ADDRESS_1.display.title)).toBeVisible() | ||
}) | ||
|
||
test('address can be directly navigated to by id', async ({ page }) => { | ||
await explorerApp.goTo('/address/' + TEST_ADDRESS_1.id) | ||
|
||
await expect(page.getByText(TEST_ADDRESS_1.display.title)).toBeVisible() | ||
}) | ||
|
||
test('address displays the intended data', async ({ page }) => { | ||
const displayKeys = Object.keys(TEST_ADDRESS_1.display) | ||
|
||
await explorerApp.goTo('/address/' + TEST_ADDRESS_1.id) | ||
|
||
for (const key of displayKeys) { | ||
const currentProperty = TEST_ADDRESS_1.display[key] | ||
await expect(page.getByText(currentProperty)).toBeVisible() | ||
} | ||
}) | ||
|
||
test('address can navigate to the unspent outputs list', async ({ page }) => { | ||
await explorerApp.goTo('/address/' + TEST_ADDRESS_1.id) | ||
await page.getByRole('tab').getByText('Unspent outputs').click() | ||
|
||
await expect(page.getByText('073b0cbbdd6f...')).toBeVisible() | ||
}) | ||
|
||
test('address can navigate through to a transaction', async ({ page }) => { | ||
await explorerApp.goTo('/address/' + TEST_ADDRESS_1.id) | ||
|
||
await page | ||
.getByTestId( | ||
'entity-link-/tx/23e427949a6360014602cff7cfa9aa0c3b87765b94c6b37accfb661d3365336a' | ||
) | ||
.click() | ||
|
||
await expect(page.getByText('Transaction 23e427949a63600...')).toBeVisible() | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
import { test, expect } from '@playwright/test' | ||
import { ExplorerApp } from '../fixtures/ExplorerApp' | ||
import { TEST_BLOCK_1 } from '../fixtures/constants' | ||
|
||
let explorerApp: ExplorerApp | ||
|
||
test.beforeEach(async ({ page }) => { | ||
explorerApp = new ExplorerApp(page) | ||
}) | ||
|
||
test('block can be searched by height', async ({ page }) => { | ||
await explorerApp.goTo('/') | ||
await explorerApp.navigateBySearchBar(TEST_BLOCK_1.height) | ||
|
||
await expect(page.getByText(TEST_BLOCK_1.display.title).nth(0)).toBeVisible() | ||
}) | ||
|
||
test('block can be searched by id', async ({ page }) => { | ||
await explorerApp.goTo('/') | ||
await explorerApp.navigateBySearchBar(TEST_BLOCK_1.id) | ||
|
||
await expect(page.getByText(TEST_BLOCK_1.display.title).nth(0)).toBeVisible() | ||
}) | ||
|
||
test('block can be directly navigated to by height', async ({ page }) => { | ||
await explorerApp.goTo('/block/' + TEST_BLOCK_1.height) | ||
|
||
await expect(page.getByText(TEST_BLOCK_1.display.title).nth(0)).toBeVisible() | ||
}) | ||
|
||
test('block can be directly navigated to by id', async ({ page }) => { | ||
await explorerApp.goTo('/block/' + TEST_BLOCK_1.id) | ||
|
||
await expect(page.getByText(TEST_BLOCK_1.display.title).nth(0)).toBeVisible() | ||
}) | ||
|
||
test('block can click through to a transaction', async ({ page }) => { | ||
await explorerApp.goTo('/block/' + TEST_BLOCK_1.id) | ||
await page | ||
.getByTestId( | ||
'entity-link-/tx/8a03682f22857f306a95f55a28fa9edf111e1d11803f8b4a91bd01d2803a4eb6' | ||
) | ||
.click() | ||
|
||
await expect(page.getByText('Transaction 8a03682f22857f3...')).toBeVisible() | ||
}) | ||
|
||
test('block displays the intended data', async ({ page }) => { | ||
const displayKeys = Object.keys(TEST_BLOCK_1.display) | ||
|
||
await explorerApp.goTo('/block/' + TEST_BLOCK_1.height) | ||
|
||
for (const key of displayKeys) { | ||
const currentProperty = TEST_BLOCK_1.display[key] | ||
await expect(page.getByText(currentProperty)).toBeVisible() | ||
} | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
import { test, expect } from '@playwright/test' | ||
import { ExplorerApp } from '../fixtures/ExplorerApp' | ||
import { | ||
RENEWED_FROM_BUTTON, | ||
RENEWED_TO_BUTTON, | ||
TEST_CONTRACT_1, | ||
} from '../fixtures/constants' | ||
|
||
let explorerApp: ExplorerApp | ||
|
||
test.beforeEach(async ({ page }) => { | ||
explorerApp = new ExplorerApp(page) | ||
}) | ||
|
||
test('contract can be searched by id', async ({ page }) => { | ||
await explorerApp.goTo('/') | ||
await explorerApp.navigateBySearchBar(TEST_CONTRACT_1.id) | ||
|
||
await expect(page.getByText(TEST_CONTRACT_1.display.title)).toBeVisible() | ||
}) | ||
|
||
test('contract can be directly navigated to', async ({ page }) => { | ||
await explorerApp.goTo('/contract/' + TEST_CONTRACT_1.id) | ||
|
||
await expect(page.getByText(TEST_CONTRACT_1.display.title)).toBeVisible() | ||
}) | ||
|
||
test('contract displays the intended data', async ({ page }) => { | ||
const displayKeys = Object.keys(TEST_CONTRACT_1.display) | ||
|
||
await explorerApp.goTo('/contract/' + TEST_CONTRACT_1.id) | ||
|
||
for (const key of displayKeys) { | ||
const currentProperty = TEST_CONTRACT_1.display[key] | ||
await expect(page.getByText(currentProperty)).toBeVisible() | ||
} | ||
}) | ||
|
||
test('contract can navigate to renewed from contract', async ({ page }) => { | ||
await explorerApp.goTo('/contract/' + TEST_CONTRACT_1.id) | ||
await page.getByTestId(RENEWED_FROM_BUTTON).click() | ||
|
||
await expect(page.getByText(TEST_CONTRACT_1.renewedFromTitle)).toBeVisible() | ||
}) | ||
|
||
test('contract can navigate to renewed to contract', async ({ page }) => { | ||
await explorerApp.goTo('/contract/' + TEST_CONTRACT_1.id) | ||
await page.getByTestId(RENEWED_TO_BUTTON).click() | ||
|
||
await expect(page.getByText(TEST_CONTRACT_1.renewedToTitle)).toBeVisible() | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import { test, expect } from '@playwright/test' | ||
import { ExplorerApp } from '../fixtures/ExplorerApp' | ||
import { | ||
APP_NAME, | ||
APP_NETWORK, | ||
LATEST_BLOCKS_ITEM, | ||
METRICS_ITEM, | ||
TOP_HOSTS_ITEMS, | ||
} from '../fixtures/constants' | ||
|
||
let explorerApp: ExplorerApp | ||
|
||
test.beforeEach(async ({ page }) => { | ||
explorerApp = new ExplorerApp(page) | ||
|
||
await explorerApp.goTo('/') | ||
}) | ||
|
||
test('home displays app identity', async ({ page }) => { | ||
await expect(page.getByTestId(APP_NAME)).toContainText('siascan') | ||
await expect(page.getByTestId(APP_NETWORK)).toContainText('zen') // Can we get this via environmental variables? Will we always run these on zen? | ||
}) | ||
|
||
// The expectations below have their boundary around the display of a sucessful network call. | ||
// If the call fails, we fail, but if the call's contents change, we do not fail, as long as | ||
// we display something. | ||
test('home displays metrics', async ({ page }) => { | ||
expect((await page.getByTestId(METRICS_ITEM).count()) > 0).toBeTruthy() | ||
}) | ||
|
||
test('home displays latest blocks', async ({ page }) => { | ||
expect((await page.getByTestId(LATEST_BLOCKS_ITEM).count()) > 0).toBeTruthy() | ||
}) | ||
|
||
test('home displays top hosts', async ({ page }) => { | ||
expect((await page.getByTestId(TOP_HOSTS_ITEMS).count()) > 0).toBeTruthy() | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
import { test, expect } from '@playwright/test' | ||
import { ExplorerApp } from '../fixtures/ExplorerApp' | ||
import { | ||
DATUM_VALUE, | ||
TEST_HOST_1, | ||
HOST_SETTINGS_PATTERNS, | ||
HOST_PRICING, | ||
} from '../fixtures/constants' | ||
|
||
// Hosts can not be guaranteed like other test slices. Therefore, we'll grab | ||
|
||
let explorerApp: ExplorerApp | ||
|
||
test.beforeEach(async ({ page }) => { | ||
explorerApp = new ExplorerApp(page) | ||
}) | ||
|
||
test('host can be searched by id', async ({ page }) => { | ||
await explorerApp.goTo('/') | ||
await explorerApp.navigateBySearchBar(TEST_HOST_1.pubkey) | ||
|
||
await expect(page.getByText(TEST_HOST_1.display.title)).toBeVisible() | ||
}) | ||
|
||
test('host can be directly navigated to', async ({ page }) => { | ||
await explorerApp.goTo('/host/' + TEST_HOST_1.pubkey) | ||
|
||
await expect(page.getByText(TEST_HOST_1.display.title)).toBeVisible() | ||
}) | ||
|
||
test('host displays properly formatted host pricing', async ({ page }) => { | ||
await explorerApp.goTo('/host/' + TEST_HOST_1.pubkey) | ||
|
||
const hostSettings = await page.getByTestId(HOST_PRICING).allInnerTexts() | ||
|
||
for (const text of hostSettings) { | ||
const matched = HOST_SETTINGS_PATTERNS.some((pattern) => { | ||
return text.match(new RegExp(pattern)) | ||
}) | ||
// If we're failing, uncomment this and check console. | ||
// console.log(matched || text) | ||
expect(matched).toBe(true) | ||
} | ||
}) | ||
|
||
test('host displays properly formatted host settings', async ({ page }) => { | ||
await explorerApp.goTo('/host/' + TEST_HOST_1.pubkey) | ||
|
||
const hostSettings = await page.getByTestId(DATUM_VALUE).allInnerTexts() | ||
|
||
for (const text of hostSettings) { | ||
const matched = HOST_SETTINGS_PATTERNS.some((pattern) => { | ||
return text.match(new RegExp(pattern)) | ||
}) | ||
// If we're failing, uncomment this and check console. | ||
// console.log(matched || text) | ||
expect(matched).toBe(true) | ||
} | ||
}) |
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.