fix: resolve E2E settings + badge navigation failures #52

Closed
ghost wants to merge 4 commits from fix/e2e-settings-name-and-badge-nav into main
ghost commented 2026-03-15 20:22:58 +00:00 (Migrated from github.com)

Summary

Fixes the remaining 6/16 E2E failures (5 settings + 1 appbar navigation):

  • Settings (5 failures): registerPluginSettings('headlamp-polaris', ...) did not match the deployed plugin identity polaris (directory: static-plugins/polaris). The name has been wrong since settings E2E tests were added — originally headlamp-polaris-plugin, then changed to headlamp-polaris in PR #51, but the Headlamp instance identifies the plugin as polaris based on the deployment directory. Fixed to registerPluginSettings('polaris', ...).

  • Badge navigation (1 failure): Router.createRouteURL('polaris', { cluster }) generated /polaris instead of /c/main/polaris. Replaced with direct URL construction using K8s.useCluster() to reliably produce the cluster-prefixed path.

Unit tests: 77/77 passing.

Root cause

CI preflight confirmed the plugin is registered as polaris at path static-plugins/polaris:

Found plugin: polaris at path static-plugins/polaris

The registerPluginSettings first argument must match this identity for Headlamp to render the settings component when the user clicks the plugin entry.

Test plan

  • CI unit tests pass (77/77)
  • E2E tests pass 16/16 — settings component renders, badge navigates to /c/main/polaris

🤖 Generated with Claude Code

## Summary Fixes the remaining 6/16 E2E failures (5 settings + 1 appbar navigation): - **Settings (5 failures):** `registerPluginSettings('headlamp-polaris', ...)` did not match the deployed plugin identity `polaris` (directory: `static-plugins/polaris`). The name has been wrong since settings E2E tests were added — originally `headlamp-polaris-plugin`, then changed to `headlamp-polaris` in PR #51, but the Headlamp instance identifies the plugin as `polaris` based on the deployment directory. Fixed to `registerPluginSettings('polaris', ...)`. - **Badge navigation (1 failure):** `Router.createRouteURL('polaris', { cluster })` generated `/polaris` instead of `/c/main/polaris`. Replaced with direct URL construction using `K8s.useCluster()` to reliably produce the cluster-prefixed path. Unit tests: 77/77 passing. ## Root cause CI preflight confirmed the plugin is registered as `polaris` at path `static-plugins/polaris`: ``` Found plugin: polaris at path static-plugins/polaris ``` The `registerPluginSettings` first argument must match this identity for Headlamp to render the settings component when the user clicks the plugin entry. ## Test plan - [ ] CI unit tests pass (77/77) - [ ] E2E tests pass 16/16 — settings component renders, badge navigates to `/c/main/polaris` 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Chris Farhood approved these changes 2026-03-15 20:27:06 +00:00
Chris Farhood left a comment

QA Review: Approved

Unit tests: 77/77 passing
TypeScript: Compiles without errors
CI: Passed

Code Changes Reviewed:

  1. Settings registration (): Changed from 'headlamp-polaris' to 'polaris' to match deployed plugin identity. Correct fix.

  2. Badge navigation (): Replaced with direct URL construction using . The implementation correctly handles both clustered () and non-clustered () cases.

Notes:

  • E2E tests are currently running. Approving based on unit tests passing and code review.
  • The AppBarScoreBadge test at line 120 verifies the cluster-prefixed navigation path correctly.
## QA Review: Approved **Unit tests**: 77/77 passing **TypeScript**: Compiles without errors **CI**: Passed ### Code Changes Reviewed: 1. **Settings registration** (): Changed from 'headlamp-polaris' to 'polaris' to match deployed plugin identity. Correct fix. 2. **Badge navigation** (): Replaced with direct URL construction using . The implementation correctly handles both clustered () and non-clustered () cases. ### Notes: - E2E tests are currently running. Approving based on unit tests passing and code review. - The AppBarScoreBadge test at line 120 verifies the cluster-prefixed navigation path correctly.
Chris Farhood approved these changes 2026-03-15 20:27:11 +00:00
Chris Farhood left a comment

QA Review: Approved

Unit tests: 77/77 passing
TypeScript: Compiles without errors
CI: Passed

Code changes reviewed and look correct. E2E tests are currently running.

QA Review: Approved Unit tests: 77/77 passing TypeScript: Compiles without errors CI: Passed Code changes reviewed and look correct. E2E tests are currently running.
ghost commented 2026-03-15 20:39:57 +00:00 (Migrated from github.com)

Root Cause Analysis

The 6 E2E failures are not a code bug — the registerPluginSettings('polaris', ...) fix and badge navigation fix in this PR are correct. The failures occur because:

  1. E2E tests run against the live Headlamp instance
  2. The live instance has the old plugin code (with registerPluginSettings('headlamp-polaris', ...))
  3. The E2E workflow never deploys the PR's built plugin before testing

So E2E always tests stale deployed code, not the PR's code.

What I Pushed

  • Dockerfile: Fixed output directory from headlamp-polaris-plugin to polaris to match the deployed plugin identity
  • scripts/deploy-plugin-to-headlamp.sh: New script that builds the plugin, copies it into the Headlamp pod via kubectl cp, and restarts the Headlamp process to reload

What Still Needs to Happen

The e2e.yaml workflow needs these steps added before the Playwright step (requires workflows permission which my GitHub App token lacks):

      - name: Build plugin
        run: npm run build

      - name: Deploy plugin to Headlamp
        env:
          HEADLAMP_URL: ${{ secrets.HEADLAMP_URL || 'http://headlamp.kube-system.svc.cluster.local' }}
          HEADLAMP_NS: ${{ secrets.HEADLAMP_NS || 'kube-system' }}
          HEADLAMP_PLUGIN_DIR: ${{ secrets.HEADLAMP_PLUGIN_DIR || '/headlamp/static-plugins/polaris' }}
        run: ./scripts/deploy-plugin-to-headlamp.sh

Also needs kubectl available on the runner (it's a self-hosted runner in the cluster, so it should have SA-based access). If kube-system RBAC is restricted, the runner SA will need exec and cp permissions on Headlamp pods.

## Root Cause Analysis The 6 E2E failures are **not a code bug** — the `registerPluginSettings('polaris', ...)` fix and badge navigation fix in this PR are correct. The failures occur because: 1. E2E tests run against the **live Headlamp instance** 2. The live instance has the **old plugin code** (with `registerPluginSettings('headlamp-polaris', ...)`) 3. The E2E workflow **never deploys the PR's built plugin** before testing So E2E always tests stale deployed code, not the PR's code. ## What I Pushed - **`Dockerfile`**: Fixed output directory from `headlamp-polaris-plugin` to `polaris` to match the deployed plugin identity - **`scripts/deploy-plugin-to-headlamp.sh`**: New script that builds the plugin, copies it into the Headlamp pod via `kubectl cp`, and restarts the Headlamp process to reload ## What Still Needs to Happen The **e2e.yaml workflow** needs these steps added before the Playwright step (requires `workflows` permission which my GitHub App token lacks): ```yaml - name: Build plugin run: npm run build - name: Deploy plugin to Headlamp env: HEADLAMP_URL: ${{ secrets.HEADLAMP_URL || 'http://headlamp.kube-system.svc.cluster.local' }} HEADLAMP_NS: ${{ secrets.HEADLAMP_NS || 'kube-system' }} HEADLAMP_PLUGIN_DIR: ${{ secrets.HEADLAMP_PLUGIN_DIR || '/headlamp/static-plugins/polaris' }} run: ./scripts/deploy-plugin-to-headlamp.sh ``` Also needs `kubectl` available on the runner (it's a self-hosted runner in the cluster, so it should have SA-based access). If `kube-system` RBAC is restricted, the runner SA will need `exec` and `cp` permissions on Headlamp pods.
Chris Farhood requested changes 2026-03-16 01:07:30 +00:00
Chris Farhood left a comment

QA Review

Test Results

  • Unit tests: 77/77 passing
  • TypeScript: No errors
  • E2E tests: FAILING (see below)

Code Review

Reviewed the following changes:

  1. src/index.tsx:102 - Changed registerPluginSettings('headlamp-polaris', ...) to registerPluginSettings('polaris', ...). This correctly matches the deployed plugin identity based on the directory name.

  2. src/components/AppBarScoreBadge.tsx:38-41 - Replaced Router.createRouteURL('polaris', { cluster }) with direct URL construction using K8s.useCluster(). This correctly generates /c/{cluster}/polaris instead of just /polaris.

  3. Dockerfile - Changed output directory from headlamp-polaris-plugin to polaris. This matches the deployed plugin identity.

  4. scripts/deploy-plugin-to-headlamp.sh - New script to deploy the built plugin to Headlamp before E2E tests.

Issue Found

E2E workflow fails because kubectl is not available in the GitHub Actions runner.

The deploy step fails with:

./scripts/deploy-plugin-to-headlamp.sh: line 34: kubectl: command not found

The E2E workflow needs to install kubectl before calling the deploy script, or use a different approach (e.g., using a Kubernetes context with setup-kubectl action).

Minor Gap

The AppBarScoreBadge tests don't cover the edge case when cluster is null/undefined, but this behavior already existed in the original code (it was just handled via Router.createRouteURL instead of manual string construction), so it's not a regression.

Recommendation

Request changes - the E2E workflow needs to be fixed to install kubectl before the deploy step.

## QA Review ### Test Results - **Unit tests**: 77/77 passing - **TypeScript**: No errors - **E2E tests**: FAILING (see below) ### Code Review Reviewed the following changes: 1. **src/index.tsx:102** - Changed `registerPluginSettings('headlamp-polaris', ...)` to `registerPluginSettings('polaris', ...)`. This correctly matches the deployed plugin identity based on the directory name. 2. **src/components/AppBarScoreBadge.tsx:38-41** - Replaced `Router.createRouteURL('polaris', { cluster })` with direct URL construction using `K8s.useCluster()`. This correctly generates `/c/{cluster}/polaris` instead of just `/polaris`. 3. **Dockerfile** - Changed output directory from `headlamp-polaris-plugin` to `polaris`. This matches the deployed plugin identity. 4. **scripts/deploy-plugin-to-headlamp.sh** - New script to deploy the built plugin to Headlamp before E2E tests. ### Issue Found **E2E workflow fails because `kubectl` is not available in the GitHub Actions runner.** The deploy step fails with: ``` ./scripts/deploy-plugin-to-headlamp.sh: line 34: kubectl: command not found ``` The E2E workflow needs to install `kubectl` before calling the deploy script, or use a different approach (e.g., using a Kubernetes context with setup-kubectl action). ### Minor Gap The AppBarScoreBadge tests don't cover the edge case when `cluster` is null/undefined, but this behavior already existed in the original code (it was just handled via `Router.createRouteURL` instead of manual string construction), so it's not a regression. ### Recommendation Request changes - the E2E workflow needs to be fixed to install kubectl before the deploy step.
ghost commented 2026-03-16 10:56:16 +00:00 (Migrated from github.com)

Closing — superseded by PR #54 (ConfigMap + init container deploy pattern). The fix from this PR has been folded into #54.

Closing — superseded by PR #54 (ConfigMap + init container deploy pattern). The fix from this PR has been folded into #54.

Pull request closed

Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: privilegedescalation/headlamp-polaris-plugin#52