Skip to content

Commit

Permalink
sync main
Browse files Browse the repository at this point in the history
  • Loading branch information
LeonmanRolls committed Nov 21, 2024
2 parents 9de73df + bc42d4f commit 38b5a26
Show file tree
Hide file tree
Showing 11 changed files with 319 additions and 61 deletions.
235 changes: 232 additions & 3 deletions e2e/specs/stateless/myNames.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
import { expect } from '@playwright/test'
import { testClient } from '@root/playwright/fixtures/contracts/utils/addTestContracts'
import { createAccounts } from '@root/playwright/fixtures/accounts'
import {
testClient,
walletClient,
} from '@root/playwright/fixtures/contracts/utils/addTestContracts'
import { Address, labelhash } from 'viem'

import { deleteSubname } from '@ensdomains/ensjs/wallet'

import { test } from '../../../playwright'
import { Name } from '../../../playwright/fixtures/makeName'
Expand All @@ -18,7 +25,6 @@ test('myNames', async ({ page, login, makeName }) => {

await page.goto('/')
await login.connect('user2')
await page.pause()

await page.goto('/my/names')

Expand All @@ -32,6 +38,229 @@ test('myNames', async ({ page, login, makeName }) => {
)

expect(timestamps.every((timestamp) => timestamp === timestamps[0])).toBe(true)
})

test.describe.serial('myNames', () => {
test.beforeAll(async ({ subgraph }) => {
// Move time to the future to force previous names to expire
await testClient.increaseTime({ seconds: 2 * 365 * 24 * 60 * 60 })
await testClient.mine({ blocks: 1 })
await subgraph.sync()
})

let subnamesToDelete: string[] = []
let allNames: string[] = []

test.afterAll(async () => {
console.log('cleaning up subnames')
const account = createAccounts().getAddress('user4') as Address
for (const subname of subnamesToDelete) {
const contract = subname.includes('wrapped') ? 'nameWrapper' : 'registry'
console.log('deleting subname:', subname, 'on', contract)
// eslint-disable-next-line no-await-in-loop
await deleteSubname(walletClient, {
name: subname,
account,
contract,
})
}
})

const makeSubnamesConfig = (type: 'legacy' | 'wrapped') =>
Array.from(
{ length: 10 },
(_, i) =>
({
label: `sub${i}`,
owner: 'user4',
type,
...(type === 'wrapped'
? {
fuses: {
parent: {
named: ['PARENT_CANNOT_CONTROL'],
},
},
}
: {}),
}) as any,
)

test('should display all names for expiry date ASC', async ({ page, login, makeName }) => {
const earlierName = await makeName({
label: 'earlier-wrapped',
type: 'wrapped',
owner: 'user4',
fuses: {
named: ['CANNOT_UNWRAP'],
},
subnames: makeSubnamesConfig('wrapped'),
})
const concurrentNames = await makeName([
{
label: `concurrent-legacy`,
type: 'legacy',
owner: 'user4',
subnames: makeSubnamesConfig('legacy'),
} as Name,
{
label: `concurrent-wrapped`,
type: 'wrapped',
owner: 'user4',
fuses: {
named: ['CANNOT_UNWRAP'],
},
subnames: makeSubnamesConfig('wrapped'),
},
])
const laterName = await makeName({
label: 'later-legacy-name',
type: 'legacy',
owner: 'user4',
subnames: makeSubnamesConfig('legacy'),
})

subnamesToDelete = [earlierName, ...concurrentNames, laterName].flatMap((name) =>
Array.from({ length: 10 }, (_, i) => `sub${i}.${name}`),
)
allNames = [earlierName, ...concurrentNames, laterName, ...subnamesToDelete]

await page.goto('/')
await login.connect('user4')
await page.goto('/my/names')

await expect(page.getByTestId('names-list')).toBeVisible({ timeout: 10000 })

await page.evaluate(async () => {
let previousScrollHeight = 0
let { scrollHeight } = document.body
do {
window.scrollTo(0, scrollHeight)
// eslint-disable-next-line no-await-in-loop
await new Promise((resolve) => {
setTimeout(resolve, 1000)
})
previousScrollHeight = scrollHeight
scrollHeight = document.body.scrollHeight
} while (previousScrollHeight !== scrollHeight)
})

for (const name of allNames) {
const decryptedLocator = page.getByTestId(`name-item-${name}`)
const nameParts = name.split('.')
const label = nameParts.shift()!
const labelHash = `[${labelhash(label).replace('0x', '')}]`
const encryptedLocator = page.getByTestId(`name-item-${[labelHash, ...nameParts].join('.')}`)
// eslint-disable-next-line no-await-in-loop
await expect(decryptedLocator.or(encryptedLocator)).toBeVisible()
}
})

test('should display all names for expiry date DESC', async ({ page, login }) => {
await page.goto('/')
await login.connect('user4')
await page.goto('/my/names')

await expect(page.getByTestId('names-list')).toBeVisible({ timeout: 10000 })

await page.getByTestId('sort-desc').click()
await page.waitForTimeout(1000)

await page.evaluate(async () => {
let previousScrollHeight = 0
let { scrollHeight } = document.body
do {
window.scrollTo(0, scrollHeight)
// eslint-disable-next-line no-await-in-loop
await new Promise((resolve) => {
setTimeout(resolve, 1000)
})
previousScrollHeight = scrollHeight
scrollHeight = document.body.scrollHeight
} while (previousScrollHeight !== scrollHeight)
})

for (const name of allNames) {
const decryptedLocator = page.getByTestId(`name-item-${name}`)
const nameParts = name.split('.')
const label = nameParts.shift()!
const labelHash = `[${labelhash(label).replace('0x', '')}]`
const encryptedLocator = page.getByTestId(`name-item-${[labelHash, ...nameParts].join('.')}`)
// eslint-disable-next-line no-await-in-loop
await expect(decryptedLocator.or(encryptedLocator)).toBeVisible()
}
})

test('should display all names for createdAt ASC', async ({ page, login }) => {
await page.goto('/')
await login.connect('user4')
await page.goto('/my/names')

await expect(page.getByTestId('names-list')).toBeVisible({ timeout: 10000 })

await page.getByTestId('select-container').getByRole('button').click()
await page.getByTestId('select-option-createdAt').click()
await page.waitForTimeout(1000)

await page.evaluate(async () => {
let previousScrollHeight = 0
let { scrollHeight } = document.body
do {
window.scrollTo(0, scrollHeight)
// eslint-disable-next-line no-await-in-loop
await new Promise((resolve) => {
setTimeout(resolve, 1000)
})
previousScrollHeight = scrollHeight
scrollHeight = document.body.scrollHeight
} while (previousScrollHeight !== scrollHeight)
})

for (const name of allNames) {
const decryptedLocator = page.getByTestId(`name-item-${name}`)
const nameParts = name.split('.')
const label = nameParts.shift()!
const labelHash = `[${labelhash(label).replace('0x', '')}]`
const encryptedLocator = page.getByTestId(`name-item-${[labelHash, ...nameParts].join('.')}`)
// eslint-disable-next-line no-await-in-loop
await expect(decryptedLocator.or(encryptedLocator)).toBeVisible()
}
})

test('should display all names for createdAt DESC', async ({ page, login }) => {
await page.goto('/')
await login.connect('user4')
await page.goto('/my/names')

await expect(page.getByTestId('names-list')).toBeVisible({ timeout: 10000 })

await page.getByTestId('select-container').getByRole('button').click()
await page.getByTestId('select-option-createdAt').click()
await page.getByTestId('sort-desc').click()
await page.waitForTimeout(1000)

await page.evaluate(async () => {
let previousScrollHeight = 0
let { scrollHeight } = document.body
do {
window.scrollTo(0, scrollHeight)
// eslint-disable-next-line no-await-in-loop
await new Promise((resolve) => {
setTimeout(resolve, 1000)
})
previousScrollHeight = scrollHeight
scrollHeight = document.body.scrollHeight
} while (previousScrollHeight !== scrollHeight)
})

await page.pause()
for (const name of allNames) {
const decryptedLocator = page.getByTestId(`name-item-${name}`)
const nameParts = name.split('.')
const label = nameParts.shift()!
const labelHash = `[${labelhash(label).replace('0x', '')}]`
const encryptedLocator = page.getByTestId(`name-item-${[labelHash, ...nameParts].join('.')}`)
// eslint-disable-next-line no-await-in-loop
await expect(decryptedLocator.or(encryptedLocator)).toBeVisible()
}
})
})
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,11 @@
"knip:fix": "knip --fix --allow-remove-files"
},
"dependencies": {
"@adraffy/ens-normalize": "1.10.1",
"@ensdomains/address-encoder": "1.1.1",
"@ensdomains/content-hash": "^3.0.0-beta.5",
"@ensdomains/ens-contracts": "1.2.0-beta.0",
"@ensdomains/ensjs": "4.0.0",
"@ensdomains/ensjs": "4.0.2",
"@ensdomains/thorin": "0.6.50",
"@metamask/post-message-stream": "^6.1.2",
"@metamask/providers": "^14.0.2",
Expand Down Expand Up @@ -208,4 +209,4 @@
}
},
"packageManager": "[email protected]"
}
}
5 changes: 2 additions & 3 deletions playwright/fixtures/accounts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,12 @@ const shortenAddress = (address = '', maxLength = 10, leftSlice = 5, rightSlice

export type Accounts = ReturnType<typeof createAccounts>

export type User = 'user' | 'user2' | 'user3'
const users = ['user', 'user2', 'user3', 'user4'] as const
export type User = typeof users[number]

export const createAccounts = (stateful = false) => {
const mnemonic = stateful ? process.env.SECRET_WORDS || DEFAULT_MNEMONIC : DEFAULT_MNEMONIC

const users: User[] = ['user', 'user2', 'user3']

const { accounts, privateKeys } = users.reduce<{ accounts: Account[]; privateKeys: Hash[] }>(
(acc, _, index) => {
const { getHdKey } = mnemonicToAccount(mnemonic, { addressIndex: index })
Expand Down
17 changes: 8 additions & 9 deletions playwright/fixtures/makeName/generators/legacyNameGenerator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,16 +101,15 @@ export const makeLegacyNameGenerator = ({ accounts }: Dependencies) => ({
configure: async (nameConfig: LegacyName) => {
const { label, owner, manager, subnames = [], secret } = nameWithDefaults(nameConfig)
const name = `${label}.eth`

// Create subnames
await Promise.all(
subnames.map((subname) => {
return generateLegacySubname({ accounts })({
...subname,
name: `${label}.eth`,
nameOwner: owner,
})
}),
)
for (const subname of subnames) {
await generateLegacySubname({ accounts })({
...subname,
name: `${label}.eth`,
nameOwner: owner,
})
}

if (!!manager && manager !== owner) {
console.log('setting manager:', name, manager)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,16 +130,14 @@ export const makeLegacyWithConfigNameGenerator = ({ accounts }: Dependencies) =>
await generateRecords({ accounts })({ name: `${label}.eth`, owner, resolver, records })

// Create subnames
await Promise.all(
subnames.map((subname) =>
generateLegacySubname({ accounts })({
...subname,
name,
nameOwner: owner,
resolver: subname.resolver ?? _resolver,
}),
),
)
for (const subname of subnames) {
await generateLegacySubname({ accounts })({
...subname,
name,
nameOwner: owner,
resolver: subname.resolver ?? _resolver,
})
}

// Set resolver if not valid
if (!hasValidResolver && resolver) {
Expand Down
10 changes: 4 additions & 6 deletions playwright/fixtures/makeName/generators/wrappedNameGenerator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -159,16 +159,14 @@ export const makeWrappedNameGenerator = ({ accounts }: Dependencies) => ({
})
}

await Promise.all(
subnames.map((subname) =>
generateWrappedSubname({ accounts })({
for (const subname of subnames) {
await generateWrappedSubname({ accounts })({
...subname,
name: `${label}.eth`,
nameOwner: owner,
resolver: subname.resolver ?? _resolver,
}),
),
)
})
}

if (!hasValidResolver && resolver) {
console.log('setting resolver: ', name, resolver)
Expand Down
19 changes: 11 additions & 8 deletions playwright/fixtures/makeName/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,18 +91,21 @@ export function createMakeNames({ accounts, time, subgraph }: Dependencies) {

await testClient.setAutomine(true)

// Finish setting up names
await Promise.all(
adjustedNames.map((name) => {
// Make sure that registration and subnames are on different block or it might cause the subgraph to crash due to
// RegisterName and TransferName event having the same event ids.
await testClient.mine({ blocks: 1 })

// Finish setting up names
for (const name of adjustedNames) {
if (isWrappendName(name)) {
return wrappedNameGenerator.configure(name)
await wrappedNameGenerator.configure(name)
} else if (isLegacyName(name)) {
return legacyRegisterNameGenerator.configure(name)
console.log('registering legacy name:', name)
await legacyRegisterNameGenerator.configure(name)
} else {
return legacyNameGenerator.configure(name)
await legacyNameGenerator.configure(name)
}
}),
)
}

if (offset > 0) {
console.warn('You are increasing the block timestamp. Do not run this test in parallel mode.')
Expand Down
Loading

0 comments on commit 38b5a26

Please sign in to comment.