From d955991c43626238439b5615e2ab29bac15185c8 Mon Sep 17 00:00:00 2001 From: shikanime Date: Wed, 26 Aug 2026 01:22:58 +0200 Subject: [PATCH 1/3] test(playwright): user-acceptance gap-fill secrets journeys Co-authored-by: Automata --- playwright/e2e-tests/secrets.spec.ts | 55 ++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 playwright/e2e-tests/secrets.spec.ts diff --git a/playwright/e2e-tests/secrets.spec.ts b/playwright/e2e-tests/secrets.spec.ts new file mode 100644 index 0000000000..26550726f9 --- /dev/null +++ b/playwright/e2e-tests/secrets.spec.ts @@ -0,0 +1,55 @@ +import { expect, test } from '@playwright/test' +import { clientURL, signInCloudPiNative, testUser } from 'config/console' +import { createProject, deleteProject } from 'helpers/project' + +/** + * Cahier de tests fonctionnels — SECR-001 / SECR-003 + * SECR-001: Affichage des secrets de projet (toggle "Afficher les secrets des services") + * SECR-003: Bouton indisponible (projet verrouillé) — covered indirectly here by the + * visibility contract on a fresh project; the locked-project variant requires an + * archived/locked fixture the CI stack does not provision (see skip below). + */ +test.describe('Secrets du projet (SECR)', { tag: '@e2e' }, () => { + let projectName: string + + test.beforeEach(async ({ page }) => { + await page.goto(clientURL) + await signInCloudPiNative({ page, credentials: testUser }) + const { name } = await createProject({ page }) + projectName = name + }) + + test('SECR-001: the secrets toggle is visible on a fresh project dashboard', async ({ page }) => { + await page.getByTestId('menuMyProjects').click() + await page.getByRole('link', { name: projectName }).click() + + // The toggle button exists and defaults to the hidden state + const toggle = page.getByRole('button', { name: 'Afficher les secrets des services' }) + await expect(toggle).toBeVisible() + }) + + test('SECR-001: toggling switches the label between show/hide', async ({ page }) => { + await page.getByTestId('menuMyProjects').click() + await page.getByRole('link', { name: projectName }).click() + + const toggle = page.getByRole('button', { name: 'Afficher les secrets des services' }) + await toggle.click() + await expect(page.getByRole('button', { name: 'Cacher les secrets des services' })).toBeVisible() + // toggle back for state cleanliness + await page.getByRole('button', { name: 'Cacher les secrets des services' }).click() + await expect(page.getByRole('button', { name: 'Afficher les secrets des services' })).toBeVisible() + }) + + test.skip('SECR-003: secrets button unavailable on a locked project', async () => { + // Requires provisioning a project with status locked/archived plus its plugin stack. + // The merge-queue CI stack does not seed locked projects; to enable, seed a locked + // project via admin API in beforeEach and assert the toggle is not rendered. + }) + + test.afterEach(async ({ page }) => { + if (!projectName) + return + await deleteProject({ page, projectName }) + projectName = '' + }) +}) From ca5bee8be8af0a6dfe06afb6bf41473ab08657c4 Mon Sep 17 00:00:00 2001 From: William Phetsinorath Date: Fri, 28 Aug 2026 17:03:26 +0200 Subject: [PATCH 2/3] test(playwright): trim project secrets journey spec MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Retire le test redondant (visibilité du toggle, déjà couvert par 'Should show project secrets' dans dashboard.spec.ts), le skip verrouillé (0 assertion) et le guard afterEach superflu (deleteProject gère sa navigation). Un seul test conserve le contrat : libellé Afficher/Cacher. Signed-off-by: William Phetsinorath Change-Id: I0e1156816ab0c44aebbbdfbf7be968576a6a6964 Co-authored-by: Automata --- playwright/e2e-tests/secrets.spec.ts | 32 ++++++---------------------- 1 file changed, 7 insertions(+), 25 deletions(-) diff --git a/playwright/e2e-tests/secrets.spec.ts b/playwright/e2e-tests/secrets.spec.ts index 26550726f9..b5c1530f19 100644 --- a/playwright/e2e-tests/secrets.spec.ts +++ b/playwright/e2e-tests/secrets.spec.ts @@ -1,15 +1,12 @@ import { expect, test } from '@playwright/test' import { clientURL, signInCloudPiNative, testUser } from 'config/console' +import { openMyProjects } from 'helpers/navigation' import { createProject, deleteProject } from 'helpers/project' -/** - * Cahier de tests fonctionnels — SECR-001 / SECR-003 - * SECR-001: Affichage des secrets de projet (toggle "Afficher les secrets des services") - * SECR-003: Bouton indisponible (projet verrouillé) — covered indirectly here by the - * visibility contract on a fresh project; the locked-project variant requires an - * archived/locked fixture the CI stack does not provision (see skip below). - */ -test.describe('Secrets du projet (SECR)', { tag: '@e2e' }, () => { +// Parcours secrets du projet : bascule du bouton « Afficher/Cacher les secrets +// des services ». Le cas projet verrouillé (bouton indisponible) n'est pas +// couvert — la stack CI ne provisionne pas de projet verrouillé. +test.describe('Secrets du projet', { tag: '@e2e' }, () => { let projectName: string test.beforeEach(async ({ page }) => { @@ -19,33 +16,18 @@ test.describe('Secrets du projet (SECR)', { tag: '@e2e' }, () => { projectName = name }) - test('SECR-001: the secrets toggle is visible on a fresh project dashboard', async ({ page }) => { - await page.getByTestId('menuMyProjects').click() + test('toggling switches the label between show/hide', async ({ page }) => { + await openMyProjects({ page }) await page.getByRole('link', { name: projectName }).click() - // The toggle button exists and defaults to the hidden state const toggle = page.getByRole('button', { name: 'Afficher les secrets des services' }) await expect(toggle).toBeVisible() - }) - - test('SECR-001: toggling switches the label between show/hide', async ({ page }) => { - await page.getByTestId('menuMyProjects').click() - await page.getByRole('link', { name: projectName }).click() - - const toggle = page.getByRole('button', { name: 'Afficher les secrets des services' }) await toggle.click() await expect(page.getByRole('button', { name: 'Cacher les secrets des services' })).toBeVisible() - // toggle back for state cleanliness await page.getByRole('button', { name: 'Cacher les secrets des services' }).click() await expect(page.getByRole('button', { name: 'Afficher les secrets des services' })).toBeVisible() }) - test.skip('SECR-003: secrets button unavailable on a locked project', async () => { - // Requires provisioning a project with status locked/archived plus its plugin stack. - // The merge-queue CI stack does not seed locked projects; to enable, seed a locked - // project via admin API in beforeEach and assert the toggle is not rendered. - }) - test.afterEach(async ({ page }) => { if (!projectName) return From 48f61fa4d4d6e0fa091c1e542e9fbd65d449f3fb Mon Sep 17 00:00:00 2001 From: William Phetsinorath Date: Thu, 10 Sep 2026 17:30:09 +0200 Subject: [PATCH 3/3] test(playwright): add secrets and user-flow uat specs Co-authored-by: Automata --- playwright/integration-tests/user-flow.spec.ts | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/playwright/integration-tests/user-flow.spec.ts b/playwright/integration-tests/user-flow.spec.ts index a27b10139b..7cc2ff733f 100644 --- a/playwright/integration-tests/user-flow.spec.ts +++ b/playwright/integration-tests/user-flow.spec.ts @@ -95,6 +95,21 @@ test.describe('Integration tests user flow: first checks', { tag: '@integ' }, () await expect(page1.getByRole('link', { name: 'forge-dso' })).not.toBeVisible() }) + test('Check project secrets', { tag: '@replayable' }, async ({ page }) => { + await page.goto(clientURL) + await signInCloudPiNative({ page, credentials: testUser }) + await page.getByTestId('menuMyProjects').click() + await page.getByRole('link', { name: projectName }).click() + await page.getByTestId('showSecretsBtn').click() + const modal = page.getByTestId('projectSecretsZone') + // Keys only — secret values rotate with the project's provisioning. + await expect(modal.getByRole('heading', { name: 'GITLAB' })).toBeVisible() + await expect(modal.getByText('GIT_MIRROR_PROJECT_ID')).toBeVisible() + await expect(modal.getByText('GIT_MIRROR_TOKEN')).toBeVisible() + await expect(modal.locator('pre').first()).not.toBeEmpty() + await expect(modal.getByRole('heading', { name: 'VAULT' })).toBeVisible() + }) + test('Project permissions', async ({ page }) => { await page.goto(clientURL) await signInCloudPiNative({ page, credentials: testUser })