feat(ci): add UI E2E tests on GKE by davdhacs · Pull Request #21421 · stackrox/stackrox · GitHub
Skip to content

feat(ci): add UI E2E tests on GKE#21421

Draft
davdhacs wants to merge 4 commits into
masterfrom
davdhacs/ui-e2e-gke-only
Draft

feat(ci): add UI E2E tests on GKE#21421
davdhacs wants to merge 4 commits into
masterfrom
davdhacs/ui-e2e-gke-only

Conversation

@davdhacs

Copy link
Copy Markdown
Contributor

Description

Adds Cypress UI E2E tests running on GKE in GitHub Actions. Uses a shared GKE cluster with 9 parallel Cypress shards, triggered by the e2e-ui-gke label on PRs or via workflow_dispatch.

Components:

  • ui-e2e.yaml workflow: setup-shards (waterline bin-packing), provision-gke, sharded gke-e2e, cleanup-gke
  • deploy-stackrox action: deploys StackRox via roxie with scanner v2 and API token generation
  • create-gke-cluster action: adds auto-cleanup input so multi-job workflows can disable the post-step cleanup
  • build.yaml: adds ui-e2e job gated on e2e-ui-gke label
  • networkDeploymentSidebar.test.js: uses deploymentNode selector instead of fragile selectDeployment dropdown filter

Stripped-down version of #20345 with only GKE support (no KinD, no infra, no OCP).

User-facing documentation

Testing and quality

  • the change is production ready: the change is GA, or otherwise the functionality is gated by a feature flag
  • CI results are inspected

Automated testing

  • added unit tests
  • added e2e tests
  • added regression tests
  • added compatibility tests
  • modified existing tests

How I validated my change

3 verification runs on the davdhacs/ui-e2e branch with 9/9 GKE shards passing. This PR is a minimal extraction of the proven workflow.

Add a Cypress UI E2E workflow that runs on GKE with 9 parallel shards.
Triggered by the `e2e-ui-gke` label on PRs, or via workflow_dispatch.

New files:
- .github/workflows/ui-e2e.yaml: orchestrates setup-shards, provision-gke,
  gke-e2e (sharded Cypress), and cleanup-gke
- .github/actions/deploy-stackrox: deploys StackRox via roxie with API
  token generation

Modified:
- .github/actions/create-gke-cluster: add auto-cleanup input (default true)
  so multi-job workflows can disable the post-step cleanup
- .github/workflows/build.yaml: add ui-e2e job gated on e2e-ui-gke label
- networkDeploymentSidebar test: use deploymentNode selector instead of
  fragile selectDeployment dropdown filter

Partially generated by AI.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@openshift-ci

openshift-ci Bot commented Jun 25, 2026

Copy link
Copy Markdown

@coderabbitai

coderabbitai Bot commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Summary by CodeRabbit

  • New Features
    • Added a reusable UI E2E testing workflow that provisions a temporary GKE environment and runs Cypress tests against a deployed StackRox instance.
    • Updated the main build pipeline to conditionally run the UI E2E job on PRs with the specified label.
    • Enhanced GKE cluster creation with an auto-cleanup toggle (enabled by default).
    • Added a new deployment action with configurable image tag, sizing, scanner mode, exposure, and background execution.
  • Bug Fixes
    • Improved Network Graph sidebar testing to validate the correct sensor node details for the selected namespace.

Walkthrough

The PR adds a reusable UI E2E workflow that shards Cypress specs, provisions a GKE cluster, deploys StackRox, runs shard-parallel tests, and cleans up the cluster. It also wires the workflow into the build pipeline, adds a deploy-stackrox composite action, and updates one Cypress sidebar test.

Changes

UI E2E provisioning and deployment

Layer / File(s) Summary
GKE cleanup gating
.github/actions/create-gke-cluster/action.yaml
create-gke-cluster adds auto-cleanup and gates cleanup registration on the new input.
Deploy StackRox action interface
.github/actions/deploy-stackrox/action.yaml
Deploy StackRox declares its inputs, describes foreground and background execution, and installs roxctl and roxie before deployment.
StackRox deployment flow
.github/actions/deploy-stackrox/action.yaml
The deploy script exports registry credentials, creates the admin password, writes the roxie override YAML, runs roxie deploy, records the API endpoint, and switches between foreground and background logging.
Workflow entrypoint and shard planning
.github/workflows/build.yaml, .github/workflows/ui-e2e.yaml
The build workflow calls the reusable UI E2E workflow, which defines callable and dispatch inputs and computes a Cypress shard matrix from integration specs.
Cluster run and teardown
.github/workflows/ui-e2e.yaml
The reusable workflow provisions a GKE cluster, deploys StackRox, uploads credentials, runs shard-parallel Cypress tests with shard-specific readiness checks, and deletes the cluster asynchronously.
Network graph sidebar test
ui/apps/platform/cypress/integration/networkGraph/networkDeploymentSidebar.test.js
The Cypress test clicks the sensor node and checks the sidebar title and subtitle for that node in the stackrox namespace.

Sequence Diagram(s)

sequenceDiagram
  participant build_ui_e2e_job
  participant ui_e2e_workflow
  participant setup_shards_job
  participant provision_gke_job
  participant deploy_stackrox_action
  participant gke_e2e_job
  participant cleanup_gke_job

  build_ui_e2e_job->>ui_e2e_workflow: calls reusable workflow with build-tag
  ui_e2e_workflow->>setup_shards_job: discovers Cypress specs
  setup_shards_job-->>ui_e2e_workflow: emits shard matrix JSON
  ui_e2e_workflow->>provision_gke_job: provisions a GKE cluster
  provision_gke_job->>deploy_stackrox_action: deploys StackRox with scanner v2
  ui_e2e_workflow->>gke_e2e_job: runs shard-parallel Cypress tests
  ui_e2e_workflow->>cleanup_gke_job: deletes the GKE cluster asynchronously
Loading

🎯 4 (Complex) | ⏱️ ~60 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the main change: adding UI E2E tests on GKE.
Description check ✅ Passed The description follows the template and includes the required sections with concrete testing and validation details.
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.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch davdhacs/ui-e2e-gke-only

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.

@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: 6

🧹 Nitpick comments (1)
.github/actions/deploy-stackrox/action.yaml (1)

97-114: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win

Pass action inputs through env: instead of ${{ }} interpolation in run scripts.

${{ inputs.cluster-name }}, ${{ inputs.tag }}, ${{ inputs.scanner }}, ${{ inputs.resources }}, and ${{ inputs.exposure }} are expanded into the shell before execution (e.g. embedded inside the yq string on Line 97). If any value ever contains shell metacharacters, this is a template-injection vector. The registry credentials already follow the safe env: pattern (Lines 66-67); apply the same to the rest.

🔒 Sketch
     - name: Deploy StackRox
       shell: bash
       env:
         INPUT_REGISTRY_USERNAME: ${{ inputs.registry-username }}
         INPUT_REGISTRY_PASSWORD: ${{ inputs.registry-password }}
+        INPUT_CLUSTER_NAME: ${{ inputs.cluster-name }}
+        INPUT_TAG: ${{ inputs.tag }}
+        INPUT_SCANNER: ${{ inputs.scanner }}
+        INPUT_RESOURCES: ${{ inputs.resources }}
+        INPUT_EXPOSURE: ${{ inputs.exposure }}

Then reference "$INPUT_CLUSTER_NAME", "$INPUT_TAG", etc. in the script.

🤖 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 @.github/actions/deploy-stackrox/action.yaml around lines 97 - 114, Move the
action inputs used in the deploy script to env variables instead of
interpolating `${{ inputs.* }}` directly inside the run block. Update the
`action.yaml` step that builds `/tmp/roxie-override.yaml` and calls `roxie
deploy` to reference safe shell variables like `"$INPUT_CLUSTER_NAME"`,
`"$INPUT_SCANNER"`, `"$INPUT_RESOURCES"`, `"$INPUT_EXPOSURE"`, and
`"$INPUT_TAG"` rather than expanding inputs inline. Keep the existing logic in
the same step, but read all input-derived values from `env:` so the `yq` and
`roxie deploy` commands use quoted shell variables throughout.
🤖 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 @.github/actions/deploy-stackrox/action.yaml:
- Line 116: The current env export in the action is too brittle because the sed
cleanup in the step that writes to GITHUB_ENV strips quotes from all values and
cannot safely handle multiline entries. Update the export logic around the
roxie-env.sh processing so it preserves quoted content correctly and writes
multiline values using GITHUB_ENV heredoc syntax, or otherwise parse and emit
each variable explicitly in the deploy-stackrox action instead of relying on
global sed replacements.

In @.github/workflows/build.yaml:
- Around line 913-923: The `ui-e2e` caller job is using the default GitHub token
scope and `secrets: inherit`, which is too broad for this reusable workflow. Add
an explicit least-privilege `permissions:` block on the `ui-e2e` job in
`build.yaml`, and update the `uses: ./.github/workflows/ui-e2e.yaml` call to
pass only the named secrets that `ui-e2e.yaml` actually needs instead of
inheriting everything. Use the `ui-e2e` job and the reusable `ui-e2e.yaml`
workflow as the points to align the permissions and secret inputs.

In @.github/workflows/ui-e2e.yaml:
- Line 238: Avoid interpolating matrix-derived values directly in the shell
script for the Wait for shard-specific data step and the other referenced run
steps. In ui-e2e workflow, bind matrix.name and matrix.specs through env: on the
affected steps, then reference those environment variables in the script instead
of using ${{ matrix.name }} or ${{ matrix.specs }} inline. This applies to the
step using SHARD and the matching Run Cypress-related steps so the shell never
expands untrusted directory-name content directly.
- Around line 118-120: The `gke-zone` workflow output is reading `env.ZONE`, but
`ZONE` is only populated indirectly by `ci_export` in `scripts/ci/gke.sh` and
must be available before the job output is evaluated. Make sure the
`provision-gke` job step that runs `create-gke-cluster` executes before the
outputs are consumed, and verify the workflow passes the exported `ZONE` through
correctly so `gke-e2e` and `cleanup-gke` receive a non-empty zone. Use
`provision-gke`, `create-gke-cluster`, and `ci_export` to locate the relevant
places.
- Around line 27-31: Add a top-level permissions block to the ui-e2e workflow so
the default GITHUB_TOKEN scope is least-privilege; since the jobs only need
checkout, GCP auth, and artifact upload/download, set workflow-level permissions
to contents: read and override per-job only if a later step needs more access.
Place it alongside the existing defaults/jobs section so the workflow uses the
narrower token by default.

In
`@ui/apps/platform/cypress/integration/networkGraph/networkDeploymentSidebar.test.js`:
- Around line 23-29: The Cypress sidebar test is using substring-based selectors
that can pass on the wrong deployment, so tighten it to exact matching in the
networkDeploymentSidebar test. Update the assertions around
networkGraphSelectors.deploymentNode('sensor'),
networkGraphSelectors.drawerTitle, and networkGraphSelectors.drawerSubtitle so
they verify the intended deployment and subtitle exactly rather than relying on
:contains() behavior. This should make the sidebar flow fail unless the correct
sensor node and matching drawer content are selected.

---

Nitpick comments:
In @.github/actions/deploy-stackrox/action.yaml:
- Around line 97-114: Move the action inputs used in the deploy script to env
variables instead of interpolating `${{ inputs.* }}` directly inside the run
block. Update the `action.yaml` step that builds `/tmp/roxie-override.yaml` and
calls `roxie deploy` to reference safe shell variables like
`"$INPUT_CLUSTER_NAME"`, `"$INPUT_SCANNER"`, `"$INPUT_RESOURCES"`,
`"$INPUT_EXPOSURE"`, and `"$INPUT_TAG"` rather than expanding inputs inline.
Keep the existing logic in the same step, but read all input-derived values from
`env:` so the `yq` and `roxie deploy` commands use quoted shell variables
throughout.
🪄 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: Central YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: fc2ddb24-3a6b-43b9-828e-532cf29cfd14

📥 Commits

Reviewing files that changed from the base of the PR and between b8d55db and d198431.

📒 Files selected for processing (5)
  • .github/actions/create-gke-cluster/action.yaml
  • .github/actions/deploy-stackrox/action.yaml
  • .github/workflows/build.yaml
  • .github/workflows/ui-e2e.yaml
  • ui/apps/platform/cypress/integration/networkGraph/networkDeploymentSidebar.test.js

--tag ${{ inputs.tag }} \
$exposure_flag

sed "s/^export //; s/['\"]//g" /tmp/roxie-env.sh >> "$GITHUB_ENV"

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.

🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

sed-based env export is fragile.

s/['\"]//g strips every quote from values (not just wrapping quotes), and any multiline value would corrupt $GITHUB_ENV, which requires heredoc delimiters for multiline content. If roxie-env.sh only ever emits single-line, quote-free values this is safe; otherwise downstream steps will read truncated values.

🤖 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 @.github/actions/deploy-stackrox/action.yaml at line 116, The current env
export in the action is too brittle because the sed cleanup in the step that
writes to GITHUB_ENV strips quotes from all values and cannot safely handle
multiline entries. Update the export logic around the roxie-env.sh processing so
it preserves quoted content correctly and writes multiline values using
GITHUB_ENV heredoc syntax, or otherwise parse and emit each variable explicitly
in the deploy-stackrox action instead of relying on global sed replacements.

Source: Linters/SAST tools

Comment on lines +913 to +923
ui-e2e:
needs:
- define-job-matrix
- push-main-manifests
if: >-
!cancelled() && needs.push-main-manifests.result == 'success' &&
contains(github.event.pull_request.labels.*.name, 'e2e-ui-gke')
uses: ./.github/workflows/ui-e2e.yaml
with:
tag: ${{ needs.define-job-matrix.outputs.build-tag }}
secrets: inherit

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.

🔒 Security & Privacy | 🟡 Minor | ⚡ Quick win

Add an explicit least-privilege permissions: block and scope inherited secrets.

This caller job runs with the default token permissions and forwards every secret via secrets: inherit. The reusable ui-e2e.yaml only needs read access plus the specific GCP/Quay/bot secrets, so granting all of them broadens the blast radius unnecessarily. Add a minimal permissions: block here and prefer passing named secrets to the reusable workflow over inherit.

🔒 Suggestion
   ui-e2e:
+    permissions:
+      contents: read
     needs:
     - define-job-matrix
     - push-main-manifests
🧰 Tools
🪛 zizmor (1.26.1)

[warning] 913-923: overly broad permissions (excessive-permissions): default permissions used due to no permissions: block

(excessive-permissions)


[warning] 920-920: secrets unconditionally inherited by called workflow (secrets-inherit): this reusable workflow

(secrets-inherit)

🤖 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 @.github/workflows/build.yaml around lines 913 - 923, The `ui-e2e` caller job
is using the default GitHub token scope and `secrets: inherit`, which is too
broad for this reusable workflow. Add an explicit least-privilege `permissions:`
block on the `ui-e2e` job in `build.yaml`, and update the `uses:
./.github/workflows/ui-e2e.yaml` call to pass only the named secrets that
`ui-e2e.yaml` actually needs instead of inheriting everything. Use the `ui-e2e`
job and the reusable `ui-e2e.yaml` workflow as the points to align the
permissions and secret inputs.

Source: Linters/SAST tools

Comment on lines +27 to +31
defaults:
run:
shell: bash

jobs:

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.

🔒 Security & Privacy | 🟡 Minor | ⚡ Quick win

Add a top-level least-privilege permissions: block.

None of the jobs declare permissions, so they all run with the default (broad) GITHUB_TOKEN scope. These jobs only check out code, auth to GCP, and up/download artifacts, so contents: read at the workflow level (overriding per-job where needed) is sufficient.

🔒 Suggestion
 name: UI E2E
+
+permissions:
+  contents: read
 
 on:
📝 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
defaults:
run:
shell: bash
jobs:
defaults:
run:
shell: bash
permissions:
contents: read
jobs:
🤖 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 @.github/workflows/ui-e2e.yaml around lines 27 - 31, Add a top-level
permissions block to the ui-e2e workflow so the default GITHUB_TOKEN scope is
least-privilege; since the jobs only need checkout, GCP auth, and artifact
upload/download, set workflow-level permissions to contents: read and override
per-job only if a later step needs more access. Place it alongside the existing
defaults/jobs section so the workflow uses the narrower token by default.

Source: Linters/SAST tools

Comment on lines +118 to +120
outputs:
cluster-name: ${{ env.CLUSTER_NAME }}
gke-zone: ${{ env.ZONE }}

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.

🩺 Stability & Availability | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Confirm provision_gke_cluster (or related) writes ZONE to GITHUB_ENV
fd -t f 'gke.sh' scripts | xargs -r rg -nC3 'ZONE'
rg -nC2 'GITHUB_ENV' scripts/ci/gke.sh 2>/dev/null

Repository: stackrox/stackrox

Length of output: 1029


🏁 Script executed:

#!/bin/bash
# Search for ZONE export or usage and how ZONE is propagated from the ci_export function
grep -n 'ZONE' scripts/ci/gke.sh | head -20

# Verify what ci_export does with the ZONE variable
grep -A 5 -B 5 'ci_export\|ZONE' scripts/ci/gke.sh | head -40

# Check if GITHUB_ENV is written with ZONE
grep -n "ZONE" scripts/ci/gke.sh | grep -i "GITHUB_ENV"

Repository: stackrox/stackrox

Length of output: 1591


🏁 Script executed:

#!/bin/bash
# Investigate the ci_export function to see if it writes to GITHUB_ENV
grep -n "^ci_export" scripts/ci/gke.sh -A 20

Repository: stackrox/stackrox

Length of output: 155


🏁 Script executed:

#!/bin/bash
# Search for the definition of ci_export function in gke.sh and surrounding utils functions
grep -n "ci_export" scripts/ci/gke.sh
# Also search for where GITHUB_ENV is used to export variables
grep -n "GITHUB_ENV" scripts/ci/gke.sh

Repository: stackrox/stackrox

Length of output: 236


🏁 Script executed:

#!/bin/bash
# Locate the definition of ci_export function to see if it appends to GITHUB_ENV
grep -n "ci_export" scripts/ci/gke.sh
# Search for the function definition in this file or sourced files
sed -n '1,200p' scripts/ci/gke.sh | grep -n "ci_export"
# Look for the function body definition, likely near the top of the file or in a sourced file
head -100 scripts/ci/gke.sh | grep -n "^ci_export\|function ci_export\|ci_export()"
# Search for 'GITHUB_ENV' in context of script files to find where exports happen
grep -rn "GITHUB_ENV" scripts/ci/ --include="*.sh" | head -20

Repository: stackrox/stackrox

Length of output: 641


🏁 Script executed:

#!/bin/bash
# Read the ci_export function definition from lib.sh
sed -n '30,50p' scripts/ci/lib.sh

Repository: stackrox/stackrox

Length of output: 698


The gke-zone output relies on ZONE being exported to $GITHUB_ENV.

The provision-gke job defines outputs: gke-zone: ${{ env.ZONE }}, but the job environment does not explicitly set ZONE. Verification of scripts/ci/gke.sh confirms that the ZONE variable is set via the ci_export helper function (line 169), which is defined in scripts/ci/lib.sh to append variables to $GITHUB_ENV when running in a GitHub Actions context. While this mechanism should propagate the value to subsequent steps in the same job, ensuring the step running ci_export create-gke-cluster is correctly executed earlier in the workflow chain is required to prevent the gke-e2e and cleanup-gke jobs from failing with an empty zone.

Expand to view verification details

The variable is set as follows:

scripts/ci/gke.sh
169:        ci_export ZONE "$zone"

The ci_export function handles the $GITHUB_ENV writing:

scripts/ci/lib.sh
37:        if [[ -n "${GITHUB_ENV:-}" ]]; then
38:            printf '%s=%q\n' "${env_name}" "${env_value}" >> "$GITHUB_ENV"
🤖 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 @.github/workflows/ui-e2e.yaml around lines 118 - 120, The `gke-zone`
workflow output is reading `env.ZONE`, but `ZONE` is only populated indirectly
by `ci_export` in `scripts/ci/gke.sh` and must be available before the job
output is evaluated. Make sure the `provision-gke` job step that runs
`create-gke-cluster` executes before the outputs are consumed, and verify the
workflow passes the exported `ZONE` through correctly so `gke-e2e` and
`cleanup-gke` receive a non-empty zone. Use `provision-gke`,
`create-gke-cluster`, and `ci_export` to locate the relevant places.

Comment thread .github/workflows/ui-e2e.yaml Outdated
Comment on lines +23 to +29
cy.get(networkGraphSelectors.deploymentNode('sensor'), { timeout: 30000 });

// Click on sensor node to open sidebar (force: nodes may overlap in topology)
cy.get(networkGraphSelectors.deploymentNode('sensor')).click({ force: true });

cy.get(networkGraphSelectors.drawerTitle).contains('sensor');
cy.get(`${networkGraphSelectors.drawerSubtitle}:contains("stackrox")`);

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.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Use exact matching here to avoid false-positive E2E passes.

networkGraphSelectors.deploymentNode('sensor') expands to a :contains("sensor") selector, and the drawer checks also use substring matching. That means this test can still pass if it hits any node/title containing sensor rather than the exact deployment, which weakens the signal for the new shard-gated UI workflow.

Suggested tightening
-        cy.get(networkGraphSelectors.deploymentNode('sensor'), { timeout: 30000 });
+        cy.contains(
+            `${networkGraphSelectors.nodes} [data-type="node"] .pf-topology__node__label`,
+            /^sensor$/,
+            { timeout: 30000 }
+        );

-        cy.get(networkGraphSelectors.deploymentNode('sensor')).click({ force: true });
+        cy.contains(
+            `${networkGraphSelectors.nodes} [data-type="node"] .pf-topology__node__label`,
+            /^sensor$/
+        ).click({ force: true });

-        cy.get(networkGraphSelectors.drawerTitle).contains('sensor');
-        cy.get(`${networkGraphSelectors.drawerSubtitle}:contains("stackrox")`);
+        cy.get(networkGraphSelectors.drawerTitle).should('have.text', 'sensor');
+        cy.get(networkGraphSelectors.drawerSubtitle).should('contain.text', 'stackrox');

As per path instructions, focus on major issues impacting maintainability and test reliability.

📝 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
cy.get(networkGraphSelectors.deploymentNode('sensor'), { timeout: 30000 });
// Click on sensor node to open sidebar (force: nodes may overlap in topology)
cy.get(networkGraphSelectors.deploymentNode('sensor')).click({ force: true });
cy.get(networkGraphSelectors.drawerTitle).contains('sensor');
cy.get(`${networkGraphSelectors.drawerSubtitle}:contains("stackrox")`);
cy.contains(
`${networkGraphSelectors.nodes} [data-type="node"] .pf-topology__node__label`,
/^sensor$/,
{ timeout: 30000 }
);
// Click on sensor node to open sidebar (force: nodes may overlap in topology)
cy.contains(
`${networkGraphSelectors.nodes} [data-type="node"] .pf-topology__node__label`,
/^sensor$/
).click({ force: true });
cy.get(networkGraphSelectors.drawerTitle).should('have.text', 'sensor');
cy.get(networkGraphSelectors.drawerSubtitle).should('contain.text', 'stackrox');
🤖 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
`@ui/apps/platform/cypress/integration/networkGraph/networkDeploymentSidebar.test.js`
around lines 23 - 29, The Cypress sidebar test is using substring-based
selectors that can pass on the wrong deployment, so tighten it to exact matching
in the networkDeploymentSidebar test. Update the assertions around
networkGraphSelectors.deploymentNode('sensor'),
networkGraphSelectors.drawerTitle, and networkGraphSelectors.drawerSubtitle so
they verify the intended deployment and subtitle exactly rather than relying on
:contains() behavior. This should make the sidebar flow fail unless the correct
sensor node and matching drawer content are selected.

Source: Path instructions

@github-actions

github-actions Bot commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

🚀 Build Images Ready

Images are ready for commit 566e4d4. To use with deploy scripts:

export MAIN_IMAGE_TAG=4.12.x-325-g566e4d4fcc

@codecov

codecov Bot commented Jun 25, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 50.07%. Comparing base (d5fcd2f) to head (566e4d4).

Additional details and impacted files
@@            Coverage Diff             @@
##           master   #21421      +/-   ##
==========================================
- Coverage   50.12%   50.07%   -0.05%     
==========================================
  Files        2835     2835              
  Lines      217546   217546              
==========================================
- Hits       109049   108945     -104     
- Misses     100615   100698      +83     
- Partials     7882     7903      +21     
Flag Coverage Δ
go-unit-tests 50.07% <ø> (-0.05%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

davdhacs added a commit that referenced this pull request Jun 25, 2026
The Cypress before() hook already waits for process events —
the workflow-level wait is redundant. Keeps this PR as a pure
test fix with no workflow file overlap with PR #21421.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
davdhacs and others added 2 commits June 25, 2026 12:38
Data readiness waits belong in the Cypress tests that need them,
not scattered across the workflow. Tests use before() hooks to
poll APIs for their specific data dependencies.

Keep only the image scan trigger (seeds initial scan data for all
shards to use).

Partially generated by AI.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Remove test changes from the workflow PR — test fixes belong in
separate PRs. The network flow data wait in PR #21422 should
make this test work without modifications.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

@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: 1

🤖 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 @.github/workflows/ui-e2e.yaml:
- Around line 238-241: Fail fast in the seeded image scan step instead of
swallowing errors with `|| true`; the `curl ... | jq ...` pipeline in the UI e2e
workflow should surface auth/API/scan/JSON failures so the job stops immediately
if the seed scan cannot be triggered. Update the scan command in this workflow
to remove the unconditional success override and, if needed, make the pipeline
itself fail on bad responses while still keeping the `jq` extraction for the
successful case.
🪄 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: Central YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: 982173e7-980c-45d8-aab9-56f87aa51e62

📥 Commits

Reviewing files that changed from the base of the PR and between d198431 and c2f7bbd.

📒 Files selected for processing (1)
  • .github/workflows/ui-e2e.yaml

Comment on lines +238 to +241
curl -sk -u "admin:${ADMIN_PASSWORD}" \
"https://${API_ENDPOINT}/v1/images/scan" \
-X POST -d '{"imageName":"docker.io/nginx:1.12","force":true}' 2>&1 \
| jq -r '.name // .error // .message' || true

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.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Fail fast if the seed image scan cannot be triggered.

Line 240 currently swallows auth/API/scan/JSON failures with || true, so shards can proceed without the seeded scan data and fail later with less actionable Cypress errors.

Suggested change
-        curl -sk -u "admin:${ADMIN_PASSWORD}" \
+        curl -skS --fail --retry 3 -u "admin:${ADMIN_PASSWORD}" \
+          -H "Content-Type: application/json" \
           "https://${API_ENDPOINT}/v1/images/scan" \
           -X POST -d '{"imageName":"docker.io/nginx:1.12","force":true}' 2>&1 \
-          | jq -r '.name // .error // .message' || true
+          | jq -r '.name // .error // .message'
📝 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
🤖 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 @.github/workflows/ui-e2e.yaml around lines 238 - 241, Fail fast in the
seeded image scan step instead of swallowing errors with `|| true`; the `curl
... | jq ...` pipeline in the UI e2e workflow should surface auth/API/scan/JSON
failures so the job stops immediately if the seed scan cannot be triggered.
Update the scan command in this workflow to remove the unconditional success
override and, if needed, make the pipeline itself fail on bad responses while
still keeping the `jq` extraction for the successful case.

@davdhacs davdhacs added the e2e-ui-gke Run UI E2E tests on shared GKE cluster label Jun 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant