Merged PR 2558: updated link on awaiting submission view allin welsh
updated link on awaiting submission view allin welsh Related work items: #24389
This commit is contained in:
@@ -0,0 +1,377 @@
|
||||
import { test, expect } from "@playwright/test";
|
||||
import path from "path";
|
||||
import * as XLSX from "xlsx";
|
||||
|
||||
import {
|
||||
login,
|
||||
fillYesNoConditional,
|
||||
fillQuillEditor,
|
||||
toDDMMYYYY,
|
||||
} from "../../helpers";
|
||||
|
||||
const workbook = XLSX.readFile("./testFiles/newappeals_s78.xlsx");
|
||||
const sheetName = workbook.SheetNames[0];
|
||||
const data = XLSX.utils.sheet_to_json(workbook.Sheets[sheetName], {
|
||||
defval: "",
|
||||
cellDates: true,
|
||||
});
|
||||
|
||||
// console.log("sheetName :", sheetName);
|
||||
// console.log("Loaded rows:", data);
|
||||
|
||||
data.forEach((row, index) => {
|
||||
test(`Import new appeal for ${row["Appellant / Organisation"]}`, async ({
|
||||
page,
|
||||
}) => {
|
||||
await login(page);
|
||||
|
||||
await page.getByRole("link", { name: "Make a new appeal" }).click();
|
||||
await page
|
||||
.getByRole("textbox", { name: "Appellant or organisation's" })
|
||||
.click();
|
||||
await page
|
||||
.getByRole("textbox", { name: "Appellant or organisation's" })
|
||||
.fill(row["Appellant / Organisation"]);
|
||||
|
||||
await page
|
||||
.getByRole("radio", { name: row["Appellant / Agent Radio Button"] })
|
||||
.click();
|
||||
|
||||
await page.locator("#pinswg_appellantfirstname").fill(row["First Name"]);
|
||||
await page.locator("#pinswg_appellantlastname").fill(row["Last Name"]);
|
||||
await page.locator("#pinswg_appellantaddress").fill(row["Address"]);
|
||||
await page
|
||||
.locator("#pinswg_appellantemailaddress")
|
||||
.fill(row["Email Address"]);
|
||||
await page
|
||||
.locator("#pinswg_appellantphonenumber")
|
||||
.fill(row["Telephone Number"]);
|
||||
|
||||
// Excel value: "English" or "Welsh"
|
||||
const languageText = row["Language Preference Radio Button"]?.trim();
|
||||
|
||||
// Map Excel text to radio button value
|
||||
const radioValueLang = languageText === "Welsh" ? "846040001" : "846040000";
|
||||
|
||||
// Select the radio by name and value
|
||||
await page
|
||||
.locator(
|
||||
`input[name="pinswg_languagepreference"][value="${radioValueLang}"]`
|
||||
)
|
||||
.check();
|
||||
|
||||
if (row["Appellant / Agent Radio Button"] == "Agent") {
|
||||
await page.locator("#pinswg_agentcompanyname").fill(row["Company Name"]);
|
||||
await page
|
||||
.locator("#pinswg_agentreference")
|
||||
.fill(row["Agent's Reference"]);
|
||||
|
||||
await page.locator("#pinswg_agentfirstname").fill(row["First Name_1"]);
|
||||
await page.locator("#pinswg_agentlastname").fill(row["Last Name_1"]);
|
||||
await page.locator("#pinswg_agentaddress").fill(row["Address_1"]);
|
||||
await page
|
||||
.locator("#pinswg_agentemailaddress")
|
||||
.fill(row["Email Address_1"]);
|
||||
await page
|
||||
.locator("#pinswg_agentphonenumber")
|
||||
.fill(row["Telephone Number_1"]);
|
||||
|
||||
const agentLanguageText =
|
||||
row["Agent Language Preference Radio Button"]?.trim();
|
||||
const agentRadioValue =
|
||||
agentLanguageText === "Welsh" ? "846040001" : "846040000";
|
||||
|
||||
await page
|
||||
.locator(
|
||||
`input[name="pinswg_agentlanguagepreference"][value="${agentRadioValue}"]`
|
||||
)
|
||||
.check();
|
||||
}
|
||||
await page.getByText("I confirm that I am making an").click();
|
||||
await page.getByRole("button", { name: "Continue" }).click();
|
||||
await page
|
||||
.getByLabel("Select your Local Planning")
|
||||
.selectOption({ label: row["Select LPA"] });
|
||||
await page.getByLabel("Select a case type").selectOption("846040000");
|
||||
await page.getByRole("button", { name: "Continue" }).click();
|
||||
await page.getByRole("button", { name: "Continue" }).click();
|
||||
|
||||
const step2 = page.locator('[aria-controls="step-panel-appeal-details"]');
|
||||
await step2.click();
|
||||
|
||||
await page
|
||||
.getByRole("textbox", { name: "Development description" })
|
||||
.click();
|
||||
await page
|
||||
.getByRole("textbox", { name: "Development description" })
|
||||
.fill(row["Development Description"]);
|
||||
await page.getByText("No", { exact: true }).click();
|
||||
await page
|
||||
.getByRole("textbox", { name: "LPA's application reference" })
|
||||
.fill(row["LPA's Application Ref Num"]);
|
||||
|
||||
await page
|
||||
.locator("#pinswg_dateofapplication")
|
||||
.fill(toDDMMYYYY(row["App Form Dated"]));
|
||||
await page
|
||||
.getByLabel("Reason for appeal")
|
||||
.selectOption({ label: row["Reason for Appeal"] });
|
||||
|
||||
await page.getByRole("textbox", { name: "Site address line 1" }).click();
|
||||
await page
|
||||
.getByRole("textbox", { name: "Site address line 1" })
|
||||
.fill(row["Site Address Line 1"]);
|
||||
await page
|
||||
.getByRole("textbox", { name: "Site address line 2" })
|
||||
.fill(row["Site Address Line 2"]);
|
||||
await page
|
||||
.getByRole("textbox", { name: "Site address town" })
|
||||
.fill(row["Site Address Town"]);
|
||||
await page
|
||||
.getByRole("textbox", { name: "Site address county" })
|
||||
.fill(row["Site Address County"]);
|
||||
|
||||
await page
|
||||
.getByRole("textbox", { name: "Site address postcode" })
|
||||
.fill(row["Site Address Postcode"]);
|
||||
|
||||
await page
|
||||
.getByRole("textbox", { name: "Size of overall appeal site (" })
|
||||
.fill(String(row["Size of Overall Appeal Site"]));
|
||||
|
||||
await page
|
||||
.getByRole("textbox", { name: "What is the area of floor" })
|
||||
.fill(String(row["Floor Space (Sq Metres)"]));
|
||||
await page.getByRole("button", { name: "Continue" }).click();
|
||||
|
||||
// Ownership Certificate selection and conditional fields
|
||||
const ownershipMap = {
|
||||
"Certificate A": "846040001",
|
||||
"Certificate B": "846040002",
|
||||
"Certificate C": "846040003",
|
||||
"Certificate D": "846040003", // C and D share same option
|
||||
};
|
||||
|
||||
const cert = row["Ownership Certificate"]?.trim();
|
||||
const value = ownershipMap[cert];
|
||||
|
||||
if (!value) throw new Error(`Unknown ownership certificate: ${cert}`);
|
||||
|
||||
// Select the certificate radio
|
||||
await page
|
||||
.locator(`input[name="pinswg_ownershipcertificate"][value="${value}"]`)
|
||||
.check();
|
||||
|
||||
// Conditional fields for Certificate B
|
||||
if (cert === "Certificate B") {
|
||||
// Wait for Owner Name input to appear (dynamic rendering)
|
||||
const ownerInput = page.locator(
|
||||
'input[id^="pinswg_owners"][id$=".pinswg_owners"]'
|
||||
);
|
||||
await ownerInput.waitFor({ state: "visible", timeout: 5000 });
|
||||
await ownerInput.fill(row["Owner Name"] || "");
|
||||
|
||||
// Wait for Date Served input to appear
|
||||
const dateServedInput = page.locator(
|
||||
".react-datepicker__input-container input"
|
||||
);
|
||||
await dateServedInput.waitFor({ state: "visible", timeout: 5000 });
|
||||
await dateServedInput.fill(toDDMMYYYY(row["Date Served"]) || "");
|
||||
}
|
||||
|
||||
// Ownership Certificate selection and conditional fields
|
||||
const agHoldingMap = {
|
||||
"(a)": "846040002",
|
||||
"(b) (i)": "846040001",
|
||||
"(b) (ii)": "846040000",
|
||||
};
|
||||
|
||||
const agriculturalHolding = row["Agricultural Holding"]?.trim();
|
||||
const agValue = agHoldingMap[agriculturalHolding];
|
||||
|
||||
if (!agValue) throw new Error(`Unknown ownership certificate: ${cert}`);
|
||||
|
||||
// Select the certificate radio
|
||||
await page
|
||||
.locator(`input[name="pinswg_agriculturalholding"][value="${agValue}"]`)
|
||||
.check();
|
||||
|
||||
// Conditional fields for b (ii)
|
||||
if (agriculturalHolding === "(b) (ii)") {
|
||||
// Wait for Owner Name input to appear (dynamic rendering)
|
||||
const tenantInput = page.locator(
|
||||
'input[id^="pinswg_agriculturaltenantname"][id$=".pinswg_agriculturaltenantname"]'
|
||||
);
|
||||
await tenantInput.waitFor({ state: "visible", timeout: 5000 });
|
||||
await tenantInput.fill(row["Tenant Name"] || "");
|
||||
|
||||
// Wait for Date Served input to appear
|
||||
const dateServedInput = page.locator(
|
||||
".react-datepicker__input-container input"
|
||||
);
|
||||
await dateServedInput.waitFor({ state: "visible", timeout: 5000 });
|
||||
await dateServedInput.fill(toDDMMYYYY(row["Date Served_1"]) || "");
|
||||
}
|
||||
|
||||
await page.getByRole("button", { name: "Continue" }).click();
|
||||
|
||||
// Site viewable from road
|
||||
await fillYesNoConditional(
|
||||
page,
|
||||
"pinswg_siteviewablefromroad",
|
||||
row["See Relevant Parts?"],
|
||||
null,
|
||||
null
|
||||
);
|
||||
|
||||
// Inspector needed on site
|
||||
await fillYesNoConditional(
|
||||
page,
|
||||
"pinswg_inspectorneededonsite",
|
||||
row["Essential to Enter?"],
|
||||
"#pinswg_whyisinspectorneededonsite",
|
||||
row["Please Explain (Enter)"]
|
||||
);
|
||||
|
||||
// Health & safety issues
|
||||
await fillYesNoConditional(
|
||||
page,
|
||||
"pinswg_healthandsafetyissuesonsite",
|
||||
row["Any H&S Issues?"],
|
||||
"#pinswg_outlinehealthandsafetyissuesonsite",
|
||||
row["Set out H&S Issues"]
|
||||
);
|
||||
|
||||
await page.getByRole("button", { name: "Continue" }).click();
|
||||
|
||||
// Step 5 Other Appeals
|
||||
|
||||
await fillYesNoConditional(
|
||||
page,
|
||||
"pinswg_additionalappealsmade", // radio name
|
||||
row["Any Other Appeals?"], // "Y" or blank from Excel
|
||||
"#pinswg_additionalappealsmadedetails", // Quill editor selector
|
||||
row["Other Appeal Details"], // text to fill
|
||||
false // flag that it's a Quill editor
|
||||
);
|
||||
|
||||
await page.getByRole("button", { name: "Continue" }).click();
|
||||
|
||||
// Step 6 Submission of Case
|
||||
|
||||
// Q.1
|
||||
const subnissionOfCaseInput = page.locator(".ql-editor");
|
||||
await subnissionOfCaseInput.waitFor({ state: "visible", timeout: 100000 });
|
||||
await subnissionOfCaseInput.fill(row["Submit Statement of Case"]);
|
||||
|
||||
// Q.2
|
||||
const attachSocValue = (row["Attached Separate Case Doc?"] || "")
|
||||
.trim()
|
||||
.toUpperCase();
|
||||
|
||||
const radioValue = attachSocValue === "Y" ? "true" : "false";
|
||||
|
||||
// Select the radio
|
||||
await page
|
||||
.locator(`input[name="pinswg_attachsoc"][value="${radioValue}"]`)
|
||||
.check();
|
||||
|
||||
// Q.3
|
||||
const procedureValue = row["What Procedure?"]?.trim(); // e.g., "Written representation"
|
||||
|
||||
// Wait for the dropdown to appear
|
||||
const procedureSelect = page.locator("#pinswg_procedure");
|
||||
await procedureSelect.waitFor({ state: "visible", timeout: 5000 });
|
||||
|
||||
// Select by label (the visible text)
|
||||
await procedureSelect.selectOption({ label: procedureValue });
|
||||
|
||||
// If not "Written representation", fill the explanation box
|
||||
if (
|
||||
procedureValue &&
|
||||
procedureValue.toLowerCase() !== "written representation"
|
||||
) {
|
||||
const explanation =
|
||||
row["Procedure Explanation"] ||
|
||||
"Default explanation: A hearing/inquiry is required due to case complexity and witnesses.";
|
||||
|
||||
const textArea = page.locator("#pinswg_chosenprocedureexplanation");
|
||||
await textArea.waitFor({ state: "visible", timeout: 5000 });
|
||||
await textArea.fill(explanation);
|
||||
}
|
||||
|
||||
// Q.4
|
||||
await fillYesNoConditional(
|
||||
page,
|
||||
"pinswg_costappliedforindicator", // radio name
|
||||
row["Cost Applied For"], // "Y" or blank from Excel
|
||||
".ql-editor", // Quill editor selector
|
||||
row["Cost Application"], // text to fill
|
||||
true // flag that it's a Quill editor
|
||||
);
|
||||
|
||||
// Q.5
|
||||
await fillYesNoConditional(
|
||||
page,
|
||||
"pinswg_s106unilateralsubmitted", // radio name
|
||||
row["Submit S106?"] // "Y" or blank from Excel
|
||||
);
|
||||
|
||||
await page.getByRole("button", { name: "Continue" }).click();
|
||||
|
||||
// Step 7 Upload Documents
|
||||
|
||||
const files = [
|
||||
path.resolve(__dirname, "../../testFiles/file1.pdf"),
|
||||
path.resolve(__dirname, "../../testFiles/file2.pdf"),
|
||||
];
|
||||
|
||||
const firstInputFiles = [
|
||||
path.resolve(__dirname, "../../testFiles/file1.pdf"),
|
||||
];
|
||||
|
||||
const fileInputs = [
|
||||
"#pinswg_fileUpload",
|
||||
"#pinswg_fileUpload1",
|
||||
"#pinswg_fileUpload2",
|
||||
"#pinswg_fileUpload3",
|
||||
"#pinswg_fileUpload4",
|
||||
"#pinswg_fileUpload5",
|
||||
"#pinswg_fileUpload6",
|
||||
"#pinswg_fileUpload7",
|
||||
"#pinswg_fileUpload8",
|
||||
"#pinswg_fileUpload9",
|
||||
"#pinswg_fileUpload10",
|
||||
"#pinswg_fileUpload11",
|
||||
"#pinswg_fileUpload12",
|
||||
"#pinswg_fileUpload13",
|
||||
"#pinswg_fileUpload14",
|
||||
"#pinswg_fileUpload15",
|
||||
];
|
||||
|
||||
for (let i = 0; i < fileInputs.length; i++) {
|
||||
const selector = fileInputs[i];
|
||||
if (i === 0) {
|
||||
// First input gets its specific files
|
||||
await page.locator(selector).setInputFiles(firstInputFiles);
|
||||
} else {
|
||||
// All other inputs get the common files
|
||||
await page.locator(selector).setInputFiles(files);
|
||||
}
|
||||
const uploadedFiles = page
|
||||
.locator("h4", { hasText: "Uploaded files" })
|
||||
.first();
|
||||
await expect(uploadedFiles).toBeVisible({ timeout: 60000 });
|
||||
}
|
||||
|
||||
await page.getByRole("button", { name: "Submit" }).click();
|
||||
|
||||
// Check and Confirm
|
||||
await page
|
||||
.getByRole("checkbox", { name: "I confirm that all sections" })
|
||||
.check();
|
||||
await page.getByText("Submit appeal").click();
|
||||
|
||||
await page.waitForTimeout(20000);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user