1- import { BrowserContext , expect , Page , test } from '@playwright/test'
1+ import { expect , test } from '@playwright/test'
22import dappwright from '@tenkeylabs/dappwright'
33import type { Dappwright } from '@tenkeylabs/dappwright'
44
55import { SafeEnsConfig } from './config/safe-ens-config'
6- import { confirmTransactionWithMetaMask , connectWalletToEns } from './config/wallet-ens-config'
6+ import {
7+ closeTransactionModal ,
8+ navigateToHome ,
9+ openWalletAndConfirm ,
10+ searchForName ,
11+ waitForTransactionComplete ,
12+ } from './config/test-utilities'
13+ import { connectWalletToEns } from './config/wallet-ens-config'
714
8- // Global variables to share state
915let metaMask : Dappwright
10- let page : Page
11- let context : BrowserContext
16+ let page : any
17+ let context : any
1218let ensName : string
1319
1420// Create subname
@@ -18,10 +24,7 @@ async function createSubName(name: string): Promise<void> {
1824 console . log ( `🎯 Creating a new subname for ${ walletName } ` )
1925
2026 // Search for name
21- const searchInput = page . locator ( 'input[placeholder="Search for a name"]' )
22- await searchInput . waitFor ( { timeout : 15000 } )
23- await searchInput . fill ( walletName )
24- await searchInput . press ( 'Enter' )
27+ await searchForName ( page , walletName )
2528
2629 // Navigate to subname tab
2730 const subnameTab = page . getByTestId ( 'subnames-tab' )
@@ -35,85 +38,77 @@ async function createSubName(name: string): Promise<void> {
3538
3639 // Enter subname name
3740 const subnameInput = page . getByTestId ( 'add-subname-input' )
38- const subnameNext = page . getByTestId ( 'create-subname-next' )
39- await subnameInput . waitFor ( )
41+ await subnameInput . waitFor ( { state : 'visible' , timeout : 15000 } )
4042 await subnameInput . fill ( name )
43+
44+ const subnameNext = page . getByTestId ( 'create-subname-next' )
45+ await subnameNext . waitFor ( { state : 'visible' , timeout : 15000 } )
4146 await subnameNext . click ( )
4247
4348 // Skip profile creation
4449 const subnameProfileNext = page . getByTestId ( 'create-subname-profile-next' )
50+ await subnameProfileNext . waitFor ( { state : 'visible' , timeout : 15000 } )
4551 await subnameProfileNext . click ( )
4652
47- // Start and confirm transaction
48- await page . locator ( 'text=Open Wallet' ) . waitFor ( { timeout : 10000 } )
49- await page . locator ( 'text=Open Wallet' ) . click ( )
50- await confirmTransactionWithMetaMask ( page )
53+ // Open wallet and confirm transaction
54+ await openWalletAndConfirm ( page , { type : 'subname creation' } )
5155
52- // Wait for transaction to complete
53- await page . waitForTimeout ( 25000 )
56+ // Wait for transaction to complete using event-driven approach
57+ await waitForTransactionComplete ( page , { action : 'subname creation' } )
5458
5559 // Check subname is opened after transaction complete
5660 const nameProfileName = page . getByTestId ( 'profile-snippet-name' )
5761 const expectedSubname = `${ ensName } .subname-test.eth`
58- await expect ( nameProfileName ) . toHaveText ( expectedSubname )
62+ await expect ( nameProfileName ) . toHaveText ( expectedSubname , { timeout : 30000 } )
5963
6064 // Check parent is correct
6165 const parentLabel = page . getByTestId ( 'owner-profile-button-name.parent' )
62- await expect ( parentLabel ) . toBeVisible ( )
63- await expect ( parentLabel ) . toContainText ( 'subname-test.eth' )
66+ await expect ( parentLabel ) . toBeVisible ( { timeout : 15000 } )
67+ await expect ( parentLabel ) . toContainText ( 'subname-test.eth' , { timeout : 10000 } )
6468}
6569
6670// Delete subname
6771async function deleteSubName ( name : string ) : Promise < void > {
6872 const walletName = 'subname-test.eth'
73+ const fullSubname = `${ name } .subname-test.eth`
6974
70- console . log ( `🎯 Deleting ${ name } .subname-test.eth ` )
75+ console . log ( `🎯 Deleting ${ fullSubname } ` )
7176
7277 // Access created subname through search bar
73- const searchInput = page . locator ( 'input[placeholder="Search for a name"]' )
74- await searchInput . waitFor ( { timeout : 15000 } )
75- await searchInput . fill ( `${ name } .subname-test.eth` )
76- await searchInput . press ( 'Enter' )
78+ await searchForName ( page , fullSubname )
7779
78- // Confirm subname then click delete
80+ // Confirm subname profile loaded before deleting
7981 const profileName = page . getByTestId ( 'profile-snippet-name' )
8082 const expectedSubname = `${ ensName } .subname-test.eth`
81- await expect ( profileName ) . toHaveText ( expectedSubname )
83+ await expect ( profileName ) . toHaveText ( expectedSubname , { timeout : 30000 } )
8284
8385 const deleteSubnameButton = page . getByTestId ( 'profile-action-Delete subname' )
86+ await deleteSubnameButton . waitFor ( { state : 'visible' , timeout : 15000 } )
8487 await deleteSubnameButton . click ( )
8588
86- // Start and confirm transaction
87- await page . locator ( 'text=Open Wallet' ) . waitFor ( { timeout : 10000 } )
88- await page . locator ( 'text=Open Wallet' ) . click ( )
89- await confirmTransactionWithMetaMask ( page )
89+ // Open wallet and confirm transaction
90+ await openWalletAndConfirm ( page , { type : 'subname deletion' } )
9091
91- // Wait for transaction to complete
92- await page . waitForTimeout ( 25000 )
92+ // Wait for transaction to complete using event-driven approach
93+ await waitForTransactionComplete ( page , { action : 'subname deletion' } )
9394
94- // Click done to return to subname profile
95- const transactionCompleteButton = page . getByTestId ( 'transaction-modal-complete-button' )
96- await transactionCompleteButton . click ( )
95+ // Close the completion modal
96+ await closeTransactionModal ( page )
9797
98- // Check expiry has no expiry
99- const expiryBox = page . getByTestId ( 'owner-profile-button-name.expiry' )
100- await expect ( expiryBox ) . toContainText ( 'no expiry' , { timeout : 15000 } )
101-
102- // Enter parent name profile
103- const parentSubnameTab = page . getByTestId ( 'subnames-tab' )
104- await searchInput . waitFor ( { timeout : 15000 } )
105- await searchInput . fill ( walletName )
106- await searchInput . press ( 'Enter' )
107- await expect ( profileName ) . toHaveText ( walletName , { timeout : 10000 } )
98+ // Navigate to parent name profile
99+ await searchForName ( page , walletName )
100+ await expect ( profileName ) . toHaveText ( walletName , { timeout : 30000 } )
108101
109102 // Switch to subname tab
103+ const parentSubnameTab = page . getByTestId ( 'subnames-tab' )
104+ await parentSubnameTab . waitFor ( { state : 'visible' , timeout : 15000 } )
110105 await parentSubnameTab . click ( )
111106
112107 // Check deleted subname is no longer appearing
113108 const subnameItem = page . getByTestId ( `name-item-${ ensName } .subname-test.eth` )
114109 await expect ( subnameItem ) . not . toBeVisible ( { timeout : 15000 } )
115110
116- console . log ( `⚔️ {name} has been deleted` )
111+ console . log ( `⚔️ $ {name } has been deleted` )
117112}
118113
119114test . describe ( 'ENS Subname Checks' , ( ) => {
@@ -157,9 +152,8 @@ test.describe('ENS Subname Checks', () => {
157152 } )
158153
159154 test . beforeEach ( 'Navigate to home page' , async ( ) => {
160- // Navigate back to home page before each test to ensure clean state
161- await page . goto ( 'http://localhost:3000/' )
162- await page . waitForTimeout ( 2000 )
155+ // Use utility function instead of manual navigation + timeout
156+ await navigateToHome ( page )
163157 } )
164158
165159 test ( 'Connect MetaMask to ENS localhost' , async ( ) => {
0 commit comments