diff --git a/.github/workflows/playwright.yml b/.github/workflows/playwright.yml new file mode 100644 index 0000000..17d073a --- /dev/null +++ b/.github/workflows/playwright.yml @@ -0,0 +1,27 @@ +name: Playwright Tests +on: + pull_request: + types: [opened, synchronize, reopened] +jobs: + test: + timeout-minutes: 60 + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: lts/* + - name: Install dependencies + run: npm install -g yarn && yarn + - name: Install Playwright Browsers + run: yarn playwright install --with-deps + - name: Run Playwright tests + run: xvfb-run --auto-servernum --server-args='-screen 0 1920x1080x24' yarn playwright test + env: + CI: true + - uses: actions/upload-artifact@v4 + if: always() + with: + name: playwright-report + path: playwright-report/ + retention-days: 30 diff --git a/.gitignore b/.gitignore index 925ce47..c58a00b 100644 --- a/.gitignore +++ b/.gitignore @@ -36,3 +36,7 @@ yarn-error.log* next-env.d.ts .env +/test-results/ +/playwright-report/ +/blob-report/ +/playwright/.cache/ diff --git a/package.json b/package.json index 870bab8..28e98d4 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ "dependencies": { "@rainbow-me/rainbowkit": "^2.0.6", "@tanstack/react-query": "^5.28.4", + "@tenkeylabs/dappwright": "^2.8.4", "@web3-onboard/core": "^2.21.3", "@web3-onboard/injected-wallets": "^2.10.13", "antd": "^5.16.5", @@ -27,11 +28,11 @@ "usehooks-ts": "^3.0.2", "viem": "^2.8.12", "wagmi": "^2.5.11", - "web3": "^4.7.0", - "yarn": "^1.22.22" + "web3": "^4.7.0" }, "devDependencies": { "@biomejs/biome": "1.7.1", + "@playwright/test": "^1.44.1", "@types/node": "^20", "@types/react": "^18", "@types/react-dom": "^18", diff --git a/playwright.config.ts b/playwright.config.ts new file mode 100644 index 0000000..c98dca6 --- /dev/null +++ b/playwright.config.ts @@ -0,0 +1,88 @@ +import { defineConfig, devices } from "@playwright/test"; + +/** + * Read environment variables from file. + * https://github.com/motdotla/dotenv + */ +// require('dotenv').config(); + +/** + * See https://playwright.dev/docs/test-configuration. + */ +export default defineConfig({ + testDir: "./tests/test-specs/", + // /* Maximum time one test can run for. */ + // timeout: 240 * 1000, + timeout: 100000, + expect: { + /** + * Maximum time expect() should wait for the condition to be met. + * For example in `await expect(locator).toHaveText();` + */ + timeout: 60000, + }, + /* Run tests in files in parallel */ + fullyParallel: true, + /* Fail the build on CI if you accidentally left test.only in the source code. */ + forbidOnly: !!process.env.CI, + /* Retry on CI only */ + retries: process.env.CI ? 2 : 0, + /* Opt out of parallel tests on CI. */ + workers: process.env.CI ? 1 : undefined, + /* Reporter to use. See https://playwright.dev/docs/test-reporters */ + reporter: "html", + /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */ + use: { + /* Base URL to use in actions like `await page.goto('/')`. */ + baseURL: "http://127.0.0.1:3000", + + /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */ + trace: "on-first-retry", + headless: !!process.env.CI, + actionTimeout: 10000, // Increase action timeout + navigationTimeout: 30000, // Increase navigation timeout + }, + + /* Configure projects for major browsers */ + projects: [ + // { + // name: "chromium", + // use: { ...devices["Desktop Chrome"] }, + // }, + { + name: "Google Chrome", + use: { ...devices["Desktop Chrome"], channel: "chrome" }, + }, + // { + // name: "firefox", + // use: { ...devices["Desktop Firefox"] }, + // }, + // { + // name: "Mobile Safari", + // use: { ...devices["iPhone 12"] }, + // }, + + // { + // name: "webkit", + // use: { ...devices["Desktop Safari"] }, + // }, + + /* Test against mobile viewports. */ + // { + // name: "Mobile Chrome", + // use: { ...devices["Pixel 5"] }, + // }, + /* Test against branded browsers. */ + // { + // name: 'Microsoft Edge', + // use: { ...devices['Desktop Edge'], channel: 'msedge' }, + // }, + ], + + /* Run your local dev server before starting the tests */ + webServer: { + command: "yarn dev", + url: "http://127.0.0.1:3000", + reuseExistingServer: !process.env.CI, + }, +}); diff --git a/src/hooks/useRainbowContext.tsx b/src/hooks/useRainbowContext.tsx index 73176b0..bba93a9 100644 --- a/src/hooks/useRainbowContext.tsx +++ b/src/hooks/useRainbowContext.tsx @@ -15,7 +15,7 @@ import { bscTestnet, mainnet } from 'wagmi/chains'; const config = getDefaultConfig({ appName: 'Portal dApp', - projectId: process.env.NEXT_PUBLIC_WC_ID || '', + projectId: '9761436f8aff7e7f24f34dd711430e8e', chains: [bscTestnet, astarEvm, astarZkEvm, zKyoto, mainnet, sepoliaTestnet], ssr: true, }); diff --git a/tests/constants.ts b/tests/constants.ts new file mode 100644 index 0000000..6de4a93 --- /dev/null +++ b/tests/constants.ts @@ -0,0 +1,2 @@ +export const TEST_ACCOUNT_SEED = + "bottom drive obey lake curtain smoke basket hold race lonely fit walk"; diff --git a/tests/test-specs/example/example.spec.ts b/tests/test-specs/example/example.spec.ts new file mode 100644 index 0000000..5cd42d6 --- /dev/null +++ b/tests/test-specs/example/example.spec.ts @@ -0,0 +1,47 @@ +import { + type BrowserContext, + test as baseTest, + expect, +} from "@playwright/test"; +import dappwright, { + type Dappwright, + MetaMaskWallet, +} from "@tenkeylabs/dappwright"; +import { TEST_ACCOUNT_SEED } from "../../constants"; + +const test = baseTest.extend<{ + context: BrowserContext; + wallet: Dappwright; +}>({ + context: async ({ browser }, use) => { + const [wallet, _, context] = await dappwright.bootstrap("", { + wallet: "metamask", + version: MetaMaskWallet.recommendedVersion, + seed: TEST_ACCOUNT_SEED, + headless: !!process.env.CI, + }); + + await wallet.switchNetwork("Sepolia"); + await use(context); + await context.close(); + }, + + wallet: async ({ context }, use) => { + const metamask = await dappwright.getWallet("metamask", context); + await use(metamask); + }, +}); + +test.beforeEach(async ({ page, context, wallet }) => { + await page.goto("/"); + await page.getByTestId("rk-connect-button").click(); + await page.getByTestId("rk-wallet-option-io.metamask").click(); + await wallet.approve(); +}); + +test("Check the connected wallet address", async ({ page }) => { + const accountButton = page.getByTestId("rk-account-button"); + await accountButton.click(); + const shortenAddress = await page.textContent("#rk_profile_title"); + expect(shortenAddress).toBe("0xf2…6cac"); +}); diff --git a/yarn.lock b/yarn.lock index a30835d..67ebc69 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1898,6 +1898,13 @@ resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33" integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== +"@playwright/test@^1.44.1": + version "1.44.1" + resolved "https://registry.yarnpkg.com/@playwright/test/-/test-1.44.1.tgz#cc874ec31342479ad99838040e99b5f604299bcb" + integrity sha512-1hZ4TNvD5z9VuhNJ/walIjvMVvYkZKf71axoF/uiAqpntQJXpG64dlXhoDXE3OczPuTuvjf/M5KWFg5VAVUS3Q== + dependencies: + playwright "1.44.1" + "@radix-ui/primitive@1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@radix-ui/primitive/-/primitive-1.0.1.tgz#e46f9958b35d10e9f6dc71c497305c22e3e55dbd" @@ -2480,6 +2487,13 @@ dependencies: "@tanstack/query-core" "5.32.0" +"@tenkeylabs/dappwright@^2.8.4": + version "2.8.4" + resolved "https://registry.yarnpkg.com/@tenkeylabs/dappwright/-/dappwright-2.8.4.tgz#dfda29b4a51471c775937ba06d2854b72b3865a8" + integrity sha512-pv5UIel9VzoaKF1CAA3Dsq5DFJWxu+L2VQam/o2kDeY8x2zGrtEYciPB7/AeDjUktpoOVjDCCGFiIXcJEwITgQ== + dependencies: + node-stream-zip "^1.13.0" + "@types/connect@^3.4.33": version "3.4.38" resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.38.tgz#5ba7f3bc4fbbdeaff8dded952e5ff2cc53f8d858" @@ -5348,6 +5362,11 @@ fs.realpath@^1.0.0: resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== +fsevents@2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" + integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== + fsevents@~2.3.2: version "2.3.3" resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" @@ -6715,6 +6734,11 @@ node-releases@^2.0.14: resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.14.tgz#2ffb053bceb8b2be8495ece1ab6ce600c4461b0b" integrity sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw== +node-stream-zip@^1.13.0: + version "1.15.0" + resolved "https://registry.yarnpkg.com/node-stream-zip/-/node-stream-zip-1.15.0.tgz#158adb88ed8004c6c49a396b50a6a5de3bca33ea" + integrity sha512-LN4fydt9TqhZhThkZIVQnF9cwjU3qmUH9h78Mx/K7d3VvfRqqwthLwJEUOEL0QPZ0XQmNN7be5Ggit5+4dq3Bw== + normalize-path@^3.0.0, normalize-path@~3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" @@ -7063,6 +7087,20 @@ pkg-types@^1.0.3: mlly "^1.6.1" pathe "^1.1.2" +playwright-core@1.44.1: + version "1.44.1" + resolved "https://registry.yarnpkg.com/playwright-core/-/playwright-core-1.44.1.tgz#53ec975503b763af6fc1a7aa995f34bc09ff447c" + integrity sha512-wh0JWtYTrhv1+OSsLPgFzGzt67Y7BE/ZS3jEqgGBlp2ppp1ZDj8c+9IARNW4dwf1poq5MgHreEM2KV/GuR4cFA== + +playwright@1.44.1: + version "1.44.1" + resolved "https://registry.yarnpkg.com/playwright/-/playwright-1.44.1.tgz#5634369d777111c1eea9180430b7a184028e7892" + integrity sha512-qr/0UJ5CFAtloI3avF95Y0L1xQo6r3LQArLIg/z/PoGJ6xa+EwzrwO5lpNr/09STxdHuUoP2mvuELJS+hLdtgg== + dependencies: + playwright-core "1.44.1" + optionalDependencies: + fsevents "2.3.2" + pngjs@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-5.0.0.tgz#e79dd2b215767fd9c04561c01236df960bce7fbb" @@ -9388,11 +9426,6 @@ yargs@^17.5.1: y18n "^5.0.5" yargs-parser "^21.1.1" -yarn@^1.22.22: - version "1.22.22" - resolved "https://registry.yarnpkg.com/yarn/-/yarn-1.22.22.tgz#ac34549e6aa8e7ead463a7407e1c7390f61a6610" - integrity sha512-prL3kGtyG7o9Z9Sv8IPfBNrWTDmXB4Qbes8A9rEzt6wkJV8mUvoirjU0Mp3GGAU06Y0XQyA3/2/RQFVuK7MTfg== - yocto-queue@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b"