-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: use playwright instead of testing library and msw (#11)
* feat: use playwright instead of testing library and msw * test: complete all features * test(todo-detail): complete * test(todo): change baseUrl to localhost * ci: give up test on CI, just test on local
- Loading branch information
Showing
77 changed files
with
1,040 additions
and
2,602 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 |
---|---|---|
|
@@ -4,13 +4,12 @@ on: | |
push: | ||
branches: | ||
- main | ||
|
||
pull_request: | ||
branches: | ||
- main | ||
|
||
jobs: | ||
lint-format: | ||
lint-and-format: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- name: Checkout branch | ||
|
@@ -39,45 +38,65 @@ jobs: | |
node-version: lts/* | ||
cache: pnpm # Package manager should be pre-installed | ||
|
||
- name: Setup globally | ||
run: npm i -g @antfu/ni | ||
|
||
- name: Install | ||
run: nci | ||
- name: Clean install | ||
run: pnpm i --frozen-lockfile | ||
|
||
- name: Typecheck | ||
run: nr typecheck | ||
|
||
test: | ||
runs-on: ${{ matrix.os }} | ||
|
||
strategy: | ||
matrix: | ||
node: [lts/*] | ||
os: [ubuntu-latest] # adding "windows-latest" and "macos-latest" will only slows down CI/CD | ||
fail-fast: false | ||
|
||
steps: | ||
- name: Checkout branch | ||
uses: actions/[email protected] | ||
|
||
- name: Install pnpm | ||
uses: pnpm/action-setup@v3 | ||
|
||
- name: Set node version to ${{ matrix.node }} | ||
uses: actions/[email protected] | ||
with: | ||
node-version: ${{ matrix.node }} | ||
cache: pnpm | ||
|
||
- name: Setup | ||
run: npm i -g @antfu/ni | ||
|
||
- name: Install | ||
run: nci | ||
|
||
- name: Build | ||
run: nr build | ||
|
||
- name: Test | ||
run: nr test | ||
run: pnpm typecheck | ||
|
||
# e2e: | ||
# timeout-minutes: 30 | ||
# runs-on: ubuntu-latest | ||
# steps: | ||
# - name: Checkout branch | ||
# uses: actions/[email protected] | ||
|
||
# - name: Install pnpm | ||
# uses: pnpm/action-setup@v3 | ||
|
||
# - name: Install node | ||
# uses: actions/[email protected] | ||
# with: | ||
# node-version: 18 | ||
|
||
# - name: Clean install | ||
# run: pnpm i --frozen-lockfile | ||
|
||
# - name: Install playwright browsers | ||
# # since we are installing dependencies beforehand, we can `exec` the binaries directly, instead of `dlx` | ||
# run: pnpm test:install | ||
|
||
# - name: Run playwright tests | ||
# run: pnpm test | ||
|
||
# - name: Save playwright report as artifact | ||
# uses: actions/[email protected] | ||
# if: always() | ||
# with: | ||
# name: playwright-report | ||
# path: playwright-report/ | ||
# retention-days: 30 | ||
|
||
# e2e: | ||
# runs-on: ubuntu-latest | ||
# container: | ||
# image: mcr.microsoft.com/playwright:v1.42.0-focal | ||
# steps: | ||
# - name: Checkout branch | ||
# uses: actions/[email protected] | ||
|
||
# - name: Install pnpm | ||
# uses: pnpm/action-setup@v3 | ||
|
||
# - name: Install node | ||
# uses: actions/[email protected] | ||
# with: | ||
# node-version: lts/* | ||
|
||
# - name: Clean install | ||
# run: pnpm i --frozen-lockfile | ||
|
||
# - name: Run playwright tests | ||
# run: pnpm test | ||
# env: | ||
# HOME: /root |
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
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,7 @@ | ||
# Linting and Formatting | ||
|
||
## Biome | ||
|
||
Biome is a all-in-one javascript tooling. It's built on Rust, so it's really fast. This repo actually implements eslint and prettier before migrating it to biome, and I saw a significant upgrade to the speed. | ||
|
||
In vscode, make sure you disable your ESLint and Prettier extensions, and install/enable Biome extension instead. You can override the linting and formatting rules in `biome.json` file in the root folder. |
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,19 @@ | ||
# Testing | ||
|
||
## Playwright | ||
|
||
We use Playwright for our End-to-End tests in this project. You'll find those in | ||
the `e2e` directory. As you make changes, add to an existing file or create a | ||
new file in the `e2e` directory to test your changes. | ||
|
||
To run these tests in development, run `pnpm run test` which will start | ||
the dev server for the app and run Playwright on it. | ||
|
||
We have a setup test to automate authentication/login flow in `auth.setup.ts` file by default. If you want to opt out of it, you can specify it in the test file, like so: | ||
|
||
```ts | ||
test.describe('unauthorized', () => { | ||
// reset storage state in a test file to avoid authentication that was set up for the whole project | ||
test.use({ storageState: { cookies: [], origins: [] } }); | ||
}); | ||
``` |
This file was deleted.
Oops, something went wrong.
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,10 @@ | ||
{ | ||
"id": 15, | ||
"username": "kminchelle", | ||
"email": "[email protected]", | ||
"firstName": "Jeanne", | ||
"lastName": "Halvorson", | ||
"gender": "female", | ||
"image": "https://robohash.org/Jeanne.png?set=set4", | ||
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MTUsInVzZXJuYW1lIjoia21pbmNoZWxsZSIsImVtYWlsIjoia21pbmNoZWxsZUBxcS5jb20iLCJmaXJzdE5hbWUiOiJKZWFubmUiLCJsYXN0TmFtZSI6IkhhbHZvcnNvbiIsImdlbmRlciI6ImZlbWFsZSIsImltYWdlIjoiaHR0cHM6Ly9yb2JvaGFzaC5vcmcvSmVhbm5lLnBuZz9zZXQ9c2V0NCIsImlhdCI6MTcwOTEyMDM5NywiZXhwIjoxNzA5MTIzOTk3fQ.P-ZpBhrCMltUGv5SgxXzpkVOqSeJjJDnzldUn9VMxoo" | ||
} |
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,31 @@ | ||
import { LoginApiResponseSchema } from '#auth/apis/auth.api'; | ||
import { UserStoreState } from '#auth/hooks/use-user-store.hook'; | ||
import { faker } from '@faker-js/faker'; | ||
|
||
export function seedUser(): LoginApiResponseSchema { | ||
return { | ||
id: faker.number.int(), | ||
username: faker.person.middleName(), | ||
email: faker.internet.email(), | ||
firstName: faker.person.firstName(), | ||
lastName: faker.person.lastName(), | ||
gender: faker.helpers.arrayElement(['male', 'female']), | ||
image: faker.image.avatar(), | ||
token: faker.string.uuid(), | ||
}; | ||
} | ||
|
||
export function getLocalStorageUser(): { | ||
version: number; | ||
state: UserStoreState; | ||
} | null { | ||
if (!localStorage) throw new Error('You are not in the browser env!'); | ||
|
||
return JSON.parse(localStorage.getItem('app-user') ?? 'null'); | ||
} | ||
|
||
export function setLocalStorageUser(user: LoginApiResponseSchema) { | ||
if (!localStorage) throw new Error('You are not in the browser env!'); | ||
|
||
localStorage.setItem('app-user', JSON.stringify(user)); | ||
} |
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,21 @@ | ||
import { expect, test } from '@playwright/test'; | ||
|
||
test('auth setup', async ({ page }) => { | ||
// when we're not authenticated, the app redirects to the login page | ||
await page.goto(''); | ||
|
||
const usernameInput = page.getByRole('textbox', { name: /username/i }); | ||
const passwordInput = page.getByRole('textbox', { name: /password/i }); | ||
const submitBtn = page.getByRole('button', { name: /login/i }); | ||
|
||
await usernameInput.fill('kminchelle'); | ||
await passwordInput.fill('0lelplR'); | ||
await submitBtn.click(); | ||
|
||
await page.waitForURL(''); | ||
await expect(usernameInput).not.toBeVisible(); | ||
await expect(passwordInput).not.toBeVisible(); | ||
await expect(submitBtn).not.toBeVisible(); | ||
|
||
await page.context().storageState({ path: 'playwright/.auth/user.json' }); | ||
}); |
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,53 @@ | ||
import { expect, test } from '@playwright/test'; | ||
|
||
test.beforeEach(async ({ page }) => { | ||
await page.goto('/'); | ||
}); | ||
|
||
test.describe('authorized', () => { | ||
test('should have title', async ({ page }) => { | ||
const title = page.getByRole('heading', { level: 1 }); | ||
|
||
await expect(title).toBeVisible(); | ||
}); | ||
|
||
test('should be able to sort, toggle clock, and navigate to /todos', async ({ | ||
page, | ||
}) => { | ||
const clockTimer = page.getByRole('img', { name: /clock timer/i }); | ||
const sortBtn = page.getByRole('button', { name: /sort/i }); | ||
const toggleClockBtn = page.getByRole('button', { name: /clock/i }); | ||
const getStartedBtn = page.getByRole('button', { name: /start/i }); | ||
|
||
await expect(clockTimer).toBeVisible(); | ||
await expect(sortBtn).toBeVisible(); | ||
await expect(toggleClockBtn).toBeVisible(); | ||
await expect(getStartedBtn).toBeVisible(); | ||
|
||
// we don't assert sort button, because there's a possibility the position would be the same as before | ||
await toggleClockBtn.click(); | ||
await expect(clockTimer).not.toBeVisible(); | ||
await getStartedBtn.click(); | ||
|
||
await page.waitForURL('/todos'); | ||
await expect(sortBtn).not.toBeVisible(); | ||
await expect(toggleClockBtn).not.toBeVisible(); | ||
await expect(getStartedBtn).not.toBeVisible(); | ||
}); | ||
}); | ||
|
||
test.describe('unauthorized', () => { | ||
// reset storage state in a test file to avoid authentication that was set up for the whole project | ||
test.use({ storageState: { cookies: [], origins: [] } }); | ||
|
||
test('should redirect back to /login', async ({ page }) => { | ||
const usernameInput = page.getByRole('textbox', { name: /username/i }); | ||
const passwordInput = page.getByRole('textbox', { name: /password/i }); | ||
const submitBtn = page.getByRole('button', { name: /login/i }); | ||
|
||
await page.waitForURL('/login'); | ||
await expect(usernameInput).toBeVisible(); | ||
await expect(passwordInput).toBeVisible(); | ||
await expect(submitBtn).toBeVisible(); | ||
}); | ||
}); |
Oops, something went wrong.