diff --git a/.gitignore b/.gitignore index 2ebbc5f..c61c77c 100644 --- a/.gitignore +++ b/.gitignore @@ -30,3 +30,9 @@ dist-ssr !.yarn/releases !.yarn/sdks !.yarn/versions + +# Playwright +/test-results/ +/playwright-report/ +/blob-report/ +/playwright/.cache/ diff --git a/CHANGELOG.md b/CHANGELOG.md index 4c25351..946f6b5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,16 +1,14 @@ ## [1.9.2](https://github.com/vault-developer/event-loop-explorer/compare/v1.9.1...v1.9.2) (2024-10-30) - ### Bug Fixes -* update husky scripts ([#22](https://github.com/vault-developer/event-loop-explorer/issues/22)) ([2a8b320](https://github.com/vault-developer/event-loop-explorer/commit/2a8b3209719bb65d2f124f07e8ce43e4573b44a7)) +- update husky scripts ([#22](https://github.com/vault-developer/event-loop-explorer/issues/22)) ([2a8b320](https://github.com/vault-developer/event-loop-explorer/commit/2a8b3209719bb65d2f124f07e8ce43e4573b44a7)) ## [1.9.1](https://github.com/vault-developer/event-loop-explorer/compare/v1.9.0...v1.9.1) (2024-10-30) - ### Bug Fixes -* Add margin to modals ([#21](https://github.com/vault-developer/event-loop-explorer/issues/21)) ([8ed6a5c](https://github.com/vault-developer/event-loop-explorer/commit/8ed6a5ce4b47db15c3a34a1dc088b6f2e4ee17ef)) +- Add margin to modals ([#21](https://github.com/vault-developer/event-loop-explorer/issues/21)) ([8ed6a5c](https://github.com/vault-developer/event-loop-explorer/commit/8ed6a5ce4b47db15c3a34a1dc088b6f2e4ee17ef)) # [1.9.0](https://github.com/vault-developer/event-loop-explorer/compare/v1.8.0...v1.9.0) (2024-10-29) diff --git a/package.json b/package.json index d262b36..7b6cd27 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,9 @@ "typecheck": "tsc --noEmit", "preview": "vite preview", "prepare": "husky", - "commit": "cz" + "commit": "cz", + "e2e": "playwright test", + "e2e:ui": "playwright test --ui" }, "dependencies": { "@commitlint/cli": "^19.4.0", @@ -33,8 +35,10 @@ }, "devDependencies": { "@commitlint/config-conventional": "^19.2.2", + "@playwright/test": "^1.48.2", "@semantic-release/changelog": "^6.0.3", "@semantic-release/git": "^10.0.1", + "@types/node": "^22.9.0", "@types/react": "^18.3.4", "@types/react-dom": "^18.3.0", "@typescript-eslint/eslint-plugin": "^8.2.0", diff --git a/playwright.config.ts b/playwright.config.ts new file mode 100644 index 0000000..535dcc1 --- /dev/null +++ b/playwright.config.ts @@ -0,0 +1,34 @@ +import { defineConfig, devices } from '@playwright/test'; + +/** + * See https://playwright.dev/docs/test-configuration. + */ +export default defineConfig({ + testDir: './tests', + /* Run tests in files in parallel */ + fullyParallel: false, + /* 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: { + baseURL: 'http://localhost:5173/event-loop-explorer/', + trace: 'on-first-retry', + }, + projects: [ + { + name: 'chromium', + use: { ...devices['Desktop Chrome'] }, + }, + ], + webServer: { + command: 'yarn dev', + url: 'http://localhost:5173/event-loop-explorer/', + reuseExistingServer: !process.env.CI, + }, +}); diff --git a/src/App.tsx b/src/App.tsx index 9d37f5e..110dfc9 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -20,6 +20,7 @@ function App() { GitHub diff --git a/src/components/Editor/Editor.tsx b/src/components/Editor/Editor.tsx index 96e9848..6c319ea 100644 --- a/src/components/Editor/Editor.tsx +++ b/src/components/Editor/Editor.tsx @@ -126,16 +126,25 @@ function EditorComponent() { onChange={onSelect} style={{ minWidth: 200, textAlign: 'start' }} variant="outlined" + data-testid="example-select" > {codeExamples.map(({ title }) => ( - + {title} ))} - + run @@ -144,7 +153,7 @@ function EditorComponent() { {status !== 'disabled' && ( <> -
+
speed: {Math.round(speedFactorState.speed * 100)}%
css` position: absolute; diff --git a/tests/explorer.spec.ts b/tests/explorer.spec.ts new file mode 100644 index 0000000..e5cf34b --- /dev/null +++ b/tests/explorer.spec.ts @@ -0,0 +1,80 @@ +import { test, expect } from '@playwright/test'; + +test.describe('Explorer', () => { + test.beforeEach(async ({ page }) => { + await page.goto('/'); + }); + + test('Run synchronous loop', async ({ page }) => { + const exampleSelect = await page.getByTestId('example-select'); + + await exampleSelect.click(); + await page.getByTestId('example-menu-item').nth(0).click(); + await expect(exampleSelect.locator('input')).toHaveValue('synchronous'); + await page.getByTestId('run-button').click(); + await expect(page.getByTestId('speed-slider')).toBeVisible(); + }); + + test('Run task queue loop', async ({ page }) => { + const exampleSelect = await page.getByTestId('example-select'); + + await exampleSelect.click(); + await page.getByTestId('example-menu-item').nth(1).click(); + await expect(exampleSelect.locator('input')).toHaveValue('tasks queue'); + await page.getByTestId('run-button').click(); + await expect(page.getByTestId('speed-slider')).toBeVisible(); + }); + + test('Run callstack loop', async ({ page }) => { + const exampleSelect = await page.getByTestId('example-select'); + + await exampleSelect.click(); + await page.getByTestId('example-menu-item').nth(2).click(); + await expect(exampleSelect.locator('input')).toHaveValue('callstack'); + await page.getByTestId('run-button').click(); + await expect(page.getByTestId('speed-slider')).toBeVisible(); + }); + + test('Run microtasks loop', async ({ page }) => { + const exampleSelect = await page.getByTestId('example-select'); + + await expect(exampleSelect.locator('input')).toHaveValue('microtasks'); + await page.getByTestId('run-button').click(); + await expect(page.getByTestId('speed-slider')).toBeVisible(); + }); + + test('Run request animation frame loop', async ({ page }) => { + const exampleSelect = await page.getByTestId('example-select'); + + await exampleSelect.click(); + await page.getByTestId('example-menu-item').nth(4).click(); + await expect(exampleSelect.locator('input')).toHaveValue( + 'requestAnimationFrame' + ); + await page.getByTestId('run-button').click(); + await expect(page.getByTestId('speed-slider')).toBeVisible(); + }); + + test('Run everything loop', async ({ page }) => { + const exampleSelect = await page.getByTestId('example-select'); + + await exampleSelect.click(); + await page.getByTestId('example-menu-item').nth(5).click(); + await expect(exampleSelect.locator('input')).toHaveValue('everything'); + await page.getByTestId('run-button').click(); + await expect(page.getByTestId('speed-slider')).toBeVisible(); + }); + + test('Visit github repo link', async ({ page, context }) => { + const [repoPage] = await Promise.all([ + context.waitForEvent('page'), + page.getByTestId('github-repo-link').click(), + ]); + + await repoPage.waitForLoadState(); + + expect(repoPage.url()).toBe( + 'https://github.com/vault-developer/event-loop-explorer' + ); + }); +}); diff --git a/yarn.lock b/yarn.lock index 756e6e7..a6323bd 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1533,6 +1533,17 @@ __metadata: languageName: node linkType: hard +"@playwright/test@npm:^1.48.2": + version: 1.48.2 + resolution: "@playwright/test@npm:1.48.2" + dependencies: + playwright: "npm:1.48.2" + bin: + playwright: cli.js + checksum: 10c0/68bab3bee8d716111e9a166785e6c3c406b6a184fc46d03b5468fcbb92b6242e5628f6a75f9d286e2491ec0e9e59af67542a1f114b6659d790b5a1f41e4d305b + languageName: node + linkType: hard + "@pnpm/config.env-replace@npm:^1.1.0": version: 1.1.0 resolution: "@pnpm/config.env-replace@npm:1.1.0" @@ -1981,6 +1992,15 @@ __metadata: languageName: node linkType: hard +"@types/node@npm:^22.9.0": + version: 22.9.0 + resolution: "@types/node@npm:22.9.0" + dependencies: + undici-types: "npm:~6.19.8" + checksum: 10c0/3f46cbe0a49bab4ba30494025e4c8a6e699b98ac922857aa1f0209ce11a1313ee46e6808b8f13fe5b8b960a9d7796b77c8d542ad4e9810e85ef897d5593b5d51 + languageName: node + linkType: hard + "@types/normalize-package-data@npm:^2.4.3": version: 2.4.4 resolution: "@types/normalize-package-data@npm:2.4.4" @@ -3565,8 +3585,10 @@ __metadata: "@eslint/js": "npm:^9.9.1" "@mui/icons-material": "npm:^6.0.1" "@mui/material": "npm:^5.16.7" + "@playwright/test": "npm:^1.48.2" "@semantic-release/changelog": "npm:^6.0.3" "@semantic-release/git": "npm:^10.0.1" + "@types/node": "npm:^22.9.0" "@types/react": "npm:^18.3.4" "@types/react-dom": "npm:^18.3.0" "@typescript-eslint/eslint-plugin": "npm:^8.2.0" @@ -3953,6 +3975,16 @@ __metadata: languageName: node linkType: hard +"fsevents@npm:2.3.2": + version: 2.3.2 + resolution: "fsevents@npm:2.3.2" + dependencies: + node-gyp: "npm:latest" + checksum: 10c0/be78a3efa3e181cda3cf7a4637cb527bcebb0bd0ea0440105a3bb45b86f9245b307dc10a2507e8f4498a7d4ec349d1910f4d73e4d4495b16103106e07eee735b + conditions: os=darwin + languageName: node + linkType: hard + "fsevents@npm:~2.3.2, fsevents@npm:~2.3.3": version: 2.3.3 resolution: "fsevents@npm:2.3.3" @@ -3963,6 +3995,15 @@ __metadata: languageName: node linkType: hard +"fsevents@patch:fsevents@npm%3A2.3.2#optional!builtin": + version: 2.3.2 + resolution: "fsevents@patch:fsevents@npm%3A2.3.2#optional!builtin::version=2.3.2&hash=df0bf1" + dependencies: + node-gyp: "npm:latest" + conditions: os=darwin + languageName: node + linkType: hard + "fsevents@patch:fsevents@npm%3A~2.3.2#optional!builtin, fsevents@patch:fsevents@npm%3A~2.3.3#optional!builtin": version: 2.3.3 resolution: "fsevents@patch:fsevents@npm%3A2.3.3#optional!builtin::version=2.3.3&hash=df0bf1" @@ -6379,6 +6420,30 @@ __metadata: languageName: node linkType: hard +"playwright-core@npm:1.48.2": + version: 1.48.2 + resolution: "playwright-core@npm:1.48.2" + bin: + playwright-core: cli.js + checksum: 10c0/511da53d9df01fec5e5798915c68e7d1574890a504d1aae05430bf538d0080efa8db86e3dafdcd450f084ce7622f6bbede23ca52e798bfc4c3b3ea8da52a51f5 + languageName: node + linkType: hard + +"playwright@npm:1.48.2": + version: 1.48.2 + resolution: "playwright@npm:1.48.2" + dependencies: + fsevents: "npm:2.3.2" + playwright-core: "npm:1.48.2" + dependenciesMeta: + fsevents: + optional: true + bin: + playwright: cli.js + checksum: 10c0/ecde4ee4767556868b24d7700f3502692a3cb14c8ef127052b51b48833ffcce80942954fb188a9b72505122b48b1b625d1bb486721e1c4f2e980215328ba1ad5 + languageName: node + linkType: hard + "postcss-selector-parser@npm:^6.0.10": version: 6.1.2 resolution: "postcss-selector-parser@npm:6.1.2" @@ -7675,7 +7740,7 @@ __metadata: languageName: node linkType: hard -"undici-types@npm:~6.19.2": +"undici-types@npm:~6.19.2, undici-types@npm:~6.19.8": version: 6.19.8 resolution: "undici-types@npm:6.19.8" checksum: 10c0/078afa5990fba110f6824823ace86073b4638f1d5112ee26e790155f481f2a868cc3e0615505b6f4282bdf74a3d8caad715fd809e870c2bb0704e3ea6082f344