Skip to content

Commit 54185f7

Browse files
authored
Merge branch 'main' into feature/fet-2911-update-ensjs-version-in-manager-v3
2 parents 6098d71 + 8062421 commit 54185f7

File tree

85 files changed

+641
-3113
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

85 files changed

+641
-3113
lines changed

e2e/specs/stateful/profile.spec.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
/* eslint-disable no-await-in-loop */
2+
/* eslint-disable no-restricted-syntax */
23
import { expect } from '@playwright/test'
34

45
import { test } from '../../../playwright/index.js'
@@ -49,6 +50,12 @@ const profiles = [
4950
value: '0xFc5...7acf0',
5051
fullValue: '0xFc5958B4B6F9a06D21E06429c8833f865577acf0',
5152
},
53+
{
54+
type: 'address',
55+
key: 'sui',
56+
value: '0x123...31231',
57+
fullValue: '0x1231231231231231231231231231231231231231231231231231231231231231',
58+
},
5259
{
5360
type: 'other',
5461
key: 'avatar',

e2e/specs/stateless/addressPageErrorHandling.spec.ts renamed to e2e/specs/stateless/addressPage.spec.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,30 @@ test.describe('Address page error handling', () => {
176176
expect(requestCount).toBeGreaterThanOrEqual(3) // At least 2 failures + 1 success
177177
})
178178

179+
test('should display no-profile-snippet when no primary name set with invalid resolver', async ({
180+
page,
181+
login,
182+
makeName,
183+
makePageObject,
184+
}) => {
185+
test.slow()
186+
187+
// SETUP: Create name with invalid resolver (triggers ContractFunctionExecutionError)
188+
// Deliberately NOT setting as primary name to test no-primary-name scenario
189+
const name = await createUserName(makeName, 'no-primary-invalid-resolver')
190+
await setInvalidResolver(page, name, login, makePageObject)
191+
192+
// ACTION: Navigate to address page
193+
const userAddress = getUserAddress()
194+
await page.goto(`/${userAddress}`)
195+
196+
// ASSERT: Page loads gracefully showing no-profile-snippet (not profile-snippet)
197+
await expect(page.getByTestId('no-profile-snippet')).toBeVisible()
198+
199+
// ASSERT: Names list loads despite invalid resolver on owned name
200+
await expect(page.getByTestId('names-list')).toBeVisible({ timeout: NAMES_LIST_TIMEOUT })
201+
})
202+
179203
test.afterEach(async () => {
180204
// Clean up: reset primary name after each test
181205
await setPrimaryName(walletClient, {

e2e/specs/stateless/advancedEditor.spec.ts

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,11 @@ test('should be able to maintain state when returning from transaction modal whe
2525
{ coin: 'SOL', value: 'HN7cABqLq46Es1jh92dQQisAq662SmxELLLsHHe4YWrH' },
2626
{ coin: 'ETH', value: '0xbec1C7C11F2Fa9AB24b9E49122D26e721766DAF6' },
2727
{ coin: 'BTC', value: '1PzAJcFtEiXo9UGtRU6iqXQKj8NXtcC7DE' },
28+
{
29+
coin: 'SUI',
30+
// eslint-disable-next-line no-restricted-syntax -- SUI addresses are 64 hex chars, not private keys
31+
value: '0x1231231231231231231231231231231231231231231231231231231231231231',
32+
},
2833
],
2934
contentHash: 'ipfs://bafybeico3uuyj3vphxpvbowchdwjlrlrh62awxscrnii7w7flu5z6fk77y',
3035
abi: await encodeAbi({ encodeAs: 'json', data: dummyABI }),
@@ -51,6 +56,10 @@ test('should be able to maintain state when returning from transaction modal whe
5156
await expect(recordsPage.getRecordValue('address', 'BTC')).toHaveText(
5257
'1PzAJcFtEiXo9UGtRU6iqXQKj8NXtcC7DE',
5358
)
59+
await expect(recordsPage.getRecordValue('address', 'SUI')).toHaveText(
60+
// eslint-disable-next-line no-restricted-syntax -- SUI addresses are 64 hex chars, not private keys
61+
'0x1231231231231231231231231231231231231231231231231231231231231231',
62+
)
5463
await expect(recordsPage.getRecordValue('contentHash')).toHaveText(
5564
'ipfs://bafybeico3uuyj3vphxpvbowchdwjlrlrh62awxscrnii7w7flu5z6fk77y',
5665
)
@@ -71,6 +80,10 @@ test('should be able to maintain state when returning from transaction modal whe
7180
await expect(await advancedEditor.recordInput('address', 'BTC')).toHaveValue(
7281
'1PzAJcFtEiXo9UGtRU6iqXQKj8NXtcC7DE',
7382
)
83+
await expect(await advancedEditor.recordInput('address', 'SUI')).toHaveValue(
84+
// eslint-disable-next-line no-restricted-syntax -- SUI addresses are 64 hex chars, not private keys
85+
'0x1231231231231231231231231231231231231231231231231231231231231231',
86+
)
7487
await expect(await advancedEditor.recordInput('contentHash')).toHaveValue(
7588
'ipfs://bafybeico3uuyj3vphxpvbowchdwjlrlrh62awxscrnii7w7flu5z6fk77y',
7689
)
@@ -79,34 +92,37 @@ test('should be able to maintain state when returning from transaction modal whe
7992
await advancedEditor.recordClearButton('text', 'text').then((button) => button.click())
8093
await advancedEditor.recordClearButton('address', 'SOL').then((button) => button.click())
8194
await advancedEditor.recordClearButton('address', 'ETH').then((button) => button.click())
95+
await advancedEditor.recordClearButton('address', 'SUI').then((button) => button.click())
8296
await advancedEditor.recordInput('contentHash').then((input) => input.fill(''))
8397
await advancedEditor.recordInput('abi').then((input) => input.fill(''))
8498

8599
await advancedEditor.saveButton.click()
86100

87101
// Validate transaction display item
88-
await expect(transactionModal.displayItem('update')).toHaveText('5 records')
102+
await expect(transactionModal.displayItem('update')).toHaveText('6 records')
89103

90104
await transactionModal.backButton.click()
91105

92106
// Validate inputs have been rebuilt correctly
93107
await expect(await advancedEditor.recordComponent('text', 'text')).toHaveCount(0)
94108
await expect(await advancedEditor.recordComponent('address', 'SOL')).toHaveCount(0)
95109
await expect(await advancedEditor.recordComponent('address', 'ETH')).toHaveCount(0)
110+
await expect(await advancedEditor.recordComponent('address', 'SUI')).toHaveCount(0)
96111
await expect(await advancedEditor.recordInput('contentHash')).toHaveValue('')
97112
await expect(await advancedEditor.recordInput('abi')).toHaveValue('')
98113

99114
await advancedEditor.saveButton.click()
100115

101116
// Validate transaction display item
102-
await expect(transactionModal.displayItem('update')).toHaveText('5 records')
117+
await expect(transactionModal.displayItem('update')).toHaveText('6 records')
103118

104119
await transactionModal.autoComplete()
105120

106121
// Validate change in records
107122
await expect(recordsPage.getRecordButton('text', 'text')).toHaveCount(0)
108123
await expect(recordsPage.getRecordButton('address', 'SOL')).toHaveCount(0)
109124
await expect(recordsPage.getRecordButton('address', 'ETH')).toHaveCount(0)
125+
await expect(recordsPage.getRecordButton('address', 'SUI')).toHaveCount(0)
110126
await expect(recordsPage.getRecordButton('contentHash')).toHaveCount(0)
111127
await expect(recordsPage.getRecordButton('abi')).toHaveCount(0)
112128
})

e2e/specs/stateless/box.spec.ts

Lines changed: 0 additions & 101 deletions
This file was deleted.

e2e/specs/stateless/extendNames.spec.ts

Lines changed: 54 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -112,10 +112,10 @@ test('should be able to extend multiple names (including names in grace preiod)
112112
const label = name.replace('.eth', '')
113113
await addresPage.search(label)
114114
await expect(addresPage.getNameRow(name)).toBeVisible({ timeout: 5000 })
115-
const newTs = await addresPage.getTimestamp(name)
116-
expect(newTs).not.toBe(timestampDict[name])
117-
// Allow 1 day tolerance for block timestamp rounding
118-
expect(Math.abs(newTs - timestampDict[name] - 31536000000 * 3)).toBeLessThanOrEqual(86400000)
115+
await expect(await addresPage.getTimestamp(name)).not.toBe(timestampDict[name])
116+
// Allow up to 3 days tolerance for leap year differences across 3 years
117+
const ts = await addresPage.getTimestamp(name)
118+
expect(Math.abs(ts - timestampDict[name] - 31536000000 * 3)).toBeLessThanOrEqual(86400000 * 3)
119119
}
120120
})
121121

@@ -181,7 +181,7 @@ test('should be able to extend a single unwrapped name from profile', async ({
181181
await extendNamesModal.getExtendButton.click()
182182
await transactionModal.autoComplete()
183183
const newTimestamp = await profilePage.getExpiryTimestamp()
184-
// Allow 1 day tolerance for block timestamp rounding
184+
// Allow 1 day tolerance for leap year differences
185185
expect(Math.abs(newTimestamp - timestamp - 31536000000)).toBeLessThanOrEqual(86400000)
186186
})
187187
})
@@ -244,7 +244,7 @@ test('should be able to extend a single unwrapped name in grace period from prof
244244
await transactionModal.autoComplete()
245245

246246
const newTimestamp = await profilePage.getExpiryTimestamp()
247-
// Allow 1 day tolerance for block timestamp rounding
247+
// Allow 1 day tolerance for leap year differences
248248
expect(Math.abs(newTimestamp - timestamp - 31536000000)).toBeLessThanOrEqual(86400000)
249249
})
250250
})
@@ -308,7 +308,7 @@ test('should be able to extend a single unwrapped name in grace period from prof
308308
const transactionModal = makePageObject('TransactionModal')
309309
await transactionModal.autoComplete()
310310
const newTimestamp = await profilePage.getExpiryTimestamp()
311-
// Allow 1 day tolerance for block timestamp rounding
311+
// Allow 1 day tolerance for leap year differences
312312
expect(Math.abs(newTimestamp - timestamp - 31536000000)).toBeLessThanOrEqual(86400000)
313313
})
314314
})
@@ -1151,4 +1151,51 @@ test.describe('Wrapped Name Renewal with Referrer', () => {
11511151
// Note: Bulk renewals should use the legacy bulk renewal contract
11521152
// which doesn't support referrers
11531153
})
1154+
1155+
test('should extend wrapped name in grace period with referrer', async ({
1156+
page,
1157+
login,
1158+
makeName,
1159+
makePageObject,
1160+
}) => {
1161+
const name = await makeName({
1162+
label: 'wrapped-grace-referrer',
1163+
type: 'wrapped',
1164+
owner: 'user',
1165+
duration: -24 * 60 * 60, // Expired 1 day ago
1166+
})
1167+
1168+
const referrerAddress = '0x1234567890123456789012345678901234567890'
1169+
1170+
const profilePage = makePageObject('ProfilePage')
1171+
const transactionModal = makePageObject('TransactionModal')
1172+
1173+
await profilePage.goto(name)
1174+
await login.connect()
1175+
1176+
// Verify name is in grace period
1177+
await expect(page.getByText(`${name} has expired`)).toBeVisible()
1178+
1179+
// Add referrer to URL and navigate
1180+
await page.goto(`/${name}?referrer=${referrerAddress}`)
1181+
1182+
// Click extend button
1183+
await profilePage.getExtendButton.click()
1184+
1185+
// Set extension and proceed
1186+
await expect(page.getByTestId('plus-minus-control-label')).toHaveText('1 year')
1187+
await page.locator('button:has-text("Next")').click()
1188+
1189+
// Complete transaction
1190+
await transactionModal.confirm()
1191+
1192+
await expect(page.getByText('Your "Extend names" transaction was successful')).toBeVisible({
1193+
timeout: 10000,
1194+
})
1195+
1196+
// Verify referrer included in the transaction calldata
1197+
const latestTransaction = await publicClient.getTransaction({ blockTag: 'latest', index: 0 })
1198+
const referrerHex = addressToBytes32(referrerAddress)
1199+
expect(latestTransaction.input).toContain(referrerHex.slice(2)) // Remove '0x' prefix for comparison
1200+
})
11541201
})

0 commit comments

Comments
 (0)