Skip to content

Commit

Permalink
test(add another): add tests for add another component (#1081)
Browse files Browse the repository at this point in the history
  • Loading branch information
chrispymm authored Jan 15, 2025
1 parent 2d3796e commit 78113c7
Show file tree
Hide file tree
Showing 2 changed files with 165 additions and 1 deletion.
2 changes: 1 addition & 1 deletion src/moj/components/add-another/add-another.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,5 +79,5 @@ MOJFrontend.AddAnother.prototype.onRemoveButtonClick = function(e) {
};

MOJFrontend.AddAnother.prototype.focusHeading = function() {
this.container.find('.moj-add-another__heading').focus();
this.container.find('.moj-add-another__heading').get(0).focus();
};
164 changes: 164 additions & 0 deletions src/moj/components/add-another/add-another.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
const {
getByLabelText,
getByRole,
queryByRole,
} = require("@testing-library/dom");
const { userEvent } = require("@testing-library/user-event");

require("./add-another.js");

const user = userEvent.setup();

const createComponent = () => {
const html = `
<div data-module="moj-add-another">
<h2 class="govuk-heading-l moj-add-another__heading" tabindex="-1">Add a person</h2>
<form>
<fieldset class="govuk-fieldset moj-add-another__item">
<legend>Person</legend>
<div class="govuk-form-group">
<label for="person[0][first_name]">First name</label>
<input class="govuk-input" id="person[0][first_name]" name="person[0][first_name]" type="text" data-name="person[%index%][first_name]" data-id="person[%index%][first_name]">
</div>
<div class="govuk-form-group">
<label for="person[0][last_name]">Last name</label>
<input class="govuk-input" id="person[0][last_name]" name="person[0][last_name]" type="text" data-name="person[%index%][last_name]" data-id="person[%index%][last_name]">
</div>
</fieldset>
<button type="button" class="govuk-button moj-add-another__add-button">Add another person</button>
</form>
</div>`;
document.body.innerHTML = html;
const component = document.querySelector('[data-module="moj-add-another"]');
return component;
};

describe("Add Another component", () => {
let component;
let addButton;

beforeEach(() => {
component = createComponent();
new MOJFrontend.AddAnother(component);
addButton = getByRole(component, "button", { name: "Add another person" });
});

afterEach(() => {
document.body.innerHTML = "";
component = undefined;
});

test('adds a new item when "Add another person" is clicked', async () => {
const initialItems = component.querySelectorAll(".moj-add-another__item");
expect(initialItems.length).toBe(1);

await user.click(addButton);

const updatedItems = component.querySelectorAll(".moj-add-another__item");
expect(updatedItems.length).toBe(2);

const secondItemFirstName = updatedItems[1].querySelector(
'[name="person[1][first_name]"]',
);
expect(secondItemFirstName).toBeInTheDocument();
expect(secondItemFirstName.value).toBe("");
});

test("adds a remove button to new items", async () => {
await user.click(addButton);

const firstItem = component.querySelectorAll(".moj-add-another__item")[0];
const secondItem = component.querySelectorAll(".moj-add-another__item")[1];
const firstItemRemoveButton = getByRole(firstItem, "button", {
name: "Remove",
});
const secondItemRemoveButton = getByRole(secondItem, "button", {
name: "Remove",
});

expect(firstItemRemoveButton).toBeInTheDocument();
expect(secondItemRemoveButton).toBeInTheDocument();
});

test('removes an item when the "Remove" button is clicked', async () => {
await user.click(addButton);

const secondItem = component.querySelectorAll(".moj-add-another__item")[1];
const removeButton = getByRole(secondItem, "button", { name: "Remove" });

await user.click(removeButton);

const remainingItems = component.querySelectorAll(".moj-add-another__item");

expect(remainingItems.length).toBe(1);
expect(
queryByRole(component, "button", { name: "Remove" }),
).not.toBeInTheDocument();
});

test("new item inputs have no value", async () => {
await user.click(addButton);

const secondItem = component.querySelectorAll(".moj-add-another__item")[1];
const firstNameInput = getByLabelText(secondItem, "First name");
const lastNameInput = getByLabelText(secondItem, "Last name");

expect(firstNameInput.value).toBe("");
expect(lastNameInput.value).toBe("");
});

test("resets form values in a new item", async () => {
await user.click(addButton);

const firstItem = component.querySelectorAll(".moj-add-another__item")[0];
const firstItemFirstNameInput = getByLabelText(firstItem, "First name");
const firstItemLastNameInput = getByLabelText(firstItem, "Last name");

await user.type(firstItemFirstNameInput, "Steve");
await user.type(firstItemLastNameInput, "Jobs");

expect(firstItemFirstNameInput.value).toBe("Steve");
expect(firstItemLastNameInput.value).toBe("Jobs");

const secondItem = component.querySelectorAll(".moj-add-another__item")[1];
const secondItemFirstNameInput = getByLabelText(secondItem, "First name");
const secondItemLastNameInput = getByLabelText(secondItem, "Last name");

expect(secondItemFirstNameInput.value).toBe("");
expect(secondItemLastNameInput.value).toBe("");
});

test("focuses the heading after removing an item", async () => {
await user.click(addButton);

const heading = queryByRole(component, "heading", { level: 2 });
const secondItem = component.querySelectorAll(".moj-add-another__item")[1];
const removeButton = getByRole(secondItem, "button", { name: "Remove" });

await user.click(removeButton);

expect(heading).toHaveFocus();
});

test("updates attributes correctly after removing an item", async () => {
await user.click(addButton);
await user.click(addButton);

const secondItem = component.querySelectorAll(".moj-add-another__item")[1];
const removeButton = getByRole(secondItem, "button", { name: "Remove" });

await user.click(removeButton);

const remainingItems = component.querySelectorAll(".moj-add-another__item");
remainingItems.forEach((item, index) => {
const firstNameInput = item.querySelector(
'[name="person[' + index + '][first_name]"]',
);
const lastNameInput = item.querySelector(
'[name="person[' + index + '][last_name]"]',
);
expect(firstNameInput).toBeInTheDocument();
expect(lastNameInput).toBeInTheDocument();
});
});
});

0 comments on commit 78113c7

Please sign in to comment.