Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions client/e2eTests/protoFleet/helpers/buildingsTestSetup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -144,13 +144,13 @@ export async function createRackWithAssignedMiners(
await racksPage.enableCustomRackLayout();
await racksPage.inputColumns(RACK_COLUMNS);
await racksPage.inputRows(RACK_ROWS);
await racksPage.clickContinueFromRackSettings();
await racksPage.clickCreateRackFromSettings();

const selectedMinerIps = (await addSelectableMinersToSlots(racksPage, 2, [1, 2])).map((miner) => miner.ipAddress);
test.expect(selectedMinerIps).toHaveLength(2);

await racksPage.clickSaveRack();
await racksPage.validateRackToast(rackLabel);
await racksPage.clickSaveMinerPositions();
await racksPage.validateMinerPositionsToast(rackLabel);
await racksPage.clickViewList();
await racksPage.waitForRackListToLoad({ allowEmpty: false });

Expand Down
4 changes: 2 additions & 2 deletions client/e2eTests/protoFleet/helpers/racksHelpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export async function addSelectableMinersToSlots(
const selectableMinerIndexes = await racksPage.getSelectableMinerIndexes(minerCount);
const selectedMiners = await racksPage.getMinersFromSelector(selectableMinerIndexes);
await racksPage.selectMinersInSelectorByIndex(selectableMinerIndexes);
await racksPage.clickContinueInMinerSelector();
await racksPage.clickSaveInMinerSelector();

for (let i = 0; i < selectedMiners.length; i++) {
await racksPage.selectRackMiner(selectedMiners[i].ipAddress);
Expand All @@ -48,7 +48,7 @@ export async function addSelectableRigMinersToSlots(
const selectableMinerIndexes = await racksPage.getSelectableMinerIndexes(minerCount);
const selectedMiners = await racksPage.getMinersFromSelector(selectableMinerIndexes);
await racksPage.selectMinersInSelectorByIndex(selectableMinerIndexes);
await racksPage.clickContinueInMinerSelector();
await racksPage.clickSaveInMinerSelector();

for (let i = 0; i < selectedMiners.length; i++) {
await racksPage.selectRackMiner(selectedMiners[i].ipAddress);
Expand Down
4 changes: 2 additions & 2 deletions client/e2eTests/protoFleet/helpers/rbacTestSetup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -287,9 +287,9 @@ export async function createRack(racksPage: RacksPage, rackLabel: string) {
await racksPage.enableCustomRackLayout();
await racksPage.inputColumns(2);
await racksPage.inputRows(2);
await racksPage.clickContinueFromRackSettings();
await racksPage.clickSaveRack();
await racksPage.clickCreateRackFromSettings();
await racksPage.validateRackToast(rackLabel);
await racksPage.clickDismissManageRack();
await racksPage.clickViewList();
await racksPage.waitForRackListToLoad({ allowEmpty: false });
await racksPage.validateRackRow(rackLabel, RBAC_RACK_ZONE, 0);
Expand Down
40 changes: 32 additions & 8 deletions client/e2eTests/protoFleet/pages/racks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,15 @@ export class RacksPage extends BasePage {
.trim();
}

async clickContinueFromRackSettings() {
await this.clickIn("Continue", "modal");
// The Rack settings CTA creates the rack, so a new rack reads "Create rack"
// and lands on the manage-rack modal with the rack already persisted.
async clickCreateRackFromSettings() {
await this.clickIn("Create rack", "modal");
}

// Reopened on an existing rack, the same CTA updates the rack's own fields.
async clickSaveRackSettings() {
await this.clickIn("Save", "modal");
}

async validateRackSettingsFieldError(
Expand Down Expand Up @@ -176,8 +183,9 @@ export class RacksPage extends BasePage {
await this.modalMinerList.selectRowByCellText("ipAddress", ipAddress);
}

async clickContinueInMinerSelector() {
await this.clickIn("Continue", "modal");
// The miner picker commits the rack's membership itself, hence "Save".
async clickSaveInMinerSelector() {
await this.clickIn("Save", "modal");
}

async validateMinerSelectorOverflowError(selectedCount: number, maxSlots: number) {
Expand Down Expand Up @@ -303,10 +311,20 @@ export class RacksPage extends BasePage {
await this.page.getByRole("button", { name: "Clear", exact: true }).click();
}

async clickSaveRack() {
// The manage-rack modal's Save persists slot placement only, and is disabled
// until a miner's slot actually changes.
async clickSaveMinerPositions() {
await this.clickButton("Save");
}

async clickDismissManageRack() {
await this.page.getByRole("button", { name: "Close dialog", exact: true }).click();
}

async validateSaveMinerPositionsDisabled() {
await expect(this.page.getByRole("button", { name: "Save", exact: true })).toBeDisabled();
}

async clickViewMiners() {
const directButton = this.page.getByTestId("rack-page-view-miners");
if (await directButton.isVisible().catch(() => false)) {
Expand All @@ -331,15 +349,21 @@ export class RacksPage extends BasePage {
await this.validateTitleInModal("Rack settings");
}

async changeOrderIndexAndContinue(orderIndexLabel: string) {
// Reached through Edit Rack Settings, so the rack already exists and the CTA
// persists the change straight away.
async changeOrderIndexAndSaveSettings(orderIndexLabel: string) {
await this.selectOption("order-index-select", orderIndexLabel);
await this.clickContinueFromRackSettings();
await this.clickSaveRackSettings();
}

async validateRackToast(label: string, action: "created" | "updated" = "created") {
async validateRackToast(label: string, action: "created" | "saved" = "created") {
await this.validateTextInToast(`Rack "${label}" ${action}`);
}

async validateMinerPositionsToast(label: string) {
await this.validateTextInToast(`Miner positions saved for "${label}"`);
}

async validateRackCardVisible(label: string, zone: string) {
await expect(this.getRackCard(label, zone)).toBeVisible();
}
Expand Down
19 changes: 10 additions & 9 deletions client/e2eTests/protoFleet/spec/racksCreation.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ test.describe("Racks - creation", () => {
await racksPage.inputRows(RACK_ROWS);

orderIndexValue = await racksPage.getOrderIndexValue();
await racksPage.clickContinueFromRackSettings();
await racksPage.clickCreateRackFromSettings();
});

await test.step("Validate empty rack assignment state", async () => {
Expand All @@ -46,7 +46,7 @@ test.describe("Racks - creation", () => {
selectedMiners = await racksPage.getMinersFromSelector([0, 1]);
test.expect(selectedMiners).toHaveLength(2);
await racksPage.selectMinersInSelectorByIndex([0, 1]);
await racksPage.clickContinueInMinerSelector();
await racksPage.clickSaveInMinerSelector();
});

await test.step("Assign miners by name and validate positions", async () => {
Expand All @@ -55,8 +55,8 @@ test.describe("Racks - creation", () => {
});

await test.step("Save rack and validate rack grid card", async () => {
await racksPage.clickSaveRack();
await racksPage.validateRackToast(rackLabel);
await racksPage.clickSaveMinerPositions();
await racksPage.validateMinerPositionsToast(rackLabel);
await racksPage.clickViewGrid();
await racksPage.validateRackCardVisible(rackLabel, AUTOMATION_ZONE);
await racksPage.validateRackCardGrid(rackLabel, AUTOMATION_ZONE, RACK_COLUMNS, RACK_ROWS);
Expand All @@ -79,7 +79,7 @@ test.describe("Racks - creation", () => {
await racksPage.enableCustomRackLayout();
await racksPage.inputColumns(RACK_COLUMNS);
await racksPage.inputRows(RACK_ROWS);
await racksPage.clickContinueFromRackSettings();
await racksPage.clickCreateRackFromSettings();
});

await test.step("Add four miners", async () => {
Expand All @@ -89,7 +89,7 @@ test.describe("Racks - creation", () => {
selectedMiners = await racksPage.getMinersFromSelector([0, 1, 2, 3]);
test.expect(selectedMiners).toHaveLength(4);
await racksPage.selectMinersInSelectorByIndex([0, 1, 2, 3]);
await racksPage.clickContinueInMinerSelector();
await racksPage.clickSaveInMinerSelector();
});

await test.step("Assign miners manually in DOM order and validate default numbering", async () => {
Expand All @@ -103,7 +103,8 @@ test.describe("Racks - creation", () => {
for (const scenario of ORDER_INDEX_SCENARIOS.slice(1)) {
await test.step(`Change order index to ${scenario.label}`, async () => {
await racksPage.clickEditRackSettings();
await racksPage.changeOrderIndexAndContinue(scenario.label);
await racksPage.changeOrderIndexAndSaveSettings(scenario.label);
await racksPage.validateRackToast(RACK_LABEL, "saved");
await racksPage.validateRackConfiguration(RACK_COLUMNS, RACK_ROWS, scenario.label);
await racksPage.validateRackSlotNumbersInDomOrder(scenario.expectedNumbers);
await racksPage.validateMinerPositions(selectedMiners, scenario.expectedNumbers);
Expand All @@ -121,15 +122,15 @@ test.describe("Racks - creation", () => {
await racksPage.enableCustomRackLayout();
await racksPage.inputColumns(NETWORK_RACK_COLUMNS);
await racksPage.inputRows(NETWORK_RACK_ROWS);
await racksPage.clickContinueFromRackSettings();
await racksPage.clickCreateRackFromSettings();

await racksPage.clickAddMiners();
await racksPage.waitForMinerSelectorListToLoad();
allVisibleMiners = await racksPage.getAllVisibleMinersFromSelector();
test.expect(allVisibleMiners.length).toBeGreaterThan(0);
test.expect(allVisibleMiners.length).toBeLessThanOrEqual(NETWORK_RACK_COLUMNS * NETWORK_RACK_ROWS);
await racksPage.clickSelectAllMinersInSelector();
await racksPage.clickContinueInMinerSelector();
await racksPage.clickSaveInMinerSelector();
});

await test.step("Assign all miners by network and validate positions by IP and name", async () => {
Expand Down
39 changes: 22 additions & 17 deletions client/e2eTests/protoFleet/spec/racksManagement.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,11 @@ test.describe("Racks - management", () => {
await racksPage.enableCustomRackLayout();
await racksPage.inputColumns(RACK_COLUMNS);
await racksPage.inputRows(RACK_ROWS);
await racksPage.clickContinueFromRackSettings();
await addSelectableMinersToSlots(racksPage, 3, [1, 2, 3]);
await racksPage.clickSaveRack();
await racksPage.clickCreateRackFromSettings();
await racksPage.validateRackToast("A-01");
await addSelectableMinersToSlots(racksPage, 3, [1, 2, 3]);
await racksPage.clickSaveMinerPositions();
await racksPage.validateMinerPositionsToast("A-01");
await racksPage.clickViewGrid();
await racksPage.validateRackCardVisible("A-01", zoneA);
createdRackLabels.push("A-01");
Expand All @@ -42,10 +43,11 @@ test.describe("Racks - management", () => {
await racksPage.clickAddRackButton();
await racksPage.inputZone(zoneA);
await racksPage.inputRackLabel("A-02");
await racksPage.clickContinueFromRackSettings();
await addSelectableMinersToSlots(racksPage, 2, [1, 2]);
await racksPage.clickSaveRack();
await racksPage.clickCreateRackFromSettings();
await racksPage.validateRackToast("A-02");
await addSelectableMinersToSlots(racksPage, 2, [1, 2]);
await racksPage.clickSaveMinerPositions();
await racksPage.validateMinerPositionsToast("A-02");
await racksPage.clickViewGrid();
await racksPage.validateRackCardVisible("A-02", zoneA);
createdRackLabels.push("A-02");
Expand All @@ -55,10 +57,11 @@ test.describe("Racks - management", () => {
await racksPage.clickAddRackButton();
await racksPage.inputZone(zoneB);
await racksPage.inputRackLabel("B-01");
await racksPage.clickContinueFromRackSettings();
await addSelectableMinersToSlots(racksPage, 1, [1]);
await racksPage.clickSaveRack();
await racksPage.clickCreateRackFromSettings();
await racksPage.validateRackToast("B-01");
await addSelectableMinersToSlots(racksPage, 1, [1]);
await racksPage.clickSaveMinerPositions();
await racksPage.validateMinerPositionsToast("B-01");
await racksPage.clickViewGrid();
await racksPage.validateRackCardVisible("B-01", zoneB);
createdRackLabels.push("B-01");
Expand Down Expand Up @@ -107,27 +110,29 @@ test.describe("Racks - management", () => {

await test.step("Validate required label and invalid dimensions", async () => {
// Zone is optional now; the label is required and empty by default, so
// continuing without typing one surfaces the label error.
// submitting without typing one surfaces the label error instead of
// creating the rack.
await racksPage.clickAddRackButton();
await racksPage.inputZone(validationZone);
generatedRackLabel = "A-01";

await racksPage.enableCustomRackLayout();
await racksPage.inputColumns(0);
await racksPage.inputRows(13);
await racksPage.clickContinueFromRackSettings();
await racksPage.clickCreateRackFromSettings();

await racksPage.validateRackSettingsFieldError("rack-label", "A label is required");
await racksPage.validateRackSettingsFieldError("rack-columns", "Columns must be a whole number between 1 and 12");
await racksPage.validateRackSettingsFieldError("rack-rows", "Rows must be a whole number between 1 and 12");
await racksPage.validateTitleInModal("Rack settings");
});

await test.step("Correct rack settings and continue", async () => {
await test.step("Correct rack settings and create the rack", async () => {
await racksPage.inputRackLabel(generatedRackLabel);
await racksPage.inputColumns(VALIDATION_RACK_COLUMNS);
await racksPage.inputRows(VALIDATION_RACK_ROWS);
await racksPage.clickContinueFromRackSettings();
await racksPage.clickCreateRackFromSettings();
await racksPage.validateRackToast(generatedRackLabel);

await racksPage.validateRackConfiguration(VALIDATION_RACK_COLUMNS, VALIDATION_RACK_ROWS, "Bottom left");
await racksPage.validateAssignedMinersCount(0, 1);
Expand All @@ -140,18 +145,18 @@ test.describe("Racks - management", () => {
const selectableMinerIndexes = await racksPage.getSelectableMinerIndexes(2);
selectedMiners = await racksPage.getMinersFromSelector(selectableMinerIndexes);
await racksPage.selectMinersInSelectorByIndex(selectableMinerIndexes);
await racksPage.clickContinueInMinerSelector();
await racksPage.clickSaveInMinerSelector();

await racksPage.validateMinerSelectorOverflowError(2, 1);
await racksPage.toggleMinerInSelectorByIpAddress(selectedMiners[1].ipAddress);
await racksPage.clickContinueInMinerSelector();
await racksPage.clickSaveInMinerSelector();
});

await test.step("Assign remaining miner and save the rack", async () => {
await racksPage.clickAssignByNetwork();
await racksPage.validateMinersAssignedByNetwork([selectedMiners[0]]);
await racksPage.clickSaveRack();
await racksPage.validateRackToast(generatedRackLabel);
await racksPage.clickSaveMinerPositions();
await racksPage.validateMinerPositionsToast(generatedRackLabel);
await racksPage.validateRackCardVisible(generatedRackLabel, validationZone);
await racksPage.validateRackCardGrid(
generatedRackLabel,
Expand Down
19 changes: 10 additions & 9 deletions client/e2eTests/protoFleet/spec/racksManualAssignment.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ test.describe("Racks - manual assignment", () => {
await racksPage.enableCustomRackLayout();
await racksPage.inputColumns(LARGE_RACK_COLUMNS);
await racksPage.inputRows(LARGE_RACK_ROWS);
await racksPage.clickContinueFromRackSettings();
await racksPage.clickCreateRackFromSettings();
});

await test.step("Manage miners and add the first miner to the rack list", async () => {
Expand All @@ -39,7 +39,7 @@ test.describe("Racks - manual assignment", () => {
selectedMiners = await racksPage.getMinersFromSelector(selectableMinerIndexes);
test.expect(selectedMiners).toHaveLength(2);
await racksPage.selectMinersInSelectorByIndex([selectableMinerIndexes[0]]);
await racksPage.clickContinueInMinerSelector();
await racksPage.clickSaveInMinerSelector();
});

await test.step("Search and assign the second miner to slot 04", async () => {
Expand Down Expand Up @@ -102,8 +102,8 @@ test.describe("Racks - manual assignment", () => {
await racksPage.validateMinerRowPosition(selectedMiners[1].ipAddress, 9);
await racksPage.validateRackSlotsHighlighted([1, 9]);

await racksPage.clickSaveRack();
await racksPage.validateRackToast(rackLabel);
await racksPage.clickSaveMinerPositions();
await racksPage.validateMinerPositionsToast(rackLabel);
});

await test.step("Open the created rack and validate saved slots", async () => {
Expand All @@ -130,9 +130,10 @@ test.describe("Racks - manual assignment", () => {
await racksPage.enableCustomRackLayout();
await racksPage.inputColumns(OVERVIEW_RACK_COLUMNS);
await racksPage.inputRows(OVERVIEW_RACK_ROWS);
await racksPage.clickContinueFromRackSettings();
await racksPage.clickSaveRack();
await racksPage.clickCreateRackFromSettings();
await racksPage.validateRackToast(rackLabel);
// No miner has a slot yet, so there is no placement to save.
await racksPage.validateSaveMinerPositionsDisabled();
});

await test.step("Open the created rack and assign the first miner to slot 02", async () => {
Expand Down Expand Up @@ -182,10 +183,10 @@ test.describe("Racks - manual assignment", () => {
await racksPage.waitForMinerSelectorListToLoad();
await racksPage.toggleMinerInSelectorByIpAddress(selectedMiners[0].ipAddress);
await racksPage.toggleMinerInSelectorByIpAddress(selectedMiners[1].ipAddress);
await racksPage.clickContinueInMinerSelector();
await racksPage.clickSaveInMinerSelector();
await racksPage.validateTextIsVisible("No miners added to this rack yet.");
await racksPage.clickSaveRack();
await racksPage.validateRackToast(rackLabel, "updated");
await racksPage.clickSaveMinerPositions();
await racksPage.validateMinerPositionsToast(rackLabel);
});

await test.step("Validate rack overview is empty after saving", async () => {
Expand Down
Loading
Loading