assessment-model/cypress/e2e/live-tracking/halted-state.cy.js
2026-05-05 20:43:19 +00:00

109 lines
3.9 KiB
JavaScript

/**
* Live Tracking — Halted state editor (issue #255)
*
* Verifies the approver flow on the Halted section of the property detail
* drawer:
* 1. an approver can set a halted date + free-text reason and save them,
* 2. the drawer reflects the halted state (badge + persisted values),
* 3. clicking Resume clears the date but keeps the reason as the
* last-set value, both in the input and after a reload.
*
* Mirrors `pibi-dates.cy.js`. Assumes an authenticated approver session
* is reusable by the test harness; the target portfolio + a deal whose
* Halted section is editable by the current user are read from Cypress
* env vars so the spec stays portable.
*/
const PORTFOLIO_SLUG = Cypress.env("LIVE_PORTFOLIO_SLUG");
const TARGET_DEAL_NAME = Cypress.env("LIVE_HALTED_DEAL_NAME");
const HALTED_DATE = "2025-06-01";
const HALTED_REASON = "Awaiting roof access from landlord";
describe("Halted state editor — approver flow", function () {
before(function () {
if (!PORTFOLIO_SLUG) {
cy.log(
"LIVE_PORTFOLIO_SLUG env var not set — skipping live tracking specs",
);
this.skip();
}
});
function openDrawerForTargetDeal() {
cy.visit(`/portfolio/${PORTFOLIO_SLUG}/your-projects/live`);
// Switch to the Measures tab — the easiest way into the drawer.
cy.contains("button, [role=tab]", "Measures").click();
if (TARGET_DEAL_NAME) {
cy.contains("[data-testid=measures-row]", TARGET_DEAL_NAME).click();
} else {
cy.get("[data-testid=measures-row]").first().click();
}
cy.get("[data-testid=property-detail-drawer]").should("be.visible");
// Navigate to Survey & Admin tab (drawer opens on Works tab from Measures row click).
cy.get("[data-testid=drawer-tab-survey-admin]").click();
cy.get("[data-testid=drawer-section-halted]").should("exist");
}
it("lets an approver halt a property and resume it while preserving the reason", () => {
openDrawerForTargetDeal();
// Approver sees editable inputs.
cy.get("[data-testid=halted-date-input]").should("be.visible");
cy.get("[data-testid=halted-reason-input]").should("be.visible");
// Set halted date + reason.
cy.get("[data-testid=halted-date-input]").clear().type(HALTED_DATE);
cy.get("[data-testid=halted-reason-input]")
.clear()
.type(HALTED_REASON);
cy.get("[data-testid=halted-save-button]")
.should("not.be.disabled")
.click();
// Save completes — button label flips back, no error banner.
cy.get("[data-testid=halted-save-button]").should(
"contain.text",
"Save Halted State",
);
cy.get("[data-testid=halted-error]").should("not.exist");
// Drawer reflects halted state via the status badge + persisted values.
cy.get("[data-testid=halted-status-badge]").should("contain.text", "Halted");
cy.get("[data-testid=halted-date-input]").should("have.value", HALTED_DATE);
cy.get("[data-testid=halted-reason-input]").should(
"have.value",
HALTED_REASON,
);
// Now resume — date clears, reason stays.
cy.get("[data-testid=halted-resume-button]")
.should("be.visible")
.click();
// Once resumed the badge + resume button disappear, but the reason is
// still visible in the textarea.
cy.get("[data-testid=halted-status-badge]").should("not.exist");
cy.get("[data-testid=halted-resume-button]").should("not.exist");
cy.get("[data-testid=halted-date-input]").should("have.value", "");
cy.get("[data-testid=halted-reason-input]").should(
"have.value",
HALTED_REASON,
);
// Reload the page — the cleared date and preserved reason persist
// server-side.
cy.reload();
openDrawerForTargetDeal();
cy.get("[data-testid=halted-date-input]").should("have.value", "");
cy.get("[data-testid=halted-reason-input]").should(
"have.value",
HALTED_REASON,
);
});
});