diff --git a/test/ToastBodySpec.js b/test/ToastBodySpec.js
deleted file mode 100644
index aac145741f..0000000000
--- a/test/ToastBodySpec.js
+++ /dev/null
@@ -1,12 +0,0 @@
-import { mount } from 'enzyme';
-
-import Toast from '../src/Toast';
-
-describe('Toast.Body', () => {
- it('will pass all props to the created div and renders its children', () => {
- const content = Content;
- mount(
- {content},
- ).assertSingle('div.custom-class.toast-body>strong');
- });
-});
diff --git a/test/ToastBodySpec.tsx b/test/ToastBodySpec.tsx
new file mode 100644
index 0000000000..a5b3d01fbf
--- /dev/null
+++ b/test/ToastBodySpec.tsx
@@ -0,0 +1,16 @@
+import * as React from 'react';
+import { render } from '@testing-library/react';
+import Toast from '../src/Toast';
+
+describe('Toast.Body', () => {
+ it('will pass all props to the created div and renders its children', () => {
+ const content = Content;
+ const { container } = render(
+ {content},
+ );
+ container.firstElementChild!.classList.contains('custom-class').should.be
+ .true;
+ container.firstElementChild!.classList.contains('toast-body').should.be
+ .true;
+ });
+});
diff --git a/test/ToastContainerSpec.js b/test/ToastContainerSpec.js
deleted file mode 100644
index 6a199c424a..0000000000
--- a/test/ToastContainerSpec.js
+++ /dev/null
@@ -1,29 +0,0 @@
-import { mount } from 'enzyme';
-
-import ToastContainer from '../src/ToastContainer';
-
-const expectedClasses = {
- 'top-start': '.position-absolute.top-0.start-0',
- 'top-center': '.position-absolute.top-0.start-50.translate-middle-x',
- 'top-end': '.position-absolute.top-0.end-0',
- 'middle-start': '.position-absolute.top-50.start-0.translate-middle-y',
- 'middle-center': '.position-absolute.top-50.start-50.translate-middle',
- 'middle-end': '.position-absolute.top-50.end-0.translate-middle-y',
- 'bottom-start': '.position-absolute.bottom-0.start-0',
- 'bottom-center': '.position-absolute.bottom-0.start-50.translate-middle-x',
- 'bottom-end': '.position-absolute.bottom-0.end-0',
-};
-
-describe('ToastContainer', () => {
- it('should render a basic toast container', () => {
- mount().assertSingle('.toast-container');
- });
-
- Object.keys(expectedClasses).forEach((position) => {
- it(`should render position=${position}`, () => {
- mount().assertSingle(
- expectedClasses[position],
- );
- });
- });
-});
diff --git a/test/ToastContainerSpec.tsx b/test/ToastContainerSpec.tsx
new file mode 100644
index 0000000000..670b144afd
--- /dev/null
+++ b/test/ToastContainerSpec.tsx
@@ -0,0 +1,53 @@
+import { render } from '@testing-library/react';
+import ToastContainer, { ToastPosition } from '../src/ToastContainer';
+
+const expectedClasses: Record> = {
+ 'top-start': ['position-absolute', 'top-0', 'start-0'],
+ 'top-center': [
+ 'position-absolute',
+ 'top-0',
+ 'start-50',
+ 'translate-middle-x',
+ ],
+ 'top-end': ['position-absolute', 'top-0', 'end-0'],
+ 'middle-start': [
+ 'position-absolute',
+ 'top-50',
+ 'start-0',
+ 'translate-middle-y',
+ ],
+ 'middle-center': [
+ 'position-absolute',
+ 'top-50',
+ 'start-50',
+ 'translate-middle',
+ ],
+ 'middle-end': ['position-absolute', 'top-50', 'end-0', 'translate-middle-y'],
+ 'bottom-start': ['position-absolute', 'bottom-0', 'start-0'],
+ 'bottom-center': [
+ 'position-absolute',
+ 'bottom-0',
+ 'start-50',
+ 'translate-middle-x',
+ ],
+ 'bottom-end': ['position-absolute', 'bottom-0', 'end-0'],
+};
+
+describe('ToastContainer', () => {
+ it('should render a basic toast container', () => {
+ const { container } = render();
+ container.firstElementChild!.classList.contains('toast-container').should.be
+ .true;
+ });
+
+ Object.keys(expectedClasses).forEach((position: ToastPosition) => {
+ it(`should render position=${position}`, () => {
+ const { container } = render();
+ expectedClasses[position].map(
+ (className) =>
+ container.firstElementChild!.classList.contains(className).should.be
+ .true,
+ );
+ });
+ });
+});
diff --git a/test/ToastHeaderSpec.js b/test/ToastHeaderSpec.js
deleted file mode 100644
index 0153a6556b..0000000000
--- a/test/ToastHeaderSpec.js
+++ /dev/null
@@ -1,25 +0,0 @@
-import { mount } from 'enzyme';
-
-import Toast from '../src/Toast';
-
-describe('Toast.Header', () => {
- it('will pass all props to the created div and renders its children', () => {
- mount(
-
- content
- ,
- ).assertSingle('div.toast-header strong');
- });
-
- it('should render close button variant', () => {
- const wrapper = mount(
-
- content
- ,
- );
- expect(wrapper.find('CloseButton').props()).to.have.property(
- 'variant',
- 'white',
- );
- });
-});
diff --git a/test/ToastHeaderSpec.tsx b/test/ToastHeaderSpec.tsx
new file mode 100644
index 0000000000..b6daed682e
--- /dev/null
+++ b/test/ToastHeaderSpec.tsx
@@ -0,0 +1,28 @@
+import { render } from '@testing-library/react';
+
+import Toast from '../src/Toast';
+
+describe('Toast.Header', () => {
+ it('will pass all props to the created div and renders its children', () => {
+ const { container } = render(
+
+ content
+ ,
+ );
+ container.firstElementChild!.tagName === 'div';
+ container.firstElementChild!.firstElementChild!.tagName === 'strong';
+ container.firstElementChild!.classList.contains('toast-header').should.be
+ .true;
+ });
+
+ it('should render close button variant', () => {
+ const { container } = render(
+
+ content
+ ,
+ );
+ container
+ .firstElementChild!.getElementsByTagName('button')[0]
+ .classList.contains('btn-close-white').should.be.true;
+ });
+});
diff --git a/test/ToastSpec.js b/test/ToastSpec.tsx
similarity index 60%
rename from test/ToastSpec.js
rename to test/ToastSpec.tsx
index 96035eee44..d491917d4c 100644
--- a/test/ToastSpec.js
+++ b/test/ToastSpec.tsx
@@ -1,7 +1,20 @@
-import { mount } from 'enzyme';
+import { fireEvent, render } from '@testing-library/react';
+import sinon from 'sinon';
import Toast from '../src/Toast';
+const getToast = ({
+ delay = 500,
+ onCloseSpy,
+ autohide = true,
+ show = true,
+}) => (
+
+ header-content
+ body-content
+
+);
+
describe('', () => {
let clock;
@@ -14,51 +27,66 @@ describe('', () => {
});
it('should apply bg prop', () => {
- mount(Card).assertSingle('.toast.bg-primary');
+ const { container } = render(Card);
+ container.firstElementChild!.classList.contains('bg-primary').should.be
+ .true;
+ container.firstElementChild!.classList.contains('toast').should.be.true;
});
it('should render an entire toast', () => {
- mount(
+ const { container } = render(
,
- ).assertSingle(
- 'div.toast[className="fade toast show"][role="alert"][aria-live="assertive"][aria-atomic="true"]',
+ );
+ ['fade', 'toast', 'show'].map((className) =>
+ container.firstElementChild!.classList.contains(className),
+ );
+ (
+ [
+ ['role', 'alert'],
+ ['aria-live', 'assertive'],
+ ['aria-atomic', true],
+ ] as const
+ ).map(
+ ([attrName, attrVal]) =>
+ container.firstElementChild!.attributes.getNamedItem(attrName)!
+ .textContent === attrVal,
);
});
it('should render without transition if animation is false', () => {
- mount(
+ const { container } = render(
,
- ).assertSingle(
- 'div.toast[className="toast show"][role="alert"][aria-live="assertive"][aria-atomic="true"]',
+ );
+
+ ['toast', 'show'].map((className) =>
+ container.firstElementChild!.classList.contains(className),
);
});
it('should trigger the onClose event after clicking on the close button', () => {
const onCloseSpy = sinon.spy();
- mount(
+ const { container } = render(
header-content
body-content
,
- )
- .find('.toast-header')
- .at(0)
- .find('button')
- .simulate('click');
-
+ );
+ fireEvent.click(
+ container.firstElementChild!.getElementsByTagName('button')[0],
+ );
expect(onCloseSpy).to.have.been.calledOnce;
});
it('should trigger the onClose event after the autohide delay', () => {
const onCloseSpy = sinon.spy();
- mount(
+ render(
header-content
body-content
@@ -70,7 +98,7 @@ describe('', () => {
it('should not trigger the onClose event if autohide is not set', () => {
const onCloseSpy = sinon.spy();
- mount(
+ render(
header-content
body-content
@@ -82,30 +110,26 @@ describe('', () => {
it('should clearTimeout after unmount', () => {
const onCloseSpy = sinon.spy();
- const wrapper = mount(
+ const { unmount } = render(
header-content
body-content
,
);
- wrapper.unmount();
+ unmount();
clock.tick(1000);
expect(onCloseSpy).not.to.have.been.called;
});
it('should not reset autohide timer when element re-renders with same props', () => {
const onCloseSpy = sinon.spy();
- const wrapper = mount(
-
- header-content
- body-content
- ,
- );
+ const toast = getToast({ onCloseSpy });
+ const { rerender } = render(toast);
clock.tick(250);
// Trigger render with no props changes.
- wrapper.setProps({});
+ rerender(toast);
clock.tick(300);
expect(onCloseSpy).to.have.been.calledOnce;
@@ -113,16 +137,11 @@ describe('', () => {
it('should not reset autohide timer when delay is changed', () => {
const onCloseSpy = sinon.spy();
- const wrapper = mount(
-
- header-content
- body-content
- ,
- );
+ const { rerender } = render(getToast({ delay: 500, onCloseSpy }));
clock.tick(250);
- wrapper.setProps({ delay: 10000 });
+ rerender(getToast({ delay: 10000, onCloseSpy }));
clock.tick(300);
expect(onCloseSpy).to.have.been.calledOnce;
@@ -131,16 +150,12 @@ describe('', () => {
it('should not reset autohide timer when onClosed is changed', () => {
const onCloseSpy = sinon.spy();
const onCloseSpy2 = sinon.spy();
- const wrapper = mount(
-
- header-content
- body-content
- ,
- );
+
+ const { rerender } = render(getToast({ onCloseSpy }));
clock.tick(250);
- wrapper.setProps({ onClose: onCloseSpy2 });
+ rerender(getToast({ onCloseSpy: onCloseSpy2 }));
clock.tick(300);
expect(onCloseSpy).not.to.have.been.called;
@@ -149,16 +164,11 @@ describe('', () => {
it('should not call onClose if autohide is changed from true to false', () => {
const onCloseSpy = sinon.spy();
- const wrapper = mount(
-
- header-content
- body-content
- ,
- );
+ const { rerender } = render(getToast({ onCloseSpy, autohide: true }));
clock.tick(250);
- wrapper.setProps({ autohide: false });
+ rerender(getToast({ onCloseSpy, autohide: false }));
clock.tick(300);
expect(onCloseSpy).not.to.have.been.called;
@@ -166,27 +176,23 @@ describe('', () => {
it('should not call onClose if show is changed from true to false', () => {
const onCloseSpy = sinon.spy();
- const wrapper = mount(
-
- header-content
- body-content
- ,
- );
-
- clock.tick(250);
+ const { rerender } = render(getToast({ show: true, onCloseSpy }));
+ clock.tick(100);
- wrapper.setProps({ show: false });
+ rerender(getToast({ show: false, onCloseSpy }));
clock.tick(300);
expect(onCloseSpy).not.to.have.been.called;
});
it('should render with bsPrefix', () => {
- mount(
+ const { container } = render(
,
- ).assertSingle('div.my-toast');
+ );
+ container.firstElementChild!.tagName === 'div';
+ container.firstElementChild!.classList.contains('my-toast');
});
});