Skip to content

Commit 78646b0

Browse files
fix: support jest 27 (#233)
1 parent 62f105b commit 78646b0

15 files changed

+91
-95
lines changed

.eslintrc.json

-1
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,6 @@
106106
"files": ["*.spec.ts"],
107107
"extends": ["plugin:jest/recommended"],
108108
"rules": {
109-
"jest/no-done-callback": "off",
110109
"jest/expect-expect": "off"
111110
}
112111
},

.github/workflows/ci.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ jobs:
2121
with:
2222
node-version: ${{ matrix.node-version }}
2323
- name: install
24-
run: npm install --force
24+
run: npm install
2525
- name: build
2626
run: npm run build -- --skip-nx-cache
2727
- name: test

angular.json

+3-6
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,7 @@
8787
"test": {
8888
"builder": "@nrwl/jest:jest",
8989
"options": {
90-
"jestConfig": "apps/example-app/jest.config.js",
91-
"setupFile": "apps/example-app/src/test-setup.ts"
90+
"jestConfig": "apps/example-app/jest.config.js"
9291
},
9392
"outputs": ["coverage/"]
9493
}
@@ -232,8 +231,7 @@
232231
"test": {
233232
"builder": "@nrwl/jest:jest",
234233
"options": {
235-
"jestConfig": "projects/testing-library/jest.config.js",
236-
"setupFile": "projects/testing-library/test-setup.ts"
234+
"jestConfig": "projects/testing-library/jest.config.js"
237235
},
238236
"outputs": ["coverage/projects/testing-library"]
239237
}
@@ -284,8 +282,7 @@
284282
"test": {
285283
"builder": "@nrwl/jest:jest",
286284
"options": {
287-
"jestConfig": "projects/jest-utils/jest.config.js",
288-
"setupFile": "projects/jest-utils/test-setup.ts"
285+
"jestConfig": "projects/jest-utils/jest.config.js"
289286
},
290287
"outputs": ["coverage/projects/jest-utils"]
291288
}

apps/example-app/src/app/examples/14-async-component.spec.ts

+13
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,16 @@ test('can use fakeAsync utilities', fakeAsync(async () => {
1414
const hello = await screen.findByText('Hello world');
1515
expect(hello).toBeInTheDocument();
1616
}));
17+
18+
test('can use fakeTimer utilities', async () => {
19+
jest.useFakeTimers();
20+
await render(AsyncComponent);
21+
22+
const load = await screen.findByRole('button', { name: /load/i });
23+
fireEvent.click(load);
24+
25+
jest.advanceTimersByTime(10_000);
26+
27+
const hello = await screen.findByText('Hello world');
28+
expect(hello).toBeInTheDocument();
29+
});

apps/example-app/src/app/examples/15-dialog.component.spec.ts

+12-10
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { MatDialogModule, MatDialogRef } from '@angular/material/dialog';
2-
import { render, screen, fireEvent, waitForElementToBeRemoved } from '@testing-library/angular';
2+
import { render, screen, waitForElementToBeRemoved, fireEvent } from '@testing-library/angular';
3+
import userEvent from '@testing-library/user-event';
34

45
import { DialogComponent, DialogContentComponent, DialogContentComponentModule } from './15-dialog.component';
56

@@ -18,44 +19,45 @@ test('dialog closes', async () => {
1819
});
1920

2021
const cancelButton = await screen.findByRole('button', { name: /cancel/i });
21-
fireEvent.click(cancelButton);
22+
userEvent.click(cancelButton);
2223

2324
expect(closeFn).toHaveBeenCalledTimes(1);
2425
});
2526

26-
test('opens and closes the dialog with buttons', async () => {
27+
test('closes the dialog via the backdrop', async () => {
2728
await render(DialogComponent, {
2829
imports: [MatDialogModule, DialogContentComponentModule],
2930
});
3031

3132
const openDialogButton = await screen.findByRole('button', { name: /open dialog/i });
32-
fireEvent.click(openDialogButton);
33+
userEvent.click(openDialogButton);
3334

3435
await screen.findByRole('dialog');
3536
await screen.findByRole('heading', { name: /dialog title/i });
3637

37-
const cancelButton = await screen.findByRole('button', { name: /cancel/i });
38-
fireEvent.click(cancelButton);
38+
// using fireEvent because of:
39+
// unable to click element as it has or inherits pointer-events set to "none"
40+
fireEvent.click(document.querySelector('.cdk-overlay-backdrop'));
3941

4042
await waitForElementToBeRemoved(() => screen.getByRole('dialog'));
4143

4244
const dialogTitle = screen.queryByRole('heading', { name: /dialog title/i });
4345
expect(dialogTitle).not.toBeInTheDocument();
4446
});
4547

46-
test('closes the dialog via the backdrop', async () => {
48+
test('opens and closes the dialog with buttons', async () => {
4749
await render(DialogComponent, {
4850
imports: [MatDialogModule, DialogContentComponentModule],
4951
});
5052

5153
const openDialogButton = await screen.findByRole('button', { name: /open dialog/i });
52-
fireEvent.click(openDialogButton);
54+
userEvent.click(openDialogButton);
5355

5456
await screen.findByRole('dialog');
5557
await screen.findByRole('heading', { name: /dialog title/i });
5658

57-
// eslint-disable-next-line testing-library/no-node-access
58-
fireEvent.click(document.querySelector('.cdk-overlay-backdrop'));
59+
const cancelButton = await screen.findByRole('button', { name: /cancel/i });
60+
userEvent.click(cancelButton);
5961

6062
await waitForElementToBeRemoved(() => screen.getByRole('dialog'));
6163

apps/example-app/src/app/issues/issue-106.spec.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ class TestSelectComponent {
1515
}
1616
}
1717

18-
it('https://github.com/testing-library/angular-testing-library/issues/106', async () => {
18+
test('https://github.com/testing-library/angular-testing-library/issues/106', async () => {
1919
await render(TestSelectComponent);
2020
const toggle = screen.getByTestId('toggle');
2121
const hiddenText = screen.queryByTestId('getme');
@@ -30,7 +30,7 @@ it('https://github.com/testing-library/angular-testing-library/issues/106', asyn
3030
await waitFor(() => expect(screen.queryByTestId('getme')).toBeInTheDocument());
3131
});
3232

33-
it('better https://github.com/testing-library/angular-testing-library/issues/106', async () => {
33+
test('better https://github.com/testing-library/angular-testing-library/issues/106', async () => {
3434
await render(TestSelectComponent);
3535
const toggle = screen.getByTestId('toggle');
3636
const hiddenText = screen.queryByTestId('getme');

jest.preset.js

-12
Original file line numberDiff line numberDiff line change
@@ -7,22 +7,10 @@ module.exports = {
77
},
88
resolver: '@nrwl/jest/plugins/resolver',
99
moduleFileExtensions: ['ts', 'js', 'html'],
10-
coverageReporters: ['html'],
11-
snapshotSerializers: [
12-
'jest-preset-angular/build/serializers/no-ng-attributes',
13-
'jest-preset-angular/build/serializers/ng-snapshot',
14-
'jest-preset-angular/build/serializers/html-comment',
15-
],
1610
globals: {
1711
'ts-jest': {
1812
tsconfig: '<rootDir>/tsconfig.spec.json',
1913
stringifyContentPathRegex: '\\.(html|svg)$',
20-
astTransformers: {
21-
before: [
22-
'jest-preset-angular/build/InlineFilesTransformer',
23-
'jest-preset-angular/build/StripStylesTransformer',
24-
],
25-
},
2614
},
2715
},
2816
};

package.json

+29-29
Original file line numberDiff line numberDiff line change
@@ -28,18 +28,18 @@
2828
"prepare": "husky install"
2929
},
3030
"dependencies": {
31-
"@angular/animations": "12.0.0",
32-
"@angular/cdk": "12.0.0",
33-
"@angular/common": "12.0.0",
34-
"@angular/compiler": "12.0.0",
35-
"@angular/core": "12.0.0",
36-
"@angular/forms": "12.0.0",
37-
"@angular/material": "12.0.0",
38-
"@angular/platform-browser": "12.0.0",
39-
"@angular/platform-browser-dynamic": "12.0.0",
40-
"@angular/router": "12.0.0",
41-
"@ngrx/store": "12.0.0",
42-
"@nrwl/angular": "12.0.3",
31+
"@angular/animations": "12.1.1",
32+
"@angular/cdk": "12.1.1",
33+
"@angular/common": "12.1.1",
34+
"@angular/compiler": "12.1.1",
35+
"@angular/core": "12.1.1",
36+
"@angular/forms": "12.1.1",
37+
"@angular/material": "12.1.1",
38+
"@angular/platform-browser": "12.1.1",
39+
"@angular/platform-browser-dynamic": "12.1.1",
40+
"@angular/router": "12.1.1",
41+
"@ngrx/store": "12.2.0",
42+
"@nrwl/angular": "12.5.1",
4343
"@nrwl/nx-cloud": "11.2.0",
4444
"@testing-library/dom": "^8.0.0",
4545
"@testing-library/user-event": "^13.1.9",
@@ -49,23 +49,23 @@
4949
"zone.js": "~0.11.4"
5050
},
5151
"devDependencies": {
52-
"@angular-devkit/build-angular": "12.0.0",
52+
"@angular-devkit/build-angular": "12.1.0",
5353
"@angular-eslint/eslint-plugin": "~12.0.0",
5454
"@angular-eslint/eslint-plugin-template": "~12.0.0",
5555
"@angular-eslint/template-parser": "~12.0.0",
56-
"@angular/cli": "12.0.0",
57-
"@angular/compiler-cli": "12.0.0",
58-
"@angular/language-service": "12.0.0",
59-
"@nrwl/cli": "12.0.3",
60-
"@nrwl/eslint-plugin-nx": "12.0.3",
61-
"@nrwl/jest": "12.0.3",
62-
"@nrwl/linter": "12.0.3",
63-
"@nrwl/node": "12.0.3",
64-
"@nrwl/nx-plugin": "12.0.3",
65-
"@nrwl/workspace": "12.3.1",
56+
"@angular/cli": "12.1.0",
57+
"@angular/compiler-cli": "12.1.1",
58+
"@angular/language-service": "12.1.1",
59+
"@nrwl/cli": "12.5.1",
60+
"@nrwl/eslint-plugin-nx": "12.5.1",
61+
"@nrwl/jest": "12.5.1",
62+
"@nrwl/linter": "12.5.1",
63+
"@nrwl/node": "12.5.1",
64+
"@nrwl/nx-plugin": "12.5.1",
65+
"@nrwl/workspace": "12.5.1",
6666
"@testing-library/jest-dom": "^5.11.10",
6767
"@types/jasmine": "~3.5.0",
68-
"@types/jest": "~26.0.3",
68+
"@types/jest": "^26.0.23",
6969
"@types/node": "14.14.37",
7070
"@typescript-eslint/eslint-plugin": "4.22.0",
7171
"@typescript-eslint/parser": "4.22.0",
@@ -77,11 +77,11 @@
7777
"eslint-plugin-jest-dom": "3.8.0",
7878
"eslint-plugin-testing-library": "^4.0.1",
7979
"husky": "^6.0.0",
80-
"jasmine-core": "~3.6.0",
80+
"jasmine-core": "~3.7.0",
8181
"jasmine-spec-reporter": "~5.0.0",
82-
"jest": "^26.1.0",
83-
"jest-preset-angular": "8.4.0",
84-
"karma": "~5.0.0",
82+
"jest": "^27.0.6",
83+
"jest-preset-angular": "9.0.4",
84+
"karma": "~6.3.4",
8585
"karma-chrome-launcher": "~3.1.0",
8686
"karma-jasmine": "~4.0.0",
8787
"karma-jasmine-html-reporter": "^1.5.0",
@@ -90,7 +90,7 @@
9090
"prettier": "^2.3.0",
9191
"rimraf": "^3.0.2",
9292
"semantic-release": "^17.1.1",
93-
"ts-jest": "26.5.4",
93+
"ts-jest": "^27.0.3",
9494
"ts-node": "9.1.1",
9595
"typescript": "4.2.4"
9696
}

projects/jest-utils/jest.config.js

+1
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,5 @@ module.exports = {
55
color: 'magenta',
66
},
77
preset: '../../jest.preset.js',
8+
setupFilesAfterEnv: ['<rootDir>/test-setup.ts'],
89
};

projects/jest-utils/tests/create-mock.spec.ts

+4-5
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,12 @@ class FixtureComponent {
2424
}
2525
}
2626

27-
it('mocks all functions', () => {
27+
test('mocks all functions', () => {
2828
const mock = createMock(FixtureService);
2929
expect(mock.print.mock).toBeDefined();
3030
});
3131

32-
it('provides a mock service', async () => {
32+
test('provides a mock service', async () => {
3333
const { getByText } = await render(FixtureComponent, {
3434
providers: [provideMock(FixtureService)],
3535
});
@@ -39,14 +39,13 @@ it('provides a mock service', async () => {
3939
expect(service.print).toHaveBeenCalledTimes(1);
4040
});
4141

42-
// eslint-disable-next-line jest/expect-expect
43-
it('is possible to write a mock implementation', async (done) => {
42+
test('is possible to write a mock implementation', async () => {
4443
const { getByText } = await render(FixtureComponent, {
4544
providers: [provideMock(FixtureService)],
4645
});
4746

4847
const service = TestBed.inject(FixtureService) as Mock<FixtureService>;
49-
service.print.mockImplementation(() => done());
5048

5149
fireEvent.click(getByText('Print'));
50+
expect(service.print).toHaveBeenCalled();
5251
});

projects/testing-library/jest.config.js

+1
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,5 @@ module.exports = {
55
color: 'magenta',
66
},
77
preset: '../../jest.preset.js',
8+
setupFilesAfterEnv: ['<rootDir>/test-setup.ts'],
89
};

projects/testing-library/src/lib/testing-library.ts

+14-9
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import {
88
SimpleChanges,
99
ApplicationInitStatus,
1010
} from '@angular/core';
11-
import { ComponentFixture, TestBed } from '@angular/core/testing';
11+
import { ComponentFixture, TestBed, tick } from '@angular/core/testing';
1212
import { By } from '@angular/platform-browser';
1313
import { BrowserAnimationsModule, NoopAnimationsModule } from '@angular/platform-browser/animations';
1414
import { NavigationExtras, Router } from '@angular/router';
@@ -310,14 +310,21 @@ async function waitForWrapper<T>(
310310
callback: () => T extends Promise<any> ? never : T,
311311
options?: dtlWaitForOptions,
312312
): Promise<T> {
313+
let inFakeAsync = true;
314+
try {
315+
tick(0);
316+
} catch (err) {
317+
inFakeAsync = false;
318+
}
319+
313320
detectChanges();
321+
314322
return await dtlWaitFor(() => {
315-
try {
316-
return callback();
317-
} catch (error) {
318-
setImmediate(() => detectChanges());
319-
throw error;
323+
setTimeout(() => detectChanges(), 0);
324+
if (inFakeAsync) {
325+
tick(0);
320326
}
327+
return callback();
321328
}, options);
322329
}
323330

@@ -345,10 +352,8 @@ async function waitForElementToBeRemovedWrapper<T>(
345352
}
346353

347354
return await dtlWaitForElementToBeRemoved(() => {
348-
const result = cb();
349355
detectChanges();
350-
setImmediate(() => detectChanges());
351-
return result;
356+
return cb();
352357
}, options);
353358
}
354359

projects/testing-library/tests/issues/issue-188.spec.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ class BugOnChangeComponent implements OnChanges {
1717
}
1818
}
1919

20-
it('should output formatted name after rendering', async () => {
20+
test('should output formatted name after rendering', async () => {
2121
const { getByText } = await render(BugOnChangeComponent, { componentProperties: { name: 'name' } });
2222

2323
getByText('Hello NAME');

projects/testing-library/tests/issues/issue-67.spec.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,11 @@ import { render } from '../../src/public_api';
1515
})
1616
class BugGetByLabelTextComponent {}
1717

18-
it('first step to reproduce the bug: skip this test to avoid the error or remove the for attribute of label', async () => {
18+
test('first step to reproduce the bug: skip this test to avoid the error or remove the for attribute of label', async () => {
1919
expect(await render(BugGetByLabelTextComponent)).toBeDefined();
2020
});
2121

22-
it('second step: bug happens :`(', async () => {
22+
test('second step: bug happens :`(', async () => {
2323
const { getByLabelText, getByTestId } = await render(BugGetByLabelTextComponent);
2424

2525
const checkboxByTestId = getByTestId('checkbox');

0 commit comments

Comments
 (0)