-
Notifications
You must be signed in to change notification settings - Fork 25
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
test: e2e tests for BTC swaps (#655)
Co-authored-by: michael1011 <[email protected]>
- Loading branch information
1 parent
1a91eb6
commit 0fe7bcf
Showing
12 changed files
with
445 additions
and
19 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
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,3 @@ | ||
[submodule "regtest"] | ||
path = regtest | ||
url = https://github.com/BoltzExchange/regtest.git |
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,61 @@ | ||
import { expect, test } from "@playwright/test"; | ||
|
||
import { | ||
elementsSendToAddress, | ||
generateBitcoinBlock, | ||
generateLiquidBlock, | ||
getBitcoinAddress, | ||
} from "./utils"; | ||
|
||
test.describe("Chain swap", () => { | ||
test.beforeEach(async () => { | ||
await generateBitcoinBlock(); | ||
}); | ||
|
||
test("BTC/L-BTC", async ({ page }) => { | ||
await page.goto("/"); | ||
|
||
const assetSelector = page.locator("div[class='asset asset-LN'] div"); | ||
await assetSelector.click(); | ||
|
||
const lbtcAsset = page.locator("div[data-testid='select-L-BTC']"); | ||
await lbtcAsset.click(); | ||
|
||
const receiveAmount = "0.01"; | ||
const inputReceiveAmount = page.locator( | ||
"input[data-testid='receiveAmount']", | ||
); | ||
await inputReceiveAmount.fill(receiveAmount); | ||
|
||
const inputSendAmount = page.locator("input[data-testid='sendAmount']"); | ||
const sendAmount = "0.0100168"; | ||
await expect(inputSendAmount).toHaveValue(sendAmount); | ||
|
||
const inputOnchainAddress = page.locator( | ||
"input[data-testid='onchainAddress']", | ||
); | ||
await inputOnchainAddress.fill(await getBitcoinAddress()); | ||
|
||
const buttonCreateSwap = page.locator( | ||
"button[data-testid='create-swap-button']", | ||
); | ||
await buttonCreateSwap.click(); | ||
|
||
const skipDownload = page.getByText("Skip download"); | ||
await skipDownload.click(); | ||
|
||
const buttons = page.locator("div[data-testid='pay-onchain-buttons']"); | ||
const copyAddressButton = buttons.getByText("address"); | ||
expect(copyAddressButton).toBeDefined(); | ||
await copyAddressButton.click(); | ||
|
||
const sendAddress = await page.evaluate(() => { | ||
return navigator.clipboard.readText(); | ||
}); | ||
expect(sendAddress).toBeDefined(); | ||
|
||
await elementsSendToAddress(sendAddress, sendAmount); | ||
await generateLiquidBlock(); | ||
// TODO: verify amounts | ||
}); | ||
}); |
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,62 @@ | ||
import { expect, test } from "@playwright/test"; | ||
|
||
import { | ||
generateBitcoinBlock, | ||
getBitcoinAddress, | ||
getBitcoinWalletTx, | ||
payInvoiceLnd, | ||
} from "./utils"; | ||
|
||
test.describe("reverseSwap", () => { | ||
test.beforeEach(async () => { | ||
await generateBitcoinBlock(); | ||
}); | ||
|
||
test("Reverse swap BTC/BTC", async ({ page }) => { | ||
await page.goto("/"); | ||
|
||
const receiveAmount = "0.01"; | ||
const inputReceiveAmount = page.locator( | ||
"input[data-testid='receiveAmount']", | ||
); | ||
await inputReceiveAmount.fill(receiveAmount); | ||
|
||
const inputSendAmount = page.locator("input[data-testid='sendAmount']"); | ||
await expect(inputSendAmount).toHaveValue("0.01005558"); | ||
|
||
const inputOnchainAddress = page.locator( | ||
"input[data-testid='onchainAddress']", | ||
); | ||
await inputOnchainAddress.fill(await getBitcoinAddress()); | ||
|
||
const buttonCreateSwap = page.locator( | ||
"button[data-testid='create-swap-button']", | ||
); | ||
await buttonCreateSwap.click(); | ||
|
||
const payInvoiceTitle = page.locator( | ||
"h2[data-testid='pay-invoice-title']", | ||
); | ||
await expect(payInvoiceTitle).toHaveText( | ||
"Pay this invoice about 0.01005558 BTC", | ||
); | ||
|
||
const spanLightningInvoice = page.locator("span[class='btn']"); | ||
await spanLightningInvoice.click(); | ||
|
||
const lightningInvoice = await page.evaluate(() => { | ||
return navigator.clipboard.readText(); | ||
}); | ||
expect(lightningInvoice).toBeDefined(); | ||
|
||
await payInvoiceLnd(lightningInvoice); | ||
|
||
const txIdLink = page.getByText("open claim transaction"); | ||
|
||
const txId = (await txIdLink.getAttribute("href")).split("/").pop(); | ||
expect(txId).toBeDefined(); | ||
|
||
const txInfo = JSON.parse(await getBitcoinWalletTx(txId)); | ||
expect(txInfo.amount.toString()).toEqual(receiveAmount); | ||
}); | ||
}); |
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,55 @@ | ||
import { expect, test } from "@playwright/test"; | ||
|
||
import { | ||
bitcoinSendToAddress, | ||
generateBitcoinBlock, | ||
generateInvoiceLnd, | ||
} from "./utils"; | ||
|
||
test.describe("Submarine swap", () => { | ||
test.beforeEach(async () => { | ||
await generateBitcoinBlock(); | ||
}); | ||
|
||
test("Submarine swap BTC/BTC", async ({ page }) => { | ||
await page.goto("/"); | ||
|
||
const divFlipAssets = page.locator("#flip-assets"); | ||
await divFlipAssets.click(); | ||
|
||
const receiveAmount = "0.01"; | ||
const inputReceiveAmount = page.locator( | ||
"input[data-testid='receiveAmount']", | ||
); | ||
await inputReceiveAmount.fill(receiveAmount); | ||
|
||
const inputSendAmount = page.locator("input[data-testid='sendAmount']"); | ||
const sendAmount = "0.01005302"; | ||
await expect(inputSendAmount).toHaveValue(sendAmount); | ||
|
||
const invoiceInput = page.locator("textarea[data-testid='invoice']"); | ||
await invoiceInput.fill( | ||
JSON.parse(await generateInvoiceLnd(1000000)).payment_request, | ||
); | ||
const buttonCreateSwap = page.locator( | ||
"button[data-testid='create-swap-button']", | ||
); | ||
await buttonCreateSwap.click(); | ||
|
||
const skipDownload = page.getByText("Skip download"); | ||
await skipDownload.click(); | ||
|
||
const copyAddressButton = page.getByText("address"); | ||
expect(copyAddressButton).toBeDefined(); | ||
await copyAddressButton.click(); | ||
|
||
const sendAddress = await page.evaluate(() => { | ||
return navigator.clipboard.readText(); | ||
}); | ||
expect(sendAddress).toBeDefined(); | ||
await bitcoinSendToAddress(sendAddress, sendAmount); | ||
|
||
await generateBitcoinBlock(); | ||
// TODO: verify amounts | ||
}); | ||
}); |
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,67 @@ | ||
import { exec } from "child_process"; | ||
import { promisify } from "util"; | ||
|
||
const execAsync = promisify(exec); | ||
|
||
const executeInScriptsContainer = | ||
'docker exec boltz-scripts bash -c "source /etc/profile.d/utils.sh && '; | ||
|
||
const execCommand = async (command: string): Promise<string> => { | ||
try { | ||
const { stdout, stderr } = await execAsync( | ||
`${executeInScriptsContainer}${command}"`, | ||
{ shell: "/bin/bash" }, | ||
); | ||
|
||
if (stderr) { | ||
throw new Error(`Error executing command: ${stderr}`); | ||
} | ||
|
||
return stdout.trim(); | ||
} catch (error) { | ||
console.error(`Failed to execute command: ${command}`, error); | ||
throw error; | ||
} | ||
}; | ||
|
||
export const getBitcoinAddress = async (): Promise<string> => { | ||
return execCommand("bitcoin-cli-sim-client getnewaddress"); | ||
}; | ||
|
||
export const bitcoinSendToAddress = async ( | ||
address: string, | ||
amount: string, | ||
): Promise<string> => { | ||
return execCommand( | ||
`bitcoin-cli-sim-client sendtoaddress "${address}" ${amount}`, | ||
); | ||
}; | ||
|
||
export const elementsSendToAddress = async ( | ||
address: string, | ||
amount: string, | ||
): Promise<string> => { | ||
return execCommand( | ||
`elements-cli-sim-client sendtoaddress "${address}" ${amount}`, | ||
); | ||
}; | ||
|
||
export const generateBitcoinBlock = async (): Promise<string> => { | ||
return execCommand("bitcoin-cli-sim-client -generate"); | ||
}; | ||
|
||
export const generateLiquidBlock = async (): Promise<string> => { | ||
return execCommand("elements-cli-sim-client -generate"); | ||
}; | ||
|
||
export const getBitcoinWalletTx = async (txId: string): Promise<string> => { | ||
return execCommand(`bitcoin-cli-sim-client gettransaction ${txId}`); | ||
}; | ||
|
||
export const payInvoiceLnd = async (invoice: string): Promise<string> => { | ||
return execCommand(`lncli-sim 1 payinvoice -f ${invoice}`); | ||
}; | ||
|
||
export const generateInvoiceLnd = async (amount: number): Promise<string> => { | ||
return execCommand(`lncli-sim 1 addinvoice --amt ${amount}`); | ||
}; |
Oops, something went wrong.