Skip to content

Commit

Permalink
Merge branch 'main' into phantom-wallet
Browse files Browse the repository at this point in the history
  • Loading branch information
gskril authored Nov 20, 2023
2 parents f08d162 + fb93a2f commit 6d92ead
Show file tree
Hide file tree
Showing 14 changed files with 309 additions and 24 deletions.
109 changes: 109 additions & 0 deletions e2e/specs/stateless/advancedEditor.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import { expect } from '@playwright/test'
import { test } from '@root/playwright'

test('should be able to maintain state when returning from transaction modal to advanced editor', async ({
login,
makeName,
makePageObject,
}) => {
const name = await makeName({
label: 'profile',
type: 'legacy',
records: {
texts: [
{ key: 'name', value: 'Bob' },
{ key: 'text', value: 'text' },
{ key: 'com.twitter', value: '@test' },
],
coinTypes: [
{ key: 'SOL', value: 'HN7cABqLq46Es1jh92dQQisAq662SmxELLLsHHe4YWrH' },
{ key: 'ETH', value: '0xbec1C7C11F2Fa9AB24b9E49122D26e721766DAF6' },
{ key: 'BTC', value: '1PzAJcFtEiXo9UGtRU6iqXQKj8NXtcC7DE' },
],
contentHash: 'ipfs://bafybeico3uuyj3vphxpvbowchdwjlrlrh62awxscrnii7w7flu5z6fk77y',
abi: {
contentType: 1,
data: '{"test":"test"}',
},
},
})

const recordsPage = makePageObject('RecordsPage')
const advancedEditor = makePageObject('AdvancedEditorModal')
const transactionModal = makePageObject('TransactionModal')

await recordsPage.goto(name)
await login.connect()

// Validate records
await expect(recordsPage.getRecordValue('text', 'name')).toHaveText('Bob')
await expect(recordsPage.getRecordValue('text', 'text')).toHaveText('text')
await expect(recordsPage.getRecordValue('text', 'com.twitter')).toHaveText('@test')
await expect(recordsPage.getRecordValue('address', 'sol')).toHaveText(
'HN7cABqLq46Es1jh92dQQisAq662SmxELLLsHHe4YWrH',
)
await expect(recordsPage.getRecordValue('address', 'eth')).toHaveText(
'0xbec1C7C11F2Fa9AB24b9E49122D26e721766DAF6',
)
await expect(recordsPage.getRecordValue('address', 'btc')).toHaveText(
'1PzAJcFtEiXo9UGtRU6iqXQKj8NXtcC7DE',
)
await expect(recordsPage.getRecordValue('contentHash')).toHaveText(
'ipfs://bafybeico3uuyj3vphxpvbowchdwjlrlrh62awxscrnii7w7flu5z6fk77y',
)
await expect(recordsPage.getRecordValue('abi')).toHaveText('"{\\"test\\":\\"test\\"}"')

await recordsPage.editRecordsButton.click()

// Validate advanced editor
await expect(await advancedEditor.recordInput('text', 'text')).toHaveValue('text')
await expect(await advancedEditor.recordInput('text', 'name')).toHaveValue('Bob')
await expect(await advancedEditor.recordInput('text', 'com.twitter')).toHaveValue('@test')
await expect(await advancedEditor.recordInput('address', 'SOL')).toHaveValue(
'HN7cABqLq46Es1jh92dQQisAq662SmxELLLsHHe4YWrH',
)
await expect(await advancedEditor.recordInput('address', 'ETH')).toHaveValue(
'0xbec1C7C11F2Fa9AB24b9E49122D26e721766DAF6',
)
await expect(await advancedEditor.recordInput('address', 'BTC')).toHaveValue(
'1PzAJcFtEiXo9UGtRU6iqXQKj8NXtcC7DE',
)
await expect(await advancedEditor.recordInput('contentHash')).toHaveValue(
'ipfs://bafybeico3uuyj3vphxpvbowchdwjlrlrh62awxscrnii7w7flu5z6fk77y',
)
await expect(await advancedEditor.recordInput('abi')).toHaveValue('"{\\"test\\":\\"test\\"}"')

await advancedEditor.recordClearButton('text', 'text').then((button) => button.click())
await advancedEditor.recordClearButton('address', 'SOL').then((button) => button.click())
await advancedEditor.recordClearButton('address', 'ETH').then((button) => button.click())
await advancedEditor.recordInput('contentHash').then((input) => input.fill(''))
await advancedEditor.recordInput('abi').then((input) => input.fill(''))

await advancedEditor.saveButton.click()

// Validate transaction display item
await expect(transactionModal.displayItem('update')).toHaveText('5 records')

await transactionModal.backButton.click()

// Validate inputs have been rebuilt correctly
await expect(await advancedEditor.recordComponent('text', 'text')).toHaveCount(0)
await expect(await advancedEditor.recordComponent('address', 'SOL')).toHaveCount(0)
await expect(await advancedEditor.recordComponent('address', 'ETH')).toHaveCount(0)
await expect(await advancedEditor.recordInput('contentHash')).toHaveValue('')
await expect(await advancedEditor.recordInput('abi')).toHaveValue('')

await advancedEditor.saveButton.click()

// Validate transaction display item
await expect(transactionModal.displayItem('update')).toHaveText('5 records')

await transactionModal.autoComplete()

// Validate change in records
await expect(recordsPage.getRecordButton('text', 'text')).toHaveCount(0)
await expect(recordsPage.getRecordButton('address', 'sol')).toHaveCount(0)
await expect(recordsPage.getRecordButton('address', 'eth')).toHaveCount(0)
await expect(recordsPage.getRecordButton('contentHash')).toHaveCount(0)
await expect(recordsPage.getRecordButton('abi')).toHaveCount(0)
})
2 changes: 1 addition & 1 deletion e2e/specs/stateless/profileEditor.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,7 @@ test.describe('wrapped', () => {
await expect(profilePage.record('text', 'nickname')).toHaveText('Test Name')
await page.getByTestId('records-tab').click()

await expect(page.getByTestId('name-details-text')).toHaveText('[{"test":"test"}]')
await expect(page.getByTestId('name-details-abi')).toHaveText('[{"test":"test"}]')
})
})
})
Expand Down
37 changes: 37 additions & 0 deletions playwright/pageObjects/advancedEditorModal.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/* eslint-disable import/no-extraneous-dependencies */
import { Locator, Page } from '@playwright/test'

export class AdvancedEditorModal {
readonly page: Page

readonly saveButton: Locator

constructor(page: Page) {
this.page = page
this.saveButton = this.page.getByTestId('advanced-editor').getByRole('button', { name: 'Save' })
}

tab(tab: 'text' | 'address' | 'other') {
return this.page.getByTestId(`${tab}-tab`)
}

async recordComponent(type: 'text' | 'address' | 'contentHash' | 'abi', key?: string) {
if (['text', 'address'].includes(type)) {
await this.tab(type as 'text' | 'other').click()
return this.page.getByTestId(`record-input-${key}`)
}
await this.tab('other').click()
const _key = type === 'contentHash' ? 'Content Hash' : 'ABI'
return this.page.getByTestId(`record-input-${_key}`)
}

async recordInput(type: 'text' | 'address' | 'contentHash' | 'abi', key?: string) {
const component = await this.recordComponent(type, key)
return component.locator('input')
}

async recordClearButton(type: 'text' | 'address', key: string) {
const component = await this.recordComponent(type, key)
return component.locator('button')
}
}
4 changes: 4 additions & 0 deletions playwright/pageObjects/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@ import { Page } from '@playwright/test'
import { Web3ProviderBackend } from 'headless-web3-provider'

import { AddressPage } from './addressPage'
import { AdvancedEditorModal } from './advancedEditorModal'
import { EditRolesModal } from './editRolesModal'
import { ExtendNamesModal } from './extendNamesModal'
import { HomePage } from './homePage'
import { MorePage } from './morePage'
import { OwnershipPage } from './ownershipPage'
import { PermissionsPage } from './permissionsPage'
import { ProfilePage } from './profilePage'
import { RecordsPage } from './recordsPage'
import { RegistrationPage } from './registrationPage'
import { SendNameModal } from './sendNameModal'
import { SubnamesPage } from './subnamePage'
Expand All @@ -30,6 +32,8 @@ const pageObjects = {
SendNameModal,
SubnamesPage,
TransactionModal,
RecordsPage,
AdvancedEditorModal,
}

type PageObjects = typeof pageObjects
Expand Down
26 changes: 26 additions & 0 deletions playwright/pageObjects/recordsPage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/* eslint-disable import/no-extraneous-dependencies */
import { Locator, Page } from '@playwright/test'

export class RecordsPage {
readonly page: Page

readonly editRecordsButton: Locator

constructor(page: Page) {
this.page = page
this.editRecordsButton = this.page.getByRole('button', { name: 'Edit records' })
}

async goto(name: string) {
await this.page.goto(`/${name}?tab=records`)
}

getRecordButton(type: 'text' | 'address' | 'contentHash' | 'abi', key?: string) {
const testId = key ? `name-details-${type}-${key.toLowerCase()}` : `name-details-${type}`
return this.page.getByTestId(testId)
}

getRecordValue(type: 'text' | 'address' | 'contentHash' | 'abi', key?: string) {
return this.getRecordButton(type, key).locator('> div').last()
}
}
7 changes: 7 additions & 0 deletions playwright/pageObjects/transactionModal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ export class TransactionModal {

readonly transactionModal: Locator

readonly backButton: Locator

constructor(page: Page, wallet: Web3ProviderBackend) {
this.page = page
this.wallet = wallet
Expand All @@ -25,6 +27,7 @@ export class TransactionModal {
this.completeButton = this.page.getByTestId('transaction-modal-complete-button')
this.closeButton = this.page.getByTestId('close-icon')
this.transactionModal = this.page.getByTestId('transaction-modal-inner')
this.backButton = this.page.locator('body .modal').getByRole('button', { name: 'Back' })
}

async authorize() {
Expand Down Expand Up @@ -53,4 +56,8 @@ export class TransactionModal {
} while (isModalVisible)
/* eslint-enable no-await-in-loop */
}

displayItem(key: string, option = 'normal') {
return this.page.getByTestId(`display-item-${key}-${option}`).locator('> div').last()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ const TabContentContainer = styled.div(
display: flex;
flex-direction: column;
gap: ${theme.space['3']};
padding-right: ${theme.space['1']};
overflow: hidden;
flex: 1;
`,
Expand Down
2 changes: 1 addition & 1 deletion src/components/RecordItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const RecordItem = ({
itemKey?: string
value: string
showLegacy?: boolean
type: 'text' | 'address' | 'contentHash'
type: 'text' | 'address' | 'contentHash' | 'abi'
}) => {
const breakpoint = useBreakpoint()
const keyLabel = showLegacy && itemKey ? itemKey?.replace('_LEGACY', '') : itemKey
Expand Down
2 changes: 1 addition & 1 deletion src/components/pages/profile/[name]/tabs/RecordsTab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ export const RecordsTab = ({
)}
</SectionTitleContainer>
</SectionHeader>
{abi && <RecordItem type="text" value={abi.data} />}
{abi && <RecordItem type="abi" value={abi.data} />}
</RecordSection>
</AllRecords>
{canEdit && resolverAddress !== emptyAddress && (
Expand Down
54 changes: 54 additions & 0 deletions src/hooks/useAdvancedEditor.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { normalizeAbi } from './useAdvancedEditor'

describe('normalizeAbi', () => {
it('should normalize abi that is a string', () => {
expect(normalizeAbi("test")).toEqual({ contentType: 1, data: 'test' })
})

it('should normalize abi that is an empty string', () => {
expect(normalizeAbi("")).toEqual({ contentType: 1, data: '' })
})

it('should normalize abi with a string for data', () => {
expect(normalizeAbi({ data: 'test' })).toEqual({ contentType: 1, data: 'test' })
})

it('should normalize abi with an empty string for data', () => {
expect(normalizeAbi({ data: '' })).toEqual({ contentType: 1, data: '' })
})

it('should normalize abi with an object for data', () => {
expect(normalizeAbi({ data: {test: 'test'} })).toEqual({ contentType: 1, data: '{"test":"test"}' })
})
it('should normalize abi with an array for data', () => {
expect(normalizeAbi({ data: ['test'] })).toEqual({ contentType: 1, data: '["test"]' })
})

it('should normalize abi with an object for data', () => {
expect(normalizeAbi({ data: {test: 'test'} })).toEqual({ contentType: 1, data: '{"test":"test"}' })
})

it('should NOT normalize abi that is a number', () => {
expect(normalizeAbi(5 as any)).toBeUndefined()
})

it('should NOT normalize abi that is null', () => {
expect(normalizeAbi(null as any)).toBeUndefined()
})

it('should NOT normalize abi that is undefined', () => {
expect(normalizeAbi(undefined as any)).toBeUndefined()
})

it('should NOT normalize abi with null for data', () => {
expect(normalizeAbi({ data: null as any})).toBeUndefined()
})

it('should NOT normalize abi with undefined for data', () => {
expect(normalizeAbi({ data: undefined as any})).toBeUndefined()
})

it('should NOT normalize abi with a number for data', () => {
expect(normalizeAbi({ data: 5 as any})).toBeUndefined()
})
})
Loading

0 comments on commit 6d92ead

Please sign in to comment.