Skip to content

Commit

Permalink
initial
Browse files Browse the repository at this point in the history
  • Loading branch information
gbarkhatov committed Sep 2, 2024
1 parent ac2bbd0 commit 0707a72
Show file tree
Hide file tree
Showing 9 changed files with 353 additions and 1 deletion.
9 changes: 9 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -259,3 +259,12 @@ yarn-error.log*
next-env.d.ts

.env

# E2E Playwright
/test-results/
/playwright-report/
/blob-report/
/playwright/.cache/

# E2E Chrome Extensions
extensions
58 changes: 58 additions & 0 deletions e2e/app.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { expect, test } from "@playwright/test";
// from fixtures in case we are loading chrome extensions
// import { expect, test } from "../playwright.fixtures";

import { injectBBNWallet } from "./helper/bbn_wallet";
import {
acceptTermsAndConditions,
clickBrowserButton,
clickConnectButton,
} from "./helper/connect"; // Adjust the import path accordingly

test.describe("App", () => {
test("has a title", async ({ page }) => {
await page.goto("/");
await expect(page).toHaveTitle(/Staking Dashboard/);
});
});

test.describe("Connecting wallet", () => {
test.beforeEach(async ({ page }) => {
await page.goto("/");
await injectBBNWallet(page);
const connectWalletButton = page.getByRole("button", {
name: "Connect to BTC",
});
await connectWalletButton.click();
});

test("clicking the connect wallet button should open up a modal", async ({
page,
}) => {
const modalHeader = page
.getByTestId("modal")
.getByRole("heading", { name: "Connect wallet" });
await expect(modalHeader).toBeVisible();
});

test("can accept terms", async ({ page }) => {
await acceptTermsAndConditions(page);
});

test("should inject BBN wallet", async ({ page }) => {
const isWalletInjected = await page.evaluate(() => {
return window.btcwallet.getWalletProviderName() === "BBN Wallet";
});
expect(isWalletInjected).toBe(true);
});

test("should connect wallet", async ({ page }) => {
await clickBrowserButton(page);
});

test("complete flow", async ({ page }) => {
await acceptTermsAndConditions(page);
await clickBrowserButton(page);
await clickConnectButton(page);
});
});
43 changes: 43 additions & 0 deletions e2e/helper/bbn_wallet.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { Page } from "@playwright/test";

// Sample BBN Wallet implementation for E2E testing purposes
import { getTipHeight } from "@/utils/mempool_api";

export const injectBBNWallet = async (page: Page) => {
// Inject the BBNWallet methods into window.btcwallet
await page.evaluate(() => {
// wallet
const bbnWallet = {
connectWallet: () => console.log("Connected to BBN Wallet"),
getWalletProviderName: () => "BBN Wallet",
getAddress: () =>
"bc1p8gjpy0vyfdq3tty8sy0v86dvl69rquc85n2gpuztll9wxh9cpars7r97sd",
getPublicKeyHex: () =>
"4c6e2954c75bcb53aa13b7cd5d8bcdb4c9a4dd0784d68b115bd4408813b45608",
on: () => {},
getNetwork: () => "mainnet",
getBTCTipHeight: async (): Promise<number> => {
return await getTipHeight();
},
getNetworkFees: () => ({
fastestFee: 1,
halfHourFee: 1,
hourFee: 1,
economyFee: 1,
minimumFee: 1,
}),
getUtxos: () => [
{
txid: "fa4908ad8876655ccb5ffba6a9eab58e1b785af73703cd58b19526c099d67c05",
vout: 0,
value: 12345678,
scriptPubKey:
"51203a24123d844b4115ac87811ec3e9acfe8a307307a4d480f04bffcae35cb80f47",
},
],
getInscriptions: () => [],
};

window.btcwallet = bbnWallet;
});
};
38 changes: 38 additions & 0 deletions e2e/helper/connect.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { Page, expect } from "@playwright/test";

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 clickConnectButton = async (page: Page) => {
const connectButton = page.getByTestId("modal").getByRole("button", {
name: "Connect to BTC network",
});
await connectButton.click();
// expect(await connectButton.isDisabled()).toBe(false);
};

export const clickBrowserButton = async (page: Page) => {
const browserButton = page
.getByTestId("modal")
.getByRole("button", { name: "Browser" });
await browserButton.click();
};
64 changes: 64 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 5 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@
"prepare": "husky",
"sort-imports": "eslint --fix .",
"test": "jest",
"test:watch": "jest --watch"
"test:watch": "jest --watch",
"test:e2e": "playwright test",
"test:e2e:ui": "playwright test --ui",
"test:e2e:report": "playwright show-report"
},
"engines": {
"node": ">=22.0.0"
Expand Down Expand Up @@ -53,6 +56,7 @@
"@babel/preset-react": "^7.24.7",
"@babel/preset-typescript": "^7.24.7",
"@bitcoin-js/tiny-secp256k1-asmjs": "^2.2.3",
"@playwright/test": "^1.46.0",
"@tanstack/eslint-plugin-query": "^5.28.11",
"@tanstack/react-query-devtools": "^5.28.14",
"@testing-library/jest-dom": "^6.4.6",
Expand Down
89 changes: 89 additions & 0 deletions playwright.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
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}`;

/**
* Read environment variables from file.
* https://github.com/motdotla/dotenv
*/
// import dotenv from 'dotenv';
// dotenv.config({ path: path.resolve(__dirname, '.env') });

/**
* 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: !!process.env.CI,
/* Retry on CI only */
retries: process.env.CI ? 2 : 0,
/* Opt out of parallel tests on CI. */
workers: process.env.CI ? 1 : undefined,
/* 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: !process.env.CI,
},
});
39 changes: 39 additions & 0 deletions playwright.fixtures.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { test as base, chromium, type BrowserContext } from "@playwright/test";
import path from "path";

// Load the extension in the browser context
// https://playwright.dev/docs/chrome-extensions

export const test = base.extend<{
context: BrowserContext;
extensionId: string;
}>({
context: async ({}, use) => {
const okxPath = path.join(__dirname, "extensions", "okx_3_8_0");
const context = await chromium.launchPersistentContext("", {
headless: false,
args: [
`--disable-extensions-except=${okxPath}`,
`--load-extension=${okxPath}`,
],
});
await use(context);
await context.close();
},
extensionId: async ({ context }, use) => {
/*
// for manifest v2:
let [background] = context.backgroundPages()
if (!background)
background = await context.waitForEvent('backgroundpage')
*/

// for manifest v3:
let [background] = context.serviceWorkers();
if (!background) background = await context.waitForEvent("serviceworker");

const extensionId = background.url().split("/")[2];
await use(extensionId);
},
});
export const expect = test.expect;
Loading

0 comments on commit 0707a72

Please sign in to comment.