Skip to content

Commit 8d0f365

Browse files
authored
E2E (#5)
* chore(deps): 🔗 install Playwright Installed Playwright as a dev dependency for end-to-end testing * chore: 🔧 add Playwright configuration * chore: 🔧 update .gitignore to include Playwright directories * test: 🚨 test Home page * docs: 📚 update README.md Updated to include Playwright for end-to-end testing
1 parent 04cacf7 commit 8d0f365

File tree

8 files changed

+171
-0
lines changed

8 files changed

+171
-0
lines changed

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,9 @@ dist-ssr
2727

2828
# Coverage directory
2929
coverage
30+
31+
# Playwright
32+
/test-results/
33+
/playwright-report/
34+
/blob-report/
35+
/playwright/.cache/

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ Before you begin, ensure you have met the following requirements:
2525
This template includes the following additional tools and configurations:
2626

2727
- [Vitest](https://vitest.dev/) for unit testing, along with [React Testing Library](https://testing-library.com/docs/react-testing-library/intro/) for testing React components, Vitest UI, and coverage reports.
28+
- [Playwright](https://playwright.dev/) for end-to-end testing with UI and coverage support.
2829
- [Storybook](https://storybook.js.org/) for building and testing UI components in isolation.
2930
- [React Router](https://reactrouter.com/) for client-side routing.
3031
- [Vite PWA](https://vite-pwa-org.netlify.app/) (Progressive Web App) support for offline capabilities and better performance on mobile devices.

e2e/pages/Home.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import { Locator, Page } from '@playwright/test';
2+
3+
class Home {
4+
readonly page: Page;
5+
readonly title = 'Vite + React + TS';
6+
readonly viteLink: Locator;
7+
readonly reactLink: Locator;
8+
readonly heading: Locator;
9+
readonly helperText: Locator;
10+
readonly counterButton: Locator;
11+
12+
constructor(page: Page) {
13+
this.page = page;
14+
this.viteLink = page.locator('a[href="https://vite.dev"]');
15+
this.reactLink = page.locator('a[href="https://react.dev"]');
16+
this.heading = page.locator('h1');
17+
this.helperText = page.locator('.read-the-docs');
18+
this.counterButton = page.getByRole('button', { name: /count is \d+/ });
19+
}
20+
21+
async goto() {
22+
await this.page.goto('/');
23+
}
24+
25+
async incrementCounter(times: number) {
26+
for (let i = 0; i < times; i++) {
27+
await this.counterButton.click();
28+
}
29+
}
30+
}
31+
32+
export default Home;

e2e/pages/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { default as Home } from './Home';

e2e/tests/home.spec.ts

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import { expect, test } from '@playwright/test';
2+
3+
import { Home } from '../pages';
4+
5+
test.describe('Home', () => {
6+
let home: Home;
7+
8+
test.beforeEach(async ({ page }) => {
9+
home = new Home(page);
10+
11+
await home.goto();
12+
});
13+
14+
test('Home has expected title', async ({ page }) => {
15+
await expect(page).toHaveTitle(home.title);
16+
});
17+
18+
test('Vite and React logo links are correct', async () => {
19+
await expect(home.viteLink).toHaveAttribute('href', 'https://vite.dev');
20+
await expect(home.reactLink).toHaveAttribute('href', 'https://react.dev');
21+
});
22+
23+
test('Page displays correct heading and text', async () => {
24+
await expect(home.heading).toHaveText('Vite + React');
25+
await expect(home.helperText).toHaveText(
26+
'Click on the Vite and React logos to learn more'
27+
);
28+
});
29+
30+
test('Counter increments correctly', async () => {
31+
await home.incrementCounter(1);
32+
await expect(home.counterButton).toContainText('count is 1');
33+
34+
await home.incrementCounter(1);
35+
await expect(home.counterButton).toContainText('count is 2');
36+
37+
await home.incrementCounter(1);
38+
await expect(home.counterButton).toContainText('count is 3');
39+
});
40+
});

package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
"test:coverage": "vitest run --coverage",
1919
"test:ui": "vitest --ui",
2020
"test:watch": "vitest",
21+
"test:e2e": "npx playwright test",
22+
"test:e2e:ui": "npx playwright test --ui",
2123
"type-check": "tsc --noEmit"
2224
},
2325
"lint-staged": {
@@ -31,6 +33,7 @@
3133
"devDependencies": {
3234
"@chromatic-com/storybook": "^3.2.2",
3335
"@eslint/js": "^9.15.0",
36+
"@playwright/test": "^1.51.1",
3437
"@storybook/addon-essentials": "^8.4.7",
3538
"@storybook/addon-interactions": "^8.4.7",
3639
"@storybook/addon-onboarding": "^8.4.7",

playwright.config.ts

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import { defineConfig, devices } from '@playwright/test';
2+
3+
/**
4+
* See https://playwright.dev/docs/test-configuration.
5+
*/
6+
export default defineConfig({
7+
testDir: './e2e',
8+
fullyParallel: true,
9+
forbidOnly: !!process.env.CI,
10+
retries: process.env.CI ? 2 : 0,
11+
workers: process.env.CI ? 1 : undefined,
12+
reporter: 'html',
13+
use: {
14+
baseURL: 'http://localhost:5173',
15+
trace: 'on-first-retry',
16+
},
17+
18+
/* Configure projects for major browsers */
19+
projects: [
20+
{
21+
name: 'chromium',
22+
use: { ...devices['Desktop Chrome'] },
23+
},
24+
25+
{
26+
name: 'firefox',
27+
use: { ...devices['Desktop Firefox'] },
28+
},
29+
30+
{
31+
name: 'webkit',
32+
use: { ...devices['Desktop Safari'] },
33+
},
34+
35+
/* Test against mobile viewports. */
36+
{
37+
name: 'Mobile Chrome',
38+
use: { ...devices['Pixel 5'] },
39+
},
40+
{
41+
name: 'Mobile Safari',
42+
use: { ...devices['iPhone 12'] },
43+
},
44+
45+
/* Test against branded browsers. */
46+
// {
47+
// name: 'Microsoft Edge',
48+
// use: { ...devices['Desktop Edge'], channel: 'msedge' },
49+
// },
50+
// {
51+
// name: 'Google Chrome',
52+
// use: { ...devices['Desktop Chrome'], channel: 'chrome' },
53+
// },
54+
],
55+
56+
/* Run your local dev server before starting the tests */
57+
webServer: {
58+
command: 'yarn start',
59+
url: 'http://localhost:5173',
60+
reuseExistingServer: !process.env.CI,
61+
},
62+
});

yarn.lock

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1287,6 +1287,13 @@
12871287
resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33"
12881288
integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==
12891289

1290+
"@playwright/test@^1.51.1":
1291+
version "1.51.1"
1292+
resolved "https://registry.yarnpkg.com/@playwright/test/-/test-1.51.1.tgz#75357d513221a7be0baad75f01e966baf9c41a2e"
1293+
integrity sha512-nM+kEaTSAoVlXmMPH10017vn3FSiFqr/bh4fKg9vmAdMfd9SDqRZNvPSiAHADc/itWak+qPvMPZQOPwCBW7k7Q==
1294+
dependencies:
1295+
playwright "1.51.1"
1296+
12901297
"@polka/url@^1.0.0-next.24":
12911298
version "1.0.0-next.28"
12921299
resolved "https://registry.yarnpkg.com/@polka/url/-/url-1.0.0-next.28.tgz#d45e01c4a56f143ee69c54dd6b12eade9e270a73"
@@ -3141,6 +3148,11 @@ fs.realpath@^1.0.0:
31413148
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
31423149
integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==
31433150

3151+
3152+
version "2.3.2"
3153+
resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a"
3154+
integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==
3155+
31443156
fsevents@~2.3.2, fsevents@~2.3.3:
31453157
version "2.3.3"
31463158
resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6"
@@ -4171,6 +4183,20 @@ picomatch@^4.0.2:
41714183
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-4.0.2.tgz#77c742931e8f3b8820946c76cd0c1f13730d1dab"
41724184
integrity sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==
41734185

4186+
4187+
version "1.51.1"
4188+
resolved "https://registry.yarnpkg.com/playwright-core/-/playwright-core-1.51.1.tgz#d57f0393e02416f32a47cf82b27533656a8acce1"
4189+
integrity sha512-/crRMj8+j/Nq5s8QcvegseuyeZPxpQCZb6HNk3Sos3BlZyAknRjoyJPFWkpNn8v0+P3WiwqFF8P+zQo4eqiNuw==
4190+
4191+
4192+
version "1.51.1"
4193+
resolved "https://registry.yarnpkg.com/playwright/-/playwright-1.51.1.tgz#ae1467ee318083968ad28d6990db59f47a55390f"
4194+
integrity sha512-kkx+MB2KQRkyxjYPc3a0wLZZoDczmppyGJIvQ43l+aZihkaVvmu/21kiyaHeHjiFxjxNNFnUncKmcGIyOojsaw==
4195+
dependencies:
4196+
playwright-core "1.51.1"
4197+
optionalDependencies:
4198+
fsevents "2.3.2"
4199+
41744200
polished@^4.2.2:
41754201
version "4.3.1"
41764202
resolved "https://registry.yarnpkg.com/polished/-/polished-4.3.1.tgz#5a00ae32715609f83d89f6f31d0f0261c6170548"

0 commit comments

Comments
 (0)