Skip to content

Commit e66ac47

Browse files
committed
Replace Happy DOM with Vitest Browser Mode
1 parent 65156c3 commit e66ac47

File tree

10 files changed

+185
-124
lines changed

10 files changed

+185
-124
lines changed

.github/workflows/ci.yml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ jobs:
5252

5353
- name: Install dependencies
5454
run: yarn --immutable
55+
env:
56+
PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: true
5557

5658
- name: Build package
5759
run: yarn build
@@ -91,6 +93,15 @@ jobs:
9193
restore-keys: |
9294
${{ runner.os }}-${{ env.cache-name }}
9395
96+
- name: Cache ~/.cache/ms-playwright
97+
id: playwright-cache
98+
uses: actions/cache@v4
99+
env:
100+
cache-name: playwright-cache
101+
with:
102+
path: ~/.cache/ms-playwright
103+
key: ${{ runner.os }}-${{ env.cache-name }}-${{ hashFiles('**/yarn.lock') }}
104+
94105
- name: Use Node.js
95106
uses: actions/setup-node@v4
96107
with:
@@ -102,5 +113,9 @@ jobs:
102113
- name: Install dependencies
103114
run: yarn --immutable
104115

116+
- name: Install Playwright browsers
117+
if: steps.playwright-cache.outputs.cache-hit != 'true'
118+
run: yarn workspace react-datetime-picker playwright install chromium-headless-shell
119+
105120
- name: Run tests
106121
run: yarn unit

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
!**/.yarn/versions
1919

2020
# Project-generated directories and files
21+
__screenshots__
2122
coverage
2223
dist
2324
node_modules

.yarnrc.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
enableScripts: false
2+
13
logFilters:
24
- code: YN0076
35
level: discard

packages/react-datetime-picker/package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,18 +75,18 @@
7575
"@testing-library/dom": "^10.0.0",
7676
"@testing-library/jest-dom": "^6.0.0",
7777
"@testing-library/react": "^16.0.0",
78-
"@testing-library/user-event": "^14.5.0",
7978
"@types/node": "*",
8079
"@types/react": "*",
8180
"@types/react-dom": "*",
81+
"@vitest/browser": "^3.2.3",
8282
"cpy-cli": "^5.0.0",
83-
"happy-dom": "^15.10.2",
83+
"playwright": "^1.51.1",
8484
"react": "^18.2.0",
8585
"react-dom": "^18.2.0",
8686
"replace-in-files-cli": "^3.0.0",
8787
"typescript": "^5.5.2",
8888
"vitest": "^3.2.3",
89-
"vitest-canvas-mock": "^0.2.2"
89+
"vitest-browser-react": "^1.0.1"
9090
},
9191
"peerDependencies": {
9292
"@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",

packages/react-datetime-picker/src/DateTimeInput.spec.tsx

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import { beforeEach, describe, expect, it, vi } from 'vitest';
1+
import { userEvent } from '@vitest/browser/context';
2+
import { describe, expect, it, vi } from 'vitest';
23
import { fireEvent, render } from '@testing-library/react';
3-
import { userEvent } from '@testing-library/user-event';
44

55
import DateTimeInput from './DateTimeInput.js';
66

@@ -25,13 +25,6 @@ describe('DateTimeInput', () => {
2525
className: 'react-datetime-picker__inputGroup',
2626
};
2727

28-
let user: ReturnType<typeof userEvent.setup>;
29-
beforeEach(() => {
30-
user = userEvent.setup({
31-
advanceTimers: vi.advanceTimersByTime.bind(vi),
32-
});
33-
});
34-
3528
it('renders a native input and custom inputs', () => {
3629
const { container } = render(<DateTimeInput {...defaultProps} />);
3730

@@ -496,7 +489,7 @@ describe('DateTimeInput', () => {
496489
const monthInput = customInputs[0] as HTMLInputElement;
497490
const dayInput = customInputs[1];
498491

499-
await user.type(monthInput, '{arrowright}');
492+
await userEvent.type(monthInput, '{arrowright}');
500493

501494
expect(dayInput).toHaveFocus();
502495
});
@@ -514,7 +507,7 @@ describe('DateTimeInput', () => {
514507
.filter((el) => el.trim());
515508
const separatorKey = separatorsTexts[0] as string;
516509

517-
await user.type(monthInput, separatorKey);
510+
await userEvent.type(monthInput, separatorKey);
518511

519512
expect(dayInput).toHaveFocus();
520513
});
@@ -532,7 +525,7 @@ describe('DateTimeInput', () => {
532525
.filter((el) => el.trim());
533526
const separatorKey = separatorsTexts[separatorsTexts.length - 1] as string;
534527

535-
await user.type(monthInput, separatorKey);
528+
await userEvent.type(monthInput, separatorKey);
536529

537530
expect(dayInput).toHaveFocus();
538531
});
@@ -543,7 +536,7 @@ describe('DateTimeInput', () => {
543536

544537
const select = container.querySelector('select') as HTMLSelectElement;
545538

546-
await user.type(select, '{arrowright}');
539+
await userEvent.type(select, '{arrowright}');
547540

548541
expect(select).toHaveFocus();
549542
});
@@ -555,7 +548,7 @@ describe('DateTimeInput', () => {
555548
const monthInput = customInputs[0];
556549
const dayInput = customInputs[1] as HTMLInputElement;
557550

558-
await user.type(dayInput, '{arrowleft}');
551+
await userEvent.type(dayInput, '{arrowleft}');
559552

560553
expect(monthInput).toHaveFocus();
561554
});
@@ -566,7 +559,7 @@ describe('DateTimeInput', () => {
566559
const customInputs = container.querySelectorAll('input[data-input]');
567560
const monthInput = customInputs[0] as HTMLInputElement;
568561

569-
await user.type(monthInput, '{arrowleft}');
562+
await userEvent.type(monthInput, '{arrowleft}');
570563

571564
expect(monthInput).toHaveFocus();
572565
});
@@ -578,7 +571,7 @@ describe('DateTimeInput', () => {
578571
const monthInput = customInputs[0] as HTMLInputElement;
579572
const dayInput = customInputs[1];
580573

581-
await user.type(monthInput, '4');
574+
await userEvent.type(monthInput, '4');
582575

583576
expect(dayInput).toHaveFocus();
584577
});
@@ -590,7 +583,7 @@ describe('DateTimeInput', () => {
590583
const monthInput = customInputs[0] as HTMLInputElement;
591584
const dayInput = customInputs[1];
592585

593-
await user.type(monthInput, '03');
586+
await userEvent.type(monthInput, '03');
594587

595588
expect(dayInput).toHaveFocus();
596589
});
@@ -638,7 +631,7 @@ describe('DateTimeInput', () => {
638631
const customInputs = container.querySelectorAll('input[data-input]');
639632
const monthInput = customInputs[0] as HTMLInputElement;
640633

641-
await user.type(monthInput, '1');
634+
await userEvent.type(monthInput, '1');
642635

643636
expect(monthInput).toHaveFocus();
644637
});

packages/react-datetime-picker/src/DateTimePicker.spec.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1+
import { userEvent } from '@vitest/browser/context';
12
import { describe, expect, it, vi } from 'vitest';
23
import { act, fireEvent, render, waitFor, waitForElementToBeRemoved } from '@testing-library/react';
3-
import { userEvent } from '@testing-library/user-event';
44

55
import DateTimePicker from './DateTimePicker.js';
66

@@ -563,7 +563,7 @@ describe('DateTimePicker', () => {
563563
it('closes Calendar component when clicked outside', async () => {
564564
const { container } = render(<DateTimePicker isCalendarOpen />);
565565

566-
userEvent.click(document.body);
566+
await userEvent.click(document.body);
567567

568568
await waitForElementToBeRemovedOrHidden(() =>
569569
container.querySelector('.react-datetime-picker__calendar'),
@@ -593,7 +593,7 @@ describe('DateTimePicker', () => {
593593
it('closes Clock component when clicked outside', async () => {
594594
const { container } = render(<DateTimePicker isClockOpen />);
595595

596-
userEvent.click(document.body);
596+
await userEvent.click(document.body);
597597

598598
await waitForElementToBeRemovedOrHidden(() =>
599599
container.querySelector('.react-datetime-picker__clock'),

packages/react-datetime-picker/tsconfig.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
"skipLibCheck": true,
1414
"strict": true,
1515
"target": "es2018",
16+
"types": ["@vitest/browser/matchers"],
1617
"verbatimModuleSyntax": true
1718
},
1819
"exclude": ["dist"]

packages/react-datetime-picker/vitest.config.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@ import { defineConfig } from 'vitest/config';
22

33
export default defineConfig({
44
test: {
5-
environment: 'happy-dom',
6-
server: {
7-
deps: {
8-
inline: ['vitest-canvas-mock'],
9-
},
5+
browser: {
6+
enabled: true,
7+
headless: true,
8+
instances: [{ browser: 'chromium' }],
9+
provider: 'playwright',
1010
},
1111
setupFiles: 'vitest.setup.ts',
1212
watch: false,

packages/react-datetime-picker/vitest.setup.ts

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,6 @@
1-
import { afterEach, beforeEach } from 'vitest';
1+
import { afterEach } from 'vitest';
22
import { cleanup } from '@testing-library/react';
33
import '@testing-library/jest-dom/vitest';
4-
import 'vitest-canvas-mock';
5-
6-
// Workaround for a bug in Vitest 3 or happy-dom
7-
const IntlNumberFormat = Intl.NumberFormat;
8-
9-
beforeEach(() => {
10-
Intl.NumberFormat = IntlNumberFormat;
11-
});
124

135
afterEach(() => {
146
cleanup();

0 commit comments

Comments
 (0)