11import { ElementHandle , Page } from "@astral/astral" ;
22import * as path from "@std/path" ;
3+ import { assert } from "@std/assert" ;
4+ import { ensureDirSync } from "@std/fs" ;
5+ import { join } from "@std/path" ;
36
47const COMMON_CLI_PATH = path . join ( import . meta. dirname ! , "../../common-cli" ) ;
58
@@ -8,9 +11,56 @@ export const decode = (() => {
811 return ( buffer : Uint8Array ) : string => decoder . decode ( buffer ) ;
912} ) ( ) ;
1013
14+ const RECORD_SNAPSHOTS = true ;
15+ const SNAPSHOTS_DIR = join ( Deno . cwd ( ) , "test_snapshots" ) ;
16+ console . log ( "SNAPSHOTS_DIR=" , SNAPSHOTS_DIR ) ;
17+
18+ // Helper function to assert, take screenshot and snapshot HTML
19+ export async function assertAndSnapshot (
20+ condition : unknown ,
21+ message : string ,
22+ page ?: Page | void ,
23+ snapshotName ?: string ,
24+ ) : Promise < void > {
25+ if ( ! condition ) {
26+ throw new Error ( message ) ;
27+ }
28+ assert ( condition , message ) ;
29+
30+ if ( RECORD_SNAPSHOTS && page && snapshotName ) {
31+ ensureDirSync ( SNAPSHOTS_DIR ) ;
32+ const timestamp = new Date ( ) . toISOString ( ) . replace ( / [: .] / g, "-" ) ;
33+ const filePrefix = `${ snapshotName } _${ timestamp } ` ;
34+
35+ // Take screenshot
36+ const screenshot = await page . screenshot ( ) ;
37+ Deno . writeFileSync ( `${ SNAPSHOTS_DIR } /${ filePrefix } .png` , screenshot ) ;
38+
39+ // Snapshot HTML
40+ const html = await page . content ( ) ;
41+ Deno . writeTextFileSync ( `${ SNAPSHOTS_DIR } /${ filePrefix } .html` , html ) ;
42+
43+ console . log ( `Snapshot saved: ${ filePrefix } ` ) ;
44+ }
45+ }
46+
1147export const sleep = ( ms : number ) =>
1248 new Promise ( ( resolve ) => setTimeout ( resolve , ms ) ) ;
1349
50+ export async function tryClick (
51+ el ?: ElementHandle | null ,
52+ page ?: Page ,
53+ ) : Promise < void > {
54+ await assertAndSnapshot (
55+ el !== null && el !== undefined ,
56+ "Element does not exist or is not clickable" ,
57+ page ,
58+ "try_click_element" ,
59+ ) ;
60+
61+ await el ! . click ( ) ;
62+ }
63+
1464export const login = async ( page : Page ) => {
1565 // Wait a second :(
1666 // See if #user-avatar is rendered
@@ -24,44 +74,42 @@ export const login = async (page: Page) => {
2474
2575 // If not logged in, see if any credential data is
2676 // persisting. If so, destroy local data.
27- let buttons = await page . $$ ( "button" ) ;
28- for ( const button of buttons ) {
29- if ( ( await button . innerText ( ) ) === "Clear Saved Credentials" ) {
30- await button . click ( ) ;
31- }
77+ let button = await page . $ ( "button[aria-label='clear-credentials']" ) ;
78+ if ( button ) {
79+ await tryClick ( button , page ) ;
3280 }
3381
3482 // Try log in
3583 console . log ( "Logging in" ) ;
3684
3785 // Click the first button, "register"
38- let button = await page . $ ( "button" ) ;
39- await button ! . click ( ) ;
86+ button = await page . $ ( "button[aria-label='register'] " ) ;
87+ await tryClick ( button , page ) ;
4088
4189 // Click the first button, "register with passphrase"
42- button = await page . $ ( "button" ) ;
43- await button ! . click ( ) ;
90+ button = await page . $ ( "button[aria-label='register-with-passphrase'] " ) ;
91+ await tryClick ( button , page ) ;
4492
4593 // Get the mnemonic from textarea.
46- let input = await page . $ ( "textarea" ) ;
94+ let input = await page . $ ( "textarea[aria-label='mnemonic'] " ) ;
4795 const mnemonic = await input ! . evaluate ( ( textarea : HTMLInputElement ) =>
4896 textarea . value
4997 ) ;
5098
5199 // Click the SECOND button, "continue to login"
52- buttons = await page . $$ ( "button" ) ;
53- await buttons [ 1 ] ! . click ( ) ;
100+ button = await page . $ ( "button[aria-label='continue-login'] " ) ;
101+ await tryClick ( button , page ) ;
54102
55103 // Paste the mnemonic in the input.
56- input = await page . $ ( "input" ) ;
104+ input = await page . $ ( "input[aria-label='enter-passphrase'] " ) ;
57105 await input ! . evaluate (
58106 ( input : HTMLInputElement , mnemonic : string ) => input . value = mnemonic ,
59107 { args : [ mnemonic ] } ,
60108 ) ;
61109
62110 // Click the only button, "login"
63- button = await page . $ ( "button" ) ;
64- await button ! . click ( ) ;
111+ button = await page . $ ( "button[aria-label='login'] " ) ;
112+ await tryClick ( button , page ) ;
65113} ;
66114
67115export const waitForSelectorWithText = async (
0 commit comments