-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feature: Playwright e2e initial (#77)
* initial * rm fixtures * retries and workers * connect wallet * setup wallet connection * rm unused test suite * injectbtc * split * rm dotenv * rm process.env.ci * Balance and address checks after connection * Create staking transaction * STAKING_AMOUNT constant * constants
- Loading branch information
1 parent
ac2bbd0
commit 3f88fad
Showing
12 changed files
with
358 additions
and
3 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
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,8 @@ | ||
import { expect, test } from "@playwright/test"; | ||
|
||
test.describe("App", () => { | ||
test("should have a title", async ({ page }) => { | ||
await page.goto("/"); | ||
await expect(page).toHaveTitle(/Staking Dashboard/); | ||
}); | ||
}); |
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 { expect, test } from "@playwright/test"; | ||
|
||
import { setupWalletConnection } from "./helper/connect"; | ||
|
||
test.describe("Balance and address checks after connection", () => { | ||
test.beforeEach(async ({ page }) => { | ||
await page.goto("/"); | ||
await setupWalletConnection(page); | ||
}); | ||
|
||
test("balance is correct", async ({ page }) => { | ||
const balance = await page.getByTestId("balance").textContent(); | ||
expect(balance).toBe("0.12345678 BTC"); | ||
}); | ||
|
||
test("address is correct", async ({ page }) => { | ||
const address = await page.getByTestId("address").textContent(); | ||
expect(address).toBe("bc1p...97sd"); | ||
}); | ||
}); |
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,6 @@ | ||
import { satoshiToBtc } from "@/utils/btcConversions"; | ||
|
||
export const STAKING_AMOUNT_SAT = 50000; | ||
export const STAKING_AMOUNT_BTC = satoshiToBtc(STAKING_AMOUNT_SAT); | ||
export const STAKING_TX_HASH = | ||
"47af61d63bcc6c513561d9a1198d082052cc07a81f50c6f130653f0a6ecc0fc1"; |
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,54 @@ | ||
import { Page, expect } from "@playwright/test"; | ||
|
||
import { injectBTCWallet } from "./injectBTCWallet"; | ||
|
||
export const clickConnectButton = async (page: Page) => { | ||
const connectButton = page.getByRole("button", { | ||
name: "Connect to BTC", | ||
}); | ||
await connectButton.click(); | ||
}; | ||
|
||
export const acceptTermsAndConditions = async (page: Page) => { | ||
const termsCheckbox = page | ||
.locator("label") | ||
.filter({ hasText: "I certify that I have read" }); | ||
|
||
const inscriptionsCheckbox = page | ||
.locator("label") | ||
.filter({ hasText: "I certify that there are no" }); | ||
|
||
const hwCheckbox = page | ||
.locator("label") | ||
.filter({ hasText: "I acknowledge that Keystone via QR code" }); | ||
|
||
await termsCheckbox.click(); | ||
await inscriptionsCheckbox.click(); | ||
await hwCheckbox.click(); | ||
|
||
expect(await termsCheckbox.isChecked()).toBe(true); | ||
expect(await inscriptionsCheckbox.isChecked()).toBe(true); | ||
expect(await hwCheckbox.isChecked()).toBe(true); | ||
}; | ||
|
||
export const clickInjectableWalletButton = async (page: Page) => { | ||
const browserButton = page | ||
.getByTestId("modal") | ||
.getByRole("button", { name: "Browser" }); | ||
await browserButton.click(); | ||
}; | ||
|
||
export const clickConnectWalletButton = async (page: Page) => { | ||
const connectWalletButton = page.getByTestId("modal").getByRole("button", { | ||
name: "Connect to BTC network", | ||
}); | ||
await connectWalletButton.click(); | ||
}; | ||
|
||
export const setupWalletConnection = async (page: Page) => { | ||
await injectBTCWallet(page); | ||
await clickConnectButton(page); | ||
await acceptTermsAndConditions(page); | ||
await clickInjectableWalletButton(page); | ||
await clickConnectWalletButton(page); | ||
}; |
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,47 @@ | ||
import { Page } from "@playwright/test"; | ||
|
||
// Sample wallet implementation for E2E testing purposes | ||
export const injectBTCWallet = async (page: Page) => { | ||
// Inject the wallet methods into window.btcwallet | ||
await page.evaluate(() => { | ||
// wallet | ||
const btcWallet = { | ||
connectWallet: () => { | ||
return btcWallet; | ||
}, | ||
getWalletProviderName: () => "BTC Wallet", | ||
getAddress: () => | ||
"bc1p8gjpy0vyfdq3tty8sy0v86dvl69rquc85n2gpuztll9wxh9cpars7r97sd", | ||
getPublicKeyHex: () => | ||
"024c6e2954c75bcb53aa13b7cd5d8bcdb4c9a4dd0784d68b115bd4408813b45608", | ||
on: () => {}, | ||
getNetwork: () => "mainnet", | ||
getBTCTipHeight: () => 859568, | ||
getNetworkFees: () => ({ | ||
fastestFee: 1, | ||
halfHourFee: 1, | ||
hourFee: 1, | ||
economyFee: 1, | ||
minimumFee: 1, | ||
}), | ||
getUtxos: () => [ | ||
{ | ||
txid: "fa4908ad8876655ccb5ffba6a9eab58e1b785af73703cd58b19526c099d67c05", | ||
vout: 0, | ||
value: 12345678, | ||
scriptPubKey: | ||
"51203a24123d844b4115ac87811ec3e9acfe8a307307a4d480f04bffcae35cb80f47", | ||
}, | ||
], | ||
getInscriptions: () => [], | ||
signPsbt: (_psbtHex: string) => { | ||
return "70736274ff0100fd040102000000028a12de07985b7d06d83d9683eb3c0a86284fa3cbb2df998aed61009d700748ba0200000000fdffffff4ca53ae433b535b660a2dca99724199b2219a617508eed2ccf88762683a622430200000000fdffffff0350c3000000000000225120cf7c40c6fb1395430816dbb5e1ba9f172ef25573a3b609efa1723559cd82d5590000000000000000496a4762626234004c6e2954c75bcb53aa13b7cd5d8bcdb4c9a4dd0784d68b115bd4408813b45608094f5861be4128861d69ea4b66a5f974943f100f55400bf26f5cce124b4c9af7009604450000000000002251203a24123d844b4115ac87811ec3e9acfe8a307307a4d480f04bffcae35cb80f47340e0d000001012b50ba0000000000002251203a24123d844b4115ac87811ec3e9acfe8a307307a4d480f04bffcae35cb80f470108420140f94b4114bf4c77c449fefb45d60a86831a73897e58b03ba8250e1bf877912cdcc48d106fa266e8aa4085a43e9ad348652fb7b1ad0d820b6455c06edd92cadfef0001012b79510000000000002251203a24123d844b4115ac87811ec3e9acfe8a307307a4d480f04bffcae35cb80f470108420140e7abc0544c68c94a154e9136397ad8ab7d4dce0545c7c0db89aeb9a455e9377fb1c116ca20cdcb1c1ef4c9335a85c34499f45918ee37b010b69220626c4a8d7100000000"; | ||
}, | ||
pushTx: (_txHex: string) => { | ||
return "47af61d63bcc6c513561d9a1198d082052cc07a81f50c6f130653f0a6ecc0fc1"; | ||
}, | ||
}; | ||
|
||
window.btcwallet = btcWallet; | ||
}); | ||
}; |
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,54 @@ | ||
import { expect, test } from "@playwright/test"; | ||
|
||
import { | ||
STAKING_AMOUNT_BTC, | ||
STAKING_AMOUNT_SAT, | ||
STAKING_TX_HASH, | ||
} from "./constants/staking"; | ||
import { setupWalletConnection } from "./helper/connect"; | ||
|
||
test.describe("Create staking transaction", () => { | ||
test.beforeEach(async ({ page }) => { | ||
await page.goto("/"); | ||
await setupWalletConnection(page); | ||
}); | ||
|
||
test("prepare the staking", async ({ page }) => { | ||
const previewButton = page.locator("button").filter({ hasText: "Preview" }); | ||
|
||
// Selects the first finality provider in the list | ||
await page.locator("#finality-providers>div>div").first().click(); | ||
expect(previewButton).toBeDisabled(); | ||
|
||
// Preview available after filling the amount | ||
await page.getByPlaceholder("BTC").fill(`${STAKING_AMOUNT_BTC}`); | ||
expect(previewButton).toBeEnabled(); | ||
|
||
await previewButton.click(); | ||
const stakeButton = page.locator("button").filter({ hasText: "Stake" }); | ||
await stakeButton.click(); | ||
|
||
// Success modal | ||
const success = page | ||
.getByTestId("modal") | ||
.locator("div") | ||
.filter({ hasText: "Congratulations!" }); | ||
expect(success).toBeVisible(); | ||
|
||
// Check for local storage | ||
const item = await page.evaluate(() => | ||
localStorage.getItem( | ||
"bbn-staking-delegations-4c6e2954c75bcb53aa13b7cd5d8bcdb4c9a4dd0784d68b115bd4408813b45608", | ||
), | ||
); | ||
expect(item).not.toBeNull(); | ||
|
||
const parsed = JSON.parse(item as string); | ||
expect(parsed).toHaveLength(1); | ||
|
||
// Check the staking delegation tx hash and staking value | ||
const [delegation] = parsed; | ||
expect(delegation.stakingValueSat).toBe(STAKING_AMOUNT_SAT); | ||
expect(delegation.stakingTxHashHex).toBe(STAKING_TX_HASH); | ||
}); | ||
}); |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
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
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,82 @@ | ||
import { defineConfig, devices } from "@playwright/test"; | ||
import path from "path"; | ||
|
||
// Use process.env.PORT by default and fallback to port 3000 | ||
const PORT = process.env.PORT || 3000; | ||
|
||
// Set webServer.url and use.baseURL with the location of the WebServer respecting the correct set port | ||
const baseURL = `http://localhost:${PORT}`; | ||
|
||
/** | ||
* See https://playwright.dev/docs/test-configuration. | ||
*/ | ||
export default defineConfig({ | ||
// Test directory | ||
testDir: path.join(__dirname, "e2e"), | ||
/* Run tests in files in parallel */ | ||
fullyParallel: true, | ||
/* Fail the build on CI if you accidentally left test.only in the source code. */ | ||
forbidOnly: false, | ||
/* Retry on CI only */ | ||
retries: 2, | ||
/* Opt out of parallel tests on CI. */ | ||
workers: 2, | ||
/* Reporter to use. See https://playwright.dev/docs/test-reporters */ | ||
reporter: "html", | ||
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */ | ||
use: { | ||
/* Base URL to use in actions like `await page.goto('/')`. */ | ||
// Use baseURL so to make navigations relative. | ||
// More information: https://playwright.dev/docs/api/class-testoptions#test-options-base-url | ||
baseURL, | ||
|
||
/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */ | ||
trace: "on-first-retry", | ||
}, | ||
|
||
/* Configure projects for major browsers */ | ||
projects: [ | ||
{ | ||
name: "chromium", | ||
use: { ...devices["Desktop Chrome"] }, | ||
}, | ||
|
||
// { | ||
// name: 'firefox', | ||
// use: { ...devices['Desktop Firefox'] }, | ||
// }, | ||
|
||
// { | ||
// name: 'webkit', | ||
// use: { ...devices['Desktop Safari'] }, | ||
// }, | ||
|
||
/* Test against mobile viewports. */ | ||
// { | ||
// name: 'Mobile Chrome', | ||
// use: { ...devices['Pixel 5'] }, | ||
// }, | ||
// { | ||
// name: 'Mobile Safari', | ||
// use: { ...devices['iPhone 12'] }, | ||
// }, | ||
|
||
/* Test against branded browsers. */ | ||
// { | ||
// name: 'Microsoft Edge', | ||
// use: { ...devices['Desktop Edge'], channel: 'msedge' }, | ||
// }, | ||
// { | ||
// name: 'Google Chrome', | ||
// use: { ...devices['Desktop Chrome'], channel: 'chrome' }, | ||
// }, | ||
], | ||
|
||
/* Run your local dev server before starting the tests */ | ||
webServer: { | ||
command: "npm run dev", | ||
url: baseURL, | ||
timeout: 120 * 1000, | ||
reuseExistingServer: true, | ||
}, | ||
}); |
Oops, something went wrong.