From be53f6e405bc9d1b64ff3d3af8d174cc52f6351f Mon Sep 17 00:00:00 2001 From: Damien Coraboeuf Date: Sun, 15 Dec 2024 12:44:54 +0100 Subject: [PATCH] #1236 Eligible & deployable builds --- .../environments/SlotEligibleBuildsSection.js | 1 + .../environments/SlotEligibleBuildsTable.js | 2 +- .../extension/environments/SlotView.js | 2 +- ontrack-web-core/ontrack.graphql | 2 ++ .../extensions/environments/SlotBuilds.js | 35 +++++++++++++++++++ .../tests/extensions/environments/SlotPage.js | 7 ++++ .../extensions/environments/slots.spec.js | 28 +++++++++++++++ 7 files changed, 75 insertions(+), 2 deletions(-) create mode 100644 ontrack-web-tests/tests/extensions/environments/SlotBuilds.js diff --git a/ontrack-web-core/components/extension/environments/SlotEligibleBuildsSection.js b/ontrack-web-core/components/extension/environments/SlotEligibleBuildsSection.js index 71deba4d00..8f5b7d63db 100644 --- a/ontrack-web-core/components/extension/environments/SlotEligibleBuildsSection.js +++ b/ontrack-web-core/components/extension/environments/SlotEligibleBuildsSection.js @@ -10,6 +10,7 @@ export default function SlotEligibleBuildsSection({slot, onChange}) { return ( <> diff --git a/ontrack-web-core/ontrack.graphql b/ontrack-web-core/ontrack.graphql index 8eabe6b12c..ce25bedb93 100644 --- a/ontrack-web-core/ontrack.graphql +++ b/ontrack-web-core/ontrack.graphql @@ -7074,6 +7074,8 @@ type Slot implements Authorizable { eligibleBuild: Build "Paginated list of eligible builds" eligibleBuilds( + "If true, restricts the list of builds to the ones which can actually be deployed." + deployable: Boolean, "Offset for the page" offset: Int = 0, "Size of the page" diff --git a/ontrack-web-tests/tests/extensions/environments/SlotBuilds.js b/ontrack-web-tests/tests/extensions/environments/SlotBuilds.js new file mode 100644 index 0000000000..8338160e12 --- /dev/null +++ b/ontrack-web-tests/tests/extensions/environments/SlotBuilds.js @@ -0,0 +1,35 @@ +import {expect} from "@playwright/test"; + +export class SlotBuilds { + + constructor(page, slot) { + this.page = page + this.slot = slot + } + + async selectAllBuilds() { + const section = this.#section() + const button = section.getByLabel("Show all eligible builds") + await expect(button).toBeVisible() + await button.click() + } + + async checkBuildPresent(build) { + const link = this.#buildLink(build) + await expect(link).toBeVisible() + } + + async checkBuildNotPresent(build) { + const link = this.#buildLink(build) + await expect(link).not.toBeVisible() + } + + #section() { + return this.page.getByTestId('slotBuilds') + } + + #buildLink(build) { + const section = this.#section() + return section.getByRole('link', {name: build.name}) + } +} \ No newline at end of file diff --git a/ontrack-web-tests/tests/extensions/environments/SlotPage.js b/ontrack-web-tests/tests/extensions/environments/SlotPage.js index 10c0a1f10e..ff2cc7ad6c 100644 --- a/ontrack-web-tests/tests/extensions/environments/SlotPage.js +++ b/ontrack-web-tests/tests/extensions/environments/SlotPage.js @@ -1,6 +1,7 @@ import {ui} from "@ontrack/connection"; import {expect} from "@playwright/test"; import {confirmBox} from "../../support/confirm"; +import {SlotBuilds} from "./SlotBuilds"; export class SlotPage { constructor(page, slot) { @@ -43,4 +44,10 @@ export class SlotPage { await button.click() await confirmBox(this.page, "Deleting slot", {okText: "Delete"}) } + + async getSlotBuilds() { + const slotBuildsSection = this.page.getByTestId("slotBuilds") + await expect(slotBuildsSection).toBeVisible() + return new SlotBuilds(this.page, this.slot) + } } \ No newline at end of file diff --git a/ontrack-web-tests/tests/extensions/environments/slots.spec.js b/ontrack-web-tests/tests/extensions/environments/slots.spec.js index 76b15bd0e4..1dfd3a4048 100644 --- a/ontrack-web-tests/tests/extensions/environments/slots.spec.js +++ b/ontrack-web-tests/tests/extensions/environments/slots.spec.js @@ -49,3 +49,31 @@ test('deleting a slot', async ({page}) => { const environmentsPage = new EnvironmentsPage(page) await environmentsPage.checkEnvironmentIsVisible(slot.environment.name) }) + +test('eligible and deployable builds for a slot', async ({page}) => { + const {project, slot} = await createSlot(ontrack()) + // Promotion admission rule + await ontrack().environments.addPromotionRule({slot, promotion: "BRONZE"}) + // Branch for the project + const branch = await project.createBranch() + const bronze = await branch.createPromotionLevel("BRONZE") + // Build not promoted + const build1 = await branch.createBuild() + // Build, promoted + const build2 = await branch.createBuild() + await build2.promote(bronze) + + // Login & going to the slot page + await login(page) + const slotPage = new SlotPage(page, slot) + await slotPage.goTo() + + // Gets the section about builds + const slotBuilds = await slotPage.getSlotBuilds() + await slotBuilds.checkBuildPresent(build2) + await slotBuilds.checkBuildNotPresent(build1) + // Selecting all eligible builds + await slotBuilds.selectAllBuilds() + await slotBuilds.checkBuildPresent(build2) + await slotBuilds.checkBuildPresent(build1) +})