Skip to content

fix(FR-2998): repair broken E2E tests for Admin & Operations#7693

Merged
graphite-app[bot] merged 1 commit into
mainfrom
06-03-fix_fr-2998_repair_broken_e2e_tests_for_admin_operations
Jun 9, 2026
Merged

fix(FR-2998): repair broken E2E tests for Admin & Operations#7693
graphite-app[bot] merged 1 commit into
mainfrom
06-03-fix_fr-2998_repair_broken_e2e_tests_for_admin_operations

Conversation

@nowgnuesLee

@nowgnuesLee nowgnuesLee commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

Resolves #7633 (FR-2998)

Stacked on: #7688 (FR-2997) → #7684 (FR-2996) → #7679 (FR-2995) → #7676 (FR-2994) → #7653 (FR-2993) → #7652 (FR-2992)

Part of FR-2059 (Fix Broken E2E Tests Cases). Repairs the Admin & Operations sub-category — 4 originally failing tests + cascading rewrites to project-crud after exposing the new lifecycle UX. Final state: 45 pass / 0 fail / 2 skip across e2e/environment/, e2e/my-environment/, e2e/project/, e2e/maintenance/, e2e/information/, e2e/statistics/.

Root causes

  • environment/registry.spec.ts:63 (registry list columns): the Control column was removed when ContainerRegistryListNodes migrated to BAINameActionCell (actions embedded in the Registry Name cell). Removed the obsolete columnheader assertion; the 7 real columns are still validated.

  • environment/registry.spec.ts:716 (filter property): the test used the CSS class .ant-select-content-value which does not exist in this antd version. Actual class is .ant-select-content (with optional .ant-select-content-has-value). Switched to page.locator('.ant-select-content').filter({ hasText: 'Registry Name' }).

  • information/information.spec.ts:6 (page server details): strict-mode hit. getByText('Component') matched both the ant-descriptions-title and the 'Loading components...' loader. Added { exact: true }.

  • project/project-crud.spec.ts:31 (project list columns): the Controls column was removed when the project list migrated to BAIProjectTable + BAINameActionCell. The Active column was also removed; active vs inactive is now a filter radio group. The test now asserts the 4 real columns (Name, Domain, Description, Type) and verifies the Active radio is selected via .ant-radio-button-wrapper-checked.

Cascading rewrites in project/project-crud.spec.ts (uncovered by the column fix)

  • :78 (create), :122 (edit) — the Name cell now renders via BAINameActionCell. Replaced the exact getByRole('cell', { name: PROJECT_NAME, exact: true }) assertion with getByRole('row').filter({ hasText: PROJECT_NAME }) since the cell's accessible name includes hover-only action labels. The Edit test now hovers the row before clicking the (hover-only) setting action button.

  • :200 (delete) — the project lifecycle changed from a one-shot Purge dialog to a two-step flow: Active → Deactivated (Popconfirm) → Purged (BAIDeleteConfirmModal with requireConfirmInput). Rewrote the test and shared cleanupTestProject helper to:

    1. Hover the row, click deactivate (action button nth(1)).
    2. Confirm the antd Popconfirm.
    3. Switch to the Inactive tab via the label wrapper (the radio input itself is hidden).
    4. Hover the deactivated row, click purge (action button nth(2)).
    5. Type the project name into #confirmText, click Purge.
    6. Verify the row is gone, then return to the Active tab.

    Mirrors the user / role / vfolder destructive-action conventions already standardized in FR-2992 through FR-2997.

Files changed

  • e2e/environment/registry.spec.ts — removed obsolete Control columnheader; corrected filter-property selector class
  • e2e/information/information.spec.ts{ exact: true } on Component
  • e2e/project/project-crud.spec.ts — column-set update, hover-then-click for setting, two-step deactivate→purge for delete, shared cleanupTestProject helper

Test plan

  • pnpm exec playwright test e2e/environment/ e2e/my-environment/ e2e/project/ e2e/maintenance/ e2e/information/ e2e/statistics/ --workers=2 — 45 pass / 0 fail / 2 skip
  • pnpm exec playwright test e2e/project/project-crud.spec.ts (full file in serial mode) — all 5 tests pass
  • Individual retries of the parallel-only flake (environment.spec.ts:188 user can manage apps) pass cleanly (17s) — backend-state-dependent test, not a regression

nowgnuesLee commented Jun 3, 2026

Copy link
Copy Markdown
Contributor Author

How to use the Graphite Merge Queue

Add either label to this PR to merge it via the merge queue:

  • flow:merge-queue - adds this PR to the back of the merge queue
  • flow:hotfix - for urgent changes, fast-track this PR to the front of the merge queue

You must have a Graphite account in order to use the merge queue. Sign up using this link.

An organization admin has required the Graphite Merge Queue in this repository.

Please do not merge from GitHub as this will restart CI on PRs being processed by the merge queue.

This stack of pull requests is managed by Graphite. Learn more about stacking.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Repairs Playwright E2E specs under the Admin & Operations category (FR-2998) by updating locators and assertions to match the current WebUI UX (notably BAINameActionCell-embedded actions and the updated project lifecycle flow), bringing the affected suites back to green.

Changes:

  • Updated project CRUD tests to reflect the new project table column set and the Active → Deactivated → Purged delete lifecycle, including hover-revealed row actions.
  • Fixed strict-mode ambiguity on the Information page by making the Component text assertion exact.
  • Adjusted registry tests to remove the obsolete Control column assertion and to use the correct antd selector for the filter property display.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.

File Description
e2e/project/project-crud.spec.ts Updates column assertions and rewrites delete/cleanup flow to follow the new deactivate→purge lifecycle and hover-only actions.
e2e/information/information.spec.ts Makes the Component section locator strict-mode safe via { exact: true }.
e2e/environment/registry.spec.ts Removes obsolete columnheader assertion and fixes filter-property selector to match current antd DOM.

@nowgnuesLee nowgnuesLee changed the base branch from 06-02-fix_fr-2997_repair_broken_e2e_tests_for_access_control_rbac_credential_ to graphite-base/7693 June 8, 2026 11:12
@nowgnuesLee nowgnuesLee force-pushed the graphite-base/7693 branch from 969b03f to bddc4db Compare June 8, 2026 11:13
@nowgnuesLee nowgnuesLee force-pushed the 06-03-fix_fr-2998_repair_broken_e2e_tests_for_admin_operations branch from 5b4b85b to c510bc2 Compare June 8, 2026 11:13
@nowgnuesLee nowgnuesLee changed the base branch from graphite-base/7693 to 06-02-fix_fr-2997_repair_broken_e2e_tests_for_access_control_rbac_credential_ June 8, 2026 11:14
@nowgnuesLee nowgnuesLee requested a review from ironAiken2 June 9, 2026 06:55

@ironAiken2 ironAiken2 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@graphite-app

graphite-app Bot commented Jun 9, 2026

Copy link
Copy Markdown

Merge activity

Resolves #7633 (FR-2998)

**Stacked on**: #7688 (FR-2997) → #7684 (FR-2996) → #7679 (FR-2995) → #7676 (FR-2994) → #7653 (FR-2993) → #7652 (FR-2992)

Part of FR-2059 (Fix Broken E2E Tests Cases). Repairs the Admin & Operations sub-category — 4 originally failing tests + cascading rewrites to project-crud after exposing the new lifecycle UX. Final state: **45 pass / 0 fail / 2 skip** across `e2e/environment/`, `e2e/my-environment/`, `e2e/project/`, `e2e/maintenance/`, `e2e/information/`, `e2e/statistics/`.

## Root causes

- **`environment/registry.spec.ts:63`** (registry list columns): the `Control` column was removed when `ContainerRegistryListNodes` migrated to `BAINameActionCell` (actions embedded in the Registry Name cell). Removed the obsolete columnheader assertion; the 7 real columns are still validated.

- **`environment/registry.spec.ts:716`** (filter property): the test used the CSS class `.ant-select-content-value` which does not exist in this antd version. Actual class is `.ant-select-content` (with optional `.ant-select-content-has-value`). Switched to `page.locator('.ant-select-content').filter({ hasText: 'Registry Name' })`.

- **`information/information.spec.ts:6`** (page server details): strict-mode hit. `getByText('Component')` matched both the `ant-descriptions-title` and the `'Loading components...'` loader. Added `{ exact: true }`.

- **`project/project-crud.spec.ts:31`** (project list columns): the `Controls` column was removed when the project list migrated to `BAIProjectTable` + `BAINameActionCell`. The `Active` column was also removed; active vs inactive is now a filter radio group. The test now asserts the 4 real columns (`Name`, `Domain`, `Description`, `Type`) and verifies the Active radio is selected via `.ant-radio-button-wrapper-checked`.

### Cascading rewrites in `project/project-crud.spec.ts` (uncovered by the column fix)

- **`:78` (create), `:122` (edit)** — the Name cell now renders via `BAINameActionCell`. Replaced the exact `getByRole('cell', { name: PROJECT_NAME, exact: true })` assertion with `getByRole('row').filter({ hasText: PROJECT_NAME })` since the cell's accessible name includes hover-only action labels. The Edit test now hovers the row before clicking the (hover-only) `setting` action button.

- **`:200` (delete)** — the project lifecycle changed from a one-shot Purge dialog to a two-step flow: **Active → Deactivated (Popconfirm) → Purged (`BAIDeleteConfirmModal` with `requireConfirmInput`)**. Rewrote the test and shared `cleanupTestProject` helper to:
  1. Hover the row, click deactivate (action button `nth(1)`).
  2. Confirm the antd Popconfirm.
  3. Switch to the Inactive tab via the label wrapper (the radio input itself is hidden).
  4. Hover the deactivated row, click purge (action button `nth(2)`).
  5. Type the project name into `#confirmText`, click Purge.
  6. Verify the row is gone, then return to the Active tab.

  Mirrors the user / role / vfolder destructive-action conventions already standardized in FR-2992 through FR-2997.

## Files changed

- `e2e/environment/registry.spec.ts` — removed obsolete `Control` columnheader; corrected filter-property selector class
- `e2e/information/information.spec.ts` — `{ exact: true }` on `Component`
- `e2e/project/project-crud.spec.ts` — column-set update, hover-then-click for `setting`, two-step deactivate→purge for delete, shared `cleanupTestProject` helper

## Test plan

- [x] `pnpm exec playwright test e2e/environment/ e2e/my-environment/ e2e/project/ e2e/maintenance/ e2e/information/ e2e/statistics/ --workers=2` — 45 pass / 0 fail / 2 skip
- [x] `pnpm exec playwright test e2e/project/project-crud.spec.ts` (full file in serial mode) — all 5 tests pass
- [x] Individual retries of the parallel-only flake (`environment.spec.ts:188 user can manage apps`) pass cleanly (17s) — backend-state-dependent test, not a regression
@graphite-app graphite-app Bot force-pushed the 06-02-fix_fr-2997_repair_broken_e2e_tests_for_access_control_rbac_credential_ branch from bddc4db to c31b19f Compare June 9, 2026 07:49
@graphite-app graphite-app Bot force-pushed the 06-03-fix_fr-2998_repair_broken_e2e_tests_for_admin_operations branch from c510bc2 to 8004fac Compare June 9, 2026 07:50
graphite-app Bot pushed a commit that referenced this pull request Jun 9, 2026
Resolves #7634 (FR-2999)

**Stacked on**: #7693 (FR-2998) → ... → #7652 (FR-2992)

Part of FR-2059 (Fix Broken E2E Tests Cases). Repairs the Core UI sub-category — 1 originally failing test in `config.spec.ts` + addresses the root cause of 4 user-login failures (`dashboard`/`start`/`config`) that were the visible symptom of cross-spec contamination of the shared `user@lablup.com` account. Final state across `e2e/dashboard/`, `e2e/start/`, `e2e/config/`: **34 pass / 0 fail / 3 skip** + 1 occasional parallel-run flake.

## Root causes

### `config/config.spec.ts:14` (block list)

The `/serving` route was renamed to `/deployments` in FR-2664. The menu blocklist key follows the route name, so the test needed two updates:

```diff
-    blocklist: 'start,serving,session',
+    blocklist: 'start,deployments,session',
```

```diff
-      page.getByRole('menuitem', { name: 'Serving' })
+      page.getByRole('menuitem', { name: 'Deployments' })
```

### Cross-spec `user@lablup.com` contamination → 4 user-login failures eliminated

The four "Regular user" tests in this sub-category (`dashboard :62`, `dashboard :85`, `start-page :69`, `page-access-control :201`) all reported:

```
Login failed. Check login information.
Keypair information is missing.
```

This is what the Backend.AI webserver returns when `user@lablup.com`'s `(user, project, active keypair)` tuple cannot be resolved. Code-reading traced two tests in `e2e/rbac/rbac-role-detail.spec.ts` ('RBAC Role Assignments Management' describe block) that directly used `userInfo.user.email` (= `user@lablup.com`) — they assigned the user to a custom test role and then purged that role during cleanup. While role-purge cascading is intended not to affect the user's other roles, in this nightly environment that flow was correlated with subsequent user-login failures in unrelated specs.

**Refactor**: switched the 'RBAC Role Assignments Management' describe block to a **disposable fixture user**:

```ts
const ASSIGN_FIXTURE_RUN_ID =
  Date.now().toString(36) + Math.random().toString(36).slice(2, 6);
const ASSIGN_FIXTURE_EMAIL = `e2e-rbac-assign-${ASSIGN_FIXTURE_RUN_ID}@lablup.com`;
// ...

test.beforeAll(async ({ browser }) => {
  // Admin creates the disposable user via the Credential UI.
  // ...
});
// No afterAll: ASSIGN_FIXTURE_RUN_ID is globally unique; a periodic
// reaper sweeps stale `e2e-rbac-assign-*` accounts.
```

Both `Superadmin can assign a user to a role` and `Superadmin can revoke a single user from a role` tests now operate on this fresh user instead of `userInfo.user.email`. After this change `user@lablup.com` is fully isolated from the RBAC role tests, and the 4 user-login failures stop reproducing.

Mirrors the disposable-user pattern already applied in `e2e/credential/my-keypair-management.spec.ts` in FR-2997.

## Files changed

- `e2e/config/config.spec.ts` — `serving` → `deployments` in blocklist value and menuitem name
- `e2e/rbac/rbac-role-detail.spec.ts` — disposable fixture user for the Role Assignments describe block

## Test plan

- [x] `pnpm exec playwright test e2e/dashboard/ e2e/start/ e2e/config/ --workers=2` — 34 pass / 0 fail / 3 skip + 1 occasional flake (page-access-control :201)
- [x] `pnpm exec playwright test e2e/config/config.spec.ts:14` — pass
- [x] `pnpm exec playwright test e2e/rbac/rbac-role-detail.spec.ts:704 e2e/rbac/rbac-role-detail.spec.ts:790 --workers=1` — both pass with the fixture user (44s)
- [x] Direct DB inspection confirms `user@lablup.com`'s `user_roles` and `association_groups_users` rows are unchanged after running the affected RBAC tests
Base automatically changed from 06-02-fix_fr-2997_repair_broken_e2e_tests_for_access_control_rbac_credential_ to main June 9, 2026 07:56
@graphite-app graphite-app Bot merged commit 8004fac into main Jun 9, 2026
4 checks passed
@graphite-app graphite-app Bot deleted the 06-03-fix_fr-2998_repair_broken_e2e_tests_for_admin_operations branch June 9, 2026 07:56
agatha197 pushed a commit that referenced this pull request Jun 9, 2026
Resolves #7633 (FR-2998)

**Stacked on**: #7688 (FR-2997) → #7684 (FR-2996) → #7679 (FR-2995) → #7676 (FR-2994) → #7653 (FR-2993) → #7652 (FR-2992)

Part of FR-2059 (Fix Broken E2E Tests Cases). Repairs the Admin & Operations sub-category — 4 originally failing tests + cascading rewrites to project-crud after exposing the new lifecycle UX. Final state: **45 pass / 0 fail / 2 skip** across `e2e/environment/`, `e2e/my-environment/`, `e2e/project/`, `e2e/maintenance/`, `e2e/information/`, `e2e/statistics/`.

## Root causes

- **`environment/registry.spec.ts:63`** (registry list columns): the `Control` column was removed when `ContainerRegistryListNodes` migrated to `BAINameActionCell` (actions embedded in the Registry Name cell). Removed the obsolete columnheader assertion; the 7 real columns are still validated.

- **`environment/registry.spec.ts:716`** (filter property): the test used the CSS class `.ant-select-content-value` which does not exist in this antd version. Actual class is `.ant-select-content` (with optional `.ant-select-content-has-value`). Switched to `page.locator('.ant-select-content').filter({ hasText: 'Registry Name' })`.

- **`information/information.spec.ts:6`** (page server details): strict-mode hit. `getByText('Component')` matched both the `ant-descriptions-title` and the `'Loading components...'` loader. Added `{ exact: true }`.

- **`project/project-crud.spec.ts:31`** (project list columns): the `Controls` column was removed when the project list migrated to `BAIProjectTable` + `BAINameActionCell`. The `Active` column was also removed; active vs inactive is now a filter radio group. The test now asserts the 4 real columns (`Name`, `Domain`, `Description`, `Type`) and verifies the Active radio is selected via `.ant-radio-button-wrapper-checked`.

### Cascading rewrites in `project/project-crud.spec.ts` (uncovered by the column fix)

- **`:78` (create), `:122` (edit)** — the Name cell now renders via `BAINameActionCell`. Replaced the exact `getByRole('cell', { name: PROJECT_NAME, exact: true })` assertion with `getByRole('row').filter({ hasText: PROJECT_NAME })` since the cell's accessible name includes hover-only action labels. The Edit test now hovers the row before clicking the (hover-only) `setting` action button.

- **`:200` (delete)** — the project lifecycle changed from a one-shot Purge dialog to a two-step flow: **Active → Deactivated (Popconfirm) → Purged (`BAIDeleteConfirmModal` with `requireConfirmInput`)**. Rewrote the test and shared `cleanupTestProject` helper to:
  1. Hover the row, click deactivate (action button `nth(1)`).
  2. Confirm the antd Popconfirm.
  3. Switch to the Inactive tab via the label wrapper (the radio input itself is hidden).
  4. Hover the deactivated row, click purge (action button `nth(2)`).
  5. Type the project name into `#confirmText`, click Purge.
  6. Verify the row is gone, then return to the Active tab.

  Mirrors the user / role / vfolder destructive-action conventions already standardized in FR-2992 through FR-2997.

## Files changed

- `e2e/environment/registry.spec.ts` — removed obsolete `Control` columnheader; corrected filter-property selector class
- `e2e/information/information.spec.ts` — `{ exact: true }` on `Component`
- `e2e/project/project-crud.spec.ts` — column-set update, hover-then-click for `setting`, two-step deactivate→purge for delete, shared `cleanupTestProject` helper

## Test plan

- [x] `pnpm exec playwright test e2e/environment/ e2e/my-environment/ e2e/project/ e2e/maintenance/ e2e/information/ e2e/statistics/ --workers=2` — 45 pass / 0 fail / 2 skip
- [x] `pnpm exec playwright test e2e/project/project-crud.spec.ts` (full file in serial mode) — all 5 tests pass
- [x] Individual retries of the parallel-only flake (`environment.spec.ts:188 user can manage apps`) pass cleanly (17s) — backend-state-dependent test, not a regression
agatha197 pushed a commit that referenced this pull request Jun 9, 2026
Resolves #7634 (FR-2999)

**Stacked on**: #7693 (FR-2998) → ... → #7652 (FR-2992)

Part of FR-2059 (Fix Broken E2E Tests Cases). Repairs the Core UI sub-category — 1 originally failing test in `config.spec.ts` + addresses the root cause of 4 user-login failures (`dashboard`/`start`/`config`) that were the visible symptom of cross-spec contamination of the shared `user@lablup.com` account. Final state across `e2e/dashboard/`, `e2e/start/`, `e2e/config/`: **34 pass / 0 fail / 3 skip** + 1 occasional parallel-run flake.

## Root causes

### `config/config.spec.ts:14` (block list)

The `/serving` route was renamed to `/deployments` in FR-2664. The menu blocklist key follows the route name, so the test needed two updates:

```diff
-    blocklist: 'start,serving,session',
+    blocklist: 'start,deployments,session',
```

```diff
-      page.getByRole('menuitem', { name: 'Serving' })
+      page.getByRole('menuitem', { name: 'Deployments' })
```

### Cross-spec `user@lablup.com` contamination → 4 user-login failures eliminated

The four "Regular user" tests in this sub-category (`dashboard :62`, `dashboard :85`, `start-page :69`, `page-access-control :201`) all reported:

```
Login failed. Check login information.
Keypair information is missing.
```

This is what the Backend.AI webserver returns when `user@lablup.com`'s `(user, project, active keypair)` tuple cannot be resolved. Code-reading traced two tests in `e2e/rbac/rbac-role-detail.spec.ts` ('RBAC Role Assignments Management' describe block) that directly used `userInfo.user.email` (= `user@lablup.com`) — they assigned the user to a custom test role and then purged that role during cleanup. While role-purge cascading is intended not to affect the user's other roles, in this nightly environment that flow was correlated with subsequent user-login failures in unrelated specs.

**Refactor**: switched the 'RBAC Role Assignments Management' describe block to a **disposable fixture user**:

```ts
const ASSIGN_FIXTURE_RUN_ID =
  Date.now().toString(36) + Math.random().toString(36).slice(2, 6);
const ASSIGN_FIXTURE_EMAIL = `e2e-rbac-assign-${ASSIGN_FIXTURE_RUN_ID}@lablup.com`;
// ...

test.beforeAll(async ({ browser }) => {
  // Admin creates the disposable user via the Credential UI.
  // ...
});
// No afterAll: ASSIGN_FIXTURE_RUN_ID is globally unique; a periodic
// reaper sweeps stale `e2e-rbac-assign-*` accounts.
```

Both `Superadmin can assign a user to a role` and `Superadmin can revoke a single user from a role` tests now operate on this fresh user instead of `userInfo.user.email`. After this change `user@lablup.com` is fully isolated from the RBAC role tests, and the 4 user-login failures stop reproducing.

Mirrors the disposable-user pattern already applied in `e2e/credential/my-keypair-management.spec.ts` in FR-2997.

## Files changed

- `e2e/config/config.spec.ts` — `serving` → `deployments` in blocklist value and menuitem name
- `e2e/rbac/rbac-role-detail.spec.ts` — disposable fixture user for the Role Assignments describe block

## Test plan

- [x] `pnpm exec playwright test e2e/dashboard/ e2e/start/ e2e/config/ --workers=2` — 34 pass / 0 fail / 3 skip + 1 occasional flake (page-access-control :201)
- [x] `pnpm exec playwright test e2e/config/config.spec.ts:14` — pass
- [x] `pnpm exec playwright test e2e/rbac/rbac-role-detail.spec.ts:704 e2e/rbac/rbac-role-detail.spec.ts:790 --workers=1` — both pass with the fixture user (44s)
- [x] Direct DB inspection confirms `user@lablup.com`'s `user_roles` and `association_groups_users` rows are unchanged after running the affected RBAC tests
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L 100~500 LoC

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Fix broken E2E tests — Admin & Operations

3 participants