Runtime verification · 12 Nov 2026, 18:05 UTC

Moving kubewarden-ui into security-ui-exts

The SUSE Security Admission Controller extension was built from both repositories and put through the same checks on two identical Rancher Prime servers: Martin Kravec's full Playwright suite, a recorded walkthrough of every page, a pixel comparison, the real release pipeline, and an upgrade from today's 4.2.4.

Safe to move: the moved extension behaves exactly like the original
4 full runsof the e2e suite, 51 tests each, on fresh servers
0 regressionstests the moved build fails that the baseline always passed
1,821unit tests passing in the merged repo
4.2.4 → movedupgrade through the Extensions page
73 packagesbundled, same versions in both builds

How the full check works

Each step ran on both builds the same way. Only the extension's source repository differs: rancher/kubewarden-ui at release kubewarden-4.2.4 (baseline) and security-ui-exts branch move-kubewarden-ui (moved).

Two identical servers

Fresh Rancher Prime v2.15.3 on AWS, single-node k3s v1.36.6+k3s1, same image and size.

Prime v2.15.3

Build like CI

Each server checks out its commit, runs yarn install and VERSION=0.0.1 yarn build-pkg kubewarden, the steps of the suite's pull-request job.

same steps

Martin's e2e suite

The suite from each repository, same selection as its pull-request pipeline: setup, install from AppCo, dashboard, policy servers, policies, reports, telemetry and 12 catalog policies.

51 tests each

Every page, side by side

An annotated walkthrough video per build, then a clean screenshot of each page and a pixel diff between the builds.

9 pages

Release pipeline

A test tag on a fork ran security-ui-exts' real release workflow, which built and published the kubewarden chart next to the other extensions.

workflow green

Upgrade from 4.2.4

The official 4.2.4 chart, then an upgrade to the chart the release workflow published, through Rancher's Extensions page.

same data after

Martin's e2e suite, both builds

The Kubewarden UI Playwright suite (tests/ in kubewarden-ui, tests/kubewarden/ after the move), run with ORIGIN=source, Admission Controller from AppCo, and the 90-allpolicies subset fixed to the letter C so both runs install the same policies. Rows where the two builds differ are highlighted.

Baseline · kubewarden-ui

round 2 40 passed · 8 failed · 3 skipped · report ↗
round 3 48 passed · 0 failed · 3 skipped · report ↗
commit d4a369452e8d

Moved · security-ui-exts

round 2 48 passed · 0 failed · 3 skipped · report ↗
round 3 48 passed · 0 failed · 3 skipped · report ↗
commit 2a1e3c5b4311

Reading the table

Each build ran the whole suite on its own fresh server in every round. A test the moved build fails, but the baseline passed every time, would be a regression: there are none. In round 2 the baseline's telemetry setup failed: Rancher's chart page listed every OpenTelemetry Operator version twice (the upstream index has no duplicates), so the suite's version check matched two elements and the dependent telemetry tests failed. On a fresh server in round 3 the same tests passed, and the moved build passed them in both rounds.

TestBaseline
round 2
Baseline
round 3
Moved
round 2
Moved
round 3
00-setup.spec.tsbaseline 1/1 passed every round · moved 1/1 passed every round
Initial rancher setupPassed8 sPassed8 sPassed7 sPassed7 s
10-kubewarden.spec.tsbaseline 3/3 passed every round · moved 3/3 passed every round
Install UI extensionPassed6 sPassed6 sPassed6 sPassed6 s
Install Admission ControllerPassed48 sPassed60 sPassed45 sPassed45 s
Install Kubewarden by FleetSkipped0 sSkipped0 sSkipped0 sSkipped0 s
Add Policy Catalog RepositoryPassed10 sPassed10 sPassed7 sPassed7 s
Upgrade KubewardenSkipped0 sSkipped0 sSkipped0 sSkipped0 s
20-dashboard.spec.tsbaseline 3/3 passed every round · moved 3/3 passed every round
Check kubewarden resourcesPassed73 sPassed17 sPassed31 sPassed36 s
Check landing pagesPassed6 sPassed7 sPassed9 sPassed6 s
Stats reflect resource changesPassed18 sPassed22 sPassed23 sPassed18 s
30-policyservers.spec.tsbaseline 3/3 passed every round · moved 3/3 passed every round
Policy ServersPassed77 sPassed72 sPassed75 sPassed72 s
Create with invalid valuesPassed7 sPassed6 sPassed6 sPassed8 s
Create with custom valuesPassed10 sPassed10 sPassed12 sPassed10 s
40-policies.spec.tsbaseline 11/11 passed every round · moved 11/11 passed every round
Form fields (AP)Passed27 sPassed14 sPassed15 sPassed13 s
Form fields (CAP)Passed43 sPassed14 sPassed13 sPassed20 s
Default policy settings (AP)Passed22 sPassed13 sPassed12 sPassed11 s
Default policy settings (CAP)Passed34 sPassed15 sPassed14 sPassed17 s
Modified policy settings (AP)Passed2.8 minPassed2.2 minPassed2.2 minPassed2.1 min
Modified policy settings (CAP)Passed2.6 minPassed2.1 minPassed1.9 minPassed2.1 min
Check Official policiesPassed22 sPassed9 sPassed8 sPassed14 s
Check Unofficial policiesPassed24 sPassed15 sPassed9 sPassed19 s
Recommended policiesPassed68 sPassed32 sPassed26 sPassed50 s
Match ConditionsPassed2.1 minPassed85 sPassed81 sPassed1.7 min
PaginationPassed15 sPassed10 sPassed8 sPassed11 s
50-policyreports.spec.tsbaseline 4/4 passed every round · moved 4/4 passed every round
New resources should be reportedPassed2.1 minPassed1.6 minPassed78 sPassed88 s
Check reports on resources details pagePassed21 sPassed14 sPassed10 sPassed8 s
Check reports on home pagePassed12 sPassed9 sPassed5 sPassed5 s
Cleanup & check results are gonePassed60 sPassed38 sPassed28 sPassed35 s
60-telemetry.spec.tsbaseline 4/12 passed every round · moved 12/12 passed every round
Install OpenTelemetry
baseline, round 2: Error: expect(locator).toBeVisible() failed
Failed34 sPassed58 sPassed44 sPassed44 s
Create custom PolicyServer & PolicyPassed24 sPassed17 sPassed11 sPassed12 s
Install JaegerPassed87 sPassed63 sPassed47 sPassed46 s
Configure tracing
baseline, round 2: TimeoutError: locator.click: Timeout 60000ms exceeded.
Failed74 sPassed2.1 minPassed2.0 minPassed1.8 min
Check traces are visible
baseline, round 2: Error: expect(locator).toBeVisible() failed
Failed37 sPassed18 sPassed16 sPassed38 s
Uninstall tracing
baseline, round 2: TimeoutError: locator.click: Timeout 60000ms exceeded.
Failed73 sPassed67 sPassed66 sPassed71 s
Install MonitoringPassed37 sPassed51 sPassed41 sPassed36 s
Configure metrics
baseline, round 2: TimeoutError: locator.click: Timeout 60000ms exceeded.
Failed75 sPassed2.5 minPassed2.8 minPassed2.3 min
Check metrics are visible
baseline, round 2: TimeoutError: locator.evaluate: Timeout 60000ms exceeded.
Failed74 sPassed89 sPassed17 sPassed46 s
Uninstall metrics
baseline, round 2: TimeoutError: locator.click: Timeout 60000ms exceeded.
Failed73 sPassed1.9 minPassed87 sPassed1.5 min
Delete custom PolicyServer & PolicyPassed10 sPassed14 sPassed8 sPassed8 s
Uninstall OpenTelemetry
baseline, round 2: TimeoutError: locator.click: Timeout 60000ms exceeded.
Failed69 sPassed20 sPassed19 sPassed16 s
90-allpolicies.spec.tsbaseline 11/11 passed every round · moved 11/11 passed every round
install: Custom PolicyPassed57 sPassed55 sPassed55 sPassed57 s
install: Capabilities PSPPassed56 sPassed57 sPassed56 sPassed55 s
install: CEL PolicySkipped0 sSkipped0 sSkipped0 sSkipped0 s
install: Container Block SysctlsPassed62 sPassed56 sPassed55 sPassed56 s
install: Container Block Sysctls CVE-2022-0811Passed66 sPassed57 sPassed55 sPassed54 s
install: Container ResourcesPassed75 sPassed56 sPassed56 sPassed57 s
install: Container Running As RootPassed73 sPassed53 sPassed54 sPassed58 s
install: Container Running As UserPassed63 sPassed55 sPassed53 sPassed56 s
install: Containers Block Ssh PortPassed63 sPassed54 sPassed53 sPassed58 s
install: Containers Block Specific Image NamesPassed66 sPassed54 sPassed53 sPassed57 s
install: Containers Missing Security ContextPassed56 sPassed55 sPassed57 sPassed56 s
install: Containers Should Not Run In NamespacePassed55 sPassed57 sPassed56 sPassed57 s

Skipped tests are skipped by design in this mode: the Fleet install and the Admission Controller upgrade belong to the suite's fleet and upgrade modes, and one catalog policy skips itself.

Every page, side by side

After the suite, the same pages were captured on both servers at 1440×900, with ages and timestamps masked. Changed pixels are painted magenta in the Difference view. Differences in counts or names come from the cluster's data, not from the extension.

Recorded walkthroughs

The same script on both servers, with captions naming every action. Nothing is created or changed during the walkthrough; the policy form is cancelled.

Baseline · built from rancher/kubewarden-ui
Moved · built from security-ui-exts

Upgrade from today's 4.2.4

Rancher only offers an upgrade from the repository an extension was installed from, so existing users will see the new version when rancher/ui-plugin-charts syncs it from security-ui-exts. To test that path, a Git catalog mirrors how ui-plugin-charts will look after the move: the official 4.2.4 chart copied byte for byte (all five files match), plus the 4.2.5-moved.1 chart that security-ui-exts' release workflow published. The server already had the Admission Controller, a policy server and the recommended policies.

4.2.4 → 4.2.5-moved.1 · installed from the catalog, upgraded through Extensions › Installed › Upgrade

The real release pipeline

A test tag on the fork (kubewarden-4.2.5-moved.1, version bump on a separate branch) triggered security-ui-exts' existing release workflow, the same reusable rancher/dashboard workflow both repositories use today. It built the chart and published it to gh-pages next to the Vulnerability Scanner and Runtime Enforcer charts, with no workflow changes.

Workflow run
Build and Release Extension Charts · success ↗
Published
charts/kubewarden/4.2.5-moved.1 ↗ and extensions/kubewarden/4.2.5-moved.1
Helm index
kubewarden, runtime-enforcer, sbomscanner-ui-ext and vulnerability-scanner in one index.yaml
Chart
name kubewarden, display name and Rancher annotations unchanged
Code served from
raw.githubusercontent.com/<org>/security-ui-exts/gh-pages/extensions/kubewarden/<version>

The other two extensions

The merge changes the repository's dependency tree (kubewarden-ui's security pins now apply to everything), so the Vulnerability Scanner and Runtime Enforcer were checked too. Statically, their bundles contain the same packages at the same versions on main and on the branch. At runtime, the suite's specs 80 and 81 ran on the round-2 servers with builds from security-ui-exts main (f18b5394, where the branch starts) and from the branch. These two specs are not part of the pull-request selection. On both builds the Vulnerability Scanner install outlasted the spec's two-minute wait for Helm's success line; the backend did install (every pod running), and the steps that depend on that wait fail the same way. The Runtime Enforcer install passed on the branch and timed out once on main. The branch fails nothing that main passed.

Vulnerability Scanner bundle

71 packages
identical set and versions on main and the branch

Runtime Enforcer bundle

70 packages
identical set and versions on main and the branch

Runtime specs 80 and 81

6 / 7
passed · main / branch builds, of 13 run
Playwright reports for these specs are not published: their traces record the AppCo login sent in an API request header.
Testsecurity-ui-exts mainBranch
80-sbomscanner.spec.ts Install UI extensionPassedPassed
80-sbomscanner.spec.ts Install Vulnerability ScannerFailedFailed
80-sbomscanner.spec.ts Scan Admission ControllerFailedFailed
80-sbomscanner.spec.ts RBAC rules for Policy ServerPassedPassed
80-sbomscanner.spec.ts Create test policyPassedPassed
80-sbomscanner.spec.ts Create WorkloadScanFailedFailed
80-sbomscanner.spec.ts Create test deploymentPassedPassed
80-sbomscanner.spec.ts Check compliance reportFailedFailed
80-sbomscanner.spec.ts TeardownFailedFailed
80-sbomscanner.spec.ts Check Rancher VEX HubPassedPassed
80-sbomscanner.spec.ts Trigger registry scanFailedFailed
81-runenforcer.spec.ts Install UI extensionPassedPassed
81-runenforcer.spec.ts Install Runtime EnforcerFailedPassed

Static checks

Run before the runtime checks, on the merged branch and on both original repositories.

Unit tests

1,821 / 1,821
kubewarden-ui 476 + security-ui-exts 1,345, all passing after the merge, twice, and in the repository's CI on the fork

Bundle parity

56 files
same 73 packages and versions as the kubewarden-ui build; JavaScript within 181 bytes of 3.8 MB

Lint and spelling

0 new warnings
in existing folders; kubewarden keeps its own rules. The spelling check found 9 typos to fix and 5 misspelled identifiers to leave

Environment and what we adapted

Martin's CI runs on self-hosted openSUSE runners with Rancher in k3d on the same machine. These runs used Rancher on AWS and Playwright's official image. Each difference was handled the same way for both builds:

Difference from CIWhat we did
Rancher runs on AWS instead of on the runner. Chrome blocks a public page from loading a script from 127.0.0.1 (Local Network Access).Granted the browser the local-network-access permission, as a user clicking Allow would.
k3s runs directly on the server, and every new pod adds a network interface. Chromium aborts its requests on each one (ERR_NETWORK_CHANGED).The browser runs in Playwright's official v1.64.1-noble image, with its own network namespace, the way CI's k3d hides pod interfaces.
The image's /bin/sh is dash. The suite's host commands use &>, which dash reads as "run in background", so the AppCo secret was never created.Pointed /bin/sh at bash inside the container, as on the openSUSE runners.
The image's monospace font is WenQuanYi Zen Hei Mono, a CJK font with narrow Latin letters.Installed DejaVu Sans Mono, the usual Linux default.
The suite reads shell exit codes from screenshots of the terminal, with reference images per runner (it ships a -leap set for openSUSE). Sub-pixel colour still differs on this image.Rendered this runner's three markers once with the suite's own --update-snapshots=missing and used them in place of the -leap set. The same files went into both runs: 0 a2213f39516e, 1 3d7af6355396, NaN ec0c2c8eda71.
CI installs a random letter of the 90-allpolicies catalog on each run.Fixed the letter to C (12 policies) on both servers.
EvidenceA wrapper config adds a video for every test and HTML/JSON reports. No test file was changed.

Run details

Baseline

rancher
https://mf-kw-r3-base.ui.rancher.space
commit
d4a369452e8d3264fac2920e4ccd82e999a8b670
bundle_sha256
711ebc6c1dcbccaf
policy_letter
C excluded=ABDEFGHIKLMNOPRSTUV
playwright
Version 1.64.1
node
v26.13.0 kubectl=v1.36.6+k3s1
server
v1.36.6+k3s1
started
2026-11-12T17:17:03Z
finished
2026-11-12T17:54:44Z
duration
2261s
exit
0

Moved

rancher
https://mf-kw-r3-moved.ui.rancher.space
commit
2a1e3c5b4311a4106ea6af6b2ebe1688ba8178ce
bundle_sha256
5abb7bc5338f03bd
policy_letter
C excluded=ABDEFGHIKLMNOPRSTUV
playwright
Version 1.64.1
node
v26.13.0 kubectl=v1.36.6+k3s1
server
v1.36.6+k3s1
started
2026-11-12T17:19:36Z
finished
2026-11-12T17:55:39Z
duration
2163s
exit
0

Three rounds

Round 1 ran from a Mac and then on the servers directly, before the runner fixes in the table above; both builds failed the same shell-screenshot checks (baseline 39 passed, moved 37 passed). Its reports are kept with the artifacts but not used here. Rounds 2 and 3 each used two fresh servers with the fixed runner; every e2e result on this page comes from them. Each build therefore ran the suite twice from scratch.

Migration rules this surfaced

Things the real move has to respect, found while running these checks.

Archive kubewarden-ui, never delete it

The installed 4.2.4 extension caches its code from compressedEndpoint, which points at kubewarden-ui's gh-pages 4.2.4.tgz. That archive exists only there; ui-plugin-charts has the unpacked files but no .tgz. Keep the repository and its gh-pages branch.

Keep the package name kubewarden

The upgrade is offered for the same chart name in the same catalog repository. Renaming the package would show up as a second extension instead of an upgrade.

Upgrades reach users through ui-plugin-charts

Rancher offers upgrades only from the repository an extension came from. Existing users get the moved build once rancher/ui-plugin-charts syncs it from security-ui-exts; that manifest change is aalves08's.

The release workflow is shared

Any release in security-ui-exts runs "Build and Release Extension Charts". The kubewarden e2e follow-up now starts only for kubewarden-* tags.

One server serves all three extensions

In the merged repo one yarn serve-pkgs serves kubewarden, Vulnerability Scanner and Runtime Enforcer. The suite's env-config still points the last two at port 4501: a one-line follow-up.

Make the suite portable (for Martin)

ControlOrMeta+A instead of Control+A, >/dev/null 2>&1 instead of &>, and a terminal-marker set per runner would let it run on macOS and Ubuntu as well as openSUSE.

Code owners and access

kubewarden-ui's CODEOWNERS names teams from the kubewarden GitHub org, which cannot own code in a rancher-org repository. Martin and juadk only have read on security-ui-exts today.

Card text comes from the catalog sync

ui-plugin-charts patches the extension's description when it syncs. The moved build shows its package description until that happens, as the upgrade video shows.