diff --git a/src/__internal__/fieldset/fieldset.spec.tsx b/src/__internal__/fieldset/fieldset.spec.tsx
deleted file mode 100644
index 0141cf654f..0000000000
--- a/src/__internal__/fieldset/fieldset.spec.tsx
+++ /dev/null
@@ -1,225 +0,0 @@
-import React from "react";
-import { mount, ReactWrapper } from "enzyme";
-import Fieldset, { FieldsetProps } from "./fieldset.component";
-
-import {
- StyledFieldset,
- StyledLegend,
- StyledLegendContent,
-} from "./fieldset.style";
-import {
- assertStyleMatch,
- testStyledSystemMargin,
-} from "../../__spec_helper__/__internal__/test-utils";
-
-import ValidationIcon from "../validations/validation-icon.component";
-
-const Component = () =>
;
-const RenderComponent = (props?: Partial) => (
-
-);
-
-const render = (props?: Partial) =>
- mount();
-
-const validationTypes = ["error", "warning", "info"] as const;
-
-describe("Fieldset", () => {
- let wrapper: ReactWrapper;
-
- testStyledSystemMargin((props) => );
-
- // added as `testStyledSystemMargin` will not catch if there is a regression and refactoring that will affect all tests that use it
- it.each([
- [undefined, { margin: 0 }],
- [{ m: 8 }, { margin: "var(--spacing800)" }],
- [
- { mx: 8 },
- { marginLeft: "var(--spacing800)", marginRight: "var(--spacing800)" },
- ],
- [
- { my: 8 },
- { marginTop: "var(--spacing800)", marginBottom: "var(--spacing800)" },
- ],
- [
- { mt: 8, mr: 8, mb: 8, ml: 8 },
- {
- marginTop: "var(--spacing800)",
- marginBottom: "var(--spacing800)",
- marginLeft: "var(--spacing800)",
- marginRight: "var(--spacing800)",
- },
- ],
- ])(
- "has the expected margin when %s passed as margin props",
- (props, style) => {
- wrapper = render({ legend: "Legend", ...props });
- expect(wrapper.getDOMNode()).toHaveStyle(style);
- }
- );
-
- it("renders passed on children", () => {
- wrapper = render();
- expect(wrapper.find(Component).exists()).toBe(true);
- });
-
- describe("when ml prop set", () => {
- it("should apply the correct left margin", () => {
- wrapper = render({ ml: "10%" });
- assertStyleMatch(
- {
- marginLeft: "10%",
- },
- wrapper.find(StyledFieldset)
- );
- });
- });
-
- describe("when mb prop set", () => {
- it("should apply the correct bottom margin", () => {
- wrapper = render({ mb: 2 });
- assertStyleMatch(
- {
- marginBottom: "var(--spacing200)",
- },
- wrapper.find(StyledFieldset)
- );
- });
- });
-
- describe("Fieldset Legend", () => {
- it("is rendered if supplied", () => {
- wrapper = render({ legend: "Legend" });
- expect(wrapper.find(StyledLegend).exists()).toEqual(true);
- });
-
- it("is not rendered if omitted", () => {
- wrapper = render();
- expect(wrapper.find(StyledLegend).exists()).toEqual(false);
- });
-
- describe("when inline", () => {
- it("applies the correct default styles", () => {
- wrapper = render({ inline: true, legend: "Legend" });
- assertStyleMatch(
- {
- boxSizing: "border-box",
- margin: "0",
- justifyContent: "flex-end",
- paddingRight: "var(--spacing200)",
- },
- wrapper.find(StyledLegend)
- );
- });
-
- it("applies the correct width when legendWidth prop set", () => {
- wrapper = render({ inline: true, legend: "Legend", legendWidth: 10 });
- assertStyleMatch(
- {
- width: "10%",
- },
- wrapper.find(StyledLegend)
- );
- });
-
- it("aligns the content right when legendAlign prop set", () => {
- wrapper = render({
- inline: true,
- legend: "Legend",
- legendAlign: "right",
- });
- assertStyleMatch(
- {
- justifyContent: "flex-end",
- },
- wrapper.find(StyledLegend)
- );
- });
-
- it("applies the correct right padding when legendSpacing prop set", () => {
- wrapper = render({ inline: true, legend: "Legend", legendSpacing: 1 });
- assertStyleMatch(
- {
- paddingRight: "var(--spacing100)",
- },
- wrapper.find(StyledLegend)
- );
- });
-
- describe('when legendAlign set to "left"', () => {
- it("should apply the correct justifyContent style", () => {
- wrapper = render({
- inline: true,
- legend: "Legend",
- legendAlign: "left",
- });
- assertStyleMatch(
- {
- justifyContent: "flex-start",
- },
- wrapper.find(StyledLegend)
- );
- });
- });
- });
- });
-
- describe.each(validationTypes)(
- "when prop %s === string",
- (validationType) => {
- it("shows validation icon with proper type", () => {
- wrapper = render({ legend: "Legend", [validationType]: "Message" });
- const icon = wrapper.find(ValidationIcon);
-
- expect(icon.props()[validationType]).toEqual("Message");
- });
- }
- );
-
- it("add an asterisk after the text when the field is mandatory", () => {
- assertStyleMatch(
- {
- content: '"*"',
- color: "var(--colorsSemanticNegative500)",
- fontWeight: "var(--fontWeights700)",
- marginLeft: "var(--spacing050)",
- },
- mount(),
- { modifier: "::after" }
- );
- });
-
- it("adds the required attribute to any child inputs when isRequired is true", () => {
- wrapper = mount(
-
- );
-
- expect(wrapper.find("input").first().getDOMNode()).toHaveAttribute(
- "required"
- );
- expect(wrapper.find("input").last().getDOMNode()).toHaveAttribute(
- "required"
- );
- });
-
- it("does not add the required attribute to any child inputs when isRequired is falsy", () => {
- wrapper = mount(
-
- );
-
- expect(wrapper.find("input").first().getDOMNode()).not.toHaveAttribute(
- "required"
- );
- expect(wrapper.find("input").last().getDOMNode()).not.toHaveAttribute(
- "required"
- );
- });
-});
diff --git a/src/__internal__/fieldset/fieldset.test.tsx b/src/__internal__/fieldset/fieldset.test.tsx
new file mode 100644
index 0000000000..9ae5c454f6
--- /dev/null
+++ b/src/__internal__/fieldset/fieldset.test.tsx
@@ -0,0 +1,123 @@
+import React from "react";
+import { render, screen, within } from "@testing-library/react";
+import Fieldset from ".";
+import { testStyledSystemMargin } from "../../__spec_helper__/__internal__/test-utils";
+
+test("renders with provided `children`", () => {
+ render(
+
+ );
+
+ const input = within(screen.getByRole("group")).getByRole("textbox");
+
+ expect(input).toBeVisible();
+});
+
+test("renders fieldset with provided `legend`", () => {
+ render(
+
+ );
+
+ const fieldset = screen.getByRole("group", { name: "Legend" });
+
+ expect(fieldset).toBeVisible();
+});
+
+test("sets child inputs as required when `isRequired` is true", () => {
+ render(
+
+ );
+
+ const inputs = screen.getAllByRole("textbox");
+
+ expect(inputs[0]).toBeRequired();
+ expect(inputs[1]).toBeRequired();
+});
+
+test("renders validation icon when `legend` and `error` are provided", () => {
+ render(
+
+ );
+
+ const icon = screen.getByTestId("icon-error");
+
+ expect(icon).toBeVisible();
+});
+
+test("renders validation icon when `legend` and `warning` are provided", () => {
+ render(
+
+ );
+
+ const icon = screen.getByTestId("icon-warning");
+
+ expect(icon).toBeVisible();
+});
+
+test("renders validation icon when `legend` and `info` are provided", () => {
+ render(
+
+ );
+
+ const icon = screen.getByTestId("icon-info");
+
+ expect(icon).toBeVisible();
+});
+
+// coverage
+test("renders legend with provided `legendWidth` when `inline` is true", () => {
+ render(
+
+ );
+
+ const legend = screen.getByTestId("legend");
+
+ expect(legend).toHaveStyle({ width: "30%" });
+});
+
+// coverage
+test("renders with expected styles when `inline` is true and `align` is 'left'", () => {
+ render(
+
+ );
+
+ const legend = screen.getByTestId("legend");
+
+ expect(legend).toHaveStyle({ justifyContent: "flex-start" });
+});
+
+// coverage
+test("renders with expected padding when `inline` is true and `legendSpacing` is 1", () => {
+ render(
+
+ );
+
+ const legend = screen.getByTestId("legend");
+
+ expect(legend).toHaveStyleRule("padding-right", "var(--spacing100)");
+});
+
+testStyledSystemMargin((props) => (
+
+));
diff --git a/src/__internal__/form-field/form-field.component.tsx b/src/__internal__/form-field/form-field.component.tsx
index 73395294f9..ec1ca13c48 100644
--- a/src/__internal__/form-field/form-field.component.tsx
+++ b/src/__internal__/form-field/form-field.component.tsx
@@ -182,7 +182,7 @@ const FormField = ({
return (
-
+
{reverse && children}
{label && (
diff --git a/src/__internal__/form-field/form-field.spec.tsx b/src/__internal__/form-field/form-field.spec.tsx
deleted file mode 100644
index e5a34d008b..0000000000
--- a/src/__internal__/form-field/form-field.spec.tsx
+++ /dev/null
@@ -1,283 +0,0 @@
-import React from "react";
-import { mount } from "enzyme";
-import FormField, { FormFieldProps } from "./form-field.component";
-import FieldHelp from "../field-help";
-import { FieldLineStyle } from "./form-field.style";
-import Label from "../label";
-import TabContext from "../../components/tabs/tab/__internal__/tab.context";
-import {
- assertStyleMatch,
- mockMatchMedia,
-} from "../../__spec_helper__/__internal__/test-utils";
-
-const setError = jest.fn();
-const setWarning = jest.fn();
-const setInfo = jest.fn();
-
-function render(formFieldProps: FormFieldProps) {
- return mount(
-
-
-
- );
-}
-
-function renderWithTabContext(formFieldProps: FormFieldProps) {
- return mount(
-
-
-
-
-
- );
-}
-
-describe("FormField", () => {
- it("with the mb prop set, correct bottom margin should be set", () => {
- const wrapper = render({ id: "mock-input", mb: 5 });
-
- assertStyleMatch(
- {
- marginBottom: "var(--spacing500)",
- },
- wrapper.find(FormField),
- { modifier: "&&&" }
- );
- });
-
- describe("with a label", () => {
- it("renders label alongside children", () => {
- const wrapper = render({
- id: "mock-input",
- label: "Name",
- labelAlign: "left",
- labelWidth: 20,
- });
-
- expect(wrapper.find("label[data-element='label']").exists()).toBe(true);
- expect(wrapper.find("input").exists()).toBe(true);
- });
-
- it.each([
- [false, "block"],
- [true, "flex"],
- ])(
- "when labelInline prop is %s, make container of input and label a %s container",
- (labelInline, display) => {
- const wrapper = render({
- id: "mock-input",
- label: "Name",
- labelInline,
- labelAlign: "left",
- labelWidth: 20,
- });
-
- assertStyleMatch(
- {
- display,
- },
- wrapper.find(FieldLineStyle)
- );
- }
- );
-
- it("renders label with htmlFor prop that is the id of the input", () => {
- const id = "foo";
- const wrapper = render({
- id,
- label: "Name",
- });
- expect(wrapper.find(`input[id='${id}']`).exists()).toBe(true);
- expect(wrapper.find(`label[htmlFor='${id}']`).exists()).toBe(true);
- });
-
- it("passes the tooltipId to the Label id prop", () => {
- const tooltipId = "test-help-id";
- expect(
- render({ id: "mock-input", tooltipId, label: "test label" })
- .find(Label)
- .prop("tooltipId")
- ).toBe(tooltipId);
- });
-
- describe("when validationRedesignOptIn is true", () => {
- it("does not set the validation props on the Label", () => {
- const wrapper = render({
- id: "mock-input",
- label: "test label",
- error: true,
- warning: true,
- info: true,
- validationRedesignOptIn: true,
- });
- const { error, warning, info } = wrapper.find(Label).props();
-
- expect(error).toEqual(false);
- expect(warning).toEqual(false);
- expect(info).toEqual(false);
- });
- });
-
- describe("when adaptiveLabelBreakpoint prop is set", () => {
- describe("when screen bigger than breakpoint", () => {
- beforeEach(() => {
- mockMatchMedia(true);
- });
-
- it("should pass labelInline to its children", () => {
- const wrapper = render({
- id: "mock-input",
- label: "Name",
- labelInline: true,
- fieldHelp: "Help",
- adaptiveLabelBreakpoint: 1000,
- });
-
- expect(wrapper.find(FieldLineStyle).props().inline).toEqual(true);
- expect(wrapper.find(Label).props().inline).toEqual(true);
- expect(wrapper.find(FieldHelp).props().labelInline).toEqual(true);
- });
- });
-
- describe("when screen smaller than breakpoint", () => {
- beforeEach(() => {
- mockMatchMedia(false);
- });
-
- it("should pass labelInline to its children", () => {
- const wrapper = render({
- id: "mock-input",
- label: "Name",
- labelInline: true,
- fieldHelp: "Help",
- adaptiveLabelBreakpoint: 1000,
- });
-
- expect(wrapper.find(FieldLineStyle).props().inline).toEqual(false);
- expect(wrapper.find(Label).props().inline).toEqual(false);
- expect(wrapper.find(FieldHelp).props().labelInline).toEqual(false);
- });
- });
- });
- });
-
- describe("with fieldHelp", () => {
- const fieldHelpId = "mock-id";
- const fieldHelp = "Help me!";
-
- it("renders field help element with correct id", () => {
- const wrapper = render({
- id: "mock-input",
- fieldHelpId,
- fieldHelp,
- labelWidth: 20,
- });
- expect(wrapper.find(`[id='${fieldHelpId}']`).exists()).toBe(true);
- });
-
- it("when fieldHelpInline and labelInline props are true, field help is rendered inline with input", () => {
- const wrapper = render({
- id: "mock-input",
- fieldHelpId,
- fieldHelp,
- labelWidth: 20,
- fieldHelpInline: true,
- labelInline: true,
- });
- assertStyleMatch({ display: "flex" }, wrapper.find(FieldLineStyle));
- expect(wrapper.find(FieldLineStyle).find(FieldHelp).exists()).toBe(true);
- });
-
- it("when fieldHelpInline prop is false and labelInline is true, field help is not rendered inline with input", () => {
- const wrapper = render({
- id: "mock-input",
- fieldHelpId,
- fieldHelp,
- labelWidth: 20,
- fieldHelpInline: false,
- labelInline: true,
- });
- assertStyleMatch({ display: "flex" }, wrapper.find(FieldLineStyle));
- expect(wrapper.find(FieldLineStyle).find(FieldHelp).exists()).toBe(false);
- });
- });
-
- describe("invariant", () => {
- it("should throw when isOptional and isRequired props are both true", () => {
- const consoleSpy = jest.spyOn(console, "error").mockImplementation();
-
- expect(() => {
- render({
- id: "mock-input",
- isOptional: true,
- isRequired: true,
- });
- }).toThrow(
- "an input cannot be set to both required and optional at the same time"
- );
-
- consoleSpy.mockRestore();
- });
-
- it("should not throw when isRequired prop is true and isOptional is false", () => {
- expect(() => {
- render({
- id: "mock-input",
- isRequired: true,
- isOptional: false,
- });
- }).not.toThrow();
- });
-
- it("should not throw when isOptional prop is true and isRequired is false", () => {
- expect(() => {
- render({
- id: "mock-input",
- isRequired: false,
- isOptional: true,
- });
- }).not.toThrow();
- });
- });
-
- describe("with TabContext", () => {
- it('calls "setError" when has "error" is true', () => {
- renderWithTabContext({ id: "foo", error: true });
- expect(setError).toHaveBeenCalledWith("foo", true);
- });
-
- it('calls "setWarning" when has "warning" is true', () => {
- renderWithTabContext({ id: "foo", warning: true });
- expect(setWarning).toHaveBeenCalledWith("foo", true);
- });
-
- it('calls "setInfo" when has "info" is true', () => {
- renderWithTabContext({ id: "foo", info: true });
- expect(setInfo).toHaveBeenCalledWith("foo", true);
- });
- });
-
- it.each(["error", "warning", "info"])(
- "validates the %s prop to throw an error if disabled is set as well",
- (validation) => {
- // Even though error is caught, it is still printed to console so mock console.error
- // to avoid this. See https://github.com/facebook/jest/issues/5785 for details
- const consoleSpy = jest.spyOn(console, "error");
- consoleSpy.mockImplementation(() => {});
-
- const error =
- `Prop \`${validation}\` cannot be used in conjunction with \`disabled\`. ` +
- "Use `readOnly` if you require users to see validations with a non-interactive field";
-
- expect(() =>
- renderWithTabContext({
- id: "mock-input",
- disabled: true,
- [validation]: true,
- })
- ).toThrow(error);
-
- consoleSpy.mockRestore();
- }
- );
-});
diff --git a/src/__internal__/form-field/form-field.test.tsx b/src/__internal__/form-field/form-field.test.tsx
new file mode 100644
index 0000000000..fee5240554
--- /dev/null
+++ b/src/__internal__/form-field/form-field.test.tsx
@@ -0,0 +1,129 @@
+import React from "react";
+import { render, screen } from "@testing-library/react";
+import FormField from ".";
+import TabContext from "../../components/tabs/tab/__internal__/tab.context";
+import { mockMatchMedia } from "../../__spec_helper__/__internal__/test-utils";
+
+test("throws a console error when `isOptional` and `isRequired` are both true", () => {
+ const consoleSpy = jest.spyOn(console, "error").mockImplementation(() => {});
+
+ expect(() => {
+ render();
+ }).toThrow(
+ "an input cannot be set to both required and optional at the same time"
+ );
+
+ consoleSpy.mockRestore();
+});
+
+test("does not throw a console error when `isRequired` is true and `isOptional` is false", () => {
+ expect(() => {
+ render();
+ }).not.toThrow();
+});
+
+test("does not throw a console error when `isOptional` is true and `isRequired` is false", () => {
+ expect(() => {
+ render();
+ }).not.toThrow();
+});
+
+test("throws a console error when `error` and `disabled` are both true", () => {
+ const consoleSpy = jest.spyOn(console, "error").mockImplementation(() => {});
+
+ expect(() => {
+ render();
+ }).toThrow(
+ `Prop \`error\` cannot be used in conjunction with \`disabled\`. ` +
+ "Use `readOnly` if you require users to see validations with a non-interactive field"
+ );
+
+ consoleSpy.mockRestore();
+});
+
+test("throws a console error when `warning` and `disabled` are both true", () => {
+ const consoleSpy = jest.spyOn(console, "error").mockImplementation(() => {});
+
+ expect(() => {
+ render();
+ }).toThrow(
+ `Prop \`warning\` cannot be used in conjunction with \`disabled\`. ` +
+ "Use `readOnly` if you require users to see validations with a non-interactive field"
+ );
+
+ consoleSpy.mockRestore();
+});
+
+test("throws a console error when `info` and `disabled` are both true", () => {
+ const consoleSpy = jest.spyOn(console, "error").mockImplementation(() => {});
+
+ expect(() => {
+ render();
+ }).toThrow(
+ `Prop \`info\` cannot be used in conjunction with \`disabled\`. ` +
+ "Use `readOnly` if you require users to see validations with a non-interactive field"
+ );
+
+ consoleSpy.mockRestore();
+});
+
+test("calls `setError` passed from `TabContext` when `error` is true", () => {
+ const setError = jest.fn();
+ render(
+
+
+
+ );
+
+ expect(setError).toHaveBeenCalledWith("foo", true);
+});
+
+test("calls `setWarning` passed from `TabContext` when `warning` is true", () => {
+ const setWarning = jest.fn();
+ render(
+
+
+
+ );
+
+ expect(setWarning).toHaveBeenCalledWith("foo", true);
+});
+
+test("calls `setInfo` passed from `TabContext` when `info` is true", () => {
+ const setInfo = jest.fn();
+ render(
+
+
+
+ );
+
+ expect(setInfo).toHaveBeenCalledWith("foo", true);
+});
+
+test("should not render with `labelInline` when `adaptiveLabelBreakpoint` set and screen is smaller than the breakpoint", () => {
+ mockMatchMedia(false);
+ render(
+
+ );
+
+ expect(screen.getByTestId("field-line")).toHaveStyle("display: block");
+});
+
+test("should render with `labelInline` when `adaptiveLabelBreakpoint` set and screen is bigger than the breakpoint", () => {
+ mockMatchMedia(true);
+ render(
+
+ );
+
+ expect(screen.getByTestId("field-line")).toHaveStyle("display: flex");
+});
diff --git a/src/__internal__/label/label.test.tsx b/src/__internal__/label/label.test.tsx
index 704e3198fa..2b6360d47e 100644
--- a/src/__internal__/label/label.test.tsx
+++ b/src/__internal__/label/label.test.tsx
@@ -155,3 +155,16 @@ test.each(["error", "warning", "info"])(
);
}
);
+
+// coverage
+test("renders with expected styles when `inline` is true and `align` is 'left'", () => {
+ render(
+
+ );
+
+ expect(screen.getByTestId("label-container")).toHaveStyle({
+ justifyContent: "flex-start",
+ });
+});