QA review of every issue in QA Review

The prompt from PR 19652 (head e54cd354) run with Opus 5.5 over all 68 open rancher/dashboard issues in the QA Review column on 2026-10-26 12:10 UTC, in 8 batches. GitHub was read-only, and every comment and label was captured to a file instead of posted, so nothing was written to the repository.

What it found

Every issue

Labels are what the agent sent to add_labels, which matched the prompt's rules for every issue (any difference would be flagged as "but sent"). None of these labels exist in the repo yet. Click a filter above to narrow the table and the comments.

IssueTitleIn QA ReviewDecisionLabels
4152 Cannot redirect back to previous page after login 13 d Tests sufficient + manual test qa-reviewed test-automation-sufficient needs-manual-test
14227 [Input Component - Cron Type] - The human readable description gets broken and overlays other elements 6 d Needs more tests + manual test qa-reviewed needs-more-test-automation needs-manual-test
16626 Incorrect validation for SAML responseType from CLI 4 d Tests sufficient + manual test qa-reviewed test-automation-sufficient needs-manual-test
16911 Viewing config for a secret causes the UI to freeze 18 d Needs more tests + manual test qa-reviewed needs-more-test-automation needs-manual-test
17256 Console Warning: `Vue received a Component that was made a reactive object. This can lead to unnecessary performance overhead and should be avoided by marking the component with `markRaw` or using `shallowRef` instead of `ref`. ` 55 d Tests sufficient, no manual test qa-reviewed test-automation-sufficient no-manual-test-needed
17265 Support certificate rotation (Imported cluster day 2 ops) 9 d Needs more tests + manual test qa-reviewed needs-more-test-automation needs-manual-test
17295 Support Multiple Auth Providers 11 d Needs more tests + manual test qa-reviewed needs-more-test-automation needs-manual-test
17340 Make Ingress-nginx option on cluster creation prime-only 38 d Needs more tests + manual test qa-reviewed needs-more-test-automation needs-manual-test
17682 Support configuring rancher and fleet agent limits for imported clusters 9 d Needs more tests + manual test qa-reviewed needs-more-test-automation needs-manual-test
18090 Allow UI Extensions to access dynamic content 11 d Tests sufficient + manual test qa-reviewed test-automation-sufficient needs-manual-test
18152 [FLEET] Allow cloning a resource into a different workspace 17 d Tests sufficient + manual test qa-reviewed test-automation-sufficient needs-manual-test
18175 Secret forms should prevent submission when fields contain invalid values 18 d Needs more tests + manual test qa-reviewed needs-more-test-automation needs-manual-test
18178 Project popover flickers, cannot use menu 32 d Needs more tests + manual test qa-reviewed needs-more-test-automation needs-manual-test
18250 Support configuration for etcd snapshot create + restore (Imported cluster day 2 ops) 9 d Tests sufficient + manual test qa-reviewed test-automation-sufficient needs-manual-test
18495 Side nav collapses and loses selection indicator when creating some resources 87 d Tests sufficient + manual test qa-reviewed test-automation-sufficient needs-manual-test
18510 Create a LabeledSelect component that supports namespace creation 79 d Tests sufficient + manual test qa-reviewed test-automation-sufficient needs-manual-test
18536 RcSection: counter badge contrast + content group slot support 40 d Tests sufficient + manual test qa-reviewed test-automation-sufficient needs-manual-test
18751 Cluster Dashboard usage percentage counts nodes that are excluded from cluster capacity, inflating it above 100% 33 d Needs more tests + manual test qa-reviewed needs-more-test-automation needs-manual-test
18756 SCC Registration page reports a registered system as unregistered for global roles that cannot read the registration Secret 19 d Tests sufficient + manual test qa-reviewed test-automation-sufficient needs-manual-test
18772 Remove Legacy feature and associated checks 73 d Needs more tests + manual test qa-reviewed needs-more-test-automation needs-manual-test
18783 Add a fallback to return the data from Cluster and Project Members 68 d Needs more tests + manual test qa-reviewed needs-more-test-automation needs-manual-test
18795 Show Principal ID whenever username cannot be resolved instead of error message 9 d Tests sufficient + manual test qa-reviewed test-automation-sufficient needs-manual-test
18831 YAML config modal is not displaying data 44 d Tests sufficient, no manual test qa-reviewed test-automation-sufficient no-manual-test-needed
18850 Content inside RcSection is not validated when collapsed 2 d Needs more tests + manual test qa-reviewed needs-more-test-automation needs-manual-test
18872 Add Restore mode to Snapshot restore action (Imported cluster day 2 ops) 9 d Tests sufficient + manual test qa-reviewed test-automation-sufficient needs-manual-test
18898 Add first-run/minor update wizard/modal 4 d Tests sufficient + manual test qa-reviewed test-automation-sufficient needs-manual-test
18940 Move version management logic into composables 46 d Needs more tests + manual test qa-reviewed needs-more-test-automation needs-manual-test
18942 Move registry config into a composable 24 d Tests sufficient + manual test qa-reviewed test-automation-sufficient needs-manual-test
18944 Move cluster memebrship management into a composable 11 d Needs more tests + manual test qa-reviewed needs-more-test-automation needs-manual-test
19023 [BUG] Carriage returns are not sanitized from agent environment variables 19 d Tests sufficient, no manual test qa-reviewed test-automation-sufficient no-manual-test-needed
19027 Support Auth Config SAML ADFS searching with LDAP 6 d Tests sufficient + manual test qa-reviewed test-automation-sufficient needs-manual-test
19084 Change imported cluster to use RcSections instead of Accordions 18 d Tests sufficient + manual test qa-reviewed test-automation-sufficient needs-manual-test
19117 a11y: Enable CI gate to not add any more a11y violations 18 d Tests sufficient, no manual test qa-reviewed test-automation-sufficient no-manual-test-needed
19147 New UX design for sortable table in functionality and style 3 d Needs more tests + manual test qa-reviewed needs-more-test-automation needs-manual-test
19172 Unhandled rejection on logout: "Schemas aren't loaded yet" from Prime registration 19 d Tests sufficient, no manual test qa-reviewed test-automation-sufficient no-manual-test-needed
19236 Add a CodeMirror 6 editor to Rancher Components 26 d Tests sufficient, no manual test qa-reviewed test-automation-sufficient no-manual-test-needed
19305 Harvester machine pools: support PCI device passthrough (hostDeviceInfo) 3 d Needs more tests + manual test qa-reviewed needs-more-test-automation needs-manual-test
19312 Role Template resource picker offers Node instead of Nodes, so the saved rule grants nothing 20 d Tests sufficient, no manual test qa-reviewed test-automation-sufficient no-manual-test-needed
19314 Add E2E to assert that YAML editor keys don't conflict keyboard shortcuts 4 d Tests sufficient, no manual test qa-reviewed test-automation-sufficient no-manual-test-needed
19334 Add principal identifier attribute fields to LDAP-based auth providers 19 d Needs more tests + manual test qa-reviewed needs-more-test-automation needs-manual-test
19374 Observed timestamps are not correct in growl message. 18 d Tests sufficient, no manual test qa-reviewed test-automation-sufficient no-manual-test-needed
19382 a11y: fix nested-interactive violation 19 d Tests sufficient, no manual test qa-reviewed test-automation-sufficient no-manual-test-needed
19383 a11y: fix aria-required-children violation 18 d Tests sufficient + manual test qa-reviewed test-automation-sufficient needs-manual-test
19387 Show new kubeconfig ACE setting 9 d Tests sufficient + manual test qa-reviewed test-automation-sufficient needs-manual-test
19428 Show the external-link icon on the Harvester learn-more links 18 d Needs more tests, no manual → Reopened qa-reviewed needs-more-test-automation no-manual-test-needed
19437 Add the RcModal component 18 d Tests sufficient + manual test qa-reviewed test-automation-sufficient needs-manual-test
19447 Extension list pages are blank on Rancher 2.10-2.15 when built with the current shell (Unknown preference: table-views) 17 d Tests sufficient, no manual test qa-reviewed test-automation-sufficient no-manual-test-needed
19449 Extension table hooks are not called when filtering a table with table views 17 d Tests sufficient, no manual test qa-reviewed test-automation-sufficient no-manual-test-needed
19472 Theme maintenance: show focus ring only on keyboard focus, and update secondary menu colors 11 d Needs more tests + manual test qa-reviewed needs-more-test-automation needs-manual-test
19484 Bug with `addTableHook` and supercharged tables 12 d Tests sufficient, no manual test qa-reviewed test-automation-sufficient no-manual-test-needed
19503 Provisioning new Ingress NGINX RKE2 clusters should be disabled for prime 2 d Tests sufficient + manual test qa-reviewed test-automation-sufficient needs-manual-test
19517 LabeledSelect: typed search text is cleared when the dropdown loses focus without a selection 5 d Tests sufficient + manual test qa-reviewed test-automation-sufficient needs-manual-test
19523 Update Operation deletion dialog to warn users of impacts of operation interruption 9 d Tests sufficient + manual test qa-reviewed test-automation-sufficient needs-manual-test
19527 Workload dashboard and cert-manager state links don't filter their list when ui-configurable-tables is off 10 d Needs more tests + manual test qa-reviewed needs-more-test-automation needs-manual-test
19536 Update encryption key rotation dialog to use RcModal 9 d Tests sufficient + manual test qa-reviewed test-automation-sufficient needs-manual-test
19544 Update the docs base to use the v2.16 once available 4 d Skipped (exclusion rule)
excluded label: QA/None
-
19561 Fleet: link the managed banner to its source and add a Managed badge 6 d Tests sufficient + manual test qa-reviewed test-automation-sufficient needs-manual-test
19565 Multiple auth providers: follow-up 10 d Needs more tests + manual test qa-reviewed needs-more-test-automation needs-manual-test
19576 Installed Apps list cleared by stale apps watch left over from Charts page 9 d Needs more tests + manual test qa-reviewed needs-more-test-automation needs-manual-test
19579 Use RcModal for the table views' Publish confirmation 9 d Tests sufficient, no manual test qa-reviewed test-automation-sufficient no-manual-test-needed
19583 A list's built-in tab loses its unsaved changes before any tab is picked 9 d Needs more tests + manual test qa-reviewed needs-more-test-automation needs-manual-test
19586 Allow provisioning extensions to add detail tabs conditional on annotations 9 d Needs more tests + manual test qa-reviewed needs-more-test-automation needs-manual-test
19611 Chart dropdown is missing when editing an installed app whose chart can't be found 4 d Tests sufficient + manual test qa-reviewed test-automation-sufficient needs-manual-test
19628 Save Changes to New View leaves the source view with unsaved changes 3 d Tests sufficient, no manual test qa-reviewed test-automation-sufficient no-manual-test-needed
19629 Undo doesn't work in the table views search bar 3 d Tests sufficient + manual test qa-reviewed test-automation-sufficient needs-manual-test
19662 The filter tabs have wrong counter when resources are deleted 3 d Tests sufficient, no manual test qa-reviewed test-automation-sufficient no-manual-test-needed
19676 Standalone Harvester gets the table views, which drop its list filters and empty the Images list 2 d Tests sufficient + manual test qa-reviewed test-automation-sufficient needs-manual-test
19683 Enter in a wizard text field jumps back to step 1 2 d Tests sufficient, no manual test qa-reviewed test-automation-sufficient no-manual-test-needed

What it would post

4152 Cannot redirect back to previous page after login Tests sufficient + manual test
In QA Review 13 d (since 2026-10-13 09:00 UTC) · issue ↗ · linked PR: 14042 (merged, 4 test files)

Labels it would add: qa-reviewed test-automation-sufficient needs-manual-test

🤖 QA review analysis

Automated tests appear sufficient for this issue. A round of manual tests is still required.

Decision: is_automatable: true · automation_sufficient: true · manual_test: true

Rationale The agreed behavior (see the 2026-10-09 recap) is: if the user was heading to a specific page before login, take them there, whatever the "Login Landing Page" preference says. PR #14042 implements this in shell/store/prefs.ts (afterLoginRoute now returns authRedirect first), shell/pages/index.vue (clears authRedirect after use, and a bookmark now wins over the release-notes redirect), and shell/utils/auth.js (no authRedirect is stored for the bare index route). Unit and e2e tests cover these paths.

Test evidence (PR #14042)

  • unit – shell/store/__tests__/prefs.test.ts: new cases check that authRedirect wins over the home preference, the cluster-<id>-dashboard pattern, and a non-string (route object) preference.
  • unit – shell/pages/__tests__/index.test.ts (new): redirects to the after-login route; clears prefs/setAuthRedirect both normally and when sending the user to release notes; a bookmark wins over unseen release notes; falls back to home for an unresolvable route (edge case).
  • unit – shell/utils/__tests__/auth.test.ts: the index route no longer sets authRedirect (edge case).
  • e2e – cypress/e2e/tests/pages/user-menu/preferences.spec.ts: the log out → visit /c/local/explorer/node → log in → land on that page flow now runs for every landing-page option, not only "last visited".

Why manual testing is still recommended

  • This changes where every user lands after login, so the regression risk is high.
  • The original report is about GitHub OAuth. The e2e only uses local login. Redirects through an external IdP (OAuth/SAML/OIDC callback via /auth/verify) aren't automated, and the preference/release-notes interaction across versions is UX-sensitive.

Residual risk to monitor

  • External auth providers (GitHub, SAML, OIDC) returning to the bookmarked page.
  • After an upgrade, users with a bookmark won't see the release notes until their next login. Check this is acceptable.
  • Session timeout (timed-out) compared with explicit logout.

This analysis was generated automatically based on unit and e2e evidence linked to this issue.

14227 [Input Component - Cron Type] - The human readable description gets broken and overlays other elements Needs more tests + manual test
In QA Review 6 d (since 2026-10-19 22:02 UTC) · issue ↗ · linked PR: 19513 (merged, 2 test files)

Labels it would add: qa-reviewed needs-more-test-automation needs-manual-test

🤖 QA review analysis

A round of manual tests is required. Automated tests are not yet sufficient for this issue.

Please address the feedback from the QA Review Decision Model:

Decision: is_automatable: true · automation_sufficient: false · manual_test: true

PR #19513 adds a showCronHint prop and a cron-hint-change event to LabeledInput, with good unit coverage in pkg/rancher-components/src/components/Form/LabeledInput/LabeledInput.test.ts. However, the actual fix lives in shell/edit/workload/index.vue: the CronJob form hides the inline hint and renders a cron-schedule-hint element next to the Schedule field. No test touches that wiring, and nothing exercises the reproduction value 53 18 30 4 3. Manual testing is recommended because this is a layout/overlap bug that depends heavily on UX and on viewport width.

Suggested tests

  1. unit – shell/edit/workload/__tests__/index.test.ts (or equivalent workload edit spec)

    • Mount the workload edit form as a CronJob.
    • Assert the schedule LabeledInput gets showCronHint=false and aria-describedby="cron-schedule-hint".
    • Emit cron-hint-change with a string and assert [data-testid="cron-schedule-hint"] shows that text.
    • Emit undefined and assert the hint is empty.
    • Assert the hint element isn't rendered for non-CronJob workloads, such as a Deployment.
  2. e2e – cypress/e2e/tests/pages/explorer/workloads/cronjobs.spec.ts (or the existing workload create spec)

    • Go to Workloads → CronJobs → Create and type 53 18 30 4 3 in Schedule.
    • Assert [data-testid="cron-schedule-hint"] is visible and contains the human-readable description.
    • Assert the old [data-testid="sub-label"] hint isn't rendered under the Schedule input.
    • Change the schedule to @daily and assert the hint updates.
    • Run at a narrow viewport (e.g. cy.viewport(1024, 768)) and assert the hint doesn't overlap the next field. For example, compare bounding boxes, or assert the Replicas/next-column input is still clickable.
  3. unit – LabeledInput.test.ts

    • Add a case for an invalid cron expression (e.g. 61 * * * *) to check that the emitted hint is the invalid/empty value, so the external hint doesn't show stale text.

This comment was generated automatically to highlight missing automated coverage and suggest next tests to add.

16626 Incorrect validation for SAML responseType from CLI Tests sufficient + manual test
In QA Review 4 d (since 2026-10-21 15:18 UTC) · issue ↗ · linked PR: 19037 (merged, 3 test files)

Labels it would add: qa-reviewed test-automation-sufficient needs-manual-test

🤖 QA review analysis

Automated tests appear sufficient for this issue. A round of manual tests is still required.

Decision: is_automatable: true · automation_sufficient: true · manual_test: true

Rationale PR #19037 replaces the strict responseType !== 'kubeconfig' check in shell/components/auth/login/saml.vue. It now accepts kubeconfig and kubeconfig_<clusterId> (split on the first underscore, cluster id required), which matches what the CLI sends and what Rancher expects. The component was also moved to <script setup>, and the shared logic now lives in the new shell/composables/useLogin.ts.

Test evidence (PR #19037)

  • unit – shell/components/auth/login/__tests__/saml.test.ts (new):
    • CLI login detection for each of cli, requestId, publicKey, responseType, and a plain browser login.
    • Accepts kubeconfig, kubeconfig_local, kubeconfig_c-m-zx8p4nvt, and a cluster id that contains an underscore.
    • Rejects json, kubeconfigs, kubeconfig_, and an empty value. Also rejects a missing requestId or publicKey (failure paths).
    • Checks that the cluster-scoped responseType reaches the auth/login dispatch unchanged.
  • unit – shell/composables/__tests__/useLogin.test.ts (new): display name and focus-on-mount behavior.
  • unit – shell/mixins/__tests__/login.test.ts: t is called with the component bound to this after the refactor.

The tests map directly to the issue's acceptance criterion, which team collie confirmed: "kubeconfig_ has to be supported".

Why manual testing is still recommended

  • The full CLI → Dashboard → SAML IdP → token round trip against a real Rancher (rancher token --server … --user <downstream cluster>) can't be exercised in unit tests.
  • This is a customer-reported (SURE) backport candidate, and saml.vue was rewritten. Browser-based SAML login (non-CLI) should get a quick regression check too.

Residual risk to monitor

  • Browser SAML login (Okta, Shibboleth, Keycloak SAML, ADFS) still focuses and submits correctly after the composition API rewrite.
  • Behavior on backport branches where useLogin/providerKey may differ.

This analysis was generated automatically based on unit and e2e evidence linked to this issue.

16911 Viewing config for a secret causes the UI to freeze Needs more tests + manual test
In QA Review 18 d (since 2026-10-07 18:57 UTC) · issue ↗ · linked PR: 19274 (merged, 20 test files)

Labels it would add: qa-reviewed needs-more-test-automation needs-manual-test

🤖 QA review analysis

A round of manual tests is required. Automated tests are not yet sufficient for this issue.

Please address the feedback from the QA Review Decision Model:

Decision: is_automatable: true · automation_sufficient: false · manual_test: true

PR #19274 fixes this indirectly by replacing the CodeMirror 5 editors with CodeMirror 6 (RcCodeMirror). It adds a lot of editor-level tests:

  • shell/components/__tests__/CodeMirror.test.ts
  • shell/utils/__tests__/codemirror-compat.test.ts
  • shell/plugins/__tests__/codemirror-vim.test.ts, codemirror-sublime.test.ts, shortkey.test.ts
  • shell/pkg/__tests__/shared-codemirror.test.ts
  • RcCodeMirror*.test.ts
  • e2e cypress/e2e/tests/components/code-mirror-shortcuts.spec.ts

None of these exercise this issue's scenario: opening Show Configuration for a helm.sh/release.v1 Secret with a large base64 release value and keeping the UI responsive. The PR states it does not filter the release field and asks QA to check the original case by hand. Manual testing is required because the editor swap affects every YAML/multiline editor in the product (high regression risk) and the PR explicitly requests it.

Suggested tests

  1. e2e – e.g. cypress/e2e/tests/pages/explorer/storage/secrets.spec.ts

    • Create a Secret of type helm.sh/release.v1 through the API with a realistically large data.release value (generate ~1–5 MB of base64 in the test).
    • Go to Secrets → All Namespaces, open the row's Show Configuration drawer, and assert the drawer and its YAML editor render within a bounded timeout (e.g. 10s).
    • Assert the page stays interactive: close the drawer and the list filter input accepts typing.
  2. e2e – same spec

    • Open the Secret detail page and the YAML view (?as=yaml) for the same large secret.
    • Assert both render and that the editor can scroll to the end of the document. For example, EditorView from the code-mirror page object reports the full document length.
  3. unit – shell/components/__tests__/YamlEditor.test.ts (or CodeMirror.test.ts)

    • Mount the YAML editor with a single very long line (e.g. 1,000,000 characters).
    • Assert it mounts without throwing and that onReady emits an EditorView whose state.doc.length matches the input. This guards against a regression to an implementation that chokes on long lines.
  4. unit – if a follow-up decides to hide or lazy-load the release key for helm.sh/release.v1 secrets in the drawer (as the issue originally proposed)

    • Assert the drawer's YAML omits or truncates data.release, while other secret types keep all their data keys.

This comment was generated automatically to highlight missing automated coverage and suggest next tests to add.

17256 Console Warning: `Vue received a Component that was made a reactive object. This can lead to unnecessary performance overhead and should be avoided by marking the component with `markRaw` or using `shallowRef` instead of `ref`. ` Tests sufficient, no manual test
In QA Review 55 d (since 2026-09-01 08:36 UTC) · issue ↗ · linked PR: 18995 (merged, 2 test files)

Labels it would add: qa-reviewed test-automation-sufficient no-manual-test-needed

🤖 QA review analysis

Automated tests appear sufficient for this issue. No manual tests required.

Decision: is_automatable: true · automation_sufficient: true · manual_test: false

Rationale PR #18995 fixes the root cause in one place. getDynamic('component', …) in shell/core/extension-manager-impl.js now returns markRaw(result), so no dynamic extension component gets wrapped in a reactive proxy. Header.vue also stores null when no NavHeaderRight component is registered. This is exactly what the Vue warning complains about.

Test evidence (PR #18995)

  • unit – shell/core/__tests__/extension-manager-impl.test.js:
    • A retrieved component stays non-reactive when placed in reactive() state (the fix).
    • Other dynamic types (e.g. models) are not marked raw, which guards against over-applying the change (edge case).
  • unit – shell/components/nav/__tests__/Header.test.ts:
    • navHeaderRight keeps the identical raw component and isReactive(stored) is false.
    • navHeaderRight is null when nothing is registered (edge case).

Manual testing: not recommended. This is a dev-only console warning with low user-facing impact, and the unit tests check the reactivity contract directly.

Residual risk to monitor

  • Other places that store a component in reactive data without going through getDynamic could still trigger the same warning. Watch the console on other pages too.
  • Optionally add an e2e console-spy assertion on the home page if this warning comes back.

This analysis was generated automatically based on unit and e2e evidence linked to this issue.

17265 Support certificate rotation (Imported cluster day 2 ops) Needs more tests + manual test
In QA Review 9 d (since 2026-10-17 05:37 UTC) · issue ↗ · linked PR: 19540 (merged, 4 test files)

Labels it would add: qa-reviewed needs-more-test-automation needs-manual-test

🤖 QA review analysis

A round of manual tests is required. Automated tests are not yet sufficient for this issue.

Please address the feedback from the QA Review Decision Model:

Decision: is_automatable: true · automation_sufficient: false · manual_test: true

PR #19540 has strong dialog-level unit coverage in shell/dialog/__tests__/RotateCertificatesDialog.test.ts:

  • service lists for RKE2, K3s and imported clusters, including supervisor
  • default "All services" state and the select/reset/"+N more" states
  • the operation CR payload for all services and for selected services
  • error banner on 403, in-flight close/rotate guard, disabled no-op
  • the RKE2 generation bump

shell/models/__tests__/provisioning.cattle.io.cluster.test.ts covers when the action is enabled and that the dialog is opened with ownsModal.

Gaps against the acceptance criteria:

  • Permission gating: the requirement is that the action shows when the user can create certrotate.operation.cattle.io. The model now gates on canDayTwoOps (ready + day-2-ops enabled + canUpdate on the cluster), and nothing tests the CR create permission.
  • "UI reflects its status": OPERATION.CERTIFICATE_ROTATE was added to the operation lists in shell/detail/provisioning.cattle.io.cluster.vue, but no test checks that a certrotate operation shows up or reports status on the cluster detail page.
  • Behavior change: the RKE1 path (mgmt.doAction('rotateCertificates')) and the mgmt.hasAction fallback were removed. No test pins the expected behavior for non-RKE2, non-day-2-ops clusters.
  • No e2e coverage.

Manual testing is required. This is a day-2 operation on real imported RKE2/K3s clusters (services restart, cluster goes to Updating) with real backend status transitions and large product impact.

Suggested tests

  1. unit – shell/models/__tests__/provisioning.cattle.io.cluster.test.ts

    • Mock schemaFor(OPERATION.CERTIFICATE_ROTATE) with and without create in collectionMethods (or canCreate).
    • Assert the rotateCertificates action is enabled only when the user can create the certrotate CR on an imported day-2-ops cluster, and disabled otherwise.
  2. unit – shell/detail/__tests__/provisioning.cattle.io.cluster.test.ts

    • Provide a certrotate operation CR for the cluster in the store.
    • Assert it's fetched and listed among the cluster's operations with its state/status (e.g. in-progress → complete, and a failed condition).
  3. unit – provisioning.cattle.io.cluster.test.ts

    • Add a case for a cluster that's neither RKE2 nor imported-with-day-2-ops, and assert the action is disabled or hidden.
    • This documents the intentional removal of the hasAction('rotateCertificates') path.
  4. e2e – e.g. cypress/e2e/tests/pages/manager/cluster-manager.spec.ts (imported cluster block)

    • Intercept POST to the certrotate operation endpoint.
    • Open the cluster's action menu → Rotate Certificates, choose Selected services, pick api-server and supervisor, and click Rotate.
    • Assert the request body has spec.clusterRef.name set to the mgmt id and spec.args.services set to ['api-server','supervisor'], the dialog closes, and the generated-name notification shows.
    • Repeat with All services and assert spec.args is absent.
    • Stub a 403 response and assert the error banner shows and the dialog stays open.

This comment was generated automatically to highlight missing automated coverage and suggest next tests to add.

17295 Support Multiple Auth Providers Needs more tests + manual test
In QA Review 11 d (since 2026-10-14 21:36 UTC) · issue ↗ · linked PR: 19495 (merged, 36 test files)

Labels it would add: qa-reviewed needs-more-test-automation needs-manual-test

🤖 QA review analysis

A round of manual tests is required. Automated tests are not yet sufficient for this issue.

Please address the feedback from the QA Review Decision Model:

Decision: is_automatable: true · automation_sufficient: false · manual_test: true

Why manual testing is required: the issue is priority/0 and a headline feature. It changes the auth config management, login and principal model, with large regression risk across every auth provider type.

Evidence found (PR #19495)

  • Substantial unit coverage:
    • shell/mixins/__tests__/auth-config.test.ts (+773)
    • shell/pages/c/_cluster/auth/config/__tests__/index.test.ts, _id.test.ts
    • new create/__tests__/provider.test.ts
    • shell/store/__tests__/auth.test.ts
    • shell/utils/__tests__/auth-providers.test.ts, auth-provider-details.test.ts
    • shell/models/__tests__/management.cattle.io.authconfig.test.ts, management.cattle.io.feature.test.ts
    • shell/components/auth/__tests__/AuthProvidersPrimeNotice.test.ts, AuthProviderAccessDrawer.test.ts
    • shell/dialog/__tests__/AddAuthProviderDialog.test.ts
    • shell/edit/auth/__tests__/github.test.ts, oidc.test.ts, ldap/__tests__/index.test.ts
    • shell/components/ResourceDetail/__tests__/index.test.ts
    • RcDropdownGroup.test.ts
  • e2e: the existing provider specs (azuread, cognito, githubapp, okta, openldap) now create configs on demand through cypress/e2e/blueprints/users/auth-config-stubs.ts. These are adaptations of single-provider flows.

Gaps against the issue scope

  • No e2e for the headline flow: several configs (including two of the same type) listed, enabled, and offered on the login page.
  • No e2e for the Community single-enabled-provider limit or the Prime notice.
  • No tests found for the login page provider list/new layout sending configName.
  • No tests found for principal display / membership management showing the auth config name (<provider type> / <config name> / <type> / <principal>), or for the Users list provider column/sort.
  • No tests for the principal id change (<config name>_<type>://<id>) being read from the principal provider field rather than parsed from the id.

Suggested tests

  1. e2e – new cypress/e2e/tests/pages/users-and-auth/multiple-auth-providers.spec.ts (Prime/feature-flag gated)

    • Use the auth-config stubs to create github, github-2 and one openldap config, and enable them.
    • Assert the Auth Provider list shows all three with their human-readable names/descriptions and enabled state.
    • Log out and assert the login page offers all three, with the right name/description.
    • Intercept the login POST for github-2 and assert the body contains configName: 'github-2'.
  2. e2e – same spec, Community / feature disabled

    • With one external provider enabled, assert Add is hidden or disabled and the Prime notice shows.
    • Disable the provider through the grouped action menu and assert Add becomes available again.
  3. unit – shell/pages/auth/__tests__/login.test.ts (or the login provider list component)

    • Given /v1-public/authproviders returning several providers (two of the same type), assert one entry is rendered per provider, labelled by loginDisplayName, and that choosing one dispatches auth/login with the matching configName.
  4. unit – shell/models/__tests__/principal.test.ts and the user model

    • Given a principal with id github-2_user://123 and provider: 'github-2', assert the display shows the provider type plus the auth config name, and that the type isn't parsed from the id prefix.
    • Assert the management.cattle.io.users provider column includes the config name and sorts secondarily on it.
  5. unit – shell/mixins/__tests__/auth-config.test.ts

    • Add a failure path: a first testAndEnable with bad credentials fails, a corrected second save succeeds, and the configName stays the same between the two calls. This is one of the PR's own manual test cases.

This comment was generated automatically to highlight missing automated coverage and suggest next tests to add.

17340 Make Ingress-nginx option on cluster creation prime-only Needs more tests + manual test
In QA Review 38 d (since 2026-09-17 18:15 UTC) · issue ↗ · linked PR: 19106 (merged, 2 test files)

Labels it would add: qa-reviewed needs-more-test-automation needs-manual-test

🤖 QA review analysis

A round of manual tests is required. Automated tests are not yet sufficient for this issue.

Please address the feedback from the QA Review Decision Model:

Decision: is_automatable: true · automation_sufficient: false · manual_test: true

PR #19106 adds good unit coverage for the main rule in shell/edit/provisioning.cattle.io.cluster/__tests__/Ingress.test.ts:

  • non-Prime + create + k8s ≥ v1.37: NGINX card disabled, with the community content and doc link
  • k8s < v1.37: enabled
  • Prime + ≥ v1.37: enabled
  • edit mode: not restricted
  • view mode: every card disabled

Basics.test.ts checks that kubernetesVersion is forwarded to the Ingress component.

Acceptance criteria that aren't fully covered

  • "Community edition should only support Traefik": the Dual Mode card (Traefik + NGINX) has no prime flag, and no test asserts whether it's allowed or blocked for Community at ≥ v1.37.
  • "Both still have an option to disable Ingress": no test asserts that the None option stays enabled for Community and Prime at ≥ v1.37.
  • No test covers a create-mode form that already has NGINX selected (e.g. a default or cloned value) when the user switches the k8s version to ≥ v1.37. A disabled card could stay selected.
  • No test covers showTransitioningBanner being hidden for Community at ≥ v1.37.
  • No e2e coverage.

Manual testing is required. The behavior depends on real Prime vs Community builds (RancherPrime version data) and real k8s 1.37 release metadata, and it affects every new RKE2 cluster provisioning flow.

Suggested tests

  1. unit – Ingress.test.ts

    • Non-Prime, _CREATE, v1.37.0+rke2r1: assert the none option is present and disabled === false.
    • Prime with the same settings: assert the same.
  2. unit – Ingress.test.ts

    • Non-Prime, _CREATE, ≥ v1.37: assert the expected state of the dual card, per the product decision (disabled if Community should be Traefik-only).
    • Add the prime flag to INGRESS_DUAL in shared.ts if that's the intended behavior.
  3. unit – Ingress.test.ts

    • Mount in _CREATE with value: INGRESS_NGINX and kubernetesVersion: 'v1.36.0', then setProps({ kubernetesVersion: 'v1.37.0+rke2r1' }) on non-Prime.
    • Assert the selection moves to Traefik (or an update:value is emitted), so no disabled option stays selected.
  4. unit – Ingress.test.ts

    • Assert the cluster.ingress.banners.transitioning.label banner is hidden for non-Prime at ≥ v1.37 create, and shown for Prime.
  5. e2e – cypress/e2e/tests/pages/manager/cluster-manager.spec.ts (RKE2 custom create)

    • Stub the version data as non-Prime and the RKE2 release list to include a v1.37 version, and select it.
    • Assert the Ingress-NGINX card is disabled and shows "This option is only available in SUSE Rancher Prime.", while Traefik and None stay selectable.
    • Edit an existing cluster that uses ingress-nginx and assert all three options are still available.

This comment was generated automatically to highlight missing automated coverage and suggest next tests to add.

17682 Support configuring rancher and fleet agent limits for imported clusters Needs more tests + manual test
In QA Review 9 d (since 2026-10-17 07:34 UTC) · issue ↗ · linked PR: 19152 (merged, 5 test files)

Labels it would add: qa-reviewed needs-more-test-automation needs-manual-test

🤖 QA review analysis

A round of manual tests is required. Automated tests are not yet sufficient for this issue.

Please address the feedback from the QA Review Decision Model:

Decision: is_automatable: true · automation_sufficient: false · manual_test: true

Evidence found (PR #19152)

  • unit – pkg/imported/components/__tests__/CruImported.test.ts (+237):
    • Registries, Cluster Agent and Fleet Agent sections render inside Advanced, with RcAgentConfiguration of type cluster/fleet and tolerations/affinity hidden.
    • The agent sections are hidden for the local cluster, and there's no Advanced section for RKE1.
    • ensureAgentConfiguration creates empty models, and agentConfigurationCleanup strips empty values.
    • Saves use replace: true only when a value was removed.
    • Empty configs are restored after a failed save (failure path).
  • unit – new shell/components/__tests__/RcContainerResourceLimit.test.ts and shell/components/form/__tests__/RcAgentConfiguration.test.ts.
  • e2e – cypress/e2e/tests/pages/manager/cluster-manager.spec.ts: only checks that the Registries / Agent Environment Variables / Cluster Agent / Fleet Agent sections exist under Advanced, and that agent sections are absent for the local cluster.

Gaps

  • No e2e actually enters CPU/memory requests and limits for the cluster agent and fleet agent on an imported cluster and checks they persist (saved payload or reload in edit mode).
  • The issue asks to make requests/limits a generic component and use it in v2prov too. The PR doesn't touch the v2prov (RKE2) agent configuration, and no test shows v2prov using RcContainerResourceLimit/RcAgentConfiguration, or that v2prov hasn't regressed.
  • No test covers validating limits against requests (e.g. invalid units, or a limit lower than its request), if the component enforces it.

Why manual testing is required: this is a priority/1, customer-escalated (SURE-7608) feature. The real outcome (limits applied to the cattle-cluster-agent and fleet-agent deployments on the downstream cluster) can only be verified against a real imported cluster.

Suggested tests

  1. e2e – cluster-manager.spec.ts, inside "can edit imported cluster and see changes afterwards"

    • Expand Advanced → Cluster Agent and set CPU request 100m, memory request 128Mi, CPU limit 500m, memory limit 256Mi.
    • Do the same under Fleet Agent and save.
    • Intercept the PUT to /v3/clusters/<id> and assert clusterAgentDeploymentCustomization.overrideResourceRequirements and fleetAgentDeploymentCustomization.overrideResourceRequirements contain those values.
    • Reopen edit and assert the inputs show the saved values.
  2. e2e – same spec

    • Clear a previously set limit and save. Assert the request removes it, which exercises the replace: true path end to end.
  3. unit – shell/components/__tests__/RcContainerResourceLimit.test.ts

    • Assert that entering values emits overrideResourceRequirements in Kubernetes quantity format ({ requests: { cpu: '100m' }, limits: { memory: '256Mi' } }).
    • Assert that clearing a field removes that key.
    • Add an invalid input case (non-numeric, or a limit lower than its request) and assert validation or the emitted value.
  4. unit – v2prov agent configuration (e.g. shell/edit/provisioning.cattle.io.cluster/__tests__/rke2.test.ts)

    • If the shared component is adopted there, assert the cluster/fleet agent sections render it and that existing v2prov values still round-trip unchanged.
    • Otherwise, track the v2prov adoption separately.

This comment was generated automatically to highlight missing automated coverage and suggest next tests to add.

18090 Allow UI Extensions to access dynamic content Tests sufficient + manual test
In QA Review 11 d (since 2026-10-15 11:23 UTC) · issue ↗ · linked PR: 19397 (merged, 1 test file)

Labels it would add: qa-reviewed test-automation-sufficient needs-manual-test

🤖 QA review analysis

Automated tests appear sufficient for this issue. A round of manual tests is still required.

Decision rationale

  • Automatable: yes. The feature is a pure client-side extension API (plugin.register('telemetry', …)) whose output is the dynamic-content query string, which can be fully exercised with mocked store getters and plugin lists.
  • Automation sufficient: yes. The linked PR #19397 adds a dedicated, behavior-focused unit suite.
  • Manual test recommended: yes. The issue carries priority/0 and is a headline feature. A human should confirm the end-to-end request against a real Rancher build with a real SUSE extension loaded.

Test evidence (PR #19397)

  • unit – shell/utils/dynamic-content/__tests__/info-extensions.test.ts (new, ~330 lines):
    • Happy path: telemetry is collected from known SUSE extensions, from built-in extensions (e.g. rancher-prime), and from extensions listed in settings.suseExtensions. It is also collected from multiple functions and multiple extensions, and the store getters are passed to each function.
    • Security/isolation:
      • Non-SUSE extensions are ignored and their function is never called.
      • Telemetry cannot overwrite existing params (dcv, s, u, uuid, v, p, cc, bl).
      • Names and values are URL-encoded, so a param cannot inject extra params.
    • Failure/edge paths:
      • A function that throws is skipped and the others are still collected.
      • Non-object, array, null and undefined return values are ignored.
      • Params with an empty or whitespace-only name are dropped.
      • Values that are objects, arrays, functions, null or undefined are dropped. 0, false and '' are kept.
      • When two functions return the same param, the first value wins.
      • Having no extensions loaded is handled.
    • Size limit: total telemetry is capped at 1024 characters with a console.debug notice, and params that fit within the limit are still included.
  • Docs: docs/developer/extensions-telemetry.md.

Residual risk to monitor

  • The tests mock uiplugins/plugins and the SUSE extension list. A manual pass should confirm that a real installed SUSE extension (and a built-in one such as Rancher Prime) registers telemetry, and that the params appear on the actual request to the dynamic content endpoint.
  • Confirm on the server side that the larger query string (up to +1024 characters) is accepted by the dynamic content endpoint.
  • Confirm that older Rancher versions loading an extension that calls register('telemetry', …) do not break (the docs claim backward compatibility).

This analysis was generated automatically based on unit and e2e evidence linked to this issue.

18152 [FLEET] Allow cloning a resource into a different workspace Tests sufficient + manual test
In QA Review 17 d (since 2026-10-08 23:46 UTC) · issue ↗ · linked PR: 19443 (merged, 13 test files)

Labels it would add: qa-reviewed test-automation-sufficient needs-manual-test

🤖 QA review analysis

Automated tests appear sufficient for this issue. A round of manual tests is still required.

Decision rationale

  • Automatable: yes. The clone-into-another-workspace flow runs entirely in the UI against standard Fleet resources and is already covered end to end.

  • Automation sufficient: yes. Both acceptance criteria are asserted in e2e:

    • the workspace is picked in the clone form and the resource is saved into the target workspace with its other options kept;
    • the header switcher stays disabled.

    Edge cases are covered extensively in unit tests.

  • Manual test recommended: yes. The change touches several multi-step Fleet wizards (GitRepo, HelmOp, Cluster Group, Policy), the header workspace switcher, and the shared NamespaceSelect/NameNsDescription components used by many other forms. That means strong UI integration and real regression risk outside Fleet.

Test evidence (PR #19443)

  • e2e
    • cypress/e2e/tests/pages/fleet/gitrepo.spec.ts – "Can clone a git repo into another workspace, picked in the form" asserts:
      • the header switcher is disabled (.vs--disabled);
      • the form's Workspace field starts on the source workspace and switches to fleet-local;
      • the POST body has the new namespace with repo/branch kept;
      • the header follows the clone's workspace and the clone is listed.
    • cypress/e2e/tests/pages/fleet/cluster-groups.spec.ts – "can clone a cluster group into another workspace, picked in the form": the same flow, including a check that the spec.selector is kept.
  • unit
    • shell/edit/__tests__/fleet.cattle.io.helmop.workspace.test.ts and fleet.cattle.io.gitrepo.workspace.test.ts, which cover:
      • valuesFrom, secrets and downstream resources being dropped or kept per workspace, with each removed name listed once in the role="status" banner;
      • the Policy default credential being swapped for the new workspace's default;
      • going back to the original workspace restoring everything that was deselected;
      • App Collection bundles staying locked to their workspace;
      • edit mode leaving the resource untouched;
      • the header moving to the saved workspace after save.
    • shell/utils/__tests__/fleet-workspace.test.ts covers workspace options (including the fallback via namespace annotation), retargeting (missing clusters/groups dropped, label selectors kept, fleet-local targets, Harvester rule), sameReference, and existsInNamespace returning false on 403/404.
    • shell/edit/__tests__/fleet.cattle.io.clustergroup.test.ts and fleet.cattle.io.policy.test.ts cover the workspace field with no namespace creation, validation that requires a workspace, and the header following the resource on save and edit.
    • NamespaceSelect.test.ts, LabeledSelectWithCreate.test.ts and NameNsDescription.test.ts cover createAllowed=false: the select cannot be cleared and cannot enter create mode.
    • FleetClusterTargets.test.ts checks that "Manually selected clusters" stays selectable in a workspace with no clusters.
    • Model tests (fleet.cattle.io.gitrepo.test.ts, fleet.cattle.io.helmop.test.ts) check that a clone keeps its workspace and correctDrift (fixing the lost drift correction).

Residual risk to monitor

  • No e2e covers cloning a HelmOp/App Bundle, or the "deselected items" banner against real secrets and config maps. These paths are unit-tested only and should be part of the manual pass.
  • Run with a Standard User who has Fleet access, where workspaces fall back to namespace annotations.
  • Regressions in non-Fleet forms that use NamespaceSelect (workload/chart create): defaults are meant to be unchanged.

This analysis was generated automatically based on unit and e2e evidence linked to this issue.

18175 Secret forms should prevent submission when fields contain invalid values Needs more tests + manual test
In QA Review 18 d (since 2026-10-07 20:13 UTC) · issue ↗ · linked PR: 19500 (open, 5 test files)

Labels it would add: qa-reviewed needs-more-test-automation needs-manual-test

🤖 QA review analysis

A round of manual tests is required. Automated tests are not yet sufficient for this issue.

Please address the feedback from the QA Review Decision Model:

Current state

  • The linked PR #19500 is still open and not merged (mergeable state: dirty, milestone v2.17.0). The fix is not yet in the codebase this issue is being QA-reviewed against.
  • Unit evidence in the PR is good for the validators and sub-forms:
    • shell/utils/validators/formRules/__tests__/index.test.ts covers pemCertificate, pemPrivateKey, sshPublicKey and dataKey, with valid and invalid cases.
    • shell/edit/secret/__tests__/tls.test.ts, ssh.test.ts and generic.test.ts assert isFormValid === false for invalid values inside a host form.
    • index.test.ts covers the name rules.
  • However, nothing asserts the acceptance criterion as the user sees it: that the Create button of the real Secret create page is disabled. The sub-form tests mount a synthetic FormHost rather than CruSecret/CruResource.

Suggested tests

  1. e2e – cypress/e2e/tests/pages/explorer/storage/secrets.spec.ts (or the existing secrets spec): Secrets > Create > TLS.
    • Enter not-a-cert / not-a-key and assert the Create button is disabled and the field shows the pemCertificate/pemPrivateKey message after blur.
    • Replace the values with valid PEM content and assert Create is enabled and the POST succeeds.
  2. e2e – Secrets > Create > SSH: an invalid public key (opa) or private key (op) keeps Create disabled, and valid keys enable it.
  3. e2e – Secrets > Create > Opaque:
    • a data key such as @##$ keeps Create disabled and shows the error on that key;
    • fixing the key re-enables Create;
    • an invalid secret name (e.g. ##^#%) also keeps it disabled.
  4. e2e – Edit an existing TLS secret:
    • with the private key field left blank, Save is enabled (the existing key is kept);
    • typing a non-PEM key disables Save.
  5. unit – shell/edit/secret/__tests__/index.test.ts: mount CruSecret in create mode with a TLS type and an invalid certificate, and assert that the CruResource stub receives validationPassed === false. With valid data it should receive true. This ties the sub-form validation to the parent form's submit gate.
  6. unit – a regression guard: a cloud credential name that is not a valid subdomain (e.g. with uppercase letters or spaces) still passes nameRules, because cloud credentials keep required only.

Manual test focus: existing secrets whose stored TLS/SSH data is not standard PEM/OpenSSH (Save is now blocked), project-scoped secrets, and cloud credential forms.

This comment was generated automatically to highlight missing automated coverage and suggest next tests to add.

18178 Project popover flickers, cannot use menu Needs more tests + manual test
In QA Review 32 d (since 2026-09-23 19:53 UTC) · issue ↗ · linked PR: 19203 (merged, 1 test file)

Labels it would add: qa-reviewed needs-more-test-automation needs-manual-test

🤖 QA review analysis

A round of manual tests is required. Automated tests are not yet sufficient for this issue.

Please address the feedback from the QA Review Decision Model:

Current state

  • The root cause, identified in this comment, is that every namespace/project update re-created the async ResourcePopover component inside a computed, which remounted it and closed the card. Merged PR #19203 hoists the component to a module-level constant.
  • The only test evidence is two unit cases in shell/components/Resource/Detail/Metadata/IdentifyingInformation/__tests__/identifying-fields.test.ts, which check that the valueOverride.component reference stays the same after a reactive update. These assert an implementation detail (object identity). They do not show the user-visible behavior: the popover stays open and its action menu stays usable while the resource updates.

Suggested tests

  1. unit – Mount the identifying information rows (or ResourcePopover via the useProject/useNamespace row) with a reactive resource.
    • Open the popover by triggering mouseenter on the target, mutate the resource (e.g. change project.nameDisplay or an annotation), and await nextTick().
    • Assert the popover card is still rendered/open and the ActionMenu trigger inside it is present.
    • This is the user-level contract that the identity test only implies.
  2. e2e – cypress/e2e/tests/pages/explorer/cluster/namespace-detail.spec.ts (or similar).
    • Create a namespace in a project, open its detail page, and hover the project name until the card is visible.
    • Then update the namespace through the API (e.g. cy.setRancherResource to add an annotation), wait for the websocket update, and assert the card is still visible.
    • Finally, open the card's ⋮ action menu and assert its items are clickable.
  3. e2e – The same flow for the namespace popover on a resource detail page (useNamespace), since both rows shared the same remount bug.

Manual test focus: this is a hover-driven interaction. Use the namespace-updater YAML from this comment on a downstream cluster and confirm the card no longer closes, in Chrome and Firefox.

This comment was generated automatically to highlight missing automated coverage and suggest next tests to add.

18250 Support configuration for etcd snapshot create + restore (Imported cluster day 2 ops) Tests sufficient + manual test
In QA Review 9 d (since 2026-10-17 03:20 UTC) · issue ↗ · linked PR: 19573 (merged, 10 test files)

Labels it would add: qa-reviewed test-automation-sufficient needs-manual-test

🤖 QA review analysis

Automated tests appear sufficient for this issue. A round of manual tests is still required.

Decision rationale

  • Automatable: yes for the UI logic: section visibility, form state, validation, and the payload written to rke2Config.etcd/k3sConfig.etcd. The real effects, snapshots actually being taken on the new schedule and landing in an S3 bucket, need a registered downstream RKE2/K3s cluster and real S3 credentials. These are not reasonable to run in routine CI.
  • Automation sufficient: yes for the UI scope. Merged PR #19573 adds broad unit coverage and updates the imported-cluster e2e flow.
  • Manual test recommended: yes. This is a Day 2 Ops feature with large product impact on imported RKE2/K3s clusters. It restructures the imported-cluster edit page (Basics → "K8s Version Management" + new "Day 2 Operations" section) and refactors the v2prov etcd tab. The PR author also notes they could not verify the real S3 step.

Test evidence (PR #19573)

  • e2e
    • cypress/e2e/tests/pages/manager/cluster-manager.spec.ts. On import, it checks that the version management and Day 2 Operations sections are hidden and that the "configure after import" banner text matches the global settings.
    • On edit of a registered imported K3s cluster, it checks the section order (K8s version management, Day 2 Operations, …) and that the etcd Automatic Backups block is visible.
    • On the local cluster, it checks that there is no Day 2 Operations section.
  • unit
    • pkg/imported/components/__tests__/CruImported.test.ts (+580 lines) covers:
      • visibility of the version management, Day 2 Ops and etcd sections for no config, RKE1, import, local, and feature on/off;
      • etcd changes being written to rke2Config.etcd and k3sConfig.etcd and saved;
      • an etcd config being created when the cluster had none;
      • save being blocked while the etcd or S3 config is invalid, including S3 validity while sections are collapsed (bucket, the credential's default bucket, unloaded credential, endpoint);
      • the etcd config being unset (with replace) when Day 2 Ops is disabled for the cluster or by the global default;
      • the S3 toggle being initialised and the cloud credential loaded on fetch.
    • shell/edit/provisioning.cattle.io.cluster/tabs/etcd/__tests__/EtcdSnapshotConfig.test.ts covers:
      • rendering of current values, and an empty config treated as snapshots enabled;
      • disabling snapshots, which clears S3 and reports valid;
      • S3 enable/disable, keeping an existing S3 config;
      • immutable update:value emits.
    • pkg/imported/components/__tests__/Basics.test.ts and DayTwoOps.test.ts are updated for the new layout.

Residual risk to monitor

  • Real backups:
    • change the cron schedule and retention on an imported RKE2/K3s cluster and confirm the downstream cluster takes snapshots on the new schedule;
    • enable S3 with a real cloud credential and confirm snapshots land in the bucket, both with and without the credential's default bucket.
  • v2prov regression: the RKE2/K3s create/edit etcd tab now delegates to EtcdSnapshotConfig. Re-check snapshot schedule, retention, S3 and the etcd-expose-metrics option.
  • Behavior change: clusters with a version management annotation but no rke2Config/k3sConfig (not yet registered) no longer show version management. Verify the banner wording for each combination of the global settings.
  • Note: the issue still carries needs-info and has no explicit acceptance criteria in its body. Use the PR's "Areas or cases that should be tested" list as the manual checklist.

This analysis was generated automatically based on unit and e2e evidence linked to this issue.

18495 Side nav collapses and loses selection indicator when creating some resources Tests sufficient + manual test
In QA Review 87 d (since 2026-07-30 16:22 UTC) · issue ↗ · linked PR: 18497 (merged, 3 test files)

Labels it would add: qa-reviewed test-automation-sufficient needs-manual-test

🤖 QA review analysis

Automated tests appear sufficient for this issue. A round of manual tests is still required.

Decision rationale

  • Automatable: yes. Whether a side-nav item is highlighted and its group stays expanded is deterministic routing logic.
  • Automation sufficient: yes. Merged PR #18497 adds a shared isNavItemActive/navItemClaimsRoute helper and unit-tests it directly and through the Group and Type components. Tests cover the positive case and the negative (sibling/unclaimed) cases.
  • Manual test recommended: yes. Side-nav state is a strongly UI-integrated behavior across many pages. The change also alters the matching logic for every nav item (the Type.vue isActive logic was replaced), and this comment explicitly asks for a manual round.

Test evidence (PR #18497)

  • unit – shell/utils/__tests__/router.test.js:
    • navItemClaimsRoute is tested with the resource taken from params or from route meta, and with an unclaimed resource, no resource, no nav item, or no route.
    • isNavItemActive is tested for:
      • its own route, and nested create/detail pages under a non-exact item;
      • not matching a sibling route or a partial path segment (kontainerDriverExtra);
      • an exact item not matching nested routes;
      • meta.nav, including case-insensitivity;
      • navResources;
      • an item with no route.
  • unit – shell/components/nav/__tests__/Group.test.ts. The group stays expanded on /management.cattle.io.project/create when a child claims it via navResources, and on /kontainerDriver/create. It is not active for unclaimed resources or for the unrelated hostedprovider route.
  • unit – shell/components/nav/__tests__/Type.test.ts checks the user-visible active class on nested routes (non-exact vs exact) and on routes for a claimed vs unclaimed resource.
  • Config: navResources added for Cluster/Project Members (CRTB/PRTB), Projects/Namespaces (Project, Namespace), and Namespaces. Cluster/Node drivers switched to exact: false.

Residual risk to monitor

  • The Cluster and Project Members add pages are only covered through the generic navResources mechanism; there is no dedicated test with the CRTB/PRTB routes. Include them in the manual pass.
  • With navResources: [NAMESPACE] on both Projects/Namespaces and Namespaces, check that only the expected item is highlighted when creating a namespace with the namespace-only view enabled or disabled.
  • Spot-check other products' side navs (Cluster Management drivers, Fleet, Apps), since all Type items now go through the new helper.

This analysis was generated automatically based on unit and e2e evidence linked to this issue.

18510 Create a LabeledSelect component that supports namespace creation Tests sufficient + manual test
In QA Review 79 d (since 2026-08-07 22:27 UTC) · issue ↗ · linked PR: 18512 (merged, 10 test files)

Labels it would add: qa-reviewed test-automation-sufficient needs-manual-test

🤖 QA review analysis

Automated tests appear sufficient for this issue. A round of manual tests is still required.

Decision rationale

  • Automatable: yes. This is a reusable form component (LabeledSelectWithCreate, NamespaceSelect) with clear inputs and outputs.
  • Automation sufficient: yes. Merged PR #18512 adds thorough unit suites for both new components, rewrites the NameNsDescription tests, and updates e2e flows to drive the new component, including inline namespace creation.
  • Manual test recommended: yes. NameNsDescription is used by most create forms across the product, so the refactor carries major regression risk. The issue itself states QA "will likely only need regression testing".

Test evidence (PR #18512)

  • unit – shell/components/form/__tests__/LabeledSelectWithCreate.test.ts covers:
    • the "Create new" entry and divider being prepended, with a custom label, or hidden when createAllowed=false;
    • the sentinel value not leaking through update:value;
    • entering create mode (via the create option or by clearing) and emitting an empty value;
    • live typing emitting values with no confirm step;
    • cancel by button or Escape resetting the input;
    • label/labelKey and other props being passed through.
  • unit – shell/components/form/__tests__/NamespaceSelect.test.ts covers:
    • disabled state (edit mode, disabled, forceNamespace);
    • the override/options sources;
    • padding the options with a not-yet-created namespace;
    • syncing external value changes;
    • the cru-resource/setCreateNamespace dispatches staying true while typing and false on cancel or when an existing namespace is picked;
    • cancel resetting to the default namespace.
  • unit – shell/components/form/__tests__/NameNsDescription.test.ts covers:
    • name and namespace disabled states;
    • hidden sections;
    • custom test IDs;
    • custom nameKey/namespaceKey;
    • forceNamespace being persisted on mount.
  • e2e
    • cypress/e2e/tests/pages/explorer2/workloads/jobs.spec.ts creates Jobs using "Create a new Namespace" through the new LabeledSelectWithCreatePo page object.
    • cypress/e2e/tests/pages/explorer/service-discovery/ingress.spec.ts selects an existing namespace through the new page object.
    • New page object: cypress/e2e/po/components/labeled-select-with-create.po.ts.

Residual risk to monitor

  • Regression across forms that use NameNsDescription: workloads, chart install, secrets/config maps, and forms passing namespacesOverride, namespaceMapper or forceNamespace.
  • Users without namespace create permission should not see the "Create a new Namespace" option.
  • Later changes in #19443 (createAllowed stops clearing from entering create mode) build on this component. Re-test inline creation and cancel once both are in the build.

This analysis was generated automatically based on unit and e2e evidence linked to this issue.

18536 RcSection: counter badge contrast + content group slot support Tests sufficient + manual test
In QA Review 40 d (since 2026-09-15 15:17 UTC) · issue ↗ · linked PR: 18776 (merged, 5 test files)

Labels it would add: qa-reviewed test-automation-sufficient needs-manual-test

🤖 QA review analysis

Automated tests appear sufficient for this issue. A round of manual tests is still required.

Decision rationale

  • Automatable: yes. The behaviors are component props, slot structure and colour resolution in the rancher-components library.
  • Automation sufficient: yes. Merged PR #18776 adds unit tests for every new behavior: the new RcContentGroup component, the RcCounterBadge status and colour layers with ariaLabel, and the RcSection default slot and counter element.
  • Manual test recommended: yes, as a light visual pass. Both items in the issue are about visual outcomes (badge contrast in light/dark mode, 16px vs 24px spacing). Jest/jsdom does not evaluate the v-bind() CSS, so it cannot confirm rendered colours or spacing. The PR also changes the default-slot spacing of every product RcSection.

Test evidence (PR #18776)

  • unit – pkg/rancher-components/src/components/Layout/RcContentGroup/RcContentGroup.test.ts checks the wrapper class, single and multiple children nested from the slot, and the re-export from the index.
  • unit – pkg/rancher-components/src/components/Pill/RcCounterBadge/RcCounterBadge.test.ts covers:
    • aria-label binding, and the dev warning when status is set without ariaLabel;
    • the colour layers: type default, active badges not reachable by an ancestor, outlined warning/error status colours, a full override beating status, a partial override, disabled active/inactive colours, and hover-border behavior.
  • unit – pkg/rancher-components/src/components/RcSection/RcSection.test.ts covers:
    • the default slot rendering straight into .section-content, and not rendering when collapsed;
    • several RcContentGroup siblings being kept as siblings;
    • the counter slot getting its own .counter element only when provided.

Residual risk to monitor

  • Visual check in Storybook (Components / RcSection, AllTypes, RcCounterBadge / Status, OverriddenColors) in light and dark themes: the counter fill is white in a secondary header and the grey badge is kept in a primary header.
  • Fleet App Bundle edit (SUSE App Collection), Deploy chart to (FleetClusterTargets) and Advanced (HelmOpAppCoConfigTab): spacing should match master now that the hand-rolled wrapper divs are gone.
  • Other product RcSection usages now get one 16px group by default instead of 24px between children. Spot-check imported-cluster edit and other pages that use RcSection.

This analysis was generated automatically based on unit and e2e evidence linked to this issue.

18751 Cluster Dashboard usage percentage counts nodes that are excluded from cluster capacity, inflating it above 100% Needs more tests + manual test
In QA Review 33 d (since 2026-09-22 22:21 UTC) · issue ↗ · linked PR: 18858 (merged, 1 test file)

Labels it would add: qa-reviewed needs-more-test-automation needs-manual-test

🤖 QA review analysis

A round of manual tests is required. Automated tests are not yet sufficient for this issue.

Please address the feedback from the QA Review Decision Model:

Decision summary

  • Automatable: yes. The gauge math lives in computed properties of shell/pages/c/_cluster/explorer/index.vue and getters of shell/models/cluster/node.js, so it can be unit tested with mocked nodes and node metrics.
  • Automation sufficient: no. The only test change in #18858 is in shell/detail/__tests__/node.test.ts, which renames mock fields (cpuCapacity → cpuAllocatable, ramReserved → ramAllocatable). None of the new aggregation logic (schedulableWorkerNodes, workerStatsAggregation, metricAggregations filtering, cpuUsed/ramUsed, hasStats, and the subtraction of system-reserved resources) is tested.
  • Manual test: yes. This is a customer-reported (SURE-11753) Cluster Dashboard regression with high visibility. The correct result depends on real node topology (tainted control-plane/etcd nodes, cordoned workers, imported clusters without worker labels), and a backport is waiting on a QA pass.

Suggested tests

  1. unit: shell/pages/c/_cluster/explorer/__tests__/index.test.ts, "usage uses the same node set for numerator and denominator"
    • Mock 4 nodes: 1 tainted control-plane/etcd node, 1 cordoned worker, 2 schedulable workers. Give each node metrics.
    • Assert that ramUsed.useful and cpuUsed.useful only sum metrics from the 2 schedulable workers, and that ramUsed.total and cpuUsed.total equal the sum of those workers' allocatable.
    • Assert the resulting percentage is ≤ 100% when every node has headroom (the regression from the issue body: 6.25 / 7.73 GiB).
  2. unit: same suite, "falls back to cluster status when there are no schedulable worker nodes"
    • Mock an imported cluster whose nodes have no worker-role labels.
    • Assert that cpuReserved, ramReserved, podsUsed, cpuUsed and ramUsed use currentCluster.status.allocatable and requested, and that metricAggregations uses all schedulable nodes. This guards the zero-usage case fixed by #16863.
  3. unit: same suite, edge cases for hasStats and the system-reserved subtraction
    • hasStats is false when allocatable.cpu === '0' and there are no schedulable workers.
    • cpuUsed and ramUsed return null when metricAggregations is unavailable.
    • useful never goes negative when systemReservedRam or systemReservedCpu is larger than the metric usage.
  4. unit: shell/models/__tests__/node.test.ts (or the existing cluster node model tests)
    • Assert cpuAllocatable, cpuCapacity, ramAllocatable, ramReserved (now taken from podRequests.memory), cpuReserved, podReserved, systemReservedRam/systemReservedCpu (clamped at 0) and isSchedulable for nodes with and without status.capacity, status.allocatable and podRequests.
    • Assert that cpuUsagePercentage now divides by allocatable.
  5. e2e: cypress/e2e/tests/pages/explorer2/cluster-dashboard.spec.ts
    • Intercept v1/nodes and v1/metrics.k8s.io.nodemetrics, including a tainted control-plane node and a cordoned worker.
    • Assert that the Memory and CPU "Used" gauges show the expected x / y values and percentage, and that the bar is not red.

Residual risk to monitor: ramReserved has changed meaning (it was allocatable, now it is pod requests) and is also used on the Node detail page. Subtracting system-reserved resources from usage is a semantic change that should be confirmed against kubectl top nodes.

This comment was generated automatically to highlight missing automated coverage and suggest next tests to add.

18756 SCC Registration page reports a registered system as unregistered for global roles that cannot read the registration Secret Tests sufficient + manual test
In QA Review 19 d (since 2026-10-07 09:48 UTC) · issue ↗ · linked PR: 19389 (merged, 3 test files)

Labels it would add: qa-reviewed test-automation-sufficient needs-manual-test

🤖 QA review analysis

Automated tests appear sufficient for this issue. A round of manual tests is still required.

Rationale #19389 follows the agreed UX decision: page actions are disabled and a permission message is shown when the registration can't be read. The new and updated unit tests directly cover the acceptance criteria and the main edge cases.

  • Automatable: yes
  • Automation sufficient: yes
  • Manual test recommended: yes. This is a Prime-only (area/scc) flow. The permission check relies on real RBAC behaviour (schemas hidden for inaccessible types, a 403 vs 404 from management/find on cattle-scc-system/scc-registration) that the unit tests can only mock. It should be checked once with the hosted-admin-style custom global role from SURE-11884, on a system registered from the backend.

Test evidence (#19389)

  • pkg/rancher-prime/pages/registration.composable.test.ts, new suite "when the user cannot read the registration":
    • the page is blocked when the secret or scc.cattle.io.registration schema is missing
    • the page is blocked on a 403 from the secret lookup by id
    • status shows unknown instead of unregistered, and registrationStatus is null
    • the forbidden warning banner is shown
    • no registration errors are reported
    • edge cases: a 404 still allows the page and shows none; an already-listed secret skips the lookup by id
  • pkg/rancher-prime/pages/Registration.test.ts, "given a user who cannot read the registration":
    • the forbidden banner text and the unknown badge are shown
    • every action (registration-code-input, online/offline CTAs, download, visit SCC, deregister) is disabled
    • online register stays disabled even after a code is entered, which prevents the 409 path
  • pkg/rancher-prime/index.test.ts: the registration notification is removed and not added when the user can't read the registration

Residual risk to monitor

  • There is no e2e test. Real RBAC responses (for example, whether Steve returns 403 or an empty list for a forbidden namespace) should be confirmed manually.
  • The original "button stuck on Registering" path in registerOnline is avoided by disabling the button, not by adding error handling. If a user can read but not write, that path is still possible.

This analysis was generated automatically based on unit and e2e evidence linked to this issue.

18772 Remove Legacy feature and associated checks Needs more tests + manual test
In QA Review 73 d (since 2026-08-13 19:08 UTC) · issue ↗ · linked PRs: none

Labels it would add: qa-reviewed needs-more-test-automation needs-manual-test

🤖 QA review analysis

A round of manual tests is required. Automated tests are not yet sufficient for this issue.

Please address the feedback from the QA Review Decision Model:

Decision summary

  • Automatable: yes. All three acceptance criteria are UI states that can be asserted with unit tests (component and store) and e2e tests.
  • Automation sufficient: no. The linked PR is #18773 ("Removed Legacy feature and unsupported Azure provider", merged; it also fixes #18224). Its test changes mostly delete tests:
    • Azure banner and cloud-provider tests were removed from shell/edit/provisioning.cattle.io.cluster/__tests__/Basics.test.ts and rke2.test.ts.
    • deployedAsLegacy and deployedAsMultiCluster mocks were removed from shell/pages/c/_cluster/apps/charts/__tests__/install.test.ts.
    • The features.test.ts case was swapped from LEGACY to UNSUPPORTED_STORAGE_DRIVERS.
    • The only new assertion is that Azure is filtered out of the cloud-provider options. Nothing asserts that the legacy banner or the legacy/MCM blocking screen is gone.
  • Manual test: yes. Removing the dead code touches two core flows, chart install/upgrade (install.vue fetch() and the template branch) and RKE2/K3s provisioning (Basics.vue, rke2.vue), so the regression risk is significant. The PR lists 11 manual scenarios.

Suggested tests

  1. unit: shell/edit/provisioning.cattle.io.cluster/__tests__/Basics.test.ts, "should not render the legacy warning banner"
    • Mount Basics with features/get returning true for every flag and kubernetesVersion: 'v1.31.0+rke2r1'.
    • Assert that no banner contains cluster.legacyWarning. This covers AC 3.
  2. unit: same suite, "cloud provider select is never disabled in edit mode"
    • Mount in _EDIT mode with the agent config set to cloud-provider-name: 'azure'.
    • Assert that [data-testid="clusterBasics__cloudProvider"] has no disabled attribute and that no Azure migration or unsupported banner is rendered.
  3. unit: shell/pages/c/_cluster/apps/charts/__tests__/install.test.ts, "upgrade of an existing app renders the install steps"
    • Mount with an existing app whose values contain global.clusterName and global.projectName (the shape that used to trigger the legacy path).
    • Assert that .install-steps renders the wizard, that no catalog.install.error.legacy.* text appears, and that existing.fetchValues is not called for legacy detection. This covers AC 2.
  4. unit: shell/models/__tests__/catalog.cattle.io.app.test.ts
    • Assert that upgradeAvailable / compatibleVersionsFor still hide pre-release versions when SHOW_PRE_RELEASE is false (the removed isPrerelease branch was dead but sat right next to it).
    • Assert that deployedAsLegacy and deployedAsMultiCluster are no longer defined.
  5. unit: shell/store/__tests__/features.test.ts
    • Assert that LEGACY is no longer exported from @shell/store/features. This covers AC 1.
  6. e2e: cypress/e2e/tests/pages/explorer/apps/charts.spec.ts (or an existing chart install spec)
    • Install a chart, then open its upgrade page.
    • Assert that the install wizard loads with no legacy/multi-cluster banner and that the upgrade completes.

Residual risk to monitor: if the backend still exposes the legacy feature flag on the Feature Flags page, toggling it should not break any UI. Existing clusters using in-tree Azure on k8s 1.27–1.30 lose the migration guard.

This comment was generated automatically to highlight missing automated coverage and suggest next tests to add.

18783 Add a fallback to return the data from Cluster and Project Members Needs more tests + manual test
In QA Review 68 d (since 2026-08-18 13:14 UTC) · issue ↗ · linked PR: 18786 (merged, 2 test files)

Labels it would add: qa-reviewed needs-more-test-automation needs-manual-test

🤖 QA review analysis

A round of manual tests is required. Automated tests are not yet sufficient for this issue.

Please address the feedback from the QA Review Decision Model:

Decision summary

  • Automatable: yes

  • Automation sufficient: no. #18786 has good unit coverage of the fallback inside the component:

    • shell/components/auth/__tests__/Principal.test.ts: a principal is built from the matching user; the provider is derived from the id rather than the aggregated user.provider; displayName falls back to nameDisplay; nothing is built when users aren't loaded or no user matches.
    • shell/models/__tests__/principal.test.ts: a GitHub principal with no picture gets an identicon.

    However, the fallback only works if the page has already loaded management.cattle.io.user into the store, and #18786 only changes Principal.vue and principal.js. No test shows that the Cluster/Project Members pages load users for a User-Base + "user manager" role, so the acceptance criterion (that user sees names, not ids, on Cluster Membership) has no automated coverage.

  • Manual test: yes. The fix depends on an RBAC-specific combination (User-Base global role, user-manager permission, cluster owner) and on data the page has to load. Unit-level mocks can't confirm that this role really gets past the typeRegistered guard.

Suggested tests

  1. unit: shell/list/__tests__/explorer-members.test.ts (or the members list component that renders Principal)
    • Assert that the members page dispatches management/findAll for MANAGEMENT.USER (or otherwise registers the user type) when the user can list users.
    • Assert that it doesn't fail when the user can't list users.
  2. unit: Principal.test.ts, "should prefer the directly fetched principal over the user fallback"
    • When rancher/find succeeds, rancher/create must not be called and the fetched principal is shown.
  3. unit: Principal.test.ts, "should render the resolved name in the template"
    • After the fallback, the rendered .name text is the user's display name and the principal.error text is not shown. This checks what the user sees, not just vm.principal.
  4. e2e: cypress/e2e/tests/pages/explorer2/cluster-project-members.spec.ts
    • Create a User-Base user with the user manager global role and make it cluster owner of local, then add a second local user as a cluster member.
    • Log in as the first user, open Cluster and Project Members, and assert that the second member's display name is shown instead of u-xxxxx.
    • Also assert that an external principal still falls back to the id or error state, since external users aren't in the management user list.

Residual risk to monitor: as the issue notes, this is only a partial fix (internal users only). External-provider members are handled by #18795.

This comment was generated automatically to highlight missing automated coverage and suggest next tests to add.

18795 Show Principal ID whenever username cannot be resolved instead of error message Tests sufficient + manual test
In QA Review 9 d (since 2026-10-17 01:02 UTC) · issue ↗ · linked PR: 19535 (merged, 1 test file)

Labels it would add: qa-reviewed test-automation-sufficient needs-manual-test

🤖 QA review analysis

Automated tests appear sufficient for this issue. A round of manual tests is still required.

Rationale #19535 replaces the red "Unable to fetch principal info" error with a readable principal ID, a question-mark avatar and an info tooltip, as agreed in the design discussion (2026-08-18 comment). Unit tests cover the rendered output in detail.

  • Automatable: yes
  • Automation sufficient: yes
  • Manual test recommended: yes. This is a kind/design change with strong UX dependence; UX questions about keeping the info icon and the question-mark avatar were still open in the 2026-10-15 demo. It also involves real external auth providers (AD/GitHub/Okta groups) that the unit tests can't exercise. Priority is High.

Test evidence (#19535, shell/components/auth/__tests__/Principal.test.ts)

  • ID formatting: it.each covers github_team://8087745 → github_team 8087745, github_user://…, okta_user://test, and a bare u-abc123.
  • Raw ID not rendered: the raw :// form never appears.
  • Avatar: a question-mark RcIcon replaces the avatar and is ariaHidden (a11y).
  • No error styling: no .text-error and no .icon-warning.
  • Tooltip: an info RcIconTooltip sits next to the name with the principal.unresolved text and an ml-5 spacing class.
  • Edge cases:
    • an empty principal ID shows principal.error, no tooltip, and still shows the question mark
    • a principal resolved through the user fallback shows no info icon
    • fetch() now awaits loadData(), so the loading state stays until the lookup finishes ("should keep fetching while the principal lookup is in flight")

Residual risk to monitor

  • There is no e2e test on the Cluster/Project Membership pages with an unresolved external group.
  • Check the layout (grid-row span) in light and dark themes, check that the tooltip works with the keyboard, and confirm that extensions built with older shells still show principal.error.

This analysis was generated automatically based on unit and e2e evidence linked to this issue.

18831 YAML config modal is not displaying data Tests sufficient, no manual test
In QA Review 44 d (since 2026-09-11 23:25 UTC) · issue ↗ · linked PR: 19090 (merged, 7 test files)

Labels it would add: qa-reviewed test-automation-sufficient no-manual-test-needed

🤖 QA review analysis

Automated tests appear sufficient for this issue. No manual tests required.

Rationale #19090 resolves the blank YAML tab by making YAML viewing unavailable for cloud credentials, which are Norman resources with no view link. The issue originally expected the YAML to be shown, so the fix changes the expected behaviour. Both the user-visible result and the shared drawer and detail changes have unit and e2e coverage.

  • Automatable: yes
  • Automation sufficient: yes
  • Manual test recommended: no. The behaviour is deterministic and covered end to end. The shared-component change only narrows YAML availability when the live resource reports canYaml === false, which means the YAML would have been blank anyway.

Test evidence (#19090)

  • e2e cypress/e2e/tests/pages/manager/cloud-credential.spec.ts: after clicking a cloud credential row, [data-testid="show-configuration-cta"] does not exist.
  • e2e cypress/e2e/tests/pages/manager/kubeconfig.spec.ts (new) plus page objects kubeconfig.po.ts and kubeconfig-list.po.ts: a regression guard that a Steve resource with canYaml: false in its type config still shows a non-empty YAML tab in Show Configuration.
  • unit shell/components/Drawer/ResourceDetailDrawer/__tests__/composables.test.ts: YAML props are returned when canYaml is true and undefined (with no fetch) when it is false. A canYaml getter that throws, or a rejected getYaml, returns undefined instead of throwing.
  • unit shell/components/ResourceDetail/__tests__/index.test.ts: canViewYaml is false when the live resource has no view link, stays true or false according to the type-map default, and is false (without breaking the page) when the getter throws.
  • unit shell/models/__tests__/cloudcredential.test.ts: disableResourceDetailDrawer is true, and doneRoute is fixed to c-cluster-manager-cloudCredential.

Residual risk to monitor

  • Other Norman-backed resource types that used to show a (blank) YAML toggle will now hide it. That is intended, but watch for reports about missing "Edit YAML"/"View YAML" on such types.
  • If product decides cloud credentials should show YAML after all, this issue's acceptance criteria will need updating.

This analysis was generated automatically based on unit and e2e evidence linked to this issue.

18850 Content inside RcSection is not validated when collapsed Needs more tests + manual test
In QA Review 2 d (since 2026-10-23 21:11 UTC) · issue ↗ · linked PR: 19380 (merged, 9 test files)

Labels it would add: qa-reviewed needs-more-test-automation needs-manual-test

🤖 QA review analysis

A round of manual tests is required. Automated tests are not yet sufficient for this issue.

Please address the feedback from the QA Review Decision Model:

Decision summary

  • Automatable: yes

  • Automation sufficient: no. #19380 has strong unit coverage at the component level:

    • pkg/rancher-components/src/components/RcSection/RcSection.test.ts:
      • collapsed content stays mounted (v-show) and its fields stay registered with vee-validate
      • form().validate() is invalid while the section is collapsed
      • content isn't remounted on toggle
      • unmountOnHide opt-out
      • invalid-fields icon, table-of-contents flag and nested propagation
      • validate-on-collapse, including fields added later
    • components/utils/reveal.test.ts and TextAreaAutoGrow.test.ts: re-measuring after the content is revealed.

    However, the user-facing acceptance criterion ("Save button should be disabled" with a collapsed invalid section) isn't asserted in any real form. The PR also removes the s3ConfigValid safeguard from pkg/imported/components/CruImported.vue and its tests in CruImported.test.ts ("should block saving an invalid s3 config…"). It now relies on RcSection keeping RcS3Config mounted, but CruImported uses the form-validation mixin (fvFormIsValid / etcdConfigValid), not vee-validate, and no test replaces the removed coverage.

  • Manual test: yes. RcSection is a shared layout component. Switching from v-if to v-show changes mount behaviour for every form that uses it (CAPA, imported clusters, RKE2 provisioning), so the regression risk is high. Components that measure the DOM while hidden (code editors, auto-grow inputs, tables) may render incorrectly.

Suggested tests

  1. unit: pkg/imported/components/__tests__/CruImported.test.ts, "should block saving an invalid S3 config while its section is collapsed"
    • Mount with day 2 ops enabled, s3Backup: true and an empty S3 config, with the etcd/S3 RcSection collapsed (not stubbed).
    • Assert that CruResource gets validationPassed === false. This replaces the removed s3ConfigValid cases, including the credential with a default bucket (valid), the missing bucket (invalid) and the https:// endpoint (invalid).
  2. unit: RcSection.test.ts, "form-validation mixin field inside a collapsed section keeps the form invalid"
    • Same as the existing vee-validate test, but for a LabeledInput with :rules inside a component using the FormValidation mixin, checking that fvFormIsValid is false.
  3. unit: LabeledInput (or another field that calls useReportInvalidToSection and useSectionShowErrors)
    • Assert that the field shows its validation error without being touched once the surrounding section has been collapsed, and doesn't show it before.
  4. e2e: cypress/e2e/tests/pages/manager/cluster-manager-imported.spec.ts (or a provisioning form with RcSection)
    • Make a required field inside an RcSection invalid, collapse the section, and assert that the Save/Create button is disabled and that [data-testid="rc-section-invalid-fields"] is visible in the section header and in the table of contents.
    • Expand the section, fix the field, and assert that Save becomes enabled.

Residual risk to monitor: check performance on forms with many collapsed sections, now that all content stays mounted. Watch for hidden components that size themselves on mount (CodeMirror/YAML editors, auto-grow text areas outside RcSection) and render at the wrong size after expanding.

This comment was generated automatically to highlight missing automated coverage and suggest next tests to add.

18872 Add Restore mode to Snapshot restore action (Imported cluster day 2 ops) Tests sufficient + manual test
In QA Review 9 d (since 2026-10-17 01:43 UTC) · issue ↗ · linked PR: 19564 (merged, 6 test files)

Labels it would add: qa-reviewed test-automation-sufficient needs-manual-test

🤖 QA review analysis

Automated tests appear sufficient for this issue. A round of manual tests is still required.

Rationale #19564 moves PromptRestore to shell/dialog/ as an RcModal, removes the Date section, and adds restore-mode handling for imported clusters. Both acceptance criteria are covered directly by thorough unit tests that include edge cases.

  • Automatable: yes
  • Automation sufficient: yes
  • Manual test recommended: yes. Restoring an etcd snapshot is destructive and depends on the backend (an operation CR is consumed by rancher/rancher#56077) on real imported RKE2/K3s clusters. The dialog was also rewritten and is shared with the RKE2 restore flow, so the regression risk is high and the product impact is large (Day 2 Ops epic #16453).

Test evidence (#19564)

  • shell/dialog/__tests__/PromptRestore.test.ts (new; replaces shell/components/__tests__/PromptRestore.test.ts):
    • AC 1, Date removed: "should not render a date section" checks the h3 headings are only name and restore mode, with no DateFormatter.
    • AC 2, imported cluster without version management: the cluster is only offered none (etcd only), with matching labels; it defaults to none; it never sends kubernetesVersion or all even if they were set; and the mode resets when the cluster's capabilities change.
    • Imported cluster with version management, and RKE2: all modes are offered; the selected mode is sent in the operation CR args or restoreRKEConfig.
    • Snapshot annotation etcdsnapshot.rke.io/restore-mode-options: filtering, whitespace and unknown values, fallback to defaults, never an empty set, and a reset or kept selection when the snapshot changes.
    • Modal behaviour: title, show/hide, cancel calls onClose, restore disabled with no snapshot, the success path (save, growl, close), the failure path (stays open and shows the error), and a 403 from the operation CR shows an alert banner.
  • shell/models/__tests__/management.cattle.io.cluster.test.ts: isVersionManagementEnabled truth table across the annotation and global setting.
  • shell/models/__tests__/rke.cattle.io.etcdsnapshot.test.ts (new): restoreEnabled and isSnapshotTooOld for imported snapshots stored in the management cluster namespace.
  • shell/plugins/steve/__tests__/actions.test.ts: promptRestore opens the dialog through promptModal with ownsModal: true.

Residual risk to monitor

  • There is no e2e test for the new RcModal dialog, for either the snapshot list action or the cluster "Restore" action.
  • Confirm the backend accepts restoreMode in the operation CR args and actually performs etcd-only restores.
  • Check that the RKE2 restore and its restore modes are unchanged after the AppModal → RcModal migration.

This analysis was generated automatically based on unit and e2e evidence linked to this issue.

18898 Add first-run/minor update wizard/modal Tests sufficient + manual test
In QA Review 4 d (since 2026-10-21 15:15 UTC) · issue ↗ · linked PR: 19324 (merged, 15 test files)

Labels it would add: qa-reviewed test-automation-sufficient needs-manual-test

🤖 QA review analysis

Automated tests appear sufficient for this issue. A round of manual tests is still required.

Rationale #19324 adds a release welcome modal that opens once per minor version. It reuses the read-whatsnew preference and the notification-centre version logic, loads content from dynamic content with a built-in fallback, and can be reopened from the user menu. The PR includes e2e tests for the user flows agreed in the 2026-10-16 decisions, plus unit tests for each card and the Header menu.

  • Automatable: yes
  • Automation sufficient: yes
  • Manual test recommended: yes. This is a headline feature with strong UX dependence (finalised Figma design, fade and height transitions, theming of the Prime surface). It has separate Community and Prime/registration variants and depends on an external dynamic-content endpoint (rancher/ui-dynamic-content#32), so a human check is worthwhile.

Test evidence (#19324)

  • e2e cypress/e2e/tests/pages/generic/release-welcome.spec.ts (new; page object release-welcome-dialog.po.ts), for admin and standard users:
    • the modal shows once per minor release; closing it marks read-whatsnew as "v2.16.0" (without the build suffix) and the release-notes notification as read
    • dynamic content replaces the features and the Prime promo (title, products, CTA link)
    • the modal opens immediately with a loading state, then shows content once the fetch finishes (delayed intercept)
    • a document with an entry only for the patch version falls back to the built-in content, matched strictly by minor version
    • a patch upgrade does not reopen the modal but marks the notification unread
    • focus starts on Close (a11y); the modal reappears on reload until closed
    • it can be reopened from the user menu "What's New" and closed with Esc
  • e2e support: cypress/support/e2e.ts hides the modal for every other spec unless showReleaseWelcome is set; user-menu.po.ts now expects 4 menu items.
  • unit shell/components/ReleaseWelcome/__tests__/WhatsNewCard.test.ts, PrimePromoCard.test.ts, PrimeRegistrationCard.test.ts, PrimeCard.test.ts: built-in vs dynamic content, empty lists hiding the card or products, links and new-tab attributes, aria-labelledby, aria-hidden icons.
  • unit shell/components/nav/__tests__/Header.test.ts: the "What's New" item is visible only in Rancher (not in single-product mode or dev builds), separators are grouped correctly, and clicking calls openReleaseWelcome.

Residual risk to monitor

  • The e2e tests only cover Community (RancherPrime: 'false'). On Prime, the registration card and the subtitle's "Registration page" link (canRegister = Prime + admin + SCC feature) only have unit coverage.
  • Check custom branding and private-label logos, the reduced-motion path, and how the modal behaves when the dynamic-content endpoint is unreachable in air-gapped setups.
  • The global read-whatsnew intercept in cypress/support/e2e.ts affects every spec. Watch for flaky specs that log in during before.

This analysis was generated automatically based on unit and e2e evidence linked to this issue.

18940 Move version management logic into composables Needs more tests + manual test
In QA Review 46 d (since 2026-09-09 19:39 UTC) · issue ↗ · linked PR: 18979 (merged, 3 test files)

Labels it would add: qa-reviewed needs-more-test-automation needs-manual-test

🤖 QA review analysis

A round of manual tests is required. Automated tests are not yet sufficient for this issue.

Please address the feedback from the QA Review Decision Model:

Decision: is_automatable=true, automation_sufficient=false, manual_test=true

Evidence found (PR #18979)

  • shell/composables/useKubernetesVersions.test.ts (new, unit): covers versionOptions grouping (rke2/k3s), edit-mode filtering, deprecated patch filtering, selectedVersion (including the "none" CNI de-duplication), chartVersions/serverArgs/agentArgs fallbacks, and fetchK8sVersions: cache short-circuit, partial retry, settings vs channel defaults, the empty-KDM error, a per-request rejection, and retry after failure. getDefaultVersion covers the Harvester path.
  • shell/composables/usePodSecurityAdmissionTemplates.test.ts (new, unit): covers fetch allowed/denied by canList, recorded errors, and errors being cleared on each fetch.
  • shell/edit/provisioning.cattle.io.cluster/__tests__/rke2.test.ts (unit): the old characterization tests were moved to the composable, and the ingress/chart tests now seed rke2Versions through the setup proxy.

Why this isn't sufficient yet: the composable logic is well covered. The PR also adds a new user-visible behavior, though: version and PSA fetch errors are shown instead of the page failing to load. That wiring in rke2.vue is not tested, and nothing covers the full provisioning form. The PR itself flags "All v2prov and Harvester provisioning could be affected", which is a large regression risk.

Suggested tests

  1. unit (rke2.test.ts): mount rke2.vue with /v1-rke2-release/releases rejecting. Assert that fetch() resolves, the form still renders, and the rejection message shows up in the component's errors (the banner shown to the user). Add the same case for fetchAllPSAs rejecting, so psaErrors is shown and the PSA dropdown falls back to empty.
  2. unit (rke2.test.ts): change value.spec.kubernetesVersion between two versions with different charts/serverArgs. Assert that chartVersions, serverArgs and the add-on list update from the composable after $nextTick. This is the PR's "versions re-render" scenario.
  3. e2e (cypress/e2e/tests/pages/manager/cluster-manager.spec.ts or the RKE2 custom create spec): intercept GET /v1-rke2-release/releases with a 500. Assert that the create page loads, an error banner is visible, and the Kubernetes Version select still renders with the k3s options.
  4. e2e: on the RKE2 custom create page, pick a non-default Kubernetes version. Assert that the Add-On Config tab shows chart entries for that version and that the PSA template dropdown lists the expected templates.

Manual testing: recommended. This is a refactor of the core RKE2/K3s/Harvester provisioning form with broad regression risk. Run a regression pass of create/edit on custom, node-driver and Harvester clusters, version switching, and a simulated KDM failure.

This comment was generated automatically to highlight missing automated coverage and suggest next tests to add.

18942 Move registry config into a composable Tests sufficient + manual test
In QA Review 24 d (since 2026-10-01 19:56 UTC) · issue ↗ · linked PR: 19267 (merged, 2 test files)

Labels it would add: qa-reviewed test-automation-sufficient needs-manual-test

🤖 QA review analysis

Automated tests appear sufficient for this issue. A round of manual tests is still required.

Decision: is_automatable=true, automation_sufficient=true, manual_test=true

Rationale: this is a refactor that should not change behavior. Before the extraction, characterization tests were written against the rke2.vue methods (initRegistry, setRegistryConfig, updateConfigs, toggleCustomRegistry, the host/secret handlers). PR #19267 carries those tests over almost 1:1 into a unit suite for the new composable. Matching tests before and after the move are strong evidence that behavior did not change.

Evidence found (PR #19267)

  • shell/composables/useRegistryConfig.test.ts (new, unit, 17 cases):
    • initRegistry: cluster registry wins over the global one, falls back to the global registry, initializes empty configs/mirrors, picks up an existing auth secret and shows the custom input, and shows the advanced input when mirrors exist.
    • setRegistryConfig: clears the override when the host is empty or matches the system registry, sets the override otherwise, creates rkeConfig when it's missing, merges with existing configs, and keeps existing mirrors.
    • updateConfigs with and without rkeConfig; host/secret handlers; toggleCustomRegistry clearing a set host vs re-initializing.
  • shell/edit/provisioning.cattle.io.cluster/__tests__/rke2.test.ts: the duplicate method tests were removed and point to the composable suite.

Manual testing: recommended. The Registries tab sits inside the shared RKE2 provisioning form. The composable now reads props.value.agentConfig and props.value.spec.rkeConfig instead of the component's this.agentConfig/this.rkeConfig, so check that the save round-trip still works end to end. Specifically: create and edit an RKE2 cluster with (a) a global system-default-registry, (b) a cluster-scoped registry with an auth secret, (c) mirrors in the advanced config. Confirm the YAML/spec is unchanged and the values are restored when you edit again.

Residual risk: no component- or e2e-level test confirms that rke2.vue still calls initRegistry/setRegistryConfig at the right lifecycle and save hooks after the move.

This analysis was generated automatically based on unit and e2e evidence linked to this issue.

18944 Move cluster memebrship management into a composable Needs more tests + manual test
In QA Review 11 d (since 2026-10-14 17:48 UTC) · issue ↗ · linked PR: 19357 (merged, 4 test files)

Labels it would add: qa-reviewed needs-more-test-automation needs-manual-test

🤖 QA review analysis

A round of manual tests is required. Automated tests are not yet sufficient for this issue.

Please address the feedback from the QA Review Decision Model:

Decision: is_automatable=true, automation_sufficient=false, manual_test=true

Evidence found (PR #19357)

  • shell/composables/useClusterMembership.test.ts (new, unit): covers canManageMembers true/false and the no-store guard, onMembershipUpdate staging, and saveRoleBindings as a no-op without save and calling save(parentId) when present.
  • pkg/eks/components/__tests__/CruEKS.test.ts, pkg/gke/components/__tests__/CruGKE.test.ts, pkg/imported/components/__tests__/CruImported.test.ts: changed only so the existing tests keep passing with the new setup(). They don't assert membership behavior.

Why this isn't sufficient yet: the composable is covered, but the refactor rewires six cluster forms: RKE2, AKS, EKS, GKE, Imported and Harvester. Each form now forwards its own saveRoleBindings method with a different id source (normanCluster.id, or value.mgmt.id after waitForMgmt() on RKE2). No test checks that wiring, or that membershipUpdate, now a setup ref, unwraps correctly on this. Member roles are assigned at cluster creation, so a regression here would quietly drop role bindings.

Suggested tests

  1. unit (shell/edit/provisioning.cattle.io.cluster/__tests__/rke2.test.ts): call onMembershipUpdate({ save: jest.fn() }), mock value.waitForMgmt and value.mgmt.id, then call saveRoleBindings(). Assert that waitForMgmt was awaited before save was called with the mgmt id.
  2. unit (one parametrized test across CruAKS, CruEKS, CruGKE, CruImported, harvesterhci.io.management.cluster.vue): stage an update through onMembershipUpdate and call saveRoleBindings(). Assert that save is called with normanCluster.id. Also assert that saveRoleBindings is registered as the save-role-bindings after-hook.
  3. unit: with canViewClusterMembershipEditor mocked to false, assert that ClusterMembershipEditor is not rendered on at least the RKE2 and imported forms.
  4. e2e (cypress/e2e/tests/pages/manager/cluster-manager.spec.ts): import a generic cluster after adding a member in the Member Roles section. Intercept the clusterroletemplatebindings POST and assert that it targets the new cluster id with the selected user and role.

Manual testing: recommended. The change crosses several providers (RKE2, hosted AKS/EKS/GKE, imported, Harvester), so the regression risk is broad. On create and edit, add and remove a member and confirm the CRTBs are created or removed. Also check that a user without permission does not see the Member Roles editor.

This comment was generated automatically to highlight missing automated coverage and suggest next tests to add.

19023 [BUG] Carriage returns are not sanitized from agent environment variables Tests sufficient, no manual test
In QA Review 19 d (since 2026-10-06 21:15 UTC) · issue ↗ · linked PR: 19362 (merged, 1 test file)

Labels it would add: qa-reviewed test-automation-sufficient no-manual-test-needed

🤖 QA review analysis

Automated tests appear sufficient for this issue. No manual tests required.

Decision: is_automatable=true, automation_sufficient=true, manual_test=false

Rationale: the fix is a small, self-contained change to KeyValue.vue: line splitting now uses /\r?\n/, lines split on the first =, keys are trimmed, and removeEmptyRows reads the configured keyName/valueName. Unit tests cover both acceptance criteria directly, plus the main edge cases.

Evidence found (PR #19362): shell/components/form/__tests__/KeyValue.test.ts, new describe('onFileSelected with parseLinesFromFile'), mounted with keyName: 'name' to match Agent Environment Vars:

  • AC1, carriage returns removed: parametrized over unix, DOS (\r\n) and mixed line endings. Asserts the rows are exactly FOO=bar/BAZ=qux with no trailing \r. Another case checks that a DOS file keeps whitespace inside the value but not the \r.
  • AC2, no error and empty rows removed: blank lines and whitespace-only lines are ignored for both unix and DOS files (the case from the reported bug). FOO= (empty value) imports without throwing. An existing empty row is removed after parsing, which exercises the removeEmptyRows field-name fix.
  • Edge cases: a value containing = (OPTS=a=b=c) and a line without =.

Manual testing: not required. The behavior is fully exercised at the component level and depends little on UI layout. Registration-command generation uses the already-sanitized values.

Residual risk to monitor: no e2e test uploads a real CRLF file through the Read From File button on the custom cluster page and checks the generated registration command. If regressions come up, add a Cypress test that selects a fixture with \r\n and asserts the registration command contains no \r/trailing spaces.

This analysis was generated automatically based on unit and e2e evidence linked to this issue.

19027 Support Auth Config SAML ADFS searching with LDAP Tests sufficient + manual test
In QA Review 6 d (since 2026-10-19 16:17 UTC) · issue ↗ · linked PR: 19378 (merged, 1 test file)

Labels it would add: qa-reviewed test-automation-sufficient needs-manual-test

🤖 QA review analysis

Automated tests appear sufficient for this issue. A round of manual tests is still required.

Decision: is_automatable=true, automation_sufficient=true, manual_test=true

Rationale: the UI scope is to show and validate the LDAP search configuration for the ADFS SAML provider, gated on Rancher Prime and the adfs-ldap-search feature flag. Unit tests cover that scope well. Per the issue comment, the API and objects match the existing Okta/Shibboleth LDAP search, so the UI reuses the existing ldap/config.vue.

Evidence found (PR #19378): shell/edit/auth/__tests__/saml.test.ts

  • supportsLDAPSearch computed: a parametrized matrix of shibboleth/okta (always on); adfs × prime × feature flag (on only when both are true); keycloak/ping/genericsaml (always off).
  • Rendering: the LDAP option appears for ADFS on Prime with the flag on, and is hidden on a community install.
  • LDAP search validation: passes with all fields; fails when hostname, port, connection timeout, service account DN, password or user search base is empty; TLS on without a certificate fails, with one it passes; ADFS with LDAP available plus empty fields fails; ADFS without LDAP available ignores the LDAP fields.

Manual testing: recommended. This is an area/auth feature, Prime-only, and the real value is LDAP user/group search against a live ADFS + LDAP backend. That third-party integration can't be reliably simulated in this repo. The issue also says Collie QA will provide an environment and coordinate with UI QA. Suggested pass: enable ADFS with LDAP search on Prime with the flag on, then search users and groups in the principal picker and on Users & Authentication. Check that it's hidden on community or with the flag off, and check that the TLS/StartTLS checkbox layout changes in ldap/config.vue look right.

Residual risk: the layout change in ldap/config.vue (TLS/StartTLS grouped into .tls-options) also affects the OpenLDAP/FreeIPA/Okta/Shibboleth forms and has no visual test.

This analysis was generated automatically based on unit and e2e evidence linked to this issue.

19084 Change imported cluster to use RcSections instead of Accordions Tests sufficient + manual test
In QA Review 18 d (since 2026-10-07 17:31 UTC) · issue ↗ · linked PR: 19153 (merged, 17 test files)

Labels it would add: qa-reviewed test-automation-sufficient needs-manual-test

🤖 QA review analysis

Automated tests appear sufficient for this issue. A round of manual tests is still required.

Decision: is_automatable=true, automation_sufficient=true, manual_test=true

Rationale: PR #19153 changes the imported cluster create/edit form from Accordions to RcSections and adds Rc variants of the form components. It includes both e2e and unit coverage aimed at the new structure.

Evidence found (PR #19153)

  • e2e: cypress/e2e/tests/pages/manager/cluster-manager.spec.ts was updated to:
    • assert the exact order of top-level sections on import (Basics, Member Roles, Labels & Annotations, Registries, Advanced), on edit (K3S Options, …, Networking, Registries, Advanced) and on local edit (no Networking);
    • check that the table of contents has one entry per top-level section and that clicking an entry scrolls to and expands that section;
    • expand the Networking and Registries sections during the edit flow to set ACE and the private registry.
  • New page object cypress/e2e/po/components/rc-section.po.ts, plus updates to cluster-create-import.po.ts and cluster-edit.po.ts.
  • unit:
    • pkg/imported/components/__tests__/Basics.test.ts (new): the selected version and the deprecated-patches toggle survive a remount.
    • RcSection.test.ts: table-of-contents navigation expands a collapsed section and calls scrollIntoView.
    • DayTwoOps.test.ts: renders as an expandable secondary section.
    • CruImported.test.ts and versionManagement.test.ts updated.
    • The PR also lists new unit tests for RcKeyValue, RcLabels, RcLabelsAndAnnotations and RcACE.

Manual testing: recommended. Much of this change is visual: 16px/24px spacing, 14px label text, section nesting, light/dark mode. It also replaces several shared form controls with new Rc copies (KeyValue, Labels, PrivateRegistry, SelectOrCreateAuthSecret, SchedulingCustomization, ACE). The PR's own test areas are a good checklist: import generic/K3s/RKE2; edit local and non-local clusters; agent env vars including Read from File; the labels/annotations system toggle in view mode; every Image Pull Secret option; the version management radio and banners; upgrade strategy validation.

Residual risk: the Rc copies now differ from the originals, so later fixes to KeyValue, for example the CRLF fix in #19023, also have to be applied to RcKeyValue. Watch for drift.

This analysis was generated automatically based on unit and e2e evidence linked to this issue.

19117 a11y: Enable CI gate to not add any more a11y violations Tests sufficient, no manual test
In QA Review 18 d (since 2026-10-07 23:49 UTC) · issue ↗ · linked PRs: 19336 (merged, 1 test file), 19440 (merged, 2 test files)

Labels it would add: qa-reviewed test-automation-sufficient no-manual-test-needed

🤖 QA review analysis

Automated tests appear sufficient for this issue. No manual tests required.

Decision: is_automatable=true, automation_sufficient=true, manual_test=false

Rationale: this issue is test infrastructure. It turns on a CI ratchet that fails the a11y-test job on any accessibility violation not in the committed baseline. The deliverable is itself automated, and the product code changed along the way has unit tests.

Evidence found

  • PR #19336 (Prepare for a11y enforcement): shrinks cypress/e2e/tests/accessibility/baseline.json from 18 known violations to 2 (both in Kubectl Shell), so the gate starts from a near-clean baseline produced by the Cypress a11y suite (shell.spec.ts).
  • PR #19440 (Enforce a11y gate):
    • .github/workflows/test.yaml: A11Y_RATCHET_ENFORCE now defaults to 'true', and the repo variable can switch it back to report-only.
    • cypress/scripts/a11y/README.md documents enforcement and re-seeding.
    • shell/components/PromptModal.vue now caches resolved dialog components so open dialogs aren't remounted. shell/components/__tests__/PromptModal.test.ts adds unit tests: the dialog mounts only once when the type-map changes while it's open, and switching to a different dialog still renders the new one.
  • The ratchet compare script has its own unit tests (yarn a11y:test, per the README).

Manual testing: not required. The change affects CI only, plus a small, unit-tested fix to dialog resolution.

Residual risk to monitor:

  • No test in these PRs proves end to end that a newly introduced violation actually fails the job. Check the first few PRs after merge to confirm the gate blocks as expected and doesn't flake.
  • The PromptModal cache keys on the dialog name. Watch for any dialog that expects a fresh instance each time it opens.

This analysis was generated automatically based on unit and e2e evidence linked to this issue.

19147 New UX design for sortable table in functionality and style Needs more tests + manual test
In QA Review 3 d (since 2026-10-22 17:50 UTC) · issue ↗ · linked PR: 19151 (merged, 3 test files)

Labels it would add: qa-reviewed needs-more-test-automation needs-manual-test

🤖 QA review analysis

A round of manual tests is required. Automated tests are not yet sufficient for this issue.

Please address the feedback from the QA Review Decision Model:

Decision: is_automatable=true, automation_sufficient=false, manual_test=true

Evidence found (PR #19151)

  • shell/components/SortableTable/__tests__/index.test.ts (new, unit): isColumnVisible matrix (missing, hidden, with and without advanced filtering); expandAll marks every row by keyField and drops stale keys; collapseAll clears the state.
  • shell/components/SortableTable/__tests__/THead.test.ts: sortedTableColsOptions (filters hidden and non-option columns, sorts case-insensitively, doesn't mutate its input, handles empty) and an isHeaderColumnVisible matrix.
  • shell/components/SortableTable/__tests__/selection.test.ts: selecting a row stops propagating row-selected at a sub-row that contains a .sub-table.

Why this isn't sufficient yet: the helper methods are covered, but two of the three acceptance criteria are not tested where the behavior happens:

  • AC3, sorting on hidden columns: nothing checks that a column with hide: true and a sort key still drives the row order, or that its header and cells are not rendered.
  • AC2, Expand all / Collapse all: nothing checks that the header-right slot actually receives expandAll/collapseAll, or that calling them shows or hides the sub-rows.
  • AC1, style changes: no borders, bold header, hover only on sub-table rows. These are CSS-only and have no assertions. Partly covered by the selection test.

SortableTable is used across most list views, so the regression risk is high.

Suggested tests

  1. unit (SortableTable/__tests__/index.test.ts, mounted): pass headers containing { name: 'age', value: 'metadata.creationTimestamp', sort: 'metadata.creationTimestamp:desc', hide: true } with defaultSortBy: 'age' and three rows with different timestamps. Assert that the rendered row order follows the hidden column and that no <th>/<td> is rendered for age.
  2. unit (same file): assert that fullColspan leaves out hidden columns and columns filtered out by advanced filtering, so the sub-row colspan stays aligned.
  3. unit (mounted with a #header-right="{ expandAll, collapseAll }" slot that renders two buttons plus a #sub-row slot): click "Expand all" and assert that every row's sub-row is rendered; click "Collapse all" and assert that none are.
  4. e2e (a list page that uses sub-tables, with a page object for the expand/collapse controls): click Expand all and Collapse all, then assert sub-table visibility. Hover a sub-table row and assert that only that row gets the hover background, not the parent main row or the sub-table header.

Manual testing: recommended. AC1 is purely visual (borders, font-weight 600, background and hover behavior) and needs a UX check in light and dark mode. Because the component is shared, do a quick regression sweep of common list pages: column visibility menu ordering, bulk selection with sub-rows, and search width.

This comment was generated automatically to highlight missing automated coverage and suggest next tests to add.

19172 Unhandled rejection on logout: "Schemas aren't loaded yet" from Prime registration Tests sufficient, no manual test
In QA Review 19 d (since 2026-10-06 15:30 UTC) · issue ↗ · linked PR: 19390 (merged, 2 test files)

Labels it would add: qa-reviewed test-automation-sufficient no-manual-test-needed

🤖 QA review analysis

Automated tests appear sufficient for this issue. No manual tests required.

Rationale: The fix is small and tightly scoped. It guards the Prime registration initRegistration() promise chain against a logout (managementReady reset) and adds a .catch. Unit tests in jsdom can simulate this race exactly with fake timers and controllable promises, and the linked PR does so.

  • Automatable: ✅ Yes
  • Automation sufficient: ✅ Yes
  • Manual test recommended: ❌ No. The behavior is internal error handling with no UX surface. The original symptom (an unhandled rejection surfacing in Cypress) is now covered by the e2e suite that used to hide it.

Test evidence (PR #19390):

  • unit: pkg/rancher-prime/index.test.ts, new suite extension: rancher-prime registration notification:
    • happy path: notification is added for an admin without an active registration
    • logout mid-resolution: management/schemaFor is not called and no notifications/* dispatch happens
    • failure path: a rejected lookup after logout is swallowed silently (console.error not called)
    • failure path while logged in: the error is still logged (Failed to resolve the registration state)
  • e2e: cypress/e2e/tests/pages/user-menu/preferences.spec.ts. The cy.on('uncaught:exception', …) suppression for Schemas aren't loaded yet is removed. This spec logs out repeatedly, so it now acts as an e2e regression guard for the original failure.

Residual risk to monitor:

  • The original reproduction was intermittent (~2/3 of runs). Watch preferences.spec.ts on Prime CI runs for flakes over the next few nightly runs.
  • The guard depends on store.state.managementReady being reset during logout. If the logout flow changes how the store is reset, this check may need to be revisited.

This analysis was generated automatically based on unit and e2e evidence linked to this issue.

19236 Add a CodeMirror 6 editor to Rancher Components Tests sufficient, no manual test
In QA Review 26 d (since 2026-09-29 19:57 UTC) · issue ↗ · linked PR: 19234 (merged, 4 test files)

Labels it would add: qa-reviewed test-automation-sufficient no-manual-test-needed

🤖 QA review analysis

Automated tests appear sufficient for this issue. No manual tests required.

Rationale: This issue adds a new shared component (RcCodeMirror) to @rancher/components and explicitly leaves existing Dashboard editors untouched (AC #4). The acceptance criteria are component-level (exports, Storybook examples, unit tests), and the linked PR ships extensive Jest coverage for the component. The user-facing replacement of the Dashboard editors is tracked separately in #19274, which is where manual validation of real screens belongs.

  • Automatable: ✅ Yes
  • Automation sufficient: ✅ Yes
  • Manual test recommended: ❌ No. No Dashboard screen consumes the component as part of this issue, so there is no product regression surface here. The Storybook stories serve as the interactive reference.

Test evidence (PR #19234, 25 files):

  • unit: pkg/rancher-components/src/components/RcCodeMirror/RcCodeMirror.test.ts covers model updates via v-model, read-only editing being blocked, the input variant (wrapping, no gutters, line-break markers), the fold gutter and marker order, and keyboard access for read-only editors (per commits 77cd5f3, 766bf4a, fcc4248, 6ab7657 and 0d671a5).
  • unit: RcCodeMirror.emacs.test.ts has a table-driven parity check of the CodeMirror 5 Emacs bindings (commit 303ea93). It checks the document and selection after each key sequence.
  • Folding helpers (foldByLineMatch, foldByYamlPath, foldMatchingLines, foldYamlPath, commentFoldService, foldAllComments) are exported from extensions/fold.ts and index.ts. They include parseDocument() handling for content beyond the initial viewport.
  • Storybook: storybook/src/stories/Components/RcCodeMirror.stories.ts and .mdx have Default, Json, ReadOnly, ReadOnlyKeyboard, Input, InputYaml, CustomFolding, BracketFolding and VModel stories, which satisfies AC #2.
  • Export: pkg/rancher-components/src/index.ts adds export * from './components/RcCodeMirror', which satisfies AC #1.
  • Supporting config: jest.setup.js (matchMedia listeners) and jest.config.js (transform for @replit/codemirror-vim-core, vendor/ excluded from coverage).

Residual risk to monitor:

  • jest.setup.js changed the global matchMedia mock. Watch for unrelated unit tests that rely on its old shape.
  • Light/dark rendering of the input variant was only checked by the author in Storybook. Visual parity should be validated when the component replaces Dashboard editors in #19274.
  • The vendored Emacs keymap (vendor/codemirror-emacs) is excluded from lint and coverage. Upstream updates will need a manual re-sync.

This analysis was generated automatically based on unit and e2e evidence linked to this issue.

19305 Harvester machine pools: support PCI device passthrough (hostDeviceInfo) Needs more tests + manual test
In QA Review 3 d (since 2026-10-23 07:07 UTC) · issue ↗ · linked PR: 19273 (merged, 1 test file)

Labels it would add: qa-reviewed needs-more-test-automation needs-manual-test

🤖 QA review analysis

A round of manual tests is required. Automated tests are not yet sufficient for this issue.

Please address the feedback from the QA Review Decision Model:

Current evidence (PR #19273): pkg/harvester-manager/machine-config/__tests__/harvester.test.ts (new, 432 lines, unit) tests the component's options-API functions in isolation (data, updateHostDevices, fetchHasHostDeviceInfo, getAvailablePciDevices, pciDeviceOptions, hostDeviceSelectOptions, hostDevicesAddDisabled, pciDeviceOptionLabel, validatorHostDevices). This logic coverage is strong. It includes PCIDeviceClaim matching, missing or failed deviceCapacity, deduping, and the allocatable validation path. No test mounts the component, though, so the template wiring added in harvester.vue is unverified.

Why manual testing is required: This is a new provisioning feature for the Harvester / Rancher Manager community. It depends on a node driver bump (hostDeviceInfo in the HarvesterConfig schema) and on real PCI passthrough on a Harvester cluster. Neither can be exercised in CI. A maintainer comment also says the feature still needs PM/UX vetting.

Suggested automated tests:

  1. unit: mount harvester.vue and assert the PCI Devices section is gated by schema support

    • Mount with management/pathExistsInSchema returning true. Assert the harvesterManager.hostDevices.title heading and the ArrayListSelect render.
    • Mount with it returning false. Assert the PCI Devices section is not rendered, so a Rancher without the driver bump never shows a picker whose value the API would drop.
  2. unit: mounted selection updates value.hostDeviceInfo

    • Emit update:value from the PCI ArrayListSelect with [GPU_TYPE, NIC_TYPE].
    • Assert value.hostDeviceInfo equals {"hostDevices":[{"name":"hostdevice-1","deviceName":GPU_TYPE},{"name":"hostdevice-2","deviceName":NIC_TYPE}]}. This verifies the @update:value="updateHostDevices" binding, not just the method.
    • Clear the selection and assert hostDeviceInfo becomes ''.
  3. unit: allocation warning banner and add-button state

    • With a device whose allocatable > 0, assert the warning Banner with cluster.credential.harvester.hostDevices.warnings.minimumAllocatable is shown in edit mode and hidden in _VIEW mode.
    • When every option is already selected, assert the ArrayList "Add" control is disabled (hostDevicesAddDisabled).
  4. unit: validationErrors surfaces the PCI error alongside vGPU

    • Call the component's top-level validation with pools that over-request a PCI device type. Assert the returned errors contain the hostDevices.errors.notAllocatable message, which confirms validatorHostDevices is wired into the form validation.
  5. e2e (optional, if Harvester mocks exist): create an RKE2 cluster on a Harvester cloud credential

    • Intercept /k8s/clusters/<id>/v1/devices.harvesterhci.io.pcidevice, …pcideviceclaim, …/harvester/cluster/local and deviceCapacity. Select a PCI device in the machine pool.
    • Assert the POST for the HarvesterConfig includes hostDeviceInfo with the selected deviceName. When the device is unclaimed, assert it is not offered.

Manual focus areas: On a Harvester cluster with a claimed GPU and its audio function (same IOMMU group), provision a pool with both selected. Confirm the VM's .spec.domain.devices.hostDevices, the pool-size warning or block behavior, editing an existing pool (the selection is kept when allocatable reports 0), and machine replacement.

This comment was generated automatically to highlight missing automated coverage and suggest next tests to add.

19312 Role Template resource picker offers Node instead of Nodes, so the saved rule grants nothing Tests sufficient, no manual test
In QA Review 20 d (since 2026-10-05 16:01 UTC) · issue ↗ · linked PR: 19313 (merged, 1 test file)

Labels it would add: qa-reviewed test-automation-sufficient no-manual-test-needed

🤖 QA review analysis

Automated tests appear sufficient for this issue. No manual tests required.

Rationale: The fix is a data correction in the hardcoded resource list shell/config/roles.ts: Node→Nodes, CSIStorageCapacitys→CSIStorageCapacities, and Endpoints moved from the bogus io.k8s.api.discovery group into the core group. RoleDetailEdit.vue lowercases each label into the saved resourceName. The new unit tests assert those computed option values directly, including that the invalid ones are gone.

  • Automatable: ✅ Yes
  • Automation sufficient: ✅ Yes
  • Manual test recommended: ❌ No. The change is limited to static option values whose saved form is asserted. The downstream kubectl auth can-i patch nodes outcome is standard Kubernetes RBAC behavior once the correct plural is saved.

Test evidence (PR #19313):

  • unit: shell/components/auth/__tests__/RoleDetailEdit.test.ts, new describe('resourceOptions'):
    • positive: offers { apiGroupValue: '', resourceName: 'nodes' }, { '', 'endpoints' } and { 'storage.k8s.io', 'csistoragecapacities' }
    • negative: does not offer { '', 'node' }, { 'io.k8s.api.discovery', 'endpoints' } or { 'storage.k8s.io', 'csistoragecapacitys' }
  • The existing suite in the same file already checks how a selected option maps to { resourceName, apiGroupValue }, so the save shape is covered end to end at the component level.

Residual risk to monitor:

  • Existing RoleTemplates and GlobalRoles saved with node are not migrated, as the issue notes. Admins must edit them by hand. Consider a release note.
  • The follow-up concern about Cordon/Uncordon/Drain visibility (Norman node actions vs. core nodes grants) is out of scope here and should be tracked separately.
  • status/backport-candidate: re-run the same unit suite on any backport branch, since roles.ts may differ there.

This analysis was generated automatically based on unit and e2e evidence linked to this issue.

19314 Add E2E to assert that YAML editor keys don't conflict keyboard shortcuts Tests sufficient, no manual test
In QA Review 4 d (since 2026-10-22 07:55 UTC) · issue ↗ · linked PR: 19315 (merged, 1 test file)

Labels it would add: qa-reviewed test-automation-sufficient no-manual-test-needed

🤖 QA review analysis

Automated tests appear sufficient for this issue. No manual tests required.

Rationale: This is a test-only task, and its deliverable is the e2e spec itself. The spec covers every scenario the issue asked for, plus more, using cypress-real-events so keys go through the browser input pipeline.

  • Automatable: ✅ Yes
  • Automation sufficient: ✅ Yes
  • Manual test recommended: ❌ No. There is no product code change in this issue's scope, and the spec runs in CI.

Test evidence (PR #19315, file cypress/e2e/tests/components/code-mirror-shortcuts.spec.ts):

  • e2e CodeMirror editor shortcuts (Emacs keymap):
    • Ctrl-K in the editor kills to end of line, and navActionBar.jumpToInput() is not focused (requested scenario 1)
    • Ctrl-P moves to the previous line, a layout-dependent check (requested scenario 2)
    • Ctrl-K outside the editor focuses the navigation search and leaves the document unchanged. This is the negative guard against a fix that disables shortcuts everywhere (requested scenario 3).
    • Extra coverage: Ctrl-Y yank, Ctrl-/ undo and Ctrl-Shift-Z redo, M-</M->, M-d, M-w + yank, the Ctrl-X H chord, Ctrl-V page down without pasting, Ctrl-F, Ctrl-H
  • e2e CodeMirror default (Sublime) shortcuts: Mod-D, Mod-Shift-D, line swap, Mod-L
  • e2e CodeMirror Vim shortcuts: $+x, dd/u, o/yy/p/u
  • Preference reset: the after() hooks log in again and call cy.setUserPreference({ keymap: 'sublime' }), which satisfies AC #2.
  • Supporting change: the cypress-real-events types in cypress/tsconfig.json and the duplicate realHover declaration removal target AC #3 (tsc clean).

Residual risk to monitor:

  • AC #1 said "passes against master (CodeMirror 5)". Master moved to CodeMirror 6 (#19274) before this merged, and the spec now uses CM6 selectors (.cm-line, .cm-focused). It therefore guards the CM6 editor, which is the one that matters going forward, and no longer exercises CM5.
  • Browser-reserved keys (Ctrl-N/Ctrl-W/Ctrl-T) are not testable over CDP, as documented in the spec.
  • The CodeMirror default (Sublime) block has no after() hook. This is fine because it sets the default value, but any future block with a non-default keymap must include a reset.

This analysis was generated automatically based on unit and e2e evidence linked to this issue.

19334 Add principal identifier attribute fields to LDAP-based auth providers Needs more tests + manual test
In QA Review 19 d (since 2026-10-06 22:01 UTC) · issue ↗ · linked PR: 19141 (merged, 6 test files)

Labels it would add: qa-reviewed needs-more-test-automation needs-manual-test

🤖 QA review analysis

A round of manual tests is required. Automated tests are not yet sufficient for this issue.

Please address the feedback from the QA Review Decision Model:

Current evidence (PR #19141):

  • unit: shell/edit/auth/ldap/__tests__/config.test.ts, new suite lDAP config principal identifier attributes. It checks that both inputs render for openldap/freeipa/activedirectory/shibboleth/okta, that inputs bind to model.userIDAttribute/groupIDAttribute, that they are unset by default, editable before enable, locked once enabled for LDAP/AD types, and editable once enabled for SAML types.
  • e2e: cypress/e2e/tests/pages/users-and-auth/openldap.spec.ts checks that the attributes are sent in testAndApply and locked when the provider is enabled. okta.spec.ts checks that the attributes are sent in openLdapConfig and stay editable when enabled. New POs are openldap.po.ts and okta.po.ts.

Gap: The acceptance item "The enabled provider summary lists both attributes when set, in the LDAP provider banner and in the SAML LDAP search details" has no test. The tooltip variants (tip / locked / samlTip) are also unasserted.

Why manual testing is required: This is an auth feature (area/auth, High priority) that changes principal identity. It depends on backend rancher/rancher#55642, #54912 and rancher/webhook#1451. Only a real directory can show that logins and RBAC bindings survive a user moving between OUs, and that the backend rejects changes on an enabled provider.

Suggested automated tests:

  1. unit: LDAP provider banner lists the attributes (shell/edit/auth/ldap/index.vue)

    • Mount with model.enabled = true, userIDAttribute: 'uid' and groupIDAttribute: 'cn'. Assert the AuthBanner rows contain authConfig.ldap.userIDAttribute: uid and authConfig.ldap.groupIDAttribute: cn.
    • Mount with both empty. Assert neither row is rendered (v-if).
  2. unit: SAML LDAP search details list the attributes (shell/edit/auth/saml.vue)

    • Mount an enabled Okta/Shibboleth config with openLdapConfig.userIDAttribute/groupIDAttribute set. Assert both rows appear in the LDAP details table. When unset, assert they are absent.
  3. unit: tooltip text matches provider state (config.vue idAttributeTooltip)

    • openldap + isCreate: true → authConfig.ldap.idAttribute.tip
    • openldap + isCreate: false → authConfig.ldap.idAttribute.locked
    • okta/shibboleth (either state) → authConfig.ldap.idAttribute.samlTip
  4. unit: index.vue passes is-create from model.enabled

    • Mount ldap/index.vue with model.enabled = true and assert the child LDAPConfig receives isCreate === false. With enabled = false, assert true. This regression-proofs the new :is-create="!model.enabled" binding that drives the lock.
  5. e2e (optional): Active Directory parity

    • Mirror openldap.spec.ts for activedirectory (AD has its own config page). Assert that userIDAttribute/groupIDAttribute are sent on enable and that the inputs are disabled once enabled.

Manual focus areas: Against a real OpenLDAP or AD: enable with userIDAttribute set, bind RBAC to a user, move the user to another OU and confirm access persists. Confirm the inputs are locked once enabled and that disabling unlocks them. For Okta/Shibboleth with LDAP search, confirm search results match logged-in principals when the attributes mirror the UID and Groups fields.

This comment was generated automatically to highlight missing automated coverage and suggest next tests to add.

19374 Observed timestamps are not correct in growl message. Tests sufficient, no manual test
In QA Review 18 d (since 2026-10-07 21:01 UTC) · issue ↗ · linked PR: 19435 (merged, 1 test file)

Labels it would add: qa-reviewed test-automation-sufficient no-manual-test-needed

🤖 QA review analysis

Automated tests appear sufficient for this issue. No manual tests required.

Rationale: The root cause was created.diff(day(), 'day'), which counts elapsed 24h periods rather than calendar days. The fix compares startOf('day') values. It is a one-line change in Notification.vue, and a new unit suite with a frozen system clock covers exactly the boundary cases that caused the bug.

  • Automatable: ✅ Yes
  • Automation sufficient: ✅ Yes
  • Manual test recommended: ❌ No. The behavior is a pure date-label computation, fully covered by deterministic tests. It has low UX complexity and no cross-page interaction.

Test evidence (PR #19435):

  • unit: shell/components/nav/NotificationCenter/__tests__/Notification.test.ts (new). It uses jest.setSystemTime('2026-10-07T11:40Z') and asserts the rendered .created text:
    • earlier today → notificationCenter.dates.today, 00:05
    • yesterday, less than 24h ago → notificationCenter.dates.yesterday, 17:04 (the reported bug: previously labeled as today)
    • yesterday, more than 24h ago → notificationCenter.dates.yesterday, 00:01 (edge case)
    • two days ago → falls back to the formatted date 2026-10-05, 23:59
  • The assertions check user-visible text, not implementation details.

Residual risk to monitor:

  • Calendar-day boundaries depend on the browser's local timezone. The tests rely on the Jest environment's timezone. If CI ever runs with a non-UTC TZ, the fixtures may shift. Pinning TZ or adding a non-UTC case would harden this.
  • The report mentioned the runtime-enforcer extension. Notifications created by extensions use the same Notification.vue renderer, so no separate handling is expected.

This analysis was generated automatically based on unit and e2e evidence linked to this issue.

19382 a11y: fix nested-interactive violation Tests sufficient, no manual test
In QA Review 19 d (since 2026-10-06 14:20 UTC) · issue ↗ · linked PR: 19384 (merged, 4 test files)

Labels it would add: qa-reviewed test-automation-sufficient no-manual-test-needed

🤖 QA review analysis

Automated tests appear sufficient for this issue. No manual tests required.

Rationale: The nested-interactive violation came from the window manager close button (RcButton) being nested inside the element with role="tab". The fix moves role="tab", tabindex, ARIA attributes and the keyboard handler onto a new inner .tab-title, so the close button becomes its sibling. The behavior is covered at both levels: unit tests assert the DOM structure and interactions, and the axe e2e baseline now fails if the violation returns.

  • Automatable: ✅ Yes
  • Automation sufficient: ✅ Yes
  • Manual test recommended: ❌ No. The change is a structural ARIA fix verified by axe in CI, with interaction parity asserted in unit tests.

Test evidence (PR #19384):

  • unit: shell/components/nav/WindowManager/panels/__tests__/HorizontalPanel.test.ts and VerticalPanel.test.ts (RIGHT and LEFT):
    • no focusable element (button, a, input, select, textarea, [tabindex]) is nested inside [role="tab"]
    • each wm-tab-close-button is the adjacent sibling of its tab
    • tab activation still works on click, keyup.enter and keyup.space
    • clicking the close button does not activate the tab (edge case)
  • e2e: cypress/e2e/tests/accessibility/baseline.json drops the nested-interactive entry for shell.spec.ts > … > Kubectl Shell, so the axe run fails on regression.
  • e2e support: cypress/e2e/po/components/kubectl.po.ts closeTerminalByTabName selector updated to [aria-label] + [data-testid="wm-tab-close-button"]. Existing kubectl/shell specs exercise it.

Residual risk to monitor:

  • Tab padding and focus-outline styling moved from .tab to .tab-title. Watch for visual regressions in the window manager tabs (focus ring, label truncation, close-button spacing) in light and dark themes.
  • Click handling and drag remain on the outer .tab, so clicking the close-button gutter still activates the tab as before.

This analysis was generated automatically based on unit and e2e evidence linked to this issue.

19383 a11y: fix aria-required-children violation Tests sufficient + manual test
In QA Review 18 d (since 2026-10-07 17:38 UTC) · issue ↗ · linked PR: 19385 (merged, 6 test files)

Labels it would add: qa-reviewed test-automation-sufficient needs-manual-test

🤖 QA review analysis

Automated tests appear sufficient for this issue. A round of manual tests is still required.

Rationale: The aria-required-children violation is fixed by moving role="tablist" off the container, which also held non-tab buttons. It now sits on an empty element that adopts the tabs through aria-owns with stable ids from a new tabId() helper. The change was applied to the Window Manager panels (Horizontal/Vertical) and to TableViewTabs.vue. Automated coverage is good, but the issue itself calls this one "a little bit hairy". aria-owns support varies across screen readers, and axe can only verify the markup, not how it is announced.

  • Automatable: ✅ Yes
  • Automation sufficient: ✅ Yes
  • Manual test recommended: ✅ Yes. The fix relies on aria-owns re-parenting, which axe accepts but which assistive technologies interpret inconsistently. A quick screen-reader pass is the only reliable check that the tabs are still announced as a tablist with the correct position and selected state. The change also affects two independent UI areas (window manager and table view tabs).

Test evidence (PR #19385):

  • unit: HorizontalPanel.test.ts / VerticalPanel.test.ts (RIGHT and LEFT). No button/[role="button"] inside [role="tablist"], and the tablist's aria-owns equals the ordered list of rendered tab ids.
  • unit: tab-body.test.ts, new fx: tabId. It covers ids built from position and tab id, and sanitization of /, :, ., spaces and empty ids.
  • unit: shell/components/TableViews/__tests__/TableViewTabs.test.ts, new the tablist suite. No tab menu button inside the tablist, and aria-owns matches every tab id.
  • e2e: cypress/e2e/tests/accessibility/baseline.json now has violations: [] (the aria-required-children entry is removed), so the axe run fails on regression. shell.spec.ts also adds an aria-labelledby assertion on the prompt modal.

Manual focus areas: With NVDA/JAWS (Windows) and VoiceOver (macOS), open several Kubectl Shell tabs and a resource list with saved Table View tabs. Check that arrow/Tab navigation and the "tab X of Y" and selected-state announcements behave correctly. Check that close and menu buttons are still reachable, and that tab reorder or drag keeps aria-owns in sync.

Residual risk to monitor:

  • The tablist element is now an empty sibling, so reordering or adding tabs depends on the reactive aria-owns string staying in sync.
  • Element ids must remain unique on the page. TableViewTabs uses useId(), and the window manager uses position plus sanitized id. Sanitization could collide for ids that differ only by special characters.

This analysis was generated automatically based on unit and e2e evidence linked to this issue.

19387 Show new kubeconfig ACE setting Tests sufficient + manual test
In QA Review 9 d (since 2026-10-16 19:53 UTC) · issue ↗ · linked PR: 19445 (merged, 2 test files)

Labels it would add: qa-reviewed test-automation-sufficient needs-manual-test

🤖 QA review analysis

Automated tests appear sufficient for this issue. A round of manual tests is still required.

Decision summary

  • Automatable: yes. This change is in the UI: it adds the kubeconfig-prefer-rancher-proxy setting to Global Settings as an enum with the options false (ACE) and true (Rancher-proxied). That can be tested with unit tests.
  • Automation sufficient: yes, for the UI scope of this issue.
  • Manual test recommended: yes. The value of this setting comes from the kubeconfig the backend generates for clusters with ACE enabled. The UI tests cannot check that, and the backend change was still marked "r/r update required, issue pending".

Test evidence (PR #19445)

  • shell/edit/__tests__/management.cattle.io.setting.kubeconfig.test.ts (unit): checks that the edit form shows a LabeledSelect with exactly the ACE (false) and Rancher-proxied (true) options and their translated labels.
  • shell/list/__tests__/management.cattle.io.setting.kubeconfig.test.ts (unit):
    • For both false and true (it.each), checks that the Settings list shows the setting with the correct translated value.
    • Edge case: checks that the setting is hidden when the backend does not provide it, so older backends don't break.
  • Supporting changes: shell/config/settings.ts (ALLOWED_SETTINGS entry) and the new advancedSettings.description / advancedSettings.enum translations.

Why manual testing is still needed

  • A human should confirm, against a backend that has the new setting, that:
    • the setting appears under Global Settings → Settings
    • it can be saved
    • a kubeconfig downloaded for a cluster with ACE enabled actually switches its current context between ACE and the Rancher proxy

Residual risk to monitor

  • The issue has no formal acceptance criteria and still carries needs-info, so the scope assumed here is "expose and edit the setting in the UI".
  • Saving the setting relies on the generic Settings edit flow. These tests don't cover it, but it is shared, existing code.
  • Backend support may land separately. Before the backend ships the setting, the UI hides it, which is covered by the test above.

This analysis was generated automatically based on unit and e2e evidence linked to this issue.

19428 Show the external-link icon on the Harvester learn-more links Needs more tests, no manual → Reopened
In QA Review 18 d (since 2026-10-07 20:13 UTC) · issue ↗ · linked PR: 19430 (merged, 0 test files)

Labels it would add: qa-reviewed needs-more-test-automation no-manual-test-needed

🤖 QA review analysis

No manual tests required. Automated tests are not yet sufficient for this issue. Please address the feedback from the QA Review Decision Model:

Why coverage is not yet sufficient

PR #19430 only changes the harvesterManager.cluster.learnMore string in pkg/harvester-manager/l10n/en-us.yaml and pkg/harvester-manager/l10n/zh-hans.yaml. It adds no unit tests and no e2e tests. The change is small and low risk, so no manual pass is needed. However, nothing stops a future edit to the translation from dropping the icon, the target="_blank" or the rel attributes.

Suggested tests

  1. unit: the learn-more links render with the external-link icon
    • Where: mount pkg/harvester-manager/list/harvesterhci.io.management.cluster.vue in the empty state (no Harvester clusters), using the real en-us translation.
    • Assert that the intro text renders two <a> elements, pointing to https://harvesterhci.io/ and https://docs.harvesterhci.io/.
    • Assert that each link has target="_blank" and rel="noopener noreferrer nofollow".
    • Assert that each link contains an i.icon.icon-external-link.inline element as its last child.
  2. unit: the old copy of the list in shell/ behaves the same
    • shell/list/harvesterhci.io.management.cluster.vue also renders harvesterManager.cluster.learnMore.
    • Add the same assertion there, or one parameterised test that covers both files, so the two cannot drift apart.
  3. unit: the Rancher Prime docs rewrite still applies (edge case)
    • With the docs rewrite from pkg/rancher-prime/docs.ts active, assert that the Docs link's href is rewritten to the SUSE documentation site.
    • Assert that the external-link icon is still inside that link.
  4. e2e (optional)
    • Visit /c/_/harvesterManager/harvesterhci.io.management.cluster with no Harvester clusters.
    • Assert that both learn-more links are visible, have target="_blank", and contain .icon-external-link.

This comment was generated automatically to highlight missing automated coverage and suggest next tests to add.

19437 Add the RcModal component Tests sufficient + manual test
In QA Review 18 d (since 2026-10-07 20:52 UTC) · issue ↗ · linked PR: 18866 (merged, 3 test files)

Labels it would add: qa-reviewed test-automation-sufficient needs-manual-test

🤖 QA review analysis

Automated tests appear sufficient for this issue. A round of manual tests is still required.

Decision summary

  • Automatable: yes. RcModal and useModal are a self-contained component and composable.
  • Automation sufficient: yes. The unit tests cover every item in the issue's "What this covers" list, including edge and failure cases.
  • Manual test recommended: yes. Three reasons:
    • The behaviour depends heavily on UX and accessibility: keyboard focus, Esc, scrolling bodies, and menus rendered outside the modal.
    • The focus trap is mocked in the unit tests.
    • The design has to match the Figma spec visually.

Test evidence (PR #18866)

  • pkg/rancher-components/src/components/RcModal/__tests__/RcModal.test.ts (unit, about 50 cases):
    • Layout: title, body and actions regions. primary-action comes paired with a large cancel button. The actions slot replaces the whole footer. The title slot replaces the title prop. No footer or heading is rendered when none is given.
    • Sizes: small, medium and large map to 480, 640 and 960px. Any other value falls back to medium.
    • Accessibility:
      • The dialog has role="dialog", aria-modal, an aria-labelledby id that is unique per modal, and tabindex=-1.
      • The focus trap is created with escapeDeactivates: false, allowOutsideClick: true and a fallback focus target.
      • The focus trap is deactivated on close.
      • A mousedown on the background is prevented.
    • Opening and closing:
      • The modal is stateless. It stays open after close until show becomes false.
      • The focus trap is set up again when the modal is reopened.
      • Esc closes the modal even when clickToClose is false.
      • A background click follows clickToClose.
      • No document-level listener is left behind after unmount.
    • Events: order is checked for open, cancel, close and primary-action. Slots receive close, cancel and primaryAction.
    • Teleport: falls back to <body> when #modals is missing, and uses #modals once it exists.
    • Scrolling body: becomes a tab stop and a named region only while it scrolls. Initial focus follows the priority autofocus → first control → scrolling body → footer.
    • Attributes: class and data-testid pass through to the dialog element.
  • pkg/rancher-components/src/components/RcModal/__tests__/useModal.test.ts (unit):
    • open and close
    • the payload is kept, replaced and cleared
    • onClose returning false keeps the modal open
    • full wiring with RcModal through Esc, a background click and the cancel button
  • shell/initialize/__tests__/install-plugins.test.ts (unit): global keyboard shortcuts are suppressed inside .rc-modal.
  • Storybook docs and stories: storybook/src/stories/Components/RcModal.mdx and RcModal.stories.ts, including WithSelect for a menu rendered outside the modal.

What manual testing should cover

  • In a real browser, check that:
    • Tab and Shift+Tab stay inside the modal.
    • Focus returns to the element that opened it.
    • Esc closes the modal.
    • A LabeledSelect dropdown inside the modal stays clickable with clickToClose false.
    • A tall body scrolls and can be read with the arrow keys.
    • The three sizes and the spacing match Figma in both light and dark themes.

Residual risk to monitor

  • focus-trap is mocked, so real trapping and focus return are only exercised manually or through Storybook.
  • No e2e tests yet. Migrating existing dialogs to RcModal is out of scope, and those migrations should add e2e coverage as each consumer moves over.

This analysis was generated automatically based on unit and e2e evidence linked to this issue.

19447 Extension list pages are blank on Rancher 2.10-2.15 when built with the current shell (Unknown preference: table-views) Tests sufficient, no manual test
In QA Review 17 d (since 2026-10-08 13:05 UTC) · issue ↗ · linked PR: 19450 (merged, 3 test files)

Labels it would add: qa-reviewed test-automation-sufficient no-manual-test-needed

🤖 QA review analysis

Automated tests appear sufficient for this issue. No manual tests required.

Decision summary

  • Automatable: yes. The failure can be reproduced in a unit test, and the scheduled Extension Compatibility Test reproduces it end to end on Rancher 2.10 to 2.15.
  • Automation sufficient: yes.
  • Manual test recommended: no. The behaviour that matters is that an extension built with the master shell renders lists on older Rancher versions. The existing matrix e2e checks exactly that on every version, which is more thorough than a manual pass would be.

Test evidence (PR #19450)

  • shell/components/__tests__/ResourceTable.extension.test.ts (unit), new block on a Rancher from before table views:
    • Builds the resource-table-views mixin's data() and computed properties against a store where both features/get and prefs/get throw Unknown feature / Unknown preference, simulating an older host.
    • Asserts that savedViews is [], openedViewId is undefined and showTableViews is false. In other words, the table renders without table views and without throwing.
    • This is the test the issue asked for: "A unit test should cover a store whose prefs/get throws for table-views".
  • Code fix: shell/mixins/resource-table-views.js. savedViewsEntry now wraps the preference read in try/catch and returns undefined if it throws.
  • e2e (existing, secondary evidence): cypress/e2e/tests/pages/extensions/extension-compatibility.spec.ts in .github/workflows/extension-compatibility-test.yml, cases 8.2 and 8.3 (Elemental Create / Create from YAML) across 2.10 to 2.15. The same PR also fixed the CodeMirror page object (cypress/e2e/po/components/code-mirror.po.ts) so those cases can run.

Residual risk to monitor

  • shell/composables/useSavedTableViews.ts still reads prefs/get(TABLE_VIEWS) without a guard. The issue names this read too. It is only reached once table views are enabled, which isConfigurableTablesEnabled prevents on older hosts. Still, a guard and a unit test there would protect against a future caller that runs without that check.
  • Keep watching the nightly Extension Compatibility Test for 2.10 to 2.15 to confirm the fix holds.

This analysis was generated automatically based on unit and e2e evidence linked to this issue.

19449 Extension table hooks are not called when filtering a table with table views Tests sufficient, no manual test
In QA Review 17 d (since 2026-10-08 13:05 UTC) · issue ↗ · linked PR: 19450 (merged, 3 test files)

Labels it would add: qa-reviewed test-automation-sufficient no-manual-test-needed

🤖 QA review analysis

Automated tests appear sufficient for this issue. No manual tests required.

Decision summary

  • Automatable: yes. The part of the extension API that matters here, the sortable-table-interaction payload that drives addTableHook, can be unit tested, and the Extension Compatibility e2e covers it end to end.
  • Automation sufficient: yes.
  • Manual test recommended: no. The behaviour is about the API contract rather than visuals, and the existing e2e case 6.1 Table Hook (load, filter, sort) checks it with a real extension on latest.

Test evidence (PR #19450)

  • shell/components/SortableTable/__tests__/table-hooks.test.ts (unit, new):
    • Without table views, the search box query is reported as filtering.searchQuery (regression guard).
    • With table views, the view query (state:Error nginx) is reported in place of the search box query.
    • Edge case: an emptied view query is reported as '' rather than falling back to the search box query.
    • A change to viewQuery triggers debouncedPaginationChanged, so hooks are called once per change.
    • Edge case: an external pagination request still uses the search box filter, so viewQuery does not leak into the request to the server.
  • Code fix:
    • shell/components/ResourceTable.vue passes :view-query="showTableViews ? settledQuery : null".
    • shell/components/SortableTable/index.vue adds the viewQuery prop, a watcher for it, and searchQuery: this.viewQuery ?? this.searchQuery.
  • e2e (existing, secondary evidence): cypress/e2e/tests/pages/extensions/extension-compatibility.spec.ts, case 6.1 Table Hook, on latest.

Residual risk to monitor

  • When the table views query was cleared and the same text retyped within the debounce, the hook was still not called. That gap was found later as #19484 and fixed in #19491 with its own unit tests.
  • ResourceTable passing settledQuery as view-query is not covered by a unit test of its own. Only the compatibility e2e covers it.

This analysis was generated automatically based on unit and e2e evidence linked to this issue.

19472 Theme maintenance: show focus ring only on keyboard focus, and update secondary menu colors Needs more tests + manual test
In QA Review 11 d (since 2026-10-15 00:57 UTC) · issue ↗ · linked PR: 19475 (merged, 1 test file)

Labels it would add: qa-reviewed needs-more-test-automation needs-manual-test

🤖 QA review analysis

A round of manual tests is required. Automated tests are not yet sufficient for this issue.

Please address the feedback from the QA Review Decision Model:

Current evidence (PR #19475)

  • The only test change is in pkg/rancher-components/src/components/Form/ToggleSwitch/ToggleSwitch.test.ts. The adds focus class / removes focus class tests were replaced with a single test, does not add a focus class when the input is focused. This meets the last acceptance criterion ("Unit tests are updated for the ToggleSwitch focus behavior").
  • The other changes are CSS only:
    • RcButton.vue, Checkbox.vue, NamespaceFilter.vue, Notification.vue, AddRepoLink.vue and ContainerShell.vue drop their :focus rules and keep :focus-visible.
    • nav/Group.vue, TopLevelMenu.vue and IconOrSvg.vue switch to the --active, --on-active, --active-hover and --rc-section-background-secondary tokens.
  • No test covers the other six acceptance criteria.
  • Manual testing is recommended because the change depends heavily on UX across many shared components and both light and dark themes. jsdom cannot evaluate :focus-visible or theme tokens.

Suggested tests

  1. e2e: a mouse click does not show the focus ring; keyboard focus does
    • Components: on Workloads → Pods, use a row action button (the RcButton link variant), a header ghost button, a ToggleSwitch, a Checkbox and the NamespaceFilter.
    • For each, realClick() it and assert that its computed outline-style is none. For ToggleSwitch, check the .slider element.
    • Then focus the same element with the keyboard (realPress('Tab')) and assert that the outline is visible, i.e. outline-style is not none, using the --primary-keyboard-focus color.
  2. e2e: focus returns to the trigger after a dropdown closes
    • Focus a row action button with the keyboard.
    • Press Enter and assert that the menu opens.
    • Press Escape and assert that document.activeElement is the trigger and that the focus ring is visible.
  3. e2e: the row action button keeps its hover background
    • Hover the row action button and record its computed background-color. It should match --accent-btn.
    • Do realMouseDown() and then realMouseUp().
    • Assert that the background does not change to transparent at any point.
  4. e2e: side nav colors
    • Open a cluster's Workloads group with Pods selected.
    • Assert that:
      • the open group (.group-highlight) uses the --rc-section-background-secondary value as its background
      • a group that is not open still uses --nav-bg
      • the active item uses --active as its background and --on-active as its text color
    • Repeat with the dark theme set through the theme preference.
  5. unit: no focus class is forced on
    • In Checkbox.test.ts and RcButton.test.ts, add tests in the style of the ToggleSwitch test.
    • Assert that triggering focus adds no focused or focus class that would force the ring on.

This comment was generated automatically to highlight missing automated coverage and suggest next tests to add.

19484 Bug with `addTableHook` and supercharged tables Tests sufficient, no manual test
In QA Review 12 d (since 2026-10-13 15:10 UTC) · issue ↗ · linked PR: 19491 (merged, 1 test file)

Labels it would add: qa-reviewed test-automation-sufficient no-manual-test-needed

🤖 QA review analysis

Automated tests appear sufficient for this issue. No manual tests required.

Decision summary

  • Automatable: yes. The bug is in the debounce logic of the view.query watcher, which can be tested exactly with fake timers.
  • Automation sufficient: yes. The new tests reproduce the exact sequence the issue describes: clear the box, then retype the same text faster than the debounce.
  • Manual test recommended: no. This is a timing and logic fix to the extension hook API, with no visual change. The existing Extension Compatibility e2e case 6.1 Table Hook (load, filter, sort) exercises it with a real extension on latest.

Test evidence (PR #19491)

  • shell/components/__tests__/ResourceTable.viewSwitch.test.ts (unit, 2 new cases):
    • should apply clearing the query at once: clearing nginx to '' updates settledQuery to '' immediately, without waiting for the debounce.
    • should settle the same query again when it is cleared and retyped faster than the debounce:
      • Starts from a settled nginx.
      • Types '', n, ng, ngi, ngin, nginx, 10ms apart.
      • Asserts that the settled values are ['', 'nginx'] rather than [].
      • This is the case the issue asked for ("Any fix should add a case for the clear-and-retype sequence").
  • Code fix: shell/mixins/resource-table-views.js now flushes the debounced settle when the query is empty (if (!typed || !query)).
  • Related coverage from #19450 (#19449): shell/components/SortableTable/__tests__/table-hooks.test.ts checks that a change to viewQuery triggers the interaction that reaches the hooks.
  • e2e (existing, secondary evidence): cypress/e2e/tests/pages/extensions/extension-compatibility.spec.ts, case 6.1, on latest.

Residual risk to monitor

  • Clearing the filter now applies immediately, which also triggers an immediate request when the list uses Steve filters on the server. Watch for extra list requests on large clusters.
  • Confirm that the nightly Rancher latest job turns green on case 6.1.

This analysis was generated automatically based on unit and e2e evidence linked to this issue.

19503 Provisioning new Ingress NGINX RKE2 clusters should be disabled for prime Tests sufficient + manual test
In QA Review 2 d (since 2026-10-23 22:00 UTC) · issue ↗ · linked PRs: 19571 (merged, 3 test files), 19673 (merged, 6 test files)

Labels it would add: qa-reviewed test-automation-sufficient needs-manual-test

🤖 QA review analysis

Automated tests appear sufficient for this issue. A round of manual tests is still required.

Decision summary

  • Automatable: yes. The gating depends on the Kubernetes version, the form mode (create or edit) and the selected ingress controller. All three can be unit tested.
  • Automation sufficient: yes. All three acceptance criteria are covered, including meaningful edge cases.
  • Manual test recommended: yes. This changes RKE2 provisioning and upgrades for both Community and Prime, so it has large product impact and carries regression risk for existing clusters. It also depends on real 1.37 RKE2 releases and the save and upgrade flow through the backend.

Test evidence

  • PR #19571
    • shell/edit/provisioning.cattle.io.cluster/__tests__/Ingress.test.ts (unit):
      • AC1, creating a cluster:

        • The nginx card is not offered when creating a cluster on v1.37.0.
        • The options update when the Kubernetes version changes from 1.36 to 1.37.
        • nginx stays available below 1.37.
        • The Prime/Community distinction was removed, so the rule now applies to both editions.
        • Enabling ingress on 1.37 with Traefik unavailable does not fall back to nginx; it emits none.
      • AC2, upgrading an existing cluster:

        • When editing a cluster that targets 1.37 or later, the nginx card is disabled with the contentUnsupported text.
        • Dual Mode stays available.
        • Selecting the disabled nginx card is ignored.
        • The nginxUpgradeBlocked banner shows when the cluster still uses standalone nginx.
      • AC3, the warning: an it.each table of 8 transitions checks when the nginxUpgradeWarning banner appears:

        • nginx → Traefik
        • nginx → Dual
        • Dual → Dual
        • Dual → Traefik
        • Traefik → Traefik
        • none → none
        • already on 1.37
        • no previous version

        A separate test checks that no warning appears when the target version is below 1.37.

    • shell/edit/provisioning.cattle.io.cluster/__tests__/rke2.test.ts (unit): ingressNginxUnsupported, which blocks saving the form, is checked across create and edit, versions 1.36 / 1.37 / 1.38, and the controllers nginx, Traefik, Dual and none.
    • shell/edit/provisioning.cattle.io.cluster/__tests__/IngressCards.test.ts (unit, new): the "Recommended" label hides when Traefik is the only option and comes back when the options change.
  • PR #19673
    • Ingress.test.ts:
      • The blocking message is now rendered with RichTranslation and includes the migration docs link.
      • New negative case: no blocking message when the cluster uses Dual Mode.
    • Shared mocks were renamed from INGRESS_MIGRATION_KB_LINK to INGRESS_MIGRATION_DOCS_LINK in Basics.test.ts, index.test.ts, rke2-fleet-cluster-agent.test.ts, rke2.test.ts and S3Config.test.ts.

What manual testing should cover

  • Creating a cluster, on Community and on Prime:
    • With a 1.37+ RKE2 version, nginx is not offered.
    • Switching the version between 1.36 and 1.37 updates the available ingress options.
  • Editing an existing 1.36 cluster:
    • A cluster on standalone nginx cannot be saved after selecting 1.37+, and the blocking banner with the docs link appears.
    • Switching it to Dual Mode or Traefik shows the "cannot switch back" warning and allows the upgrade.
  • K3s: clusters are unaffected.

Residual risk to monitor

  • No e2e test covers the RKE2 create or edit flow for this rule. Coverage is unit-level, and the shared module is mocked in these tests.
  • The rule is enforced only in the UI. Enforcement through the API depends on backend validation.

This analysis was generated automatically based on unit and e2e evidence linked to this issue.

19517 LabeledSelect: typed search text is cleared when the dropdown loses focus without a selection Tests sufficient + manual test
In QA Review 5 d (since 2026-10-20 14:12 UTC) · issue ↗ · linked PR: 19604 (merged, 5 test files)

Labels it would add: qa-reviewed test-automation-sufficient needs-manual-test

🤖 QA review analysis

Automated tests appear sufficient for this issue. A round of manual tests is still required.

Decision: automatable = ✅ · automation sufficient = ✅ · manual test = ✅

Rationale The fix in #19604 adds an opt-in keepSearchOnBlur prop to LabeledSelect and turns it on in WorkloadSearch.vue. It also drops the per-consumer lastSearchTerm workaround. The unit suite covers the acceptance criteria directly, through user-visible input value and placeholder assertions.

Test evidence (unit, #19604)

  • shell/components/form/__tests__/LabeledSelect.test.ts, new keepSearchOnBlur prop suite (17 tests):
    • On blur, the typed text replaces the placeholder (the hint styling) and the active search is emptied.
    • Re-focusing restores the text in the input and the placeholder, and emits search again with the term, so results come back.
    • Focus can be lost several ways: blur, Escape while open, forceClose(), a click outside while focus is elsewhere, and a blur that reopens the dropdown (the action-menu case). All of them keep the text consistently.
    • Edge and failure paths:
      • Prop off: the text is still cleared, so the default isn't affected.
      • Selecting an option doesn't keep the text.
      • Escape on a closed select clears the kept text and stops propagation; with no kept text it propagates normally.
      • aria-description announces the kept search.
    • forceOpen / forceClose tests were updated for the new signature.
  • shell/pages/c/_cluster/explorer/workload-dashboard/search/__tests__/WorkloadSearch.test.ts:
    • Asserts keepSearchOnBlur is passed.
    • Asserts that opening the action menu, or tabbing into results, calls forceOpen() without a search term, since the component now keeps the text itself.
  • The snapshot updates (keepsearchonblur="false") confirm other consumers keep the default.

Why manual testing is still recommended

  • Strong UX dependence: the grey hint styling, and how blur/focus feel in a real browser, can't be fully checked in jsdom.
  • LabeledSelect is a shared, widely used form component. A real browser pass on the Workload Overview search (including the row action menu and keyboard Tab/Escape) and a spot check of a regular non-search LabeledSelect will catch regressions in focus handling.

Residual risk to monitor

  • jsdom focus/document.activeElement behaviour is approximate. Watch real-browser focus order when the dropdown is appended to body (appendToBody: true).
  • There's no e2e coverage of the Workload Overview search yet. A Cypress test that types, clicks away and re-focuses would lock this behaviour in.

This analysis was generated automatically based on unit and e2e evidence linked to this issue.

19523 Update Operation deletion dialog to warn users of impacts of operation interruption Tests sufficient + manual test
In QA Review 9 d (since 2026-10-17 04:38 UTC) · issue ↗ · linked PR: 19585 (merged, 6 test files)

Labels it would add: qa-reviewed test-automation-sufficient needs-manual-test

🤖 QA review analysis

Automated tests appear sufficient for this issue. A round of manual tests is still required.

Decision: automatable = ✅ · automation sufficient = ✅ · manual test = ✅

Rationale #19585 adds a new RemoveOperationDialog built on RcModal, plus a DayTwoOperation base model that sends promptRemove to it for all four operation CR types. It also pulls the post-delete redirect logic out into shell/utils/prompt-remove.js. Both acceptance criteria (the in-progress warning, and the dialog using RcModal) are covered by unit tests that assert user-visible behaviour.

Test evidence (unit, #19585)

  • shell/dialog/__tests__/RemoveOperationDialog.test.ts (new):
    • The kind message is correct for snapshot save, snapshot restore, encryption key rotation and certificate rotation, and the operation name is shown.
    • Succeeded, Failed and Canceled operations: no warning, and Delete is enabled.
    • Pending, InProgress and missing phase: warning plus an acknowledgement checkbox, and Delete is disabled until the box is checked. Delete is disabled again if it's unchecked, and an unacknowledged click doesn't delete.
    • Autofocus goes to the checkbox.
    • Failure paths: a delete error shows an error banner and the dialog stays open; Cancel is disabled while the request is in flight; Cancel closes without deleting.
    • After deleting from the operation's detail page, the user is redirected to the list.
  • shell/models/__tests__/day-two-operation.test.ts (new): all four models extend DayTwoOperation, and promptRemove dispatches RemoveOperationDialog with ownsModal.
  • shell/utils/__tests__/operation-cr.test.ts: phase matrix for isOperationInProgress, including null/undefined status.
  • shell/utils/__tests__/prompt-remove.test.ts (new): the extracted doneLocationAfterRemove (bulk delete, doneOverride, namespaced and non-namespaced detail pages).
  • shell/components/__tests__/PromptModal.test.ts and shell/composables/__tests__/focusTrap.test.ts: the modal registers and renders, and the focus trap skips tabindex="-1".

Why manual testing is still recommended

  • Deleting an in-progress operation is destructive and can leave an imported RKE2/K3s cluster unstable. This is high-value Day 2 Ops behaviour, and it should be checked against real operation CRs whose phases are set by the controller.
  • PromptRemove.vue was refactored to use the shared doneLocationAfterRemove. Spot-check generic resource deletion (single delete from a detail page, and bulk delete from a list) for regressions.

Residual risk to monitor

  • The phase values (Succeeded / Failed / Canceled) are hard-coded. If the backend adds new terminal phases, operations in those phases would be treated as in progress.
  • The focusTrap change (skipping tabindex="-1") applies to every modal. Check initial focus in other dialogs that use custom checkboxes.

This analysis was generated automatically based on unit and e2e evidence linked to this issue.

19527 Workload dashboard and cert-manager state links don't filter their list when ui-configurable-tables is off Needs more tests + manual test
In QA Review 10 d (since 2026-10-16 11:55 UTC) · issue ↗ · linked PR: 19534 (merged, 3 test files)

Labels it would add: qa-reviewed needs-more-test-automation needs-manual-test

🤖 QA review analysis

A round of manual tests is required. Automated tests are not yet sufficient for this issue.

Please address the feedback from the QA Review Decision Model:

Decision: automatable = ✅ · automation sufficient = ❌ · manual test = ✅

What's already covered (unit, #19534)

  • shell/mixins/__tests__/resource-fetch-api-pagination.test.ts:
    • parseStateFilter and parseNameFilter, including null/empty input and trailing commas.
    • paginationChanged adds the metadata.state.name IN filter and the metadata.name CONTAINS filter only when table views are off.
    • The stateFilter / nameFilter route watchers re-request the list.
  • shell/components/ResourceList/__tests__/index.test.ts:
    • The "State filter applied" bar shows badges for stored states, model-computed states and unknown states.
    • The "Name filter applied" bar.
    • Clear filter keeps the rest of the query.
    • Neither bar shows with table views on.
  • pkg/cert-manager/list/__tests__/cert-manager.io.certificate.test.ts: client-side filtering on a single state, several states and the model-computed expired; no match; empty segments; behaviour with table views on.

Why this isn't sufficient yet The bug is a cross-page flow regression: a link on one page has to filter the list on another. Every test runs with mocked $route and is mounted on its own, so nothing checks that the links on the workload dashboard, the cert-manager overview or the Workloads Overview "+ more" rows produce a filtered list end-to-end with the flag off.

Suggested tests

  1. e2e: Workload dashboard to Pods, with the flag off.
    • Setup: ui-configurable-tables off (or a stubbed feature response).
    • Steps: open Workloads > Overview, click the Pods Completed count.
    • Assert: the URL has stateFilter=completed, the intercepted list request has a metadata.state.name filter, the "State filter applied: Completed" bar is shown, and only completed pods are listed.
    • Then click Clear filter and assert the bar is gone, the request has no state filter, and the full list comes back.
  2. e2e: Workloads Overview search "+ more", with the flag off.
    • Steps: search a term with more matches than are shown, click "+ more".
    • Assert: the "Name filter applied: " bar is shown, the request uses a partial metadata.name filter, and only matching workloads are listed. Clear filter brings back the full list.
  3. e2e: Flag on, regression guard. Repeat test 1 with ui-configurable-tables on and assert the states go into the search bar (state:completed) and the filter bar is not shown.
  4. unit: Cert-manager overview link to list. In pkg/cert-manager, assert resourceRoute(type, 'expiring') produces ?stateFilter=expiring, so the bucket link and the ClientStateFilterList filter stay in sync. Add a parametrised test that all four wrappers (certificate, issuer, clusterissuer, order) extend ClientStateFilterList.
  5. unit: Browser Back. In resource-fetch-api-pagination.test.ts, assert that changing $route.query.stateFilter from a value to undefined (Back or Clear) calls paginationChanged with the current paginationFromList, and that no state filter is sent afterwards.

Why manual testing is recommended The flow moves between several pages (dashboard or overview to a list, then Clear filter) and depends on a feature-flag toggle. Visual badge colours and states the backend computes vs. states the model computes are best confirmed by a person in a running Rancher with real workloads and cert-manager installed.

This comment was generated automatically to highlight missing automated coverage and suggest next tests to add.

19536 Update encryption key rotation dialog to use RcModal Tests sufficient + manual test
In QA Review 9 d (since 2026-10-16 22:10 UTC) · issue ↗ · linked PR: 19335 (merged, 3 test files)

Labels it would add: qa-reviewed test-automation-sufficient needs-manual-test

🤖 QA review analysis

Automated tests appear sufficient for this issue. A round of manual tests is still required.

Decision: automatable = ✅ · automation sufficient = ✅ · manual test = ✅

Rationale #19335 rewrites RotateEncryptionKeyDialog.vue as a <script setup> RcModal dialog with three states that depend on the latest backup, and opens it with ownsModal: true. The unit tests cover all three acceptance-criteria states plus the rotate and take-snapshot flows, including failure paths.

Test evidence (unit, #19335)

  • shell/dialog/__tests__/RotateEncryptionKeyDialog.test.ts:
    • No backup: the noBackup warning shows, Take Snapshot is offered, and Rotate Keys is disabled. rotate() does nothing.
    • Old backup (9 days): the outdated warning shows with the day count, Take Snapshot is offered, and rotation is allowed.
    • Fresh backup (14 minutes): no warning, no Take Snapshot, and Rotate Keys is enabled.
    • The newest of several snapshots is picked, and its date comes from snapshotFile.createdAt (regression test).
    • Rotate Keys is disabled while loading.
    • Rotate on an imported Day 2 Ops cluster creates the operation CR; rotate on other clusters bumps rotateEncryptionKeys.generation and saves.
    • Errors keep the dialog open with an error banner using role="alert".
    • While a rotation is in flight, the dialog won't close and won't start a second rotation.
    • Take Snapshot calls snapshotAction and closes the dialog.
  • shell/models/__tests__/provisioning.cattle.io.cluster.test.ts: rotateEncryptionKey dispatches with ownsModal: true.
  • shell/components/__tests__/PromptModal.test.ts: the dialog is registered as an owns-modal component and renders.

Why manual testing is still recommended

  • Encryption key rotation is a destructive, high-impact Day 2 operation that restarts control plane nodes. It should be checked against a real cluster with real etcd snapshots.
  • The layout has to match the Figma design (strong UX dependence): the large modal, the snapshot info card, a long snapshot ID that wraps or copies correctly, and the "View snapshots" link.
  • The zh-hans outdated string doesn't use ICU plural forms. Check that it renders correctly.

Residual risk to monitor

  • There's no test at the exact 1-day threshold (>= 1 day counts as stale) or for a snapshot that has no snapshotFile.createdAt. Consider adding these boundary unit tests.
  • The age is worked out from the client clock (day()), so clock skew between browser and server could misclassify how old a backup is.

This analysis was generated automatically based on unit and e2e evidence linked to this issue.

19561 Fleet: link the managed banner to its source and add a Managed badge Tests sufficient + manual test
In QA Review 6 d (since 2026-10-19 19:01 UTC) · issue ↗ · linked PR: 19562 (merged, 3 test files)

Labels it would add: qa-reviewed test-automation-sufficient needs-manual-test

🤖 QA review analysis

Automated tests appear sufficient for this issue. A round of manual tests is still required.

Decision: automatable = ✅ · automation sufficient = ✅ · manual test = ✅

Rationale #19562 adds the View in Fleet link to FleetManagedBanner.vue, with permission checks that only use data already loaded at login. It also adds a new FleetManagedBadge.vue (using icon-fleet-alt, from the @rancher/icons 2.0.66 bump) to both the legacy and the new detail masthead. The unit tests cover the link logic, including every permission rule in the issue.

Test evidence (unit, #19562)

  • shell/components/Resource/Detail/__tests__/FleetManagedBanner.test.ts:
    • The banner renders for gitrepo, helmop and bundle, names the product, and is hidden when there's no resource, no labels, or only unrelated labels.
    • Link targets: GitRepo and HelmOp link to c-cluster-fleet-application-resource-namespace-id; Bundle links to c-cluster-product-resource-namespace-id.
    • Permission rules: no link when the Fleet feature is disabled, when the user can't list the source type, when the workspace isn't one of the user's, or when the user can't list workspaces.
    • Missing data: no link for an unknown kind or when the namespace or name label is missing. The banner itself still shows.
  • shell/components/Resource/Detail/__tests__/FleetManagedBadge.test.ts (new): the badge renders with icon-fleet-alt and the "Managed" label only for Fleet-managed resources.
  • shell/components/ResourceDetail/Masthead/__tests__/latest.test.ts: the badge gets the resource through the title-suffix slot.

Why manual testing is still recommended

  • Strong UX and design dependence:
    • The badge size (16px) and its 18px icon should match the Active badge.
    • The badge colours are the RcTag inactive background with the Apps & Marketplace icon colour.
    • The secondary link style.
    • The link must move to the next line as a whole instead of breaking mid-text.
  • This needs Rancher 2.16 with Fleet v0.17.0-alpha.6 or newer for the real fleet.cattle.io/managed-by-* labels. Check with a restricted user who has partial workspace access, which covers the known dead-link limits in the issue.

Residual risk to monitor

  • shell/components/Resource/Detail/Masthead/index.vue now always renders the title-suffix slot with the badge, but no unit test covers that path. Consider adding a test that the badge appears on the new detail masthead and that consumer title-suffix content still renders.
  • The icon bump to @rancher/icons 2.0.66 applies everywhere. Watch for icon regressions elsewhere.

This analysis was generated automatically based on unit and e2e evidence linked to this issue.

19565 Multiple auth providers: follow-up Needs more tests + manual test
In QA Review 10 d (since 2026-10-15 23:57 UTC) · issue ↗ · linked PR: 19568 (merged, 9 test files)

Labels it would add: qa-reviewed needs-more-test-automation needs-manual-test

🤖 QA review analysis

A round of manual tests is required. Automated tests are not yet sufficient for this issue.

Please address the feedback from the QA Review Decision Model:

Decision: automatable = ✅ · automation sufficient = ❌ · manual test = ✅

What's already covered (unit, #19568)

  • shell/models/__tests__/principal.test.ts: displayType shows "GitHub User (github-2)" or "GitHub Team (github-2)" for a named config, plain "GitHub User" for the default config, and no config name for local principals.
  • shell/models/__tests__/management.cattle.io.user.test.ts (new):
    • provider resolves local, system, a single config, a named config and multiple configs to the right value.
    • providerDisplay gives "GitHub (github-2)" and "Multiple", and sorting puts a named config right after its provider.
  • shell/components/auth/__tests__/Principal.test.ts: the member-list fallback resolves github-2_user:// to provider github through the auth providers.
  • shell/utils/__tests__/auth-providers.test.ts:
    • configNameOfPrincipal.
    • providerOfConfig, including the case where the config isn't listed.
    • cloneableAuthConfigFields drops identity, enabled state, access mode, allowed principals, annotations and secrets (including those nested in openLdapConfig and password-typed fields), and deep-copies the values it keeps.
  • shell/models/__tests__/management.cattle.io.authconfig.test.ts:
    • canCloneConfig for local auth, the Community limit, multi-provider allowed, and providers without a form.
    • The inherited goToClone action is enabled, and the route is /auth/config/create/:provider?cloneConfig=<id>.
  • shell/pages/c/_cluster/auth/config/create/__tests__/provider.test.ts:
    • The clone values are seeded and the next free name (github-2) is used.
    • Cloning across providers is rejected.
    • The page title names the clone source, and the not-found error is shown.
  • shell/mixins/__tests__/auth-config.test.ts: the clone values override the defaults, defaults still fill in fields the clone doesn't set, and the values aren't shared with the source.
  • AuthProvidersPrimeNotice.test.ts and config/__tests__/index.test.ts: the Prime notice copy and links (SUSE product page vs. Feature Flags), and provider rows sorted by id.

Gaps against the acceptance criteria

  1. unit: SloDialog label (acceptance criterion: "the single logout dialog resolves the provider type").
    • Add shell/dialog/__tests__/SloDialog.test.ts.
    • Mount it with authProvider: { id: 'github-2', type: 'githubProvider' } and assert name resolves through model.authConfig.provider."github" to "GitHub", not the untranslated github-2.
    • Also assert the fallback to id when type is missing.
  2. unit: Clone disabled while the Community limit applies (when another provider is already enabled). Assert that the goToClone action from _availableActions comes back with enabled: false; today only the enabled case is checked.
  3. unit: Users list column sort. In the Users list header config test, assert that the Provider column sorts on providerDisplay (not the raw provider), so named configs sort next to their provider in the actual table.
  4. e2e: Clone flow with intercepted API.
    • Steps: on Auth Provider list, open a GitHub config's action menu, click Clone.
    • Assert: the URL is /auth/config/create/github?cloneConfig=github, the title is "Clone GitHub", the name field defaults to github-2, non-secret fields (hostname, client ID) are pre-filled, and client secret is empty.
    • Assert that no PUT/POST request is sent until the admin saves.
  5. e2e: Prime notice and ordering. With intercepted Community vs. Prime-with-flag-off settings, assert the notice title is "Run multiple auth providers at once with SUSE Rancher Prime" and the action link target is correct (the external SUSE URL vs. Feature Flags). Then assert a provider added during the session appears in sorted position without a reload.

Why manual testing is recommended

  • This is an auth-area change with large product impact and high priority. It touches principal labelling across members, bindings and users, plus a new clone flow that has to leave out secrets.
  • Against a real 2.16 backend, check with real named configs (e.g. two GitHub configs): Users list labels, project/cluster member labels and avatars for users without principal-read permission, single logout, and that a cloned config needs its secrets re-entered and passes the test/enable flow.

This comment was generated automatically to highlight missing automated coverage and suggest next tests to add.

19576 Installed Apps list cleared by stale apps watch left over from Charts page Needs more tests + manual test
In QA Review 9 d (since 2026-10-16 13:59 UTC) · issue ↗ · linked PR: 19566 (merged, 1 test file)

Labels it would add: qa-reviewed needs-more-test-automation needs-manual-test

🤖 QA review analysis

A round of manual tests is required. Automated tests are not yet sufficient for this issue.

Please address the feedback from the QA Review Decision Model:

Decision: automatable = ✅ · automation sufficient = ❌ · manual test = ✅

What's already covered (unit, #19566)

  • shell/pages/c/_cluster/apps/charts/__tests__/index.test.ts, hook: beforeUnmount: asserts that cluster/forgetType is dispatched with CATALOG.APP when the Charts page unmounts.

Why this isn't sufficient yet That test only checks the mechanism (a dispatch call). It doesn't check the behaviour the issue expects: the Installed Apps list keeps its rows and keeps updating after you come from Charts and an app changes. It also doesn't cover what happens when you return to Charts, or when the Charts page links to pages that may still read apps from the store.

Suggested tests

  1. unit: Charts statuses after a revisit. In charts/__tests__/index.test.ts, mount, unmount and mount again, and assert that the page fetches CATALOG.APP again on the second mount, so chart statuses (installed, upgradeable) are worked out from fresh data rather than an empty store.
  2. unit: Store-level forgetType. In the dashboard-store tests, assert that forgetType(CATALOG.APP) removes the cached apps and unwatches the apps socket subscription, so a later socket change for that watch can't reset another page's list.
  3. e2e: Charts to Installed Apps regression.
    • Setup: intercept GET /v1/catalog.cattle.io.apps with 2–3 apps.
    • Steps: open Cluster > Apps > Charts, then Cluster > Apps > Installed Apps.
    • Assert: all apps are listed and "There are no rows to show" is never shown, including after waiting for or simulating an apps change (e.g. re-intercepting with a changed app, or reloading the apps through a resource-change trigger).
  4. e2e: Charts statuses still correct. With an intercepted installed app, open Charts, go to Installed Apps, go back to Charts, and assert that the chart's installed/upgradeable badge is still shown.

Why manual testing is recommended The bug depends on live websocket watch timing that is hard to reproduce faithfully with mocks. With a real cluster that has a few apps (e.g. 2–3 Fleet GitRepos), confirm that Charts to Installed Apps stays populated while apps change. Also confirm that chart install/upgrade pages opened from Charts still detect existing installs after the apps type is forgotten (regression risk on the Apps & Marketplace flows).

This comment was generated automatically to highlight missing automated coverage and suggest next tests to add.

19579 Use RcModal for the table views' Publish confirmation Tests sufficient, no manual test
In QA Review 9 d (since 2026-10-16 13:33 UTC) · issue ↗ · linked PR: 19580 (merged, 2 test files)

Labels it would add: qa-reviewed test-automation-sufficient no-manual-test-needed

🤖 QA review analysis

Automated tests appear sufficient for this issue. No manual tests required.

Decision: automatable = ✅ · automation sufficient = ✅ · manual test = ❌

Rationale #19580 replaces the GenericPrompt Publish confirmation with a new TableViewPublishModal.vue built on RcModal, and wires it into TableViewTabs.vue as a new publish modal kind, the same way Export, Share and Import work. It's a contained UI swap that reuses the existing publish(view) logic. The unit tests cover the new modal and how it's wired in.

Test evidence (unit, #19580)

  • shell/components/TableViews/__tests__/TableViewPublishModal.test.ts (new):
    • The modal is titled "Publish" and its body says the view becomes visible to all users.
    • The filter warning shows only when hasFilter is set.
    • Confirm emits publish and closes.
    • Cancel closes without publishing (the failure path).
  • shell/components/TableViews/__tests__/TableViewTabs.test.ts (updated):
    • Sharing a view opens TableViewPublishModal and publishes nothing until it's confirmed.
    • hasFilter is true or false depending on the view's query.
    • On confirm, the view is created under its id and keeps its tab position.
    • When the write fails, the user's own view is kept and growl/fromError is called.

Why manual testing is not required This is a low-risk migration of one confirmation dialog onto the standard RcModal used by the sibling Export, Share and Import dialogs. The behaviour that matters (confirm/cancel, filter warning, publish result and error handling) is asserted in the unit tests, and the publish logic itself is unchanged.

Residual risk to monitor

  • The confirm button label uses tableViews.tab.share, and no test asserts it. Check that the wording reads correctly next to the "Publish" title.
  • The asyncButton.publish translations were removed. Check that nothing else still uses mode="publish" on an AsyncButton.

This analysis was generated automatically based on unit and e2e evidence linked to this issue.

19583 A list's built-in tab loses its unsaved changes before any tab is picked Needs more tests + manual test
In QA Review 9 d (since 2026-10-16 22:53 UTC) · issue ↗ · linked PR: 19584 (merged, 1 test file)

Labels it would add: qa-reviewed needs-more-test-automation needs-manual-test

🤖 QA review analysis

A round of manual tests is required. Automated tests are not yet sufficient for this issue.

Please address the feedback from the QA Review Decision Model:

Decision: automatable = true · automation_sufficient = false · manual_test = true

What's already covered (PR #19584, shell/components/TableViews/__tests__/TableViewTabs.test.ts)

  • selectedViewIdFor now returns null before any tab is picked, even when the table holds a saved view's config.
  • should keep a filter typed on the table's own tab before any pick there, when it is a saved view's: covers repro scenario 2 (switch to the saved view and back).
  • should leave the changes on the table's own tab when it is saved as a new view before any tab is picked: covered repro scenario 1.

⚠️ The expected result changed later. PR #19630 (for #19628) rewrote that scenario-1 test. It now expects vm.drafts.__default to be undefined, so after Save as New the built-in tab is left clean rather than keeping its unsaved changes. Scenario 1's "Expected Result" in this issue is therefore out of date. Only scenario 2 still holds as written, and the testers need to know this.

Suggested tests

  1. e2e (cypress/e2e/tests/pages/explorer2/workloads/…, eg Deployments): open the list, reload without clicking a tab, type a filter that matches an existing saved view's query, switch to that saved view, then back to the built-in tab. Assert:

    • the built-in tab is still the selected tab;
    • its unsaved-changes dot is shown;
    • the search bar still holds the typed filter.
  2. e2e: reload without picking a tab, type a filter, then use the built-in tab's menu → Save as New. Assert:

    • the new view opens in front with the filter;
    • the built-in tab shows no unsaved-changes dot, which is the behavior after #19630.

    This pins down the final agreed behavior across both fixes.

  3. unit (shell/utils/table-views/__tests__/views.test.ts or equivalent): call isViewDirty directly with pickedViewId undefined vs null, with a view that matches a saved view's config. Assert both return true (dirty on the built-in tab), so the merged undefined/null branch can't regress.

Why manual testing: the "before any tab is picked" state only happens after a reload, and the result is judged by tab selection and the dirty dot. This is UX-heavy behavior across several table-view controls, and its expectation was changed by #19630.

This comment was generated automatically to highlight missing automated coverage and suggest next tests to add.

19586 Allow provisioning extensions to add detail tabs conditional on annotations Needs more tests + manual test
In QA Review 9 d (since 2026-10-16 23:18 UTC) · issue ↗ · linked PR: 19570 (merged, 2 test files)

Labels it would add: qa-reviewed needs-more-test-automation needs-manual-test

🤖 QA review analysis

A round of manual tests is required. Automated tests are not yet sufficient for this issue.

Please address the feedback from the QA Review Decision Model:

Decision: automatable = true · automation_sufficient = false · manual_test = true

What's already covered (PR #19570)

  • shell/core/__tests__/plugin-helpers-context.test.ts (new, 11 cases) tests the subset matching in contextMatches well:
    • an exact match still works;
    • extra keys in the context are ignored (this protects the existing aks/eks/gke { provider } tabs);
    • a wrong or missing value doesn't match;
    • nested annotations match and mismatch correctly;
    • no context, arrays compared exactly, an empty requirement, and AND with other locationConfig params.

Gaps

  • Nothing tests the second acceptance criterion: that shell/detail/provisioning.cattle.io.cluster.vue actually passes annotations into extCustomParams. That covers all three branches: no provider extension, extClass provisioner, and model extension (customProvisionerHelper).
  • The PR also adds useRc / useRcButton modes to ArrayList, ArrayListGrouped, MatchExpressions, NodeAffinity, PodAffinity and RcLabelsAndAnnotations, plus descriptionColSpan to NameNsDescription. These have no tests; only a snapshot (Filters.test.ts.snap) was updated.

Suggested tests

  1. unit: shell/detail/__tests__/provisioning.cattle.io.cluster.test.ts. Mount the detail page with a cluster that has metadata.annotations. Assert:
    • extCustomParams is { annotations } when no provisioner extension is registered;
    • it is { provider, annotations } when one is registered (extClass), or when the model has a customProvisionerHelper;
    • it is {}-safe when the cluster has no annotations.
  2. unit: register a ExtensionPoint.TAB enhancement with context: { annotations: { 'ui.rancher/k3k-mode': 'hcp' } } against the provisioning cluster detail page. Assert the tab renders for a cluster that has that annotation and is absent when the value is shared. This checks the end-to-end use case from the issue.
  3. unit: ArrayListGrouped with useRc: true. Assert:
    • each item renders in an RcSection titled by getItemTitle;
    • the trash action in RcSectionActions removes that row and emits remove;
    • the legacy remove button is not rendered;
    • with useRc: false the InfoBox markup is unchanged.
  4. unit: ArrayList with useRcButton: true. Assert:
    • an RcButton with data-testid="${componentTestid}-button" is rendered and adds a row;
    • it is disabled when disableAdd / loading is set;
    • with removeAllowed: false the hide-remove class is applied.
  5. unit: MatchExpressions with useRc: true. Assert that the add-rule button (input-match-expression-add-rule) and the per-row remove button (input-match-expression-remove-control-{i}) are RcButtons and still add and remove rules.

Why manual testing: the relaxed context matching is a backwards-compatible but broader change to the extension API. It affects every extension that uses context, including the in-tree AKS/EKS/GKE detail tabs. Testers should check that those provider tabs still appear only on matching clusters. The shared form components (affinity, array lists) also got new visual modes.

This comment was generated automatically to highlight missing automated coverage and suggest next tests to add.

19611 Chart dropdown is missing when editing an installed app whose chart can't be found Tests sufficient + manual test
In QA Review 4 d (since 2026-10-22 00:27 UTC) · issue ↗ · linked PR: 19612 (merged, 2 test files)

Labels it would add: qa-reviewed test-automation-sufficient needs-manual-test

🤖 QA review analysis

Automated tests appear sufficient for this issue. A round of manual tests is still required.

Decision: automatable = true · automation_sufficient = true · manual_test = true

Rationale: the regression came from the installed-app lookup in fetchChart (shell/mixins/chart.js) being moved below the if ( !this.chart ) return check. PR #19612 moves the lookup back above that check and adds unit tests aimed at this exact root cause and at the dropdown's visibility condition.

Test evidence (PR #19612)

  • shell/mixins/__tests__/chart.test.ts, suite when the chart of an installed app cannot be found:
    • should still find the existing app from the query: asserts cluster/find is dispatched with app-ns/app-name and existing is set even though catalog/chart returns undefined;
    • should set the mode to edit.
  • shell/pages/c/_cluster/apps/charts/__tests__/install.test.ts:
    • showSelectVersionOrChart table test covers a regular app with its chart found or missing (→ shown) and a managed app with its chart found (→ shown) or missing (→ hidden). The managed-app case is the edge case;
    • fetch() when the chart is missing asserts step 1's Next stays disabled (stepBasic.ready === false).

Why manual testing: this is a regression in the core Apps upgrade flow, and reproducing it needs a real environment: add a repo, install a chart, remove the repo, then go Installed Apps → Edit/Upgrade. The unit tests check the computed flag, not that the rendered Chart dropdown lists the available charts and lets the user carry on with the upgrade. Testers should check:

  • the dropdown shows up and is populated;
  • picking a chart unlocks the Version dropdown and Next;
  • a managed (Rancher/Fleet) app whose chart is missing shows no chart selector.

Residual risk: there is no e2e coverage of the Installed Apps → Edit/Upgrade path when the chart is missing. Consider a Cypress spec later that deletes the chart repo after install.

This analysis was generated automatically based on unit and e2e evidence linked to this issue.

19628 Save Changes to New View leaves the source view with unsaved changes Tests sufficient, no manual test
In QA Review 3 d (since 2026-10-22 14:51 UTC) · issue ↗ · linked PR: 19630 (merged, 3 test files)

Labels it would add: qa-reviewed test-automation-sufficient no-manual-test-needed

🤖 QA review analysis

Automated tests appear sufficient for this issue. No manual tests required.

Decision: automatable = true · automation_sufficient = true · manual_test = false

Rationale: the fix in PR #19630 is a single, contained change. openSaveAsNew in shell/components/TableViews/TableViewTabs.vue now calls forgetDraft(tab.id), which means "left as saved = discard changes" (confirmed in the comments). The updated unit tests assert this on every kind of source tab.

Test evidence (PR #19630, shell/components/TableViews/__tests__/TableViewTabs.test.ts)

  • should save that tab's changes as a new view, leaving that tab as saved, for a non-front tab:
    • the new view holds name:bar;
    • drafts.bbb is undefined;
    • the tab that was in front keeps its own draft. This is the edge case: other tabs' drafts aren't touched.
  • should leave the tab in front as saved once its changes are saved as a new view, for the picked saved view: the new view holds the changes, the source keeps its stored state:Running, and drafts.aaa is undefined.
  • should leave the table's own tab as it comes once its changes are saved as a new view, before any tab is picked, for the built-in tab: drafts.__default is undefined.
  • Existing coverage already checks that a no-op Save as New on a clean tab does not change storage.

Manual testing not needed: the fix is small, the behavior is checked in both the stored views and the per-tab drafts, and the issue carries no priority, prime or manual-test labels.

Residual risk: this deliberately changes the Save-as-New expectation in #19583 scenario 1 (the built-in tab no longer keeps its changes). Make sure QA for #19583 checks against the new behavior.

This analysis was generated automatically based on unit and e2e evidence linked to this issue.

19629 Undo doesn't work in the table views search bar Tests sufficient + manual test
In QA Review 3 d (since 2026-10-22 14:51 UTC) · issue ↗ · linked PR: 19630 (merged, 3 test files)

Labels it would add: qa-reviewed test-automation-sufficient needs-manual-test

🤖 QA review analysis

Automated tests appear sufficient for this issue. A round of manual tests is still required.

Decision: automatable = true · automation_sufficient = true · manual_test = true

Rationale: PR #19630 adds a custom undo/redo history (shell/utils/table-views/query-history.ts) for the contenteditable search box. The box rebuilds its contents as it highlights them, so it now keeps its own history instead of relying on the browser's. That history is wired into TableViewQueryInput.vue through keydown and beforeinput handlers, and the logic is well unit-tested.

Test evidence (PR #19630)

  • shell/utils/table-views/__tests__/query-history.test.ts (new) covers:
    • undo a word at a time, and redo;
    • a new step after a pause in typing;
    • a run of deletions as one step;
    • typing over a selection;
    • paste, cut, suggestion and clear as separate steps;
    • dropping the redo stack after a new edit;
    • caret placement after undo and redo, which is the "text comes back in the wrong place" part of the bug;
    • reset;
    • the changeOf mapping of input types.
  • shell/components/TableViews/__tests__/TableViewQueryInput.test.ts, suite undo and redo:
    • Ctrl+Z, Ctrl+Shift+Z and Ctrl+Y round trip;
    • Edit-menu historyUndo through beforeinput;
    • history resets when historyKey changes (another view is put on the table).

Why manual testing: the behavior depends heavily on the platform and browser. Real contenteditable caret handling, IME composition, and the Mac Cmd+Z / Cmd+Shift+Z path (isMac branch, not unit-tested) can't be reproduced faithfully in jsdom. Testers should check on macOS and on Windows/Linux in Chrome and Firefox:

  • undo/redo while typing, deleting and pasting, and after picking a suggestion;
  • the caret position after each step;
  • the history starting fresh after switching tabs.

Residual risk: the Mac shortcut branch and redo from the Edit menu (historyRedo) have no unit tests. Small unit additions would close that gap.

This analysis was generated automatically based on unit and e2e evidence linked to this issue.

19662 The filter tabs have wrong counter when resources are deleted Tests sufficient, no manual test
In QA Review 3 d (since 2026-10-23 07:05 UTC) · issue ↗ · linked PR: 19663 (merged, 3 test files)

Labels it would add: qa-reviewed test-automation-sufficient no-manual-test-needed

🤖 QA review analysis

Automated tests appear sufficient for this issue. No manual tests required.

Decision: automatable = true · automation_sufficient = true · manual_test = false

Rationale: PR #19663 makes the tab counts refresh when the same pagination request gets a fresh answer, as happens after a delete. It also queues a recount if one is asked for while a counting round is already in flight. Both unit and e2e tests check the user-visible result from the issue.

Test evidence (PR #19663)

  • e2e: cypress/e2e/tests/pages/explorer2/workloads/pods.spec.ts, should count the All tab again as a pod is created and deleted. It reads the All (n) count, creates a pod and asserts (n + 1), then deletes it and asserts (n). This is exactly the repro scenario. It uses a new allViewTab() helper in cypress/e2e/po/components/sortable-table.po.ts.
  • unit: shell/mixins/__tests__/resource-table-views.counts.test.ts (new) checks:
    • no recount on the first answer, or on a page turn, sort or filter (the edge cases);
    • a recount when the same request is answered again, or rebuilt identically;
    • a refresh asked for mid-round runs once the current round ends;
    • a "missing counts only" call does not trigger a full recount;
    • no extra round when nothing was asked mid-round.

Manual testing not needed: the acceptance criterion is checked end-to-end on a real list, and the risky edge cases (extra recounts on paging or sorting, concurrent rounds) are unit-tested.

Residual risk: the e2e test only checks the All tab. Counts on saved-view tabs rely on the same refresh path, which the unit tests cover.

This analysis was generated automatically based on unit and e2e evidence linked to this issue.

19676 Standalone Harvester gets the table views, which drop its list filters and empty the Images list Tests sufficient + manual test
In QA Review 2 d (since 2026-10-23 12:41 UTC) · issue ↗ · linked PRs: 19677 (merged, 1 test file), 19679 (merged, 2 test files)

Labels it would add: qa-reviewed test-automation-sufficient needs-manual-test

🤖 QA review analysis

Automated tests appear sufficient for this issue. A round of manual tests is still required.

Decision: automatable = true · automation_sufficient = true · manual_test = true

Rationale: two PRs fixed this. PR #19677 first turned table views off altogether for a standalone product. PR #19679 replaced that with the current behavior, explained in the comment of 2026-10-23: isExtensionTable() now treats a single-product app (isSingleProduct getter) as an extension. Its tables keep their old layout by default and can still opt in to table views table by table. The final unit tests line up with this behavior. The #19677 assertions that table views were always off were rewritten in #19679.

Test evidence (final state after PR #19679)

  • shell/utils/table-views/__tests__/feature.test.ts:
    • isConfigurableTablesEnabled follows the feature flag in a standalone product too;
    • isExtensionTable returns true when singleProduct: true.
  • shell/components/__tests__/ResourceTable.extension.test.ts, suite a standalone product's table, eg Harvester:
    • resourceTable.showTableViews is false by default for Harvester and true once the table opts in (tableViews: true);
    • it stays true in Rancher (not a single product), which is the "Rancher unaffected" check;
    • sortableTable.useTableViewsLayout keeps its old masthead unless the table opts in, and still uses table views in Rancher.

Why manual testing: the visible symptoms (Images showing no rows, Filter labels / Filter schedule / SR-IOV parent filters / the PCI Actions menu disappearing, default group-by, Download YAML vs Export As…) only show up in a standalone Harvester build from harvester-ui-extension. That build can't be tested from this repository's CI. A standalone build should be checked once the next @rancher/shell release is out:

  • Images, Virtual Machines, PCI Devices and VM Backups show their rows and their own filters;
  • the same package loaded as an extension in Rancher, and Rancher's own lists, are unchanged.

Residual risk: this is a cross-repo integration that depends on the shell version Harvester pins.

This analysis was generated automatically based on unit and e2e evidence linked to this issue.

19683 Enter in a wizard text field jumps back to step 1 Tests sufficient, no manual test
In QA Review 2 d (since 2026-10-23 15:07 UTC) · issue ↗ · linked PR: 19684 (merged, 1 test file)

Labels it would add: qa-reviewed test-automation-sufficient no-manual-test-needed

🤖 QA review analysis

Automated tests appear sufficient for this issue. No manual tests required.

Decision: automatable = true · automation_sufficient = true · manual_test = false

Rationale: the root cause was that the step buttons in shell/components/Wizard.vue had no type, so they defaulted to submit buttons. Pressing Enter in a text field then "clicked" the first one, which jumped back to step 1. PR #19684 adds type="button" to the step RcButtons. This one-attribute fix lives in the shared component, so it applies to Fleet GitRepo and to extension wizards alike.

Test evidence (PR #19684)

  • shell/components/__tests__/Wizard.test.ts, should not submit the form the wizard is in from a step button: asserts that every step button renders with type="button". That is exactly the condition that stops a form's implicit submission from triggering them.
  • The existing Wizard suite still covers step navigation and active-step behavior.

Manual testing not needed: the fix is minimal and isolated, the test asserts the precise cause, and the issue has no priority, prime or manual-test labels.

Residual risk: there is no e2e check of pressing Enter in a field such as Repository URL on Continuous Delivery → Git Repos → Create. A small Cypress assertion that the wizard stays on "Repository details" after {enter} would guard against other submit-type buttons being added later.

This analysis was generated automatically based on unit and e2e evidence linked to this issue.

Skipped by the exclusion rules

What the agent reported

How it was run