forked from trezor/trezor-suite
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
test(transport-test): add webusb tester build
- Loading branch information
Showing
16 changed files
with
265 additions
and
12 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 |
---|---|---|
|
@@ -10,7 +10,8 @@ | |
"node-libs-browser", | ||
"rimraf", | ||
"tslib", | ||
"protobufjs-cli" | ||
"protobufjs-cli", | ||
"buffer" | ||
], | ||
"skip-missing": true | ||
} |
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 |
---|---|---|
@@ -1,5 +1,6 @@ | ||
module.exports = { | ||
rules: { | ||
'no-nested-ternary': 'off', // useful in tests.. | ||
'no-console': 'off', | ||
}, | ||
}; |
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,111 @@ | ||
import { UsbApi } from '@trezor/transport/src/api/usb'; | ||
|
||
import { buildMessage, assertMessage, assertSuccess, assertEquals } from './utils'; | ||
import { sharedTest, success, info, debug, error } from './shared'; | ||
|
||
/** | ||
* create api for both node and browser and return it | ||
*/ | ||
const setupApisUnderTest = async () => { | ||
let usbInterface: ConstructorParameters<typeof UsbApi>[0]['usbInterface']; | ||
|
||
if (typeof window !== 'undefined') { | ||
window.Buffer = (await import('buffer')).Buffer; | ||
usbInterface = window?.navigator?.usb; | ||
} else { | ||
usbInterface = await import('usb').then(lib => { | ||
return new lib.WebUSB({ allowAllDevices: true }); | ||
}); | ||
} | ||
|
||
type ApiTestFixture = { | ||
initArgs: ConstructorParameters<typeof UsbApi>[0]; | ||
description: string; | ||
}; | ||
const apiTestFixture: ApiTestFixture[] = []; | ||
if (typeof window !== 'undefined') { | ||
apiTestFixture.push({ initArgs: { usbInterface }, description: 'browser' }); | ||
} else { | ||
apiTestFixture.push( | ||
{ | ||
initArgs: { usbInterface, forceReadSerialOnConnect: true }, | ||
description: 'node, forceReadSerialOnConnect: true', | ||
}, | ||
{ | ||
initArgs: { usbInterface, forceReadSerialOnConnect: false }, | ||
description: 'node, forceReadSerialOnConnect: false', | ||
}, | ||
); | ||
} | ||
|
||
return apiTestFixture.map(f => { | ||
return { api: new UsbApi(f.initArgs), description: f.description }; | ||
}); | ||
}; | ||
|
||
const runTests = async () => { | ||
const fixtures = await setupApisUnderTest(); | ||
|
||
for (const f of fixtures) { | ||
info(`Running tests for ${f.description}`); | ||
|
||
const { api } = f; | ||
let path: string; | ||
|
||
const getConnectedDevicePath = async () => { | ||
info('getConnectedDevicePath...'); | ||
const res = await api.enumerate(); | ||
debug('getConnectedDevicePath: discovered devices', res); | ||
|
||
assertSuccess(res); | ||
if (res.payload.length !== 1) { | ||
throw new Error(error('Expected exactly one device to be connected')); | ||
} | ||
debug('getConnectedDevicePath: path set to: ', res.payload[0].path); | ||
path = res.payload[0].path; | ||
}; | ||
|
||
const pingPong = async () => { | ||
await api.openDevice(path, true); | ||
const writeResponse = await api.write(path, buildMessage('PING')); | ||
debug('writeResponse', writeResponse); | ||
assertSuccess(writeResponse); | ||
|
||
const readResponse = await api.read(path); | ||
|
||
debug('readResponse', readResponse); | ||
assertSuccess(readResponse); | ||
debug('readResponse', readResponse.payload.toString('hex')); | ||
assertMessage(readResponse.payload, 'SUCCESS'); | ||
await api.closeDevice(path); | ||
}; | ||
|
||
const concurrentEnumerate = async (concurrent: number) => { | ||
const res = await Promise.all( | ||
new Array(concurrent).fill(undefined).map(() => api.enumerate()), | ||
); | ||
res.forEach((r, index) => { | ||
assertSuccess(r); | ||
assertSuccess(res[0]); | ||
if (index > 0) { | ||
assertEquals(r.payload, res[0].payload); | ||
} | ||
}); | ||
}; | ||
|
||
// interestingly, in node, concurrent enumeration does not work if triggered as the first interaction with connected device. | ||
// concurrent enumeration triggered couple of lines below works correctly | ||
await sharedTest('concurrent enumerate - as the first operation', () => | ||
// todo: 3 doesn't work in node!!! FIX | ||
concurrentEnumerate(typeof window === 'undefined' ? 3 : 1), | ||
); | ||
await getConnectedDevicePath(); | ||
|
||
// here concurrent enumeration works correctly, even in node. | ||
await sharedTest('concurrent enumerate', () => concurrentEnumerate(3)); | ||
await sharedTest('ping pong', pingPong); | ||
} | ||
success('All tests passed'); | ||
}; | ||
|
||
runTests(); |
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,33 @@ | ||
const log = (level: 'debug' | 'info' | 'success' | 'error', ...args: any) => { | ||
if (typeof window !== 'undefined') { | ||
// append logs to div class "logs" element | ||
const logs = document.querySelector('.logs'); | ||
if (logs) { | ||
logs.innerHTML += `<p style="${level === 'debug' ? 'margin-left:20px;font-size:10px' : ''}">${level === 'success' ? '✅ ' : level === 'error' ? '❌ ' : ''}${args.map((a: any) => (typeof a === 'object' ? JSON.stringify(a) : a))}</p>`; | ||
} | ||
} | ||
console.log(args); | ||
|
||
return args.join(' '); | ||
}; | ||
|
||
export const debug = (...args: any) => log('debug', ...args); | ||
export const info = (...args: any) => log('info', ...args); | ||
export const error = (...args: any) => log('error', ...args); | ||
export const success = (...args: any) => log('success', ...args); | ||
|
||
export const sharedTest = async (description: string, callback: () => any) => { | ||
const timeout = 5000; | ||
try { | ||
info(`🔍 ${description}`); | ||
await Promise.race([ | ||
callback(), | ||
new Promise((_, reject) => | ||
setTimeout(() => reject(`Timeout after ${timeout}`), timeout), | ||
), | ||
]); | ||
success(description); | ||
} catch (e) { | ||
throw new Error(error(e)); | ||
} | ||
}; |
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,33 @@ | ||
import { error } from './shared'; | ||
|
||
export const MAGIC = '3f232300'; | ||
|
||
export const MESSAGES = { | ||
PING: '01', | ||
SUCCESS: '02', | ||
INITIALIZE: '00', | ||
FEATURES: '11', | ||
} as const; | ||
|
||
export const buildMessage = (message: keyof typeof MESSAGES) => { | ||
return Buffer.from(MAGIC + MESSAGES[message], 'hex'); | ||
}; | ||
|
||
export const assertMessage = (message: Buffer, expected: keyof typeof MESSAGES) => { | ||
const assertedChunk = message.toString('hex').substring(0, MAGIC.length + 2); | ||
if (assertedChunk !== `${MAGIC}${MESSAGES[expected]}`) { | ||
throw new Error(error(`Expected message ${expected} but got ${assertedChunk}`)); | ||
} | ||
}; | ||
export function assertSuccess(result: any): asserts result is { success: true; payload: any } { | ||
if (!result.success) { | ||
throw new Error(error(result.error)); | ||
} | ||
} | ||
export const assertEquals = (a: any, b: any) => { | ||
const strA = JSON.stringify(a); | ||
const strB = JSON.stringify(b); | ||
if (strA !== strB) { | ||
throw new Error(error(`Expected ${strA} to be equal to ${strB}`)); | ||
} | ||
}; |
4 changes: 2 additions & 2 deletions
4
...s/transport-test/e2e/tests/bridge.test.ts → .../transport-test/e2e/bridge/bridge.test.ts
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
File renamed without changes.
File renamed without changes.
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
4 changes: 2 additions & 2 deletions
4
...sport-test/e2e/tests/multi-client.test.ts → ...port-test/e2e/bridge/multi-client.test.ts
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
File renamed without changes.
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,10 @@ | ||
<html> | ||
<body style="background-color: black; color: white; font-family: monospace"> | ||
<script type="module" src="./api.test.browser.js"></script> | ||
<h1>Webusb tester</h1> | ||
<div>connect device, pair device and reload page.</div> | ||
<button onclick="navigator.usb.requestDevice({filters: []})">pair</button> | ||
<hr /> | ||
<div class="logs"></div> | ||
</body> | ||
</html> |
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