-
Notifications
You must be signed in to change notification settings - Fork 19
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[ECO-2055] Add playwright with minimal test (#193)
- Loading branch information
Showing
12 changed files
with
332 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
--- | ||
jobs: | ||
test: | ||
defaults: | ||
run: | ||
working-directory: 'src/typescript/frontend' | ||
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 pnpm && pnpm install' | ||
- env: | ||
GITHUB_ACCESS_TOKEN: '${{ secrets.TRADING_VIEW_REPO_ACCESS_TOKEN }}' | ||
TRADING_VIEW_REPO_OWNER: '${{ secrets.TRADING_VIEW_REPO_OWNER }}' | ||
name: 'Prepare CI env' | ||
run: 'pnpm run playwright-preps' | ||
- name: 'Install Playwright Browsers' | ||
run: 'pnpm exec playwright install --with-deps' | ||
- name: 'Copy env file' | ||
run: 'cp ../.env.ci .env' | ||
- env: | ||
INBOX_URL: '${{ secrets.INBOX_URL }}' | ||
NEXT_PUBLIC_MQTT_URL: '${{ secrets.NEXT_PUBLIC_MQTT_URL }}' | ||
name: 'Run Playwright tests' | ||
run: 'pnpm exec playwright test' | ||
- if: 'always()' | ||
uses: 'actions/upload-artifact@v4' | ||
with: | ||
name: 'playwright-report' | ||
path: 'playwright-report/' | ||
retention-days: 30 | ||
timeout-minutes: 60 | ||
name: 'Playwright Tests' | ||
"on": | ||
pull_request: | ||
branches: | ||
- 'main' | ||
push: | ||
branches: | ||
- 'main' | ||
... |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
# cspell:word mqtt | ||
|
||
# To run your own local node for e2e testing, set this to "false" | ||
START_LOCAL_NODE_FOR_TEST="true" | ||
|
||
# The Aptos network to use | ||
NEXT_PUBLIC_APTOS_NETWORK="testnet" | ||
|
||
# The address of the main `emojicoin_dot_fun` contract module | ||
NEXT_PUBLIC_MODULE_ADDRESS="0xbabe8f471b7f4744502b1397530bafe80e3731b358c0dfeba26b38b2603bd00d" | ||
|
||
# The address of the rewards module with the overloaded swap function | ||
NEXT_PUBLIC_REWARDS_MODULE_ADDRESS="0x76044a237dcc3f71af75fb314f016e8032633587f7d70df4e70777f2b0221e75" | ||
|
||
# The default URL for a local inbox deployment. Do not add a slash to the end | ||
# Set through CI env variables | ||
INBOX_URL="" | ||
|
||
## A `nextjs` setting to determine the query revalidation length, in seconds. | ||
REVALIDATION_TIME="1" | ||
|
||
# The integrator address for the contract. | ||
NEXT_PUBLIC_INTEGRATOR_ADDRESS="0xbabe8f471b7f4744502b1397530bafe80e3731b358c0dfeba26b38b2603bd00d" | ||
|
||
# The BPS fee rate for each swap, liquidity provision, or liquidity removal. | ||
NEXT_PUBLIC_INTEGRATOR_FEE_RATE_BPS="125" | ||
|
||
# If false, no allowlist is set up | ||
# If true, NEXT_PUBLIC_GALXE_CAMPAIGN_ID (and|or) ALLOWLISTER3K_URL needs to be set | ||
NEXT_PUBLIC_IS_ALLOWLIST_ENABLED="false" | ||
GALXE_CAMPAIGN_ID="<CAMPAIGN_ID>" | ||
|
||
# This port may interfere with `inbox` when both are run locally, | ||
# but you can change it in `src/rust/allowlister3000/src/main.rs`. | ||
ALLOWLISTER3K_URL="" | ||
|
||
# This is a private environment variable that we use to hash the user address and | ||
# store it in a cookie after the user has been verified. | ||
# This allows us to avoid fetching from the allowlist/galxe campaign endpoints for | ||
# every single route in `middleware.ts`. | ||
HASH_SEED="some random string that is not public" | ||
|
||
# The URL to redirect to after the user fails verification. | ||
NEXT_PUBLIC_GALXE_CAMPAIGN_REDIRECT="" | ||
|
||
# Since mqtt connects through a websocket, we need to specify the URL with the `ws` | ||
# protocol prefix. | ||
# Set through CI env variables | ||
NEXT_PUBLIC_MQTT_URL="" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -48,3 +48,7 @@ yarn.lock | |
.idea | ||
|
||
*storybook.log | ||
/test-results/ | ||
/playwright-report/ | ||
/blob-report/ | ||
/playwright/.cache/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
import { defineConfig, devices } from '@playwright/test'; | ||
|
||
/** | ||
* Read environment variables from file. | ||
* https://github.com/motdotla/dotenv | ||
*/ | ||
// import dotenv from 'dotenv'; | ||
// dotenv.config({ path: path.resolve(__dirname, '.env') }); | ||
|
||
/** | ||
* See https://playwright.dev/docs/test-configuration. | ||
*/ | ||
export default defineConfig({ | ||
testDir: './tests/e2e', | ||
/* 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:3001', | ||
|
||
/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */ | ||
trace: 'on-first-retry', | ||
}, | ||
|
||
/* Configure projects for major browsers */ | ||
projects: [ | ||
{ | ||
name: 'chromium', | ||
use: { ...devices['Desktop Chrome'] }, | ||
}, | ||
|
||
{ | ||
name: 'firefox', | ||
use: { ...devices['Desktop Firefox'] }, | ||
}, | ||
|
||
{ | ||
name: 'webkit', | ||
use: { ...devices['Desktop Safari'] }, | ||
}, | ||
|
||
/* Test against mobile viewports. */ | ||
// { | ||
// name: 'Mobile Chrome', | ||
// use: { ...devices['Pixel 5'] }, | ||
// }, | ||
// { | ||
// name: 'Mobile Safari', | ||
// use: { ...devices['iPhone 12'] }, | ||
// }, | ||
|
||
/* Test against branded browsers. */ | ||
// { | ||
// name: 'Microsoft Edge', | ||
// use: { ...devices['Desktop Edge'], channel: 'msedge' }, | ||
// }, | ||
// { | ||
// name: 'Google Chrome', | ||
// use: { ...devices['Desktop Chrome'], channel: 'chrome' }, | ||
// }, | ||
], | ||
|
||
/* Run your local dev server before starting the tests */ | ||
webServer: { | ||
command: 'pnpm run build && pnpm run start', | ||
url: 'http://127.0.0.1:3001/', | ||
reuseExistingServer: false, | ||
timeout: 120 * 1000, | ||
}, | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import { REVALIDATE_TEST } from "const"; | ||
import { getAptos } from "lib/utils/aptos-client"; | ||
import { NextResponse } from "next/server"; | ||
|
||
export const revalidate = REVALIDATE_TEST; | ||
|
||
export async function GET() { | ||
const aptos = getAptos(); | ||
const version = await aptos.getLedgerInfo().then(res => res.ledger_version); | ||
return new NextResponse(version.toString()); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
19 changes: 11 additions & 8 deletions
19
src/typescript/frontend/vercel-submodule.sh → src/typescript/frontend/submodule.sh
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
import { test, expect } from '@playwright/test'; | ||
import { REVALIDATE_TEST } from "../../src/const"; | ||
|
||
const sleep = (ms: number) => { | ||
return new Promise(resolve => setTimeout(resolve, ms)); | ||
} | ||
|
||
const NEXTJS_CACHE_HEADER = "x-nextjs-cache"; | ||
|
||
test('api test route', async ({ page }) => { | ||
const numericRegex = /^[0-9]+$/; | ||
|
||
let res1: Response; | ||
let res1headers: { | ||
[key: string]: string | ||
}; | ||
|
||
// Query a first time. | ||
// | ||
// We need to do this multiple times until the cache header !== "STALE". | ||
// | ||
// This is because NextJS has a "serve stale value while generating new one" | ||
// caching policy. | ||
// | ||
// Since we want a fresh value here, we will query until we get one (which | ||
// should be two times, since the first one will trigger the revalidation and | ||
// the second one should get the new result). | ||
do { | ||
await sleep(100); | ||
res1 = await page.goto('/test'); | ||
res1headers = res1.headers(); | ||
} while (res1headers[NEXTJS_CACHE_HEADER] === "STALE"); | ||
const res1text = await res1.text(); | ||
|
||
expect(res1text).toMatch(numericRegex) | ||
expect(res1headers[NEXTJS_CACHE_HEADER]).toMatch("HIT") | ||
|
||
// Query a second time after a second. | ||
// | ||
// This should hit cache and be the same value as before. | ||
await sleep(REVALIDATE_TEST / 2 * 1000); | ||
const res2 = await page.goto('/test'); | ||
const res2headers = res2.headers(); | ||
const res2text = await res2.text(); | ||
|
||
expect(res2text).toBe(res1text); | ||
expect(res2headers[NEXTJS_CACHE_HEADER]).toBe("HIT"); | ||
|
||
// Query a third time after 1200ms. | ||
// | ||
// Since this has exceeded the revalidation time of the endpoint, this should | ||
// have the cache header set to "STALE". Despite that, because of the "serve | ||
// stale value while generating new one" caching policy, this value should be | ||
// the same as the previous one. | ||
await sleep(REVALIDATE_TEST / 2 * 1.2 * 1000); | ||
|
||
const res3 = await page.goto('/test'); | ||
const res3headers = res3.headers(); | ||
const res3text = await res3.text(); | ||
|
||
expect(res3headers[NEXTJS_CACHE_HEADER]).toBe("STALE"); | ||
expect(res3text).toMatch(numericRegex); | ||
expect(res3text).toBe(res2text); | ||
|
||
// Query a fourth time. | ||
// | ||
// This should be a cache "HIT", as we will get the cached value generated on | ||
// the previous request. This should also be different than the previous | ||
// requests as it is the newly calculated value. | ||
// | ||
// We also give 200ms to finish generating the new value. | ||
await sleep(200); | ||
const res4 = await page.goto('/test'); | ||
const res4headers = res4.headers(); | ||
const res4text = await res4.text(); | ||
|
||
expect(res4headers[NEXTJS_CACHE_HEADER]).toBe("HIT"); | ||
expect(res4text).toMatch(numericRegex); | ||
|
||
expect(BigInt(res1text)).toBeLessThan(BigInt(res4text)); | ||
}); |
Oops, something went wrong.