forked from OrbitChainLabs/OrbitChain-Contracts
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathwallet-connect-mobile.spec.js
More file actions
111 lines (90 loc) · 4.49 KB
/
Copy pathwallet-connect-mobile.spec.js
File metadata and controls
111 lines (90 loc) · 4.49 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
// tests/e2e/wallet-connect-mobile.spec.js
//
// Playwright coverage for the mobile wallet deep-link flow added to
// wallet_connect.html: UA-based routing to the wallet picker, SEP-10
// challenge requests for Lobstr/Bitnovo, the desktop-path regression check,
// and the full SEP-10 return handshake.
//
// Runs against the `mobile-safari` (iPhone 13) and `mobile-chrome`
// (Pixel 7) Playwright device projects for the mobile-only specs, and
// `desktop-chromium` for the regression check — see playwright.config.js.
//
// Closes issue: "Mobile wallet deep-link & Lobstr / Bitnovo support"
import { test, expect } from '@playwright/test';
import { Keypair, Networks, Transaction } from '@stellar/stellar-sdk';
const CLIENT_ACCOUNT = 'GATOACHAPPG72R2KKG5K47ORQVZKGBQ4UYVWLIYITEKMNFXQLNPJFJI3';
const CLIENT_SECRET = 'SDU3MUQQMASWGMAY2P6ZILNP2V77BWU5NF3R6X4YDNOHPNXZYLHTXNPV';
const NETWORK_PASSPHRASE = Networks.TESTNET;
const AUTH_SERVER = 'http://localhost:4000';
function isMobileProject(testInfo) {
return testInfo.project.name !== 'desktop-chromium';
}
test.describe('mobile wallet picker', () => {
test.beforeEach(async ({ page }, testInfo) => {
test.skip(!isMobileProject(testInfo), 'mobile-only flow');
await page.goto('/wallet_connect.html');
});
test('shows Lobstr and Bitnovo when a mobile UA connects', async ({ page }) => {
await page.click('#connect-btn');
const overlay = page.locator('#wallet-picker-overlay');
await expect(overlay).toHaveClass(/open/);
await expect(page.locator('#wallet-options')).toContainText('Lobstr');
await expect(page.locator('#wallet-options')).toContainText('Bitnovo Wallet');
});
test('picking Lobstr requests a real SEP-10 challenge for the entered account', async ({ page }) => {
await page.click('#connect-btn');
await page.getByText('Lobstr', { exact: true }).click();
await page.fill('#pubkey-input', CLIENT_ACCOUNT);
const [request] = await Promise.all([
page.waitForRequest((req) => req.url().startsWith(`${AUTH_SERVER}/auth?account=`)),
page.getByRole('button', { name: 'Continue to Lobstr' }).click(),
]);
expect(request.url()).toContain(CLIENT_ACCOUNT);
});
test('picking Bitnovo requests a real SEP-10 challenge for the entered account', async ({ page }) => {
await page.click('#connect-btn');
await page.getByText('Bitnovo Wallet', { exact: true }).click();
await page.fill('#pubkey-input', CLIENT_ACCOUNT);
const [request] = await Promise.all([
page.waitForRequest((req) => req.url().startsWith(`${AUTH_SERVER}/auth?account=`)),
page.getByRole('button', { name: 'Continue to Bitnovo Wallet' }).click(),
]);
expect(request.url()).toContain(CLIENT_ACCOUNT);
});
test('rejects an invalid public key before ever calling the auth server', async ({ page }) => {
await page.click('#connect-btn');
await page.getByText('Lobstr', { exact: true }).click();
await page.fill('#pubkey-input', 'not-a-valid-key');
await page.getByRole('button', { name: 'Continue to Lobstr' }).click();
await expect(page.locator('#status')).toContainText('Enter a valid Stellar public key');
});
});
test.describe('desktop path regression', () => {
test.beforeEach(async ({ page }, testInfo) => {
test.skip(isMobileProject(testInfo), 'desktop-only check');
await page.goto('/wallet_connect.html');
});
test('desktop UA never sees the mobile wallet picker', async ({ page }) => {
page.once('dialog', (dialog) => dialog.dismiss());
await page.click('#connect-btn');
await expect(page.locator('#wallet-picker-overlay')).not.toHaveClass(/open/);
});
});
test.describe('SEP-10 return handshake', () => {
test.beforeEach(async ({}, testInfo) => {
test.skip(!isMobileProject(testInfo), 'mobile-only flow');
});
test('completes the loop when the wallet redirects back with a signed challenge', async ({ page, request }) => {
const challengeRes = await request.get(
`${AUTH_SERVER}/auth?account=${CLIENT_ACCOUNT}&home_domain=localhost`,
);
const { transaction } = await challengeRes.json();
const tx = new Transaction(transaction, NETWORK_PASSPHRASE);
tx.sign(Keypair.fromSecret(CLIENT_SECRET));
const signedXdr = tx.toXDR();
await page.goto(`/wallet_connect.html?orbitchain_xdr=1&xdr=${encodeURIComponent(signedXdr)}`);
await expect(page.locator('#wallet-info')).toBeVisible();
await expect(page.locator('#wallet-address')).toHaveText(CLIENT_ACCOUNT);
await expect(page.locator('#connect-btn')).toHaveText('Disconnect');
});
});