Skip to content

Commit

Permalink
Merge branch 'main' of github.com:ensdomains/ens-app-v3 into feat/FET…
Browse files Browse the repository at this point in the history
…-1177-add-registration-tracking-events
  • Loading branch information
nhohb committed Sep 13, 2024
2 parents d245e6b + b2157df commit eb690f3
Show file tree
Hide file tree
Showing 82 changed files with 1,370 additions and 2,600 deletions.
22 changes: 22 additions & 0 deletions .github/workflows/knip.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
name: Knip

on: [push]

jobs:
knip:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3

- name: Install pnpm
run: corepack enable pnpm

- name: Install Node.js
uses: actions/setup-node@v3
with:
node-version: 18
cache: 'pnpm'

- run: pnpm install --frozen-lockfile

- run: pnpm knip
2 changes: 2 additions & 0 deletions .github/workflows/pages-deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ jobs:
run: |
mkdir -p ./out/sitemaps
pnpm generate:sitemaps
env:
SITEMAP_GRAPH_KEY: ${{ secrets.SITEMAP_GRAPH_KEY }}

- name: Publish
uses: cloudflare/pages-action@v1
Expand Down
59 changes: 59 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -507,3 +507,62 @@ Our testing philosophy is user-centric, meaning we want to write out tests so th
A user generally clicks, types and swipes, and so most tests should include one of these actions. A user may also load a page in a specific state (by clicking, typing or swiping outside of the app) so sometimes we just want to check a page renders correctly. The vast majority of our tests will be of these kinds.

For deeper parts of the codebase that aren't directly related to a user interaction, such as utility functions, the user is the developer. So simply test the code in the way a developer would use it.

## Knip Configuration Guide

### 1. Install Knip:

Install Knip as a development dependency in your project:

```bash
pnpm add -D knip
```

### 2. Add a knip script to your package.json:

Add a script to your package.json for easy access to Knip:

```json
{
"scripts": {
...,
"knip": "knip",
"knip:fix": "knip --fix --allow-remove-files"
}
}
```

### 3. Create Knip Configuration File:

Create a `knip.config.ts` file at the root of your project. For more detail of configuration options, refer to the [knip.config.ts file](knip.config.ts) in the ENSDomains repository.

### 4. Run Knip:

To analyze your project, run Knip using the following command:

```bash
pnpm knip
```
Knip will exit with code `1` if any issues are found, such as unused files, dependencies, or exports that need to be removed.

### 5. Review and Remove Unused Files

After Knip completes its analysis, review the results. Manually remove any unused files that are safe to delete, or let Knip handle it automatically with the following command:

```bash
pnpm knip:fix
```

Ensure you carefully examine any files marked for removal to avoid accidentally deleting necessary code.

### 6. Run Unit Tests and E2E Tests:

After removing files, it's important to run your unit and end-to-end tests to ensure that everything is still functioning correctly:

```bash
pnpm test:coverage
```

```bash
pnpm e2e
```
30 changes: 30 additions & 0 deletions e2e/specs/stateless/profileEditor.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,36 @@ test.describe('profile', () => {
await expect(profilePage.record('text', 'email')).toHaveText('[email protected]')
await expect(profilePage.contentHash()).toContainText('ipfs://bafybeic...')
})

test('should redirect to profile tab if tab specified in query string does not exist', async ({
page,
login,
makeName,
makePageObject,
}) => {
const name = await makeName({
label: 'profile',
type: 'legacy',
records: await makeRecords(),
})

const profilePage = makePageObject('ProfilePage')

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

await page.goto(`/${name}?tab=customTab`)

await expect(page).toHaveURL(`/${name}`)

await page.pause()
await expect(profilePage.record('text', 'description')).toHaveText('Hello2')
await expect(profilePage.record('text', 'url')).toHaveText('twitter.com')
await expect(profilePage.record('address', 'btc')).toHaveText('bc1qj...pwa6n')
await expect(profilePage.record('address', 'etcLegacy')).toHaveText('etcLegacy0x3C4...293BC')
await expect(profilePage.record('text', 'email')).toHaveText('[email protected]')
await expect(profilePage.contentHash()).toContainText('ipfs://bafybeic...')
})
})

test.describe('migrations', () => {
Expand Down
190 changes: 185 additions & 5 deletions e2e/specs/stateless/wrapName.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ test('should not show wrap notification if the name is already wrapped', async (

await page.waitForTimeout(3000)
await expect(morePage.wrapButton).not.toBeVisible()

await expect(morePage.pccStatus).toBeVisible()
await expect(morePage.nameWrapperStatus).toHaveText('Wrapped')
})

test('should show wrap button on unwrapped name', async ({ login, makeName, makePageObject }) => {
Expand Down Expand Up @@ -213,7 +216,7 @@ test('should allow wrapping a name with an unknown label', async ({
await expect(morePage.wrapButton).toHaveCount(0)

// should direct to the known label page
await expect(page).toHaveURL(`/${unknownLabel}.${name}`)
await expect(page).toHaveURL(`/${unknownLabel}.${name}?tab=more`)
})

test('should calculate needed steps without localstorage', async ({
Expand Down Expand Up @@ -254,11 +257,9 @@ test('should calculate needed steps without localstorage', async ({
await morePage.goto(subname)
await login.connect()

await page.pause()
await expect(page.getByTestId('name-details-text-wrapper')).toContainText('unwrapped')
await expect(page.getByTestId('namewrapper-status')).toContainText('Unwrapped')

await morePage.wrapButton.click()
await page.pause()
await expect(page.getByTestId('display-item-Step 1-normal')).toContainText('Approve NameWrapper')
await expect(page.getByTestId('display-item-Step 2-normal')).toContainText('Migrate profile')
await expect(page.getByTestId('display-item-Step 3-normal')).toContainText('Wrap name')
Expand Down Expand Up @@ -291,8 +292,187 @@ test('should calculate needed steps without localstorage', async ({
await transactionModal.introButton.click()
await transactionModal.confirm()
await transactionModal.complete()
await expect(page.getByTestId('name-details-text-wrapper')).not.toContainText('unwrapped')
await expect(page.getByTestId('namewrapper-status')).not.toContainText('Unwrapped')

await profilePage.goto(subname)
await expect(profilePage.record('text', 'description')).toHaveText('test')
})

test('Wrapped, emancipated, 2LD', async ({ login, makeName, makePageObject }) => {
const name = await makeName({
label: 'wrapped',
type: 'wrapped',
owner: 'user',
})

const morePage = makePageObject('MorePage')
await morePage.goto(name)

await login.connect()

await expect(morePage.wrapButton).not.toBeVisible()
await expect(morePage.unwrapButton).toBeVisible()
await expect(morePage.nameWrapperStatus).toContainText('Wrapped')
await expect(morePage.pccStatus).toContainText('Not parent-controllable')
await expect(morePage.nameWrapperCheckIcon).toBeVisible()
await expect(morePage.npcIcon).toBeVisible()
})

test('Wrapped, locked, 2LD', async ({ login, makeName, makePageObject }) => {
const name = await makeName({
label: 'wrapped',
type: 'wrapped',
owner: 'user',
fuses: {
named: ['CANNOT_UNWRAP'],
},
})

const morePage = makePageObject('MorePage')
await morePage.goto(name)

await login.connect()

await expect(morePage.wrapButton).not.toBeVisible()
await expect(morePage.unwrapButtonDisabled).toBeVisible()
await expect(morePage.nameWrapperStatus).toContainText('Wrapped')
await expect(morePage.pccStatus).toContainText('Not parent-controllable')
await expect(morePage.nameWrapperLockIcon).toBeVisible()
await expect(morePage.npcIcon).toBeVisible()
})

test('Wrapped, not-emancipated (PCC), 3LD', async ({ login, makeName, makePageObject }) => {
const name = await makeName({
label: 'wrapped',
type: 'wrapped',
owner: 'user',
subnames: [
{
label: 'test',
owner: 'user',
},
],
})

const morePage = makePageObject('MorePage')
await morePage.goto(`test.${name}`)

await login.connect()

await expect(morePage.unwrapButton).toBeVisible()
await expect(morePage.nameWrapperStatus).toContainText('Wrapped')
await expect(morePage.pccStatus).toContainText('Parent-controllable')
await expect(morePage.nameWrapperCheckIcon).toBeVisible()
await expect(morePage.nameWrapperLockIcon).not.toBeVisible()
await expect(morePage.pccIcon).toBeVisible()
await expect(morePage.nameWrapperLockIcon).not.toBeVisible()
})

test('Wrapped, emancipated(NPC), 3LD', async ({ login, makeName, makePageObject }) => {
const name = await makeName({
label: 'wrapped',
type: 'wrapped',
owner: 'user',
fuses: {
named: ['CANNOT_UNWRAP'],
},
subnames: [
{
label: 'test',
owner: 'user',
fuses: {
parent: {
named: ['PARENT_CANNOT_CONTROL'],
},
},
},
],
})

const morePage = makePageObject('MorePage')
await morePage.goto(`test.${name}`)

await login.connect()

await expect(morePage.unwrapButton).toBeVisible()
await expect(morePage.nameWrapperStatus).toContainText('Wrapped')
await expect(morePage.pccStatus).toContainText('Not parent-controllable')
await expect(morePage.nameWrapperCheckIcon).toBeVisible()
await expect(morePage.npcIcon).toBeVisible()
await expect(morePage.nameWrapperLockIcon).not.toBeVisible()
})

test('Wrapped, emancipated(NPC), Locked, 3LD', async ({ login, makeName, makePageObject }) => {
const name = await makeName({
label: 'wrapped',
type: 'wrapped',
owner: 'user',
fuses: {
named: ['CANNOT_UNWRAP'],
},
subnames: [
{
label: 'test',
owner: 'user',
fuses: {
parent: {
named: ['PARENT_CANNOT_CONTROL'],
},
child: {
named: ['CANNOT_UNWRAP'],
},
},
},
],
})

const morePage = makePageObject('MorePage')
await morePage.goto(`test.${name}`)

await login.connect()

await expect(morePage.nameWrapperStatus).toContainText('Wrapped')
await expect(morePage.pccStatus).toContainText('Not parent-controllable')
await expect(morePage.nameWrapperLockIcon).toBeVisible()
await expect(morePage.npcIcon).toBeVisible()
await expect(morePage.unwrapButtonDisabled).toBeVisible()
})

test('Wrapped, emancipated(NPC), 3LD Manager', async ({ login, makeName, makePageObject }) => {
const name = await makeName({
label: 'wrapped',
type: 'wrapped',
owner: 'user2',
fuses: {
named: ['CANNOT_UNWRAP'],
},
subnames: [
{
label: 'test',
owner: 'user',
fuses: {
parent: {
named: ['PARENT_CANNOT_CONTROL'],
},
},
},
],
})

const morePage = makePageObject('MorePage')
const transactionModal = makePageObject('TransactionModal')
await morePage.goto(`test.${name}`)

await login.connect()

await expect(morePage.unwrapButton).toBeVisible()
await expect(morePage.nameWrapperStatus).toContainText('Wrapped')
await expect(morePage.pccStatus).toContainText('Not parent-controllable')
await expect(morePage.nameWrapperCheckIcon).toBeVisible()
await expect(morePage.npcIcon).toBeVisible()
await expect(morePage.nameWrapperLockIcon).not.toBeVisible()

await morePage.unwrapButton.click()
await transactionModal.autoComplete()
await expect(morePage.wrapButton).toBeVisible()
})
2 changes: 1 addition & 1 deletion functions/_middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ const firefoxRewrite: PagesFunction = async ({ request, next }) => {
// default headers
response.headers.set(
'Content-Security-Policy',
"worker-src 'self'; script-src 'self' 'sha256-UyYcl+sKCF/ROFZPHBlozJrndwfNiC5KT5ZZfup/pPc=' https://*.googletagmanager.com plausible.io static.cloudflareinsights.com *.ens-app-v3.pages.dev https://app.intercom.io https://widget.intercom.io https://js.intercomcdn.com 'wasm-unsafe-eval'; frame-ancestors 'self' https://app.safe.global;",
"worker-src 'self'; script-src 'self' 'sha256-UyYcl+sKCF/ROFZPHBlozJrndwfNiC5KT5ZZfup/pPc=' plausible.io static.cloudflareinsights.com *.ens-app-v3.pages.dev https://app.intercom.io https://widget.intercom.io https://js.intercomcdn.com 'wasm-unsafe-eval'; frame-ancestors 'self' https://app.safe.global;",
)
return response
}
Expand Down
30 changes: 30 additions & 0 deletions knip.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import type { KnipConfig } from 'knip'

const config: KnipConfig = {
project: ['src/**/*.{js,jsx,ts,tsx,mjs,mts}'],
include: ['files', 'duplicates'],
exclude: ['types', 'exports', 'unlisted'],
next: {
entry: ['next.config.{js,ts,cjs,mjs}', 'src/pages/**/*.{js,jsx,ts,tsx}'],
},
playwright: {
config: ['playwright.config.{js,ts}'],
entry: ['e2e/**/*.@(spec|test).?(c|m)[jt]s?(x)'],
},
vitest: {
config: ['vitest.config.{js,mjs,ts,cjs,mts,cts}'],
entry: ['src/**/*.test.{js,ts,jsx,tsx}'],
},
ignore: [
// Duplicate exports. Removal is currently blocked due to potential E2E test failures.
'src/transaction-flow/input/EditResolver/EditResolver-flow.tsx',
'src/utils/metamask/firefox.ts',
// We still need the `test-d` files
'src/hooks/ensjs/public/useRecords.test-d.ts',
'src/utils/query/match/matchExactOrNullParamItem.test-d.ts',
'src/utils/query/match/matchQueryKeyMeta.test-d.ts',
'src/utils/query/match/queryKeyToInternalParams.test-d.ts',
],
}

export default config
Loading

0 comments on commit eb690f3

Please sign in to comment.