Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,6 @@ next-env.d.ts
/.nuxt/
/.output/

# playwright
**/playwright-report/**
**/test-results/**
6 changes: 5 additions & 1 deletion examples/connectkit/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@
"dev": "vite",
"build": "tsc -b && vite build",
"lint": "eslint .",
"preview": "vite preview"
"preview": "vite preview",
"test:e2e": "playwright test",
"test:e2e:ui": "playwright test --ui",
"test:e2e:headed": "playwright test --headed"
},
"dependencies": {
"@lifi/wallet-management": "^3.19.3",
Expand All @@ -26,6 +29,7 @@
"wagmi": "^2.19.4"
},
"devDependencies": {
"@playwright/test": "^1.57.0",
"@types/react": "^19.2.5",
"@types/react-dom": "^19.2.3",
"@vitejs/plugin-react": "^5.1.1",
Expand Down
42 changes: 42 additions & 0 deletions examples/connectkit/playwright.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { defineConfig, devices } from '@playwright/test'

/**
* See https://playwright.dev/docs/test-configuration.
*/
const port = 4174
const baseURL = `http://localhost:${port}`

export default defineConfig({
testDir: './tests',
fullyParallel: false,
retries: 2,
workers: 1,
reporter: 'html',
use: {
baseURL,
trace: 'on-first-retry',
screenshot: 'only-on-failure',
},
projects: [
{
name: 'chromium',
use: { ...devices['Desktop Chrome'] },
},

{
name: 'firefox',
use: { ...devices['Desktop Firefox'] },
},

{
name: 'webkit',
use: { ...devices['Desktop Safari'] },
},
],
webServer: {
command: `NPM_CONFIG_LOGLEVEL=error npm run dev -- --port ${port}`,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(pnpm just hangs on some reason, used npm)

url: baseURL,
reuseExistingServer: true,
timeout: 120 * 1000,
},
})
40 changes: 40 additions & 0 deletions examples/connectkit/tests/widget.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { expect, test } from '@playwright/test'

test.describe('LI.FI Widget - ConnectKit Example', () => {
test.beforeEach(async ({ page }) => {
// Navigate to the page
await page.goto('/')
})

test('should render the widget', async ({ page }) => {
// Wait for the widget to be visible
// The widget container should be present in the DOM
const widgetContainer = page.locator(
'[id^="widget-app-expanded-container"]'
)
// TODO: Uncomment after widget release with data-testid support
// const widgetContainer = page.getByTestId('li.fi-widget-container')
await expect(widgetContainer).toBeVisible({ timeout: 10000 })
})

test('should successfully open the tokens selection page', async ({
page,
}) => {
// Wait for the "From" token selection button to be visible
// The button contains a p element with text "From"
const fromButton = page.locator('button:has(p:has-text("From"))').first()
// TODO: Uncomment after widget release with data-testid support
// const fromButton = page.getByTestId('li.fi-widget-select-token-button-from')
await expect(fromButton).toBeVisible({ timeout: 10000 })

// Click on the token selection button
await fromButton.click()

// Wait for the token selection page to open
// Verify the token list is visible, which confirms the token selection page has opened
const tokenList = page.locator('.long-list').first()
// TODO: Uncomment after widget release with data-testid support
// const tokenList = page.getByTestId('li.fi-widget-token-list')
await expect(tokenList).toBeVisible({ timeout: 10000 })
})
})
6 changes: 5 additions & 1 deletion examples/vite/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@
"analyze": "source-map-explorer 'dist/assets/*.js' --no-border-checks",
"dev": "vite",
"build": "tsc && vite build",
"preview": "vite preview"
"preview": "vite preview",
"test:e2e": "playwright test",
"test:e2e:ui": "playwright test --ui",
"test:e2e:headed": "playwright test --headed"
},
"dependencies": {
"@lifi/sdk": "^3.13.5",
Expand All @@ -23,6 +26,7 @@
"wagmi": "^2.19.4"
},
"devDependencies": {
"@playwright/test": "^1.57.0",
"@types/events": "^3.0.3",
"@types/node": "^24.10.1",
"@types/react": "^19.2.5",
Expand Down
42 changes: 42 additions & 0 deletions examples/vite/playwright.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { defineConfig, devices } from '@playwright/test'

/**
* See https://playwright.dev/docs/test-configuration.
*/
const port = 4173
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ports should be different for each example if we run tests in parallel (pnpm level)

const baseURL = `http://localhost:${port}`

export default defineConfig({
testDir: './tests',
fullyParallel: false,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To discuss: parallelism - pnpm level or within Playwright

retries: 2,
workers: 1,
reporter: 'html',
use: {
baseURL,
trace: 'on-first-retry',
screenshot: 'only-on-failure',
},
projects: [
{
name: 'chromium',
use: { ...devices['Desktop Chrome'] },
},

{
name: 'firefox',
use: { ...devices['Desktop Firefox'] },
},

{
name: 'webkit',
use: { ...devices['Desktop Safari'] },
},
],
webServer: {
command: `NPM_CONFIG_LOGLEVEL=error npm run dev -- --port ${port}`,
url: baseURL,
reuseExistingServer: true,
timeout: 120 * 1000,
},
})
40 changes: 40 additions & 0 deletions examples/vite/tests/widget.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { expect, test } from '@playwright/test'

test.describe('LI.FI Widget - Vite Example', () => {
test.beforeEach(async ({ page }) => {
// Navigate to the page
await page.goto('/')
})

test('should render the widget', async ({ page }) => {
// Wait for the widget to be visible
// The widget container should be present in the DOM
const widgetContainer = page.locator(
'[id^="widget-app-expanded-container"]'
)
// TODO: Uncomment after widget release with data-testid support
// const widgetContainer = page.getByTestId('li.fi-widget-container')
await expect(widgetContainer).toBeVisible({ timeout: 10000 })
})

test('should successfully open the tokens selection page', async ({
page,
}) => {
// Wait for the "From" token selection button to be visible
// The button contains a p element with text "From"
const fromButton = page.locator('button:has(p:has-text("From"))').first()
// TODO: Uncomment after widget release with data-testid support
// const fromButton = page.getByTestId('li.fi-widget-select-token-button-from')
await expect(fromButton).toBeVisible({ timeout: 10000 })

// Click on the token selection button
await fromButton.click()

// Wait for the token selection page to open
// Verify the token list is visible, which confirms the token selection page has opened
const tokenList = page.locator('.long-list').first()
// TODO: Uncomment after widget release with data-testid support
// const tokenList = page.getByTestId('li.fi-widget-token-list')
await expect(tokenList).toBeVisible({ timeout: 10000 })
})
})
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
"check:write:unsafe": "biome check --write --unsafe",
"check:types": "pnpm -r --parallel check:types",
"check:circular-deps": "pnpm -r --parallel check:circular-deps",
"test:examples": "pnpm -r --parallel --filter './examples/**' test:e2e",
"link:bigmi": "pnpm -r --parallel link:bigmi",
"unlink:bigmi": "pnpm -r --parallel unlink:bigmi",
"link:sdk": "pnpm -r --parallel link:sdk",
Expand Down
2 changes: 2 additions & 0 deletions packages/widget/src/AppLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { useWideVariant } from './hooks/useWideVariant.js'
import { useWidgetConfig } from './providers/WidgetProvider/WidgetProvider.js'
import { URLSearchParamsBuilder } from './stores/form/URLSearchParamsBuilder.js'
import { createElementId, ElementId } from './utils/elements.js'
import { getQueryKey } from './utils/queries.js'

export const AppLayout: React.FC = () => {
const { elementId, buildUrl } = useWidgetConfig()
Expand All @@ -22,6 +23,7 @@ export const AppLayout: React.FC = () => {
<AppExpandedContainer
id={createElementId(ElementId.AppExpandedContainer, elementId)}
data-version={version}
data-testid={getQueryKey('container')}
>
<AppContainer>
<Header />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { FormKeyHelper } from '../../stores/form/types.js'
import { useFieldValues } from '../../stores/form/useFieldValues.js'
import { HiddenUI } from '../../types/widget.js'
import { navigationRoutes } from '../../utils/navigationRoutes.js'
import { getQueryKey } from '../../utils/queries.js'
import { AvatarBadgedDefault, AvatarBadgedSkeleton } from '../Avatar/Avatar.js'
import { TokenAvatar } from '../Avatar/TokenAvatar.js'
import { CardTitle } from '../Card/CardTitle.js'
Expand Down Expand Up @@ -62,7 +63,11 @@ export const SelectTokenButton: React.FC<
? t('header.payWith')
: t(`main.${formType}`)
return (
<SelectTokenCard component="button" onClick={onClick}>
<SelectTokenCard
component="button"
onClick={onClick}
data-testid={getQueryKey(`select-token-button-${formType}`)}
>
<CardContent formType={formType} compact={compact} mask={!hiddenReverse}>
<CardTitle>{cardTitle}</CardTitle>
{chainId && tokenAddress && (isChainLoading || isTokenLoading) ? (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { useCallback, useEffect, useMemo, useRef } from 'react'
import { useTranslation } from 'react-i18next'
import { useAvailableChains } from '../../hooks/useAvailableChains.js'
import type { TokenAmount } from '../../types/token.js'
import { getQueryKey } from '../../utils/queries.js'
import { TokenDetailsSheet } from './TokenDetailsSheet.js'
import { List } from './TokenList.style.js'
import { TokenListItem, TokenListItemSkeleton } from './TokenListItem.js'
Expand Down Expand Up @@ -131,6 +132,7 @@ export const VirtualizedTokenList: FC<VirtualizedTokenListProps> = ({
className="long-list"
style={{ height: getTotalSize() }}
disablePadding
data-testid={getQueryKey('token-list')}
>
{getVirtualItems().map((item) => {
const currentToken = tokens[item.index]
Expand Down
Loading