Skip to content

[CONSOLE-5243] Migrate topology-ci.feature from Cypress to Playwright#16589

Open
trgeiger wants to merge 1 commit into
openshift:mainfrom
trgeiger:CONSOLE-5243
Open

[CONSOLE-5243] Migrate topology-ci.feature from Cypress to Playwright#16589
trgeiger wants to merge 1 commit into
openshift:mainfrom
trgeiger:CONSOLE-5243

Conversation

@trgeiger

@trgeiger trgeiger commented Jun 10, 2026

Copy link
Copy Markdown
Contributor
  • Convert Gherkin scenarios to idiomatic Playwright test structure
  • Add data-test attribute to git URL input field in GitSection.tsx
  • Implement test scenarios: empty state, app creation, editing groupings, display options, workload deletion
  • Create TopologyPage and TopologySidebarPage objects for Topology Playwright tests
  • Mock GitHub API requests for .NET sample repository
  • Follow Console's layered test architecture with proper cleanup

Tests migrated: 5 scenarios → 5 test cases

Analysis / Root cause:

Solution description:

Screenshots / screen recording:

Test setup:

Test cases:

Browser conformance:

  • Chrome
  • Firefox
  • Safari (or Epiphany on Linux)

Additional info:

Reviewers and assignees:

Summary by CodeRabbit

  • Tests
    • Added comprehensive end-to-end test coverage for topology features, including empty state validation, application building workflow, workload editing, display options, and workload deletion.
    • Enhanced test infrastructure with page object classes to improve test reliability and maintainability.

@coderabbitai

coderabbitai Bot commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository: openshift/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 8fc998a1-120a-4f05-b1a6-880ae168091a

📥 Commits

Reviewing files that changed from the base of the PR and between 4964f85 and 6667d99.

📒 Files selected for processing (8)
  • frontend/e2e/pages/topology-page.ts
  • frontend/e2e/pages/topology-sidebar-page.ts
  • frontend/e2e/tests/topology/topology-ci.spec.ts
  • frontend/packages/topology/integration-tests/features/e2e/topology-ci.feature
  • frontend/packages/topology/integration-tests/package.json
  • frontend/packages/topology/src/components/dropdowns/ApplicationSelector.tsx
  • frontend/packages/topology/src/components/graph-view/components/nodes/BaseNode.tsx
  • frontend/packages/topology/src/components/page/TopologyPageToolbar.tsx
💤 Files with no reviewable changes (1)
  • frontend/packages/topology/integration-tests/features/e2e/topology-ci.feature
✅ Files skipped from review due to trivial changes (3)
  • frontend/packages/topology/src/components/graph-view/components/nodes/BaseNode.tsx
  • frontend/packages/topology/src/components/page/TopologyPageToolbar.tsx
  • frontend/packages/topology/src/components/dropdowns/ApplicationSelector.tsx
🚧 Files skipped from review as they are similar to previous changes (2)
  • frontend/e2e/pages/topology-sidebar-page.ts
  • frontend/e2e/pages/topology-page.ts

Walkthrough

This PR introduces comprehensive E2E test infrastructure for the topology UI, migrating from Cypress to Playwright. It adds page-objects, test attributes to components for reliable element targeting, and a multi-scenario test suite covering empty state, application building, workload editing, display options, and deletion workflows with namespace lifecycle management.

Changes

Topology E2E Test Suite

Layer / File(s) Summary
Playwright page objects for topology UI
frontend/e2e/pages/topology-page.ts, frontend/e2e/pages/topology-sidebar-page.ts
TopologyPage and TopologySidebarPage page-objects expose locators for topology UI controls and provide helpers for navigation, node interactions, context menu selection, display options, and sidebar action invocation.
Data-test attributes for component targeting
frontend/packages/topology/src/components/dropdowns/ApplicationSelector.tsx, frontend/packages/topology/src/components/graph-view/components/nodes/BaseNode.tsx, frontend/packages/topology/src/components/page/TopologyPageToolbar.tsx
ApplicationSelector, BaseNode, and TopologyPageToolbar add data-test attributes (application-form-app-input, base-node-handler, topology-switcher-view) to enable reliable element selection in Playwright tests.
E2E test suite for topology workflows
frontend/e2e/tests/topology/topology-ci.spec.ts
Five test cases validate administrator workflows: empty state display with disabled controls, building an application via the graph with GitHub API mocking and git URL validation, editing workload application grouping via context menu, verifying Display dropdown option defaults, and deleting a workload through sidebar action menu with deletion confirmation.
Test configuration updates
frontend/packages/topology/integration-tests/package.json
Remove explicit --spec "features/*/topology-ci.feature" from test-cypress-headless script, transitioning from hard-coded Cypress spec path to default discovery.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Suggested labels

ok-to-test, kind/cypress, verified

Suggested reviewers

  • spadgett
  • sg00dwin
  • rhamilto
🚥 Pre-merge checks | ✅ 13 | ❌ 2

❌ Failed checks (2 inconclusive)

Check name Status Explanation Resolution
Description check ❓ Inconclusive The description includes a summary of key changes and migration details, but lacks required sections like Analysis/Root cause, Solution description details, Test setup, and Browser conformance checkboxes. Fill in Analysis/Root cause, complete Solution description with more details, specify Test setup requirements, select Browser conformance checkboxes, and assign appropriate reviewers per template.
Test Structure And Quality ❓ Inconclusive Custom check requests Ginkgo test review, but this PR contains only Playwright tests (TypeScript/JavaScript with @playwright/test framework). The check is inapplicable. Clarify whether the check applies to Playwright E2E tests or if it's intended only for Go/Ginkgo backend tests.
✅ Passed checks (13 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: migrating Cypress-based topology-ci.feature tests to Playwright, directly aligning with the PR's core objective.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Stable And Deterministic Test Names ✅ Passed All 5 test names are static and descriptive with no dynamic values. The dynamic namespace is properly isolated to test bodies, not titles.
Microshift Test Compatibility ✅ Passed PR adds Playwright frontend e2e tests (TypeScript), not Ginkgo backend e2e tests. MicroShift Test Compatibility check is only for Ginkgo tests, so it is not applicable.
Single Node Openshift (Sno) Test Compatibility ✅ Passed PR adds Playwright frontend e2e tests, not Ginkgo backend tests. Custom check targets Ginkgo tests (Go-based); this PR contains only TypeScript/JavaScript Playwright tests for Console frontend UI.
Topology-Aware Scheduling Compatibility ✅ Passed PR migrates Cypress tests to Playwright for frontend UI only; contains no deployment manifests, operator code, controllers, or scheduling constraints. Check is not applicable.
Ote Binary Stdout Contract ✅ Passed PR is frontend-only (Playwright and React/TypeScript). No Go code, process-level entry points, or stdout writes that could violate OTE binary contract.
Ipv6 And Disconnected Network Test Compatibility ✅ Passed Custom check applies only to Ginkgo e2e tests. PR adds Playwright UI tests using test.describe() and test() patterns, not Ginkgo's It() and Describe() patterns. Check is not applicable.
No-Weak-Crypto ✅ Passed No weak crypto patterns (MD5, SHA1, DES, RC4, 3DES, Blowfish, ECB), custom crypto, or insecure secret comparisons found. PR contains only test code with no security operations.
Container-Privileges ✅ Passed PR contains no K8s manifests or container configs with privileged settings; only TypeScript, React, and test files—check not applicable.
No-Sensitive-Data-In-Logs ✅ Passed No logging statements or sensitive data exposure detected. Code contains only test helpers, assertions, and safe test data using public repository mocks with no credentials or PII.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@openshift-ci openshift-ci Bot requested review from sg00dwin and spadgett June 10, 2026 16:25
@openshift-ci openshift-ci Bot added the component/dev-console Related to dev-console label Jun 10, 2026
@openshift-ci

openshift-ci Bot commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: trgeiger
Once this PR has been reviewed and has the lgtm label, please assign rawagner for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@openshift-ci openshift-ci Bot added the component/topology Related to topology label Jun 10, 2026
- Convert Gherkin scenarios to idiomatic Playwright test structure
- Add data-test attribute to git URL input field in GitSection.tsx
- Implement test scenarios: empty state, app creation, editing groupings, display options, workload deletion
- Create TopologyPage and TopologySidebarPage objects for Topology
  Playwright tests
- Mock GitHub API requests for .NET sample repository
- Follow Console's layered test architecture with proper cleanup
- Delete old Cypress topology CI tests

Tests migrated: 5 scenarios → 5 test cases

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@frontend/e2e/pages/topology-page.ts`:
- Around line 121-123: The method typeInQuickSearch doesn't await the Playwright
fill action, causing callers to proceed before typing finishes; update the
function to await the fill call by changing the invocation to await
this.page.getByLabel('Quick search bar').fill(text) so the Promise returned by
typeInQuickSearch resolves only after the fill completes (retain the existing
async typeInQuickSearch(text: string): Promise<void> signature).
- Around line 91-95: The clickOnNode function currently searches then grabs
this.page.getByTestId('base-node-handler').first(), which ignores nodeName and
can click the wrong node; update clickOnNode to scope the locator to the
specific nodeName (e.g., use a locator that filters handlers by the nodeName
text or an attribute after calling this.search(nodeName)) and then call
this.robustClick on that scoped locator (instead of .first()) so the clicked
handler corresponds to the requested nodeName; keep references to the existing
methods clickOnNode, search, and robustClick while replacing the unscoped
this.page.getByTestId('base-node-handler').first() with a locator that matches
nodeName.

In `@frontend/e2e/tests/topology/topology-ci.spec.ts`:
- Around line 50-170: Current tests share a workload created in the first test
("Build the application from topology page") and then rely on it in later tests,
causing cascading failures; move that provisioning into an explicit suite-level
setup/teardown or have each test create and clean its own workload. Concretely,
extract the steps that create the workload (calls to
TopologyPage.clickStartBuilding, fill Git Repo URL, form fills,
TopologyPage.verifyWorkloadVisible) into a beforeAll that creates the "dotnet"
workload and an afterAll that deletes it (use TopologyPage.clickOnNode +
TopologySidebarPage.selectAction('Delete Deployment') +
TopologyPage.clickConfirmAction), or alternatively wrap those creation and
deletion steps inside each dependent test so they are self-contained; ensure
tests that currently call navigateToTopologyGraph, verifyWorkloadVisible,
rightClickOnNode, selectContextMenuAction, clickDisplayOptions, getExpandToggle,
and getDisplayOptionCheckbox work against the explicitly provisioned workload.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository: openshift/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: a4665709-60e9-4839-bb6f-aeacfd55fddd

📥 Commits

Reviewing files that changed from the base of the PR and between d7aca4b and 4964f85.

📒 Files selected for processing (7)
  • frontend/e2e/pages/topology-page.ts
  • frontend/e2e/pages/topology-sidebar-page.ts
  • frontend/e2e/tests/topology/topology-ci.spec.ts
  • frontend/packages/dev-console/src/components/import/ImportSampleForm.tsx
  • frontend/packages/dev-console/src/components/import/app/AppSection.tsx
  • frontend/packages/dev-console/src/components/import/git/GitSection.tsx
  • frontend/packages/topology/src/components/dropdowns/ApplicationSelector.tsx

Comment on lines +91 to +95
async clickOnNode(nodeName: string): Promise<void> {
await this.search(nodeName);
const node = this.page.getByTestId('base-node-handler');
await this.robustClick(node.first());
}

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.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

clickOnNode ignores the requested node and clicks the first handler.

Line 93–94 uses base-node-handler.first() instead of a locator scoped by nodeName, so this can click the wrong workload when multiple nodes are present.

Suggested fix
 async clickOnNode(nodeName: string): Promise<void> {
   await this.search(nodeName);
-  const node = this.page.getByTestId('base-node-handler');
-  await this.robustClick(node.first());
+  const node = this.page
+    .getByTestId('base-node-handler')
+    .filter({ has: this.getNode(nodeName) })
+    .first();
+  await expect(node).toBeVisible({ timeout: 30_000 });
+  await this.robustClick(node);
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontend/e2e/pages/topology-page.ts` around lines 91 - 95, The clickOnNode
function currently searches then grabs
this.page.getByTestId('base-node-handler').first(), which ignores nodeName and
can click the wrong node; update clickOnNode to scope the locator to the
specific nodeName (e.g., use a locator that filters handlers by the nodeName
text or an attribute after calling this.search(nodeName)) and then call
this.robustClick on that scoped locator (instead of .first()) so the clicked
handler corresponds to the requested nodeName; keep references to the existing
methods clickOnNode, search, and robustClick while replacing the unscoped
this.page.getByTestId('base-node-handler').first() with a locator that matches
nodeName.

Comment on lines +121 to +123
async typeInQuickSearch(text: string): Promise<void> {
this.page.getByLabel('Quick search bar').fill(text);
}

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.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Await the quick-search fill action.

typeInQuickSearch does not await fill, so callers can continue before typing completes.

Suggested fix
 async typeInQuickSearch(text: string): Promise<void> {
-  this.page.getByLabel('Quick search bar').fill(text);
+  await this.page.getByLabel('Quick search bar').fill(text);
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
async typeInQuickSearch(text: string): Promise<void> {
this.page.getByLabel('Quick search bar').fill(text);
}
async typeInQuickSearch(text: string): Promise<void> {
await this.page.getByLabel('Quick search bar').fill(text);
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontend/e2e/pages/topology-page.ts` around lines 121 - 123, The method
typeInQuickSearch doesn't await the Playwright fill action, causing callers to
proceed before typing finishes; update the function to await the fill call by
changing the invocation to await this.page.getByLabel('Quick search
bar').fill(text) so the Promise returned by typeInQuickSearch resolves only
after the fill completes (retain the existing async typeInQuickSearch(text:
string): Promise<void> signature).

Comment on lines +50 to +170
test('Build the application from topology page', async ({ page }) => {
const topology = new TopologyPage(page);
await page.goto('/');
await topology.switchPerspective('Administrator');
await topology.navigateToTopologyGraph(NS);

await test.step('Open quick search and select .NET builder image', async () => {
await topology.clickStartBuilding();
await topology.typeInQuickSearch('.NET');
await page.getByTestId('item-name-.NET SDK-Builder Images').first().click();
});

await test.step('Create application from quick search', async () => {
await expect(page.getByRole('progressbar')).not.toBeAttached({ timeout: 60_000 });
await page
.getByRole('listitem')
.filter({ hasText: /^\.NET SDK.*Builder Images$/ })
.first()
.click();
await page.getByRole('button', { name: 'Create' }).click();
});

await test.step('Mock GitHub API and fill git repo URL', async () => {
const apiBase = 'https://api.github.com/repos/redhat-developer/s2i-dotnetcore-ex';
await page.route(new RegExp(`${apiBase.replace(/\//g, '\\/')}(\\?.*)?$`), async (route) => {
await route.fulfill({ status: 200, contentType: 'application/json', body: JSON.stringify(repoMock) });
});
await page.route(new RegExp(`${apiBase.replace(/\//g, '\\/')}\/contents\\/?(\\?.*)?$`), async (route) => {
await route.fulfill({ status: 200, contentType: 'application/json', body: JSON.stringify(contentsMock) });
});
await page.route(new RegExp(`${apiBase.replace(/\//g, '\\/')}\/.*package\\.json`), async (route) => {
await route.fulfill({ status: 404 });
});
await page.route(/\/api\/devfile\//, async (route) => {
await route.fulfill({ status: 404 });
});
await page.route(new RegExp(`${apiBase.replace(/\//g, '\\/')}\/.*func\\.yaml`), async (route) => {
await route.fulfill({ status: 404 });
});

await page.getByLabel('Git Repo URL').clear();
await page.getByLabel('Git Repo URL').fill('https://github.com/redhat-developer/s2i-dotnetcore-ex');
await expect(page.locator('#form-input-git-url-field-helper')).toContainText('Validated', {
timeout: 120_000,
});
});

await test.step('Enter application and workload names', async () => {
await page.locator('#form-input-application-name-field').fill('dotnet-app');
await page.locator('#form-input-name-field').fill('dotnet');
});

await test.step('Select Deployment resource type and submit', async () => {
await page.locator('#form-select-input-resources-field').scrollIntoViewIfNeeded();
await page.locator('#form-select-input-resources-field').click();
await page.locator('#select-option-resources-kubernetes').click();
await page.getByTestId('save-changes').click();
});

await test.step('Verify workload appears in topology', async () => {
await topology.verifyWorkloadVisible('dotnet', 60_000);
});
});

test('Edit workload application groupings: T-09-TC01', async ({ page }) => {
const topology = new TopologyPage(page);
await page.goto('/');
await topology.switchPerspective('Administrator');
await topology.navigateToTopologyGraph(NS);

await test.step('Right-click dotnet and select Edit', async () => {
await topology.rightClickOnNode('dotnet');
await topology.selectContextMenuAction('Edit dotnet');
});

await test.step('Change application groupings to "app"', async () => {
const appDropdown = page.locator('[id$="application-name-field"]');
await expect(appDropdown).toBeVisible({ timeout: 30_000 });
await appDropdown.click();
await page.getByTestId('console-select-item').first().click();
await page.getByTestId('application-form-app-input').fill('app');
});

await test.step('Save and verify workload persists', async () => {
await page.getByRole('button', { name: 'Save' }).click();
await topology.navigateToTopologyGraph(NS);
await topology.verifyWorkloadVisible('dotnet', 60_000);
await expect(topology.getGraphSurface()).toBeAttached();
});
});

test('Default state of Display dropdown: T-16-TC01', async ({ page }) => {
const topology = new TopologyPage(page);
await page.goto('/');
await topology.switchPerspective('Administrator');
await topology.navigateToTopologyGraph(NS);

await topology.clickDisplayOptions();
await expect(topology.getExpandToggle()).toBeChecked();
await expect(topology.getDisplayOptionCheckbox('Pod count')).not.toBeChecked();
await expect(topology.getDisplayOptionCheckbox('Labels')).toBeChecked();
});

test('Delete workload via Action menu: T-15-TC01', async ({ page }) => {
const topology = new TopologyPage(page);
const sidebar = new TopologySidebarPage(page);
await page.goto('/');
await topology.switchPerspective('Administrator');
await topology.navigateToTopologyGraph(NS);

await test.step('Open sidebar and delete via Actions menu', async () => {
await topology.clickOnNode('dotnet');
await sidebar.verify();
await sidebar.selectAction('Delete Deployment');
});

await test.step('Confirm deletion and verify empty state', async () => {
await topology.clickConfirmAction();
await expect(topology.getNoResourcesFound()).toBeVisible({ timeout: 60_000 });
});
});

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.

⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

Later tests depend on state created by an earlier test case.

The workload is created in one test() and then edited/deleted in subsequent test() blocks, so a single failure cascades and obscures root causes. Keep the shared-resource exception, but move shared workload provisioning to explicit suite setup (or make each test provision/cleanup its own workload).

As per coding guidelines, frontend/e2e/tests/**/*.spec.ts should keep tests self-contained; based on learnings, shared resources are acceptable when explicitly managed in suite setup/teardown.

🧰 Tools
🪛 ast-grep (0.43.0)

[warning] 73-73: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(${apiBase.replace(/\//g, '\\/')}(\\?.*)?$)
Note: [CWE-1333] Inefficient Regular Expression Complexity

(regexp-from-variable)


[warning] 76-76: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(${apiBase.replace(/\//g, '\\/')}\/contents\\/?(\\?.*)?$)
Note: [CWE-1333] Inefficient Regular Expression Complexity

(regexp-from-variable)


[warning] 79-79: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(${apiBase.replace(/\//g, '\\/')}\/.*package\\.json)
Note: [CWE-1333] Inefficient Regular Expression Complexity

(regexp-from-variable)


[warning] 85-85: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(${apiBase.replace(/\//g, '\\/')}\/.*func\\.yaml)
Note: [CWE-1333] Inefficient Regular Expression Complexity

(regexp-from-variable)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontend/e2e/tests/topology/topology-ci.spec.ts` around lines 50 - 170,
Current tests share a workload created in the first test ("Build the application
from topology page") and then rely on it in later tests, causing cascading
failures; move that provisioning into an explicit suite-level setup/teardown or
have each test create and clean its own workload. Concretely, extract the steps
that create the workload (calls to TopologyPage.clickStartBuilding, fill Git
Repo URL, form fills, TopologyPage.verifyWorkloadVisible) into a beforeAll that
creates the "dotnet" workload and an afterAll that deletes it (use
TopologyPage.clickOnNode + TopologySidebarPage.selectAction('Delete Deployment')
+ TopologyPage.clickConfirmAction), or alternatively wrap those creation and
deletion steps inside each dependent test so they are self-contained; ensure
tests that currently call navigateToTopologyGraph, verifyWorkloadVisible,
rightClickOnNode, selectContextMenuAction, clickDisplayOptions, getExpandToggle,
and getDisplayOptionCheckbox work against the explicitly provisioned workload.

Sources: Coding guidelines, Learnings

@rhamilto rhamilto left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Plus a few suggestions from Claude:

Bugs
1. Missing await in typeInQuickSearch — [topology-page.ts:121](vscode-webview://1vtcgfscfosoccqkvs1psrnb2o14e4t7o2f82teppc96updftt2k/frontend/e2e/pages/topology-page.ts#L121)

async typeInQuickSearch(text: string): Promise<void> {
    this.page.getByLabel('Quick search bar').fill(text);  // ← missing await
}

fill() returns a Promise<void> — without await, the fill races with whatever comes next. Should be:

await this.page.getByLabel('Quick search bar').fill(text);

Migration Guideline Issues

2. PR description mentions a change not in the diff. The description says "Add data-test attribute to git URL input field in GitSection.tsx" but no GitSection.tsx changes are included. The spec uses page.getByLabel('Git Repo URL') instead, which works. Either update the description to remove the stale line, or add the data-test attribute if it was intended.

3. Unused import in topology-sidebar-page.ts — [line 1](vscode-webview://1vtcgfscfosoccqkvs1psrnb2o14e4t7o2f82teppc96updftt2k/frontend/e2e/pages/topology-sidebar-page.ts#L1)

import type { Locator } from '@playwright/test';  // unused — no explicit Locator annotation
Remove the unused import; dialog and actionsDropdown types are inferred.

Suggestions (non-blocking)

4. Missing semicolons — inconsistent style — Several lines are missing trailing semicolons, which is inconsistent with the existing codebase style:

[topology-page.ts:8](vscode-webview://1vtcgfscfosoccqkvs1psrnb2o14e4t7o2f82teppc96updftt2k/frontend/e2e/pages/topology-page.ts#L8): private readonly switcher = ... (no semicolon)
[topology-page.ts:105](vscode-webview://1vtcgfscfosoccqkvs1psrnb2o14e4t7o2f82teppc96updftt2k/frontend/e2e/pages/topology-page.ts#L105): const actionButton = ... (no semicolon)
[topology-page.ts:115](vscode-webview://1vtcgfscfosoccqkvs1psrnb2o14e4t7o2f82teppc96updftt2k/frontend/e2e/pages/topology-page.ts#L115): return this.page.getByRole('menuitem', {name: label}).getByRole('checkbox'); (missing spaces in {name: label})

Also: note the console code base has a /pre-push-review skill that is helpful. Note you'll need to have the CodeRabbit CLI installed for maximum benefit.


const MOCK_DIR = path.join(
path.dirname(fileURLToPath(import.meta.url)),
'../../../packages/dev-console/integration-tests/testData/git-import/s2i-dotnetcore-ex',

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We should probably duplicate the mock data since packages/dev-console/integration-tests should eventually be deleted.

"scripts": {
"test-cypress": "../../../node_modules/.bin/cypress open --env openshift=true",
"test-cypress-headless": "node --max-old-space-size=4096 ../../../node_modules/.bin/cypress run ${CYPRESS_RECORD_KEY:+--record} --env openshift=true --browser ${BRIDGE_E2E_BROWSER_NAME:-electron} --headless --spec \"features/*/topology-ci.feature\"",
"test-cypress-headless": "node --max-old-space-size=4096 ../../../node_modules/.bin/cypress run ${CYPRESS_RECORD_KEY:+--record} --env openshift=true --browser ${BRIDGE_E2E_BROWSER_NAME:-electron} --headless",

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This whole file should be going away at some point. Up to you if that's in this PR or a separate one.

await topology.navigateToTopologyGraph(NS);
await topology.verifyWorkloadVisible('dotnet', 60_000);
await expect(topology.getGraphSurface()).toBeAttached();
});

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Claude noticed we're not confirming the application grouping exists:

In the "Edit workload application groupings" test (Scenario 3), the Cypress test verifies the grouping was renamed by searching for the new name "app". The Playwright test only checks that the workload "dotnet" is still visible — it never confirms the application grouping actually changed. To fix, the test should assert that the app group label "app" is visible, e.g., by searching for "app" and verifying the group node appears.

@openshift-ci

openshift-ci Bot commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

@trgeiger: The following tests failed, say /retest to rerun all failed tests or /retest-required to rerun all mandatory failed tests:

Test name Commit Details Required Rerun command
ci/prow/e2e-gcp-console 6667d99 link true /test e2e-gcp-console
ci/prow/frontend 6667d99 link true /test frontend
ci/prow/e2e-playwright 6667d99 link false /test e2e-playwright

Full PR test history. Your PR dashboard.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

component/dev-console Related to dev-console component/topology Related to topology

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants