diff --git a/.githooks/pre-commit b/.githooks/pre-commit
old mode 100644
new mode 100755
diff --git a/apps/example-app/src/app/examples/00-single-component.spec.ts b/apps/example-app/src/app/examples/00-single-component.spec.ts
index 73e429bb..44ad2500 100644
--- a/apps/example-app/src/app/examples/00-single-component.spec.ts
+++ b/apps/example-app/src/app/examples/00-single-component.spec.ts
@@ -1,8 +1,10 @@
-import { render, screen, fireEvent } from '@testing-library/angular';
+import { render, screen } from '@testing-library/angular';
+import userEvent from '@testing-library/user-event';
import { SingleComponent } from './00-single-component';
test('renders the current value and can increment and decrement', async () => {
+ const user = userEvent.setup();
await render(SingleComponent);
const incrementControl = screen.getByRole('button', { name: /increment/i });
@@ -11,10 +13,10 @@ test('renders the current value and can increment and decrement', async () => {
expect(valueControl).toHaveTextContent('0');
- fireEvent.click(incrementControl);
- fireEvent.click(incrementControl);
+ await user.click(incrementControl);
+ await user.click(incrementControl);
expect(valueControl).toHaveTextContent('2');
- fireEvent.click(decrementControl);
+ await user.click(decrementControl);
expect(valueControl).toHaveTextContent('1');
});
diff --git a/apps/example-app/src/app/examples/01-nested-component.spec.ts b/apps/example-app/src/app/examples/01-nested-component.spec.ts
index 8f3a242d..751d1c47 100644
--- a/apps/example-app/src/app/examples/01-nested-component.spec.ts
+++ b/apps/example-app/src/app/examples/01-nested-component.spec.ts
@@ -1,8 +1,10 @@
-import { render, screen, fireEvent } from '@testing-library/angular';
+import { render, screen } from '@testing-library/angular';
+import userEvent from '@testing-library/user-event';
import { NestedButtonComponent, NestedValueComponent, NestedContainerComponent } from './01-nested-component';
test('renders the current value and can increment and decrement', async () => {
+ const user = userEvent.setup();
await render(NestedContainerComponent, {
declarations: [NestedButtonComponent, NestedValueComponent],
});
@@ -13,10 +15,10 @@ test('renders the current value and can increment and decrement', async () => {
expect(valueControl).toHaveTextContent('0');
- fireEvent.click(incrementControl);
- fireEvent.click(incrementControl);
+ await user.click(incrementControl);
+ await user.click(incrementControl);
expect(valueControl).toHaveTextContent('2');
- fireEvent.click(decrementControl);
+ await user.click(decrementControl);
expect(valueControl).toHaveTextContent('1');
});
diff --git a/apps/example-app/src/app/examples/02-input-output.spec.ts b/apps/example-app/src/app/examples/02-input-output.spec.ts
index abb71dcb..93edee4d 100644
--- a/apps/example-app/src/app/examples/02-input-output.spec.ts
+++ b/apps/example-app/src/app/examples/02-input-output.spec.ts
@@ -1,8 +1,10 @@
-import { render, screen, fireEvent } from '@testing-library/angular';
+import { render, screen } from '@testing-library/angular';
+import userEvent from '@testing-library/user-event';
import { InputOutputComponent } from './02-input-output';
test('is possible to set input and listen for output', async () => {
+ const user = userEvent.setup();
const sendValue = jest.fn();
await render(InputOutputComponent, {
@@ -22,17 +24,18 @@ test('is possible to set input and listen for output', async () => {
expect(valueControl).toHaveTextContent('47');
- fireEvent.click(incrementControl);
- fireEvent.click(incrementControl);
- fireEvent.click(incrementControl);
+ await user.click(incrementControl);
+ await user.click(incrementControl);
+ await user.click(incrementControl);
expect(valueControl).toHaveTextContent('50');
- fireEvent.click(sendControl);
+ await user.click(sendControl);
expect(sendValue).toHaveBeenCalledTimes(1);
expect(sendValue).toHaveBeenCalledWith(50);
});
test('is possible to set input and listen for output with the template syntax', async () => {
+ const user = userEvent.setup();
const sendSpy = jest.fn();
await render('', {
@@ -48,12 +51,12 @@ test('is possible to set input and listen for output with the template syntax',
expect(valueControl).toHaveTextContent('47');
- fireEvent.click(incrementControl);
- fireEvent.click(incrementControl);
- fireEvent.click(incrementControl);
+ await user.click(incrementControl);
+ await user.click(incrementControl);
+ await user.click(incrementControl);
expect(valueControl).toHaveTextContent('50');
- fireEvent.click(sendControl);
+ await user.click(sendControl);
expect(sendSpy).toHaveBeenCalledTimes(1);
expect(sendSpy).toHaveBeenCalledWith(50);
});
diff --git a/apps/example-app/src/app/examples/03-forms.spec.ts b/apps/example-app/src/app/examples/03-forms.spec.ts
index 2a53a5f0..0e475834 100644
--- a/apps/example-app/src/app/examples/03-forms.spec.ts
+++ b/apps/example-app/src/app/examples/03-forms.spec.ts
@@ -4,6 +4,7 @@ import userEvent from '@testing-library/user-event';
import { FormsComponent } from './03-forms';
test('is possible to fill in a form and verify error messages (with the help of jest-dom https://testing-library.com/docs/ecosystem-jest-dom)', async () => {
+ const user = userEvent.setup();
await render(FormsComponent);
const nameControl = screen.getByRole('textbox', { name: /name/i });
@@ -16,19 +17,19 @@ test('is possible to fill in a form and verify error messages (with the help of
expect(errors).toContainElement(screen.queryByText('color is required'));
expect(nameControl).toBeInvalid();
- userEvent.type(nameControl, 'Tim');
- userEvent.clear(scoreControl);
- userEvent.type(scoreControl, '12');
+ await user.type(nameControl, 'Tim');
+ await user.clear(scoreControl);
+ await user.type(scoreControl, '12');
fireEvent.blur(scoreControl);
- userEvent.selectOptions(colorControl, 'G');
+ await user.selectOptions(colorControl, 'G');
expect(screen.queryByText('name is required')).not.toBeInTheDocument();
expect(screen.getByText('score must be lesser than 10')).toBeInTheDocument();
expect(screen.queryByText('color is required')).not.toBeInTheDocument();
expect(scoreControl).toBeInvalid();
- userEvent.clear(scoreControl);
- userEvent.type(scoreControl, '7');
+ await user.clear(scoreControl);
+ await user.type(scoreControl, '7');
fireEvent.blur(scoreControl);
expect(scoreControl).toBeValid();
diff --git a/apps/example-app/src/app/examples/04-forms-with-material.spec.ts b/apps/example-app/src/app/examples/04-forms-with-material.spec.ts
index e1e16e37..24b9cdc9 100644
--- a/apps/example-app/src/app/examples/04-forms-with-material.spec.ts
+++ b/apps/example-app/src/app/examples/04-forms-with-material.spec.ts
@@ -5,6 +5,8 @@ import { MaterialModule } from '../material.module';
import { MaterialFormsComponent } from './04-forms-with-material';
test('is possible to fill in a form and verify error messages (with the help of jest-dom https://testing-library.com/docs/ecosystem-jest-dom)', async () => {
+ const user = userEvent.setup();
+
const { fixture } = await render(MaterialFormsComponent, {
imports: [MaterialModule],
});
@@ -22,14 +24,14 @@ test('is possible to fill in a form and verify error messages (with the help of
expect(errors).toContainElement(screen.queryByText('color is required'));
expect(errors).toContainElement(screen.queryByText('agree is required'));
- userEvent.type(nameControl, 'Tim');
- userEvent.clear(scoreControl);
- userEvent.type(scoreControl, '12');
- userEvent.click(colorControl);
- userEvent.click(screen.getByText(/green/i));
+ await user.type(nameControl, 'Tim');
+ await user.clear(scoreControl);
+ await user.type(scoreControl, '12');
+ await user.click(colorControl);
+ await user.click(screen.getByText(/green/i));
expect(checkboxControl).not.toBeChecked();
- userEvent.click(checkboxControl);
+ await user.click(checkboxControl);
expect(checkboxControl).toBeChecked();
expect(checkboxControl).toBeValid();
@@ -39,11 +41,11 @@ test('is possible to fill in a form and verify error messages (with the help of
expect(screen.queryByText('agree is required')).not.toBeInTheDocument();
expect(scoreControl).toBeInvalid();
- userEvent.clear(scoreControl);
- userEvent.type(scoreControl, '7');
+ await user.clear(scoreControl);
+ await user.type(scoreControl, '7');
expect(scoreControl).toBeValid();
- userEvent.type(dateControl, '08/11/2022');
+ await user.type(dateControl, '08/11/2022');
expect(errors).not.toBeInTheDocument();
@@ -65,6 +67,8 @@ test('is possible to fill in a form and verify error messages (with the help of
});
test('set and show pre-set form values', async () => {
+ const user = userEvent.setup();
+
const { fixture, detectChanges } = await render(MaterialFormsComponent, {
imports: [MaterialModule],
});
@@ -87,7 +91,7 @@ test('set and show pre-set form values', async () => {
expect(scoreControl).toHaveValue(4);
expect(colorControl).toHaveTextContent('Blue');
expect(checkboxControl).toBeChecked();
- userEvent.click(checkboxControl);
+ await user.click(checkboxControl);
const form = screen.getByRole('form');
expect(form).toHaveFormValues({
diff --git a/apps/example-app/src/app/examples/05-component-provider.spec.ts b/apps/example-app/src/app/examples/05-component-provider.spec.ts
index 79811245..d23e849d 100644
--- a/apps/example-app/src/app/examples/05-component-provider.spec.ts
+++ b/apps/example-app/src/app/examples/05-component-provider.spec.ts
@@ -1,10 +1,13 @@
import { TestBed } from '@angular/core/testing';
-import { render, screen, fireEvent } from '@testing-library/angular';
+import { render, screen } from '@testing-library/angular';
import { provideMock, Mock, createMock } from '@testing-library/angular/jest-utils';
+import userEvent from '@testing-library/user-event';
import { ComponentWithProviderComponent, CounterService } from './05-component-provider';
test('renders the current value and can increment and decrement', async () => {
+ const user = userEvent.setup();
+
await render(ComponentWithProviderComponent, {
componentProviders: [
{
@@ -20,15 +23,17 @@ test('renders the current value and can increment and decrement', async () => {
expect(valueControl).toHaveTextContent('0');
- fireEvent.click(incrementControl);
- fireEvent.click(incrementControl);
+ await user.click(incrementControl);
+ await user.click(incrementControl);
expect(valueControl).toHaveTextContent('2');
- fireEvent.click(decrementControl);
+ await user.click(decrementControl);
expect(valueControl).toHaveTextContent('1');
});
test('renders the current value and can increment and decrement with a mocked jest-utils service', async () => {
+ const user = userEvent.setup();
+
const counter = createMock(CounterService);
let fakeCounterValue = 50;
counter.increment.mockImplementation(() => (fakeCounterValue += 10));
@@ -50,15 +55,17 @@ test('renders the current value and can increment and decrement with a mocked je
expect(valueControl).toHaveTextContent('50');
- fireEvent.click(incrementControl);
- fireEvent.click(incrementControl);
+ await user.click(incrementControl);
+ await user.click(incrementControl);
expect(valueControl).toHaveTextContent('70');
- fireEvent.click(decrementControl);
+ await user.click(decrementControl);
expect(valueControl).toHaveTextContent('60');
});
test('renders the current value and can increment and decrement with provideMocked from jest-utils', async () => {
+ const user = userEvent.setup();
+
await render(ComponentWithProviderComponent, {
componentProviders: [provideMock(CounterService)],
});
@@ -66,9 +73,9 @@ test('renders the current value and can increment and decrement with provideMock
const incrementControl = screen.getByRole('button', { name: /increment/i });
const decrementControl = screen.getByRole('button', { name: /decrement/i });
- fireEvent.click(incrementControl);
- fireEvent.click(incrementControl);
- fireEvent.click(decrementControl);
+ await user.click(incrementControl);
+ await user.click(incrementControl);
+ await user.click(decrementControl);
const counterService = TestBed.inject(CounterService) as Mock;
expect(counterService.increment).toHaveBeenCalledTimes(2);
diff --git a/apps/example-app/src/app/examples/06-with-ngrx-store.spec.ts b/apps/example-app/src/app/examples/06-with-ngrx-store.spec.ts
index b8a289bb..0f080658 100644
--- a/apps/example-app/src/app/examples/06-with-ngrx-store.spec.ts
+++ b/apps/example-app/src/app/examples/06-with-ngrx-store.spec.ts
@@ -1,9 +1,12 @@
-import { render, screen, fireEvent } from '@testing-library/angular';
+import { render, screen } from '@testing-library/angular';
import { StoreModule } from '@ngrx/store';
+import userEvent from '@testing-library/user-event';
import { WithNgRxStoreComponent, reducer } from './06-with-ngrx-store';
test('works with ngrx store', async () => {
+ const user = userEvent.setup();
+
await render(WithNgRxStoreComponent, {
imports: [
StoreModule.forRoot(
@@ -23,10 +26,10 @@ test('works with ngrx store', async () => {
expect(valueControl).toHaveTextContent('0');
- fireEvent.click(incrementControl);
- fireEvent.click(incrementControl);
+ await user.click(incrementControl);
+ await user.click(incrementControl);
expect(valueControl).toHaveTextContent('20');
- fireEvent.click(decrementControl);
+ await user.click(decrementControl);
expect(valueControl).toHaveTextContent('10');
});
diff --git a/apps/example-app/src/app/examples/07-with-ngrx-mock-store.spec.ts b/apps/example-app/src/app/examples/07-with-ngrx-mock-store.spec.ts
index 936168e5..eb51dbbc 100644
--- a/apps/example-app/src/app/examples/07-with-ngrx-mock-store.spec.ts
+++ b/apps/example-app/src/app/examples/07-with-ngrx-mock-store.spec.ts
@@ -1,10 +1,13 @@
import { TestBed } from '@angular/core/testing';
import { provideMockStore, MockStore } from '@ngrx/store/testing';
-import { render, screen, fireEvent } from '@testing-library/angular';
+import { render, screen } from '@testing-library/angular';
+import userEvent from '@testing-library/user-event';
import { WithNgRxMockStoreComponent, selectItems } from './07-with-ngrx-mock-store';
test('works with provideMockStore', async () => {
+ const user = userEvent.setup();
+
await render(WithNgRxMockStoreComponent, {
providers: [
provideMockStore({
@@ -21,7 +24,7 @@ test('works with provideMockStore', async () => {
const store = TestBed.inject(MockStore);
store.dispatch = jest.fn();
- fireEvent.click(screen.getByText(/seven/i));
+ await user.click(screen.getByText(/seven/i));
expect(store.dispatch).toHaveBeenCalledWith({ type: '[Item List] send', item: 'Seven' });
});
diff --git a/apps/example-app/src/app/examples/08-directive.spec.ts b/apps/example-app/src/app/examples/08-directive.spec.ts
index efd2a5b9..b81dcff0 100644
--- a/apps/example-app/src/app/examples/08-directive.spec.ts
+++ b/apps/example-app/src/app/examples/08-directive.spec.ts
@@ -1,8 +1,11 @@
-import { render, screen, fireEvent } from '@testing-library/angular';
+import { render, screen } from '@testing-library/angular';
+import userEvent from '@testing-library/user-event';
import { SpoilerDirective } from './08-directive';
test('it is possible to test directives', async () => {
+ const user = userEvent.setup();
+
await render('', {
declarations: [SpoilerDirective],
});
@@ -12,16 +15,17 @@ test('it is possible to test directives', async () => {
expect(screen.queryByText('I am visible now...')).not.toBeInTheDocument();
expect(screen.getByText('SPOILER')).toBeInTheDocument();
- fireEvent.mouseOver(directive);
+ await user.hover(directive);
expect(screen.queryByText('SPOILER')).not.toBeInTheDocument();
expect(screen.getByText('I am visible now...')).toBeInTheDocument();
- fireEvent.mouseLeave(directive);
+ await user.unhover(directive);
expect(screen.getByText('SPOILER')).toBeInTheDocument();
expect(screen.queryByText('I am visible now...')).not.toBeInTheDocument();
});
test('it is possible to test directives with props', async () => {
+ const user = userEvent.setup();
const hidden = 'SPOILER ALERT';
const visible = 'There is nothing to see here ...';
@@ -36,16 +40,17 @@ test('it is possible to test directives with props', async () => {
expect(screen.queryByText(visible)).not.toBeInTheDocument();
expect(screen.getByText(hidden)).toBeInTheDocument();
- fireEvent.mouseOver(screen.getByText(hidden));
+ await user.hover(screen.getByText(hidden));
expect(screen.queryByText(hidden)).not.toBeInTheDocument();
expect(screen.getByText(visible)).toBeInTheDocument();
- fireEvent.mouseLeave(screen.getByText(visible));
+ await user.unhover(screen.getByText(visible));
expect(screen.getByText(hidden)).toBeInTheDocument();
expect(screen.queryByText(visible)).not.toBeInTheDocument();
});
test('it is possible to test directives with props in template', async () => {
+ const user = userEvent.setup();
const hidden = 'SPOILER ALERT';
const visible = 'There is nothing to see here ...';
@@ -56,11 +61,11 @@ test('it is possible to test directives with props in template', async () => {
expect(screen.queryByText(visible)).not.toBeInTheDocument();
expect(screen.getByText(hidden)).toBeInTheDocument();
- fireEvent.mouseOver(screen.getByText(hidden));
+ await user.hover(screen.getByText(hidden));
expect(screen.queryByText(hidden)).not.toBeInTheDocument();
expect(screen.getByText(visible)).toBeInTheDocument();
- fireEvent.mouseLeave(screen.getByText(visible));
+ await user.unhover(screen.getByText(visible));
expect(screen.getByText(hidden)).toBeInTheDocument();
expect(screen.queryByText(visible)).not.toBeInTheDocument();
});
diff --git a/apps/example-app/src/app/examples/09-router.spec.ts b/apps/example-app/src/app/examples/09-router.spec.ts
index 2fd519fc..9483695d 100644
--- a/apps/example-app/src/app/examples/09-router.spec.ts
+++ b/apps/example-app/src/app/examples/09-router.spec.ts
@@ -4,6 +4,7 @@ import userEvent from '@testing-library/user-event';
import { DetailComponent, RootComponent, HiddenDetailComponent } from './09-router';
test('it can navigate to routes', async () => {
+ const user = userEvent.setup();
await render(RootComponent, {
declarations: [DetailComponent, HiddenDetailComponent],
routes: [
@@ -25,20 +26,20 @@ test('it can navigate to routes', async () => {
expect(screen.queryByText(/Detail one/i)).not.toBeInTheDocument();
- userEvent.click(screen.getByRole('link', { name: /load one/i }));
+ await user.click(screen.getByRole('link', { name: /load one/i }));
expect(await screen.findByRole('heading', { name: /Detail one/i })).toBeInTheDocument();
- userEvent.click(screen.getByRole('link', { name: /load three/i }));
+ await user.click(screen.getByRole('link', { name: /load three/i }));
expect(screen.queryByRole('heading', { name: /Detail one/i })).not.toBeInTheDocument();
expect(await screen.findByRole('heading', { name: /Detail three/i })).toBeInTheDocument();
- userEvent.click(screen.getByRole('link', { name: /back to parent/i }));
+ await user.click(screen.getByRole('link', { name: /back to parent/i }));
expect(screen.queryByRole('heading', { name: /Detail three/i })).not.toBeInTheDocument();
- userEvent.click(screen.getByRole('link', { name: /load two/i }));
+ await user.click(screen.getByRole('link', { name: /load two/i }));
expect(await screen.findByRole('heading', { name: /Detail two/i })).toBeInTheDocument();
- userEvent.click(screen.getByRole('link', { name: /hidden x/i }));
+ await user.click(screen.getByRole('link', { name: /hidden x/i }));
expect(await screen.findByText(/You found the treasure!/i)).toBeInTheDocument();
});
diff --git a/apps/example-app/src/app/examples/14-async-component.spec.ts b/apps/example-app/src/app/examples/14-async-component.spec.ts
index cdbc0d08..b54740a2 100644
--- a/apps/example-app/src/app/examples/14-async-component.spec.ts
+++ b/apps/example-app/src/app/examples/14-async-component.spec.ts
@@ -3,6 +3,7 @@ import { render, screen, fireEvent } from '@testing-library/angular';
import { AsyncComponent } from './14-async-component';
+// eslint-disable-next-line jest/no-disabled-tests
test.skip('can use fakeAsync utilities', fakeAsync(async () => {
await render(AsyncComponent);
@@ -20,6 +21,8 @@ test('can use fakeTimer utilities', async () => {
await render(AsyncComponent);
const load = await screen.findByRole('button', { name: /load/i });
+
+ // userEvent not working with fake timers
fireEvent.click(load);
jest.advanceTimersByTime(10_000);
diff --git a/apps/example-app/src/app/examples/15-dialog.component.spec.ts b/apps/example-app/src/app/examples/15-dialog.component.spec.ts
index 355b3904..1177f293 100644
--- a/apps/example-app/src/app/examples/15-dialog.component.spec.ts
+++ b/apps/example-app/src/app/examples/15-dialog.component.spec.ts
@@ -1,10 +1,12 @@
import { MatDialogModule, MatDialogRef } from '@angular/material/dialog';
-import { render, screen, fireEvent } from '@testing-library/angular';
+import { render, screen } from '@testing-library/angular';
import userEvent from '@testing-library/user-event';
import { DialogComponent, DialogContentComponent, DialogContentComponentModule } from './15-dialog.component';
test('dialog closes', async () => {
+ const user = userEvent.setup();
+
const closeFn = jest.fn();
await render(DialogContentComponent, {
imports: [MatDialogModule],
@@ -19,28 +21,28 @@ test('dialog closes', async () => {
});
const cancelButton = await screen.findByRole('button', { name: /cancel/i });
- userEvent.click(cancelButton);
+ await user.click(cancelButton);
expect(closeFn).toHaveBeenCalledTimes(1);
});
test('closes the dialog via the backdrop', async () => {
+ const user = userEvent.setup();
+
await render(DialogComponent, {
imports: [MatDialogModule, DialogContentComponentModule],
});
const openDialogButton = await screen.findByRole('button', { name: /open dialog/i });
- userEvent.click(openDialogButton);
+ await user.click(openDialogButton);
const dialogControl = await screen.findByRole('dialog');
expect(dialogControl).toBeInTheDocument();
const dialogTitleControl = await screen.findByRole('heading', { name: /dialog title/i });
expect(dialogTitleControl).toBeInTheDocument();
- // using fireEvent because of:
- // unable to click element as it has or inherits pointer-events set to "none"
- // eslint-disable-next-line testing-library/no-node-access, @typescript-eslint/no-non-null-assertion
- fireEvent.click(document.querySelector('.cdk-overlay-backdrop')!);
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion, testing-library/no-node-access
+ await user.click(document.querySelector('.cdk-overlay-backdrop')!);
expect(screen.queryByRole('dialog')).not.toBeInTheDocument();
@@ -49,12 +51,14 @@ test('closes the dialog via the backdrop', async () => {
});
test('opens and closes the dialog with buttons', async () => {
+ const user = userEvent.setup();
+
await render(DialogComponent, {
imports: [MatDialogModule, DialogContentComponentModule],
});
const openDialogButton = await screen.findByRole('button', { name: /open dialog/i });
- userEvent.click(openDialogButton);
+ await user.click(openDialogButton);
const dialogControl = await screen.findByRole('dialog');
expect(dialogControl).toBeInTheDocument();
@@ -62,7 +66,7 @@ test('opens and closes the dialog with buttons', async () => {
expect(dialogTitleControl).toBeInTheDocument();
const cancelButton = await screen.findByRole('button', { name: /cancel/i });
- userEvent.click(cancelButton);
+ await user.click(cancelButton);
expect(screen.queryByRole('dialog')).not.toBeInTheDocument();
diff --git a/apps/example-app/src/app/examples/20-test-harness.spec.ts b/apps/example-app/src/app/examples/20-test-harness.spec.ts
index b43f7f7f..5023f662 100644
--- a/apps/example-app/src/app/examples/20-test-harness.spec.ts
+++ b/apps/example-app/src/app/examples/20-test-harness.spec.ts
@@ -6,6 +6,7 @@ import user from '@testing-library/user-event';
import { SnackBarComponent } from './20-test-harness';
+// eslint-disable-next-line jest/no-disabled-tests
test.skip('can be used with TestHarness', async () => {
const view = await render(``, {
imports: [SnackBarComponent],
@@ -20,6 +21,7 @@ test.skip('can be used with TestHarness', async () => {
expect(await snackbarHarness.getMessage()).toMatch(/Pizza Party!!!/i);
});
+// eslint-disable-next-line jest/no-disabled-tests
test.skip('can be used in combination with TestHarness', async () => {
const view = await render(SnackBarComponent);
const loader = TestbedHarnessEnvironment.documentRootLoader(view.fixture);
diff --git a/apps/example-app/src/app/issues/issue-304.spec.ts b/apps/example-app/src/app/issues/issue-304.spec.ts
index d9bc355f..25d3b6f3 100644
--- a/apps/example-app/src/app/issues/issue-304.spec.ts
+++ b/apps/example-app/src/app/issues/issue-304.spec.ts
@@ -6,6 +6,8 @@ import { TestBed } from '@angular/core/testing';
// with goBackSpy, the implementation of goBack won't be invoked (because it's using the spy)
test('should call a goBack when user click in the button', async () => {
+ const user = userEvent.setup();
+
const goBackSpy = jest.fn();
await render(HeaderBackButtonComponent, {
declarations: [IconButtonComponent],
@@ -15,12 +17,14 @@ test('should call a goBack when user click in the button', async () => {
});
const button = screen.getByLabelText(/icon button/i);
- userEvent.click(button);
+ await user.click(button);
expect(goBackSpy).toHaveBeenCalled();
});
// don't spy on goBack, this way the implementation of goBack is invoked, and you can test if location.back() is called
test('should call a Location.back when user click in the button', async () => {
+ const user = userEvent.setup();
+
await render(HeaderBackButtonComponent, {
declarations: [IconButtonComponent],
});
@@ -29,7 +33,7 @@ test('should call a Location.back when user click in the button', async () => {
jest.spyOn(location, 'back');
const button = screen.getByLabelText(/icon button/i);
- userEvent.click(button);
+ await user.click(button);
expect(location.back).toHaveBeenCalled();
});
diff --git a/package.json b/package.json
index e8af8a6d..f9264f29 100644
--- a/package.json
+++ b/package.json
@@ -38,12 +38,12 @@
"@angular/platform-browser-dynamic": "16.0.0",
"@angular/router": "16.0.0",
"@ngrx/store": "16.0.0",
+ "@nx/angular": "16.1.4",
"@testing-library/dom": "^9.0.0",
"nx-cloud": "16.0.5",
"rxjs": "7.8.0",
"tslib": "~2.3.1",
- "zone.js": "0.13.0",
- "@nx/angular": "16.1.4"
+ "zone.js": "0.13.0"
},
"devDependencies": {
"@angular-devkit/build-angular": "16.0.0",
@@ -67,7 +67,7 @@
"@schematics/angular": "16.0.0",
"@testing-library/jasmine-dom": "^1.2.0",
"@testing-library/jest-dom": "^5.16.5",
- "@testing-library/user-event": "^13.5.0",
+ "@testing-library/user-event": "^14.4.3",
"@types/jasmine": "4.3.1",
"@types/jest": "29.5.1",
"@types/node": "20.1.4",
diff --git a/projects/testing-library/tests/integration.spec.ts b/projects/testing-library/tests/integration.spec.ts
index 112177e1..eedec0e9 100644
--- a/projects/testing-library/tests/integration.spec.ts
+++ b/projects/testing-library/tests/integration.spec.ts
@@ -1,9 +1,9 @@
import { Component, EventEmitter, Injectable, Input, Output } from '@angular/core';
import { TestBed } from '@angular/core/testing';
-import userEvent from '@testing-library/user-event';
import { of, BehaviorSubject } from 'rxjs';
import { debounceTime, switchMap, map, startWith } from 'rxjs/operators';
import { render, screen, waitFor, waitForElementToBeRemoved, within } from '../src/lib/testing-library';
+import userEvent from '@testing-library/user-event';
const DEBOUNCE_TIME = 1_000;
@@ -86,8 +86,9 @@ const entities = [
},
];
-test('renders the table', async () => {
+async function setup() {
jest.useFakeTimers();
+ const user = userEvent.setup();
await render(EntitiesComponent, {
declarations: [TableComponent],
@@ -106,29 +107,50 @@ test('renders the table', async () => {
},
],
});
+
const modalMock = TestBed.inject(ModalService);
+ return {
+ modalMock,
+ user,
+ };
+}
+
+test('renders the heading', async () => {
+ await setup();
+
expect(await screen.findByRole('heading', { name: /Entities Title/i })).toBeInTheDocument();
+});
+
+test('renders the entities', async () => {
+ await setup();
expect(await screen.findByRole('cell', { name: /Entity 1/i })).toBeInTheDocument();
expect(await screen.findByRole('cell', { name: /Entity 2/i })).toBeInTheDocument();
expect(await screen.findByRole('cell', { name: /Entity 3/i })).toBeInTheDocument();
+});
- userEvent.type(await screen.findByRole('textbox', { name: /Search entities/i }), 'Entity 2', {});
+test.skip('finds the cell', async () => {
+ const { user } = await setup();
+
+ await user.type(await screen.findByRole('textbox', { name: /Search entities/i }), 'Entity 2', {});
jest.advanceTimersByTime(DEBOUNCE_TIME);
await waitForElementToBeRemoved(() => screen.queryByRole('cell', { name: /Entity 1/i }));
expect(await screen.findByRole('cell', { name: /Entity 2/i })).toBeInTheDocument();
+});
- userEvent.click(await screen.findByRole('button', { name: /New Entity/i }));
+test.skip('opens the modal', async () => {
+ const { modalMock, user } = await setup();
+ await user.click(await screen.findByRole('button', { name: /New Entity/i }));
expect(modalMock.open).toHaveBeenCalledWith('new entity');
const row = await screen.findByRole('row', {
name: /Entity 2/i,
});
- userEvent.click(
+ await user.click(
await within(row).findByRole('button', {
name: /edit/i,
}),
diff --git a/projects/testing-library/tests/issues/issue-386.spec.ts b/projects/testing-library/tests/issues/issue-386.spec.ts
index a2a47865..b0c5613d 100644
--- a/projects/testing-library/tests/issues/issue-386.spec.ts
+++ b/projects/testing-library/tests/issues/issue-386.spec.ts
@@ -1,7 +1,6 @@
import { Component } from '@angular/core';
import { throwError } from 'rxjs';
-import userEvent from '@testing-library/user-event';
-import { render, screen } from '../../src/public_api';
+import { render, screen, fireEvent } from '../../src/public_api';
@Component({
selector: 'atl-fixture',
@@ -26,11 +25,11 @@ describe('TestComponent', () => {
it('does not fail', async () => {
await render(TestComponent);
- await userEvent.click(screen.getByText('Test'));
+ fireEvent.click(screen.getByText('Test'));
});
it('fails because of the previous one', async () => {
await render(TestComponent);
- await userEvent.click(screen.getByText('Test'));
+ fireEvent.click(screen.getByText('Test'));
});
});
diff --git a/projects/testing-library/tests/wait-for-element-to-be-removed.spec.ts b/projects/testing-library/tests/wait-for-element-to-be-removed.spec.ts
index 1f2f8eae..5c16a539 100644
--- a/projects/testing-library/tests/wait-for-element-to-be-removed.spec.ts
+++ b/projects/testing-library/tests/wait-for-element-to-be-removed.spec.ts
@@ -16,7 +16,7 @@ class FixtureComponent implements OnInit {
test('waits for element to be removed (callback)', async () => {
await render(FixtureComponent);
- await waitForElementToBeRemoved(() => screen.getByTestId('im-here'));
+ await waitForElementToBeRemoved(() => screen.queryByTestId('im-here'));
expect(screen.queryByTestId('im-here')).not.toBeInTheDocument();
});
@@ -24,7 +24,7 @@ test('waits for element to be removed (callback)', async () => {
test('waits for element to be removed (element)', async () => {
await render(FixtureComponent);
- await waitForElementToBeRemoved(screen.getByTestId('im-here'));
+ await waitForElementToBeRemoved(screen.queryByTestId('im-here'));
expect(screen.queryByTestId('im-here')).not.toBeInTheDocument();
});
@@ -32,7 +32,7 @@ test('waits for element to be removed (element)', async () => {
test('allows to override options', async () => {
await render(FixtureComponent);
- await expect(waitForElementToBeRemoved(() => screen.getByTestId('im-here'), { timeout: 200 })).rejects.toThrow(
+ await expect(waitForElementToBeRemoved(() => screen.queryByTestId('im-here'), { timeout: 200 })).rejects.toThrow(
/Timed out in waitForElementToBeRemoved/i,
);
});
diff --git a/projects/testing-library/tests/wait-for.spec.ts b/projects/testing-library/tests/wait-for.spec.ts
index e963b0c4..8c6562f0 100644
--- a/projects/testing-library/tests/wait-for.spec.ts
+++ b/projects/testing-library/tests/wait-for.spec.ts
@@ -1,6 +1,6 @@
import { Component } from '@angular/core';
import { timer } from 'rxjs';
-import { render, screen, fireEvent, waitFor } from '../src/public_api';
+import { render, screen, waitFor, fireEvent } from '../src/public_api';
@Component({
selector: 'atl-fixture',
@@ -24,8 +24,7 @@ test('waits for assertion to become true', async () => {
fireEvent.click(screen.getByTestId('button'));
- await screen.findByText('Success');
- expect(screen.getByText('Success')).toBeInTheDocument();
+ expect(await screen.findByText('Success')).toBeInTheDocument();
});
test('allows to override options', async () => {