chore: resource-server consolidation in uPortal-start#694
Merged
bjagg merged 9 commits intoMay 14, 2026
Conversation
33df94b to
0584ba7
Compare
bjagg
added a commit
to bjagg/uPortal-start
that referenced
this pull request
May 8, 2026
Problem: uportal-pw.config.ts pinned retries to 0, which left timing-sensitive tests (notably the BS5 options dropdown — see uPortal#2981) flaking under CI without recourse. The existing config already enables `video: "on-first-retry"` and `trace: "retain-on-failure"`, both of which assume retries happen, so retries:0 also defeated those debug aids. Goal: allow Playwright to retry transient failures up to twice before marking a test failed. Stabilizes CI signal on PR uPortal-Project#694 without masking durable failures (a test failing 3/3 still fails). Changes: - tests/uportal-pw.config.ts: retries 0 -> 2 Notes: per reviewer (Naenyn) suggestion on the uPortal-Project#694 dropdown flake. The underlying Bootstrap-5 dropdown synthetic-click issue is tracked at uPortal#2981; this is mitigation, not a fix.
bjagg
added a commit
to bjagg/uPortal-start
that referenced
this pull request
May 10, 2026
Problem: uportal-pw.config.ts pinned retries to 0, which left timing-sensitive tests (notably the BS5 options dropdown — see uPortal#2981) flaking under CI without recourse. The existing config already enables `video: "on-first-retry"` and `trace: "retain-on-failure"`, both of which assume retries happen, so retries:0 also defeated those debug aids. Goal: allow Playwright to retry transient failures up to twice before marking a test failed. Stabilizes CI signal on PR uPortal-Project#694 without masking durable failures (a test failing 3/3 still fails). Changes: - tests/uportal-pw.config.ts: retries 0 -> 2 Notes: per reviewer (Naenyn) suggestion on the uPortal-Project#694 dropdown flake. The underlying Bootstrap-5 dropdown synthetic-click issue is tracked at uPortal#2981; this is mitigation, not a fix.
f3d16a8 to
92e4dc2
Compare
…jar; visual smoke
Problem: uPortal-start's portlet-definition data files, the skinName
template, and the resource-server overlay all referenced the legacy
/ResourceServingWebapp/ context that the consolidation effort is
retiring. SimpleContentPortlet's CKEditor was being served from the
legacy 1.0.48 WAR's bundled 4.3.2 (multiple historical XSS CVEs);
the modern resource-server-webapp 1.5.x overlay didn't carry an
explicit CKEditor webjar to consume from. There was no automated
check that the consolidation didn't regress visual rendering or
quietly start emitting legacy URLs.
Goal: complete the consolidation's surface area in uPortal-start —
move every portlet-definition data file's iconUrl off the legacy
context, refresh the skinName template (used as the starting point
for institutional skins) onto the modern overlay, give the modern
overlay a webjar source for CKEditor 4 so SimpleContentPortlet's
configureContent.jsp can consume it, and add a visual smoke test
that asserts the absence of legacy URL requests on key pages.
Changes:
- data/base/portlet-definition/*.xml (31 files),
data/quickstart/portlet-definition/*.xml (40 files): swap every
iconUrl <value>/ResourceServingWebapp/rs/tango/...</value> to
/resource-server/rs/tango/... Tango/0.8.90 ships at byte-identical
paths in the modern overlay so the deployed portlet thumbnails
render unchanged.
- etc/skin/skinName/skin.xml: update the new-skin template used by
deployers — swap normalize 2.1.2 + fontawesome 4.7.0 to the
modern context; bump the jquery-ui smoothness theme from
/ResourceServingWebapp/rs/jqueryui/1.10.3/theme/smoothness/
jquery-ui-1.10.3-smoothness.{css,min.css} to
/resource-server/webjars/jquery-ui/dist/themes/smoothness/
jquery-ui.{css,min.css} (matches uPortal-webapp's defaultSkin
precedent; webjar serves jquery-ui 1.14.2). Existing skins are
unaffected — this is purely a starting-template change.
- gradle.properties: add ckeditor4Version=4.22.1. 4.22.1 is the
last truly free CKEditor 4 release; 4.23+ are LTS-only and
self-destruct without a paid license key. Comment captures that
trap so deployers don't try to bump.
- overlays/resource-server/build.gradle: declare
org.webjars.npm:ckeditor4:${ckeditor4Version} as a runtime
webjar so SimpleContentPortlet's configureContent.jsp can
consume /resource-server/webjars/ckeditor4/ckeditor.js.
- tests/ux/smoke/visual-resource-server.spec.ts: new visual smoke
spec — guest welcome, admin home, student home, CKEditor
instantiation in SimpleContentPortlet config, and a NewsReader
page that exercises the Handlebars-replacement mini-renderer.
Each test attaches console/network listeners and asserts zero
/ResourceServingWebapp/ URL requests + zero unexpected console
errors. Filters CKEditor 4.22.1's known LTS-upgrade nag.
Notes: 73 portlet-definition data files modified is a mechanical
sed-style pass (/ResourceServingWebapp/rs/tango/ →
/resource-server/rs/tango/) — review by category, not file. Existing
deployments need a fresh dataInit (or a SQL UPDATE on
up_portlet_definition_parm) to pick up the new iconUrl values; the
deployer guide documents the SQL recipe. Verified end-to-end against
uPortal-start's full Playwright suite (121/122 with 1 documented
chrome dropdown flake from uPortal#2981 unrelated to this work).
Problem: gradle.properties is the canonical place to pin uPortal and portlet versions, but every developer iterating with -SNAPSHOTs against an unreleased build either pollutes upstream history with SNAPSHOT bumps or maintains a dirty working tree. Institutional deployers who fork to maintain pinned versions hit merge conflicts on every upstream sync because both their fork and upstream edit the same file. Goal: keep canonical versions in source control as a template and let the active gradle.properties live untracked, so contributors' local SNAPSHOTs don't surface upstream and deployer forks can absorb upstream version bumps without merge conflicts. Changes: - add gradle.properties.example with the canonical version pins previously tracked at gradle.properties - stop tracking gradle.properties (git rm --cached); the file remains on disk for the developer's own iteration - .gitignore: add /gradle.properties with a comment explaining the pattern - README.md: new "Bootstrap gradle.properties" section under "Using uPortal-start" documenting the cp step for first-time clones and the deployer-fork pattern (comment out the .gitignore line on the fork so version pins commit normally; upstream changes only land in gradle.properties.example, eliminating per-merge conflicts) - .github/workflows/CI.yml: bootstrap step (cp gradle.properties .example gradle.properties) added to both the test and playwright jobs right after checkout, before any gradle invocation; shell: bash on the Windows-capable test job Notes: did not bootstrap from settings.gradle or gradlew because gradle.properties is loaded before either runs; the explicit cp is the simplest contract. Deployers who want the existing committed- gradle.properties workflow comment out the gitignore line on their fork in one step.
Problem: uPortal-Project/uPortal#2982 fixed a regression in common.less where an @import path no longer existed in the Bootstrap 5 webjar, breaking lessc compilation for any custom skin scaffolded by :overlays:uPortal:skinGenerate. Without an automated check, the next break of common/common.less only surfaces when a deployer runs tomcatDeploy in their own environment and notices missing CSS. Goal: pin the regression with a Playwright test that exercises the full scaffold-and-compile path (skinGenerate -> tomcatDeploy -> lessc) on every playwrightRun. Changes: - overlays/uPortal/build.gradle: new playwrightSkinFixture task that idempotently regenerates the playwrightSkin scaffold from etc/skin/ and ensures a <skin> entry exists in skinList.xml; scaffold-template drift is caught even when the skin files are committed, because the fixture overwrites them on every run - gradle/tasks/playwright.gradle: playwrightRun now depends on playwrightSkinFixture and :overlays:uPortal:tomcatDeploy; ordering enforced via prepareSkinResources.mustRunAfter( playwrightSkinFixture) inside gradle.projectsEvaluated to avoid eager cross-project configuration of :overlays:uPortal at root evaluation time - overlays/uPortal/src/main/webapp/media/skins/respondr/: commit the generated playwrightSkin.less, playwrightSkin/, and a skinList.xml entry so the skin-compile chain in overlays/uPortal/build.gradle (which evaluates the fileTree at configuration time) registers compileLess for our skin; the fixture overwrites these on every run - tests/ux/skin/custom-skin.spec.ts: assert /uPortal/media/skins/respondr/playwrightSkin.css returns 200, has >500 bytes, and contains a Bootstrap marker (--bs-, .btn, or @import bootstrap.css) — proves common.less's @import resolved. Pre-fix code fails compileLess0 before the spec runs; post-fix the spec passes Notes: scoped to compile-only coverage (Shape 1) rather than driving the dynamic-respondr-skin or stylesheet-descriptor default-skin switch path, since the PR #2982 regression is at lessc compile time. Activation testing is left for a follow-up if the dynamic skin path needs its own regression guard. Skin name "playwrightSkin" deliberately distinct from "test" so a developer can keep their own scaffold-named "test" skin alongside the fixture's.
Problem: tests/ux/smoke/visual-resource-server.spec.ts asserts no /ResourceServingWebapp/ requests fire on the pages it visits, but the uportal-links portlet config view (configLinks.jsp) was not in the visit list. A regression where that JSP loaded a legacy /ResourceServingWebapp/rs/lodash/4.17.4/lodash.min.js script tag was missed locally and caught only when a developer noticed it in DevTools. Goal: extend smoke coverage to the uportal-links config view so the same network-tap assertion guards configLinks.jsp. Changes: - tests/ux/smoke/visual-resource-server.spec.ts: new test case that logs in as admin, navigates to /uPortal/p/uportal-links/max/render.uP?pCm=config, and reuses the smokePage helper (which fails on legacy /ResourceServingWebapp/ hits, network 4xx/5xx, or console errors) Notes: the missed regression that prompted this was JasigWidgetPortlets 2.4.2 shipping a configLinks.jsp with a /ResourceServingWebapp/rs/lodash/... script tag; JasigWidgetPortlets@9068d91 (released as 2.4.3-SNAPSHOT) drops the lodash dep and switches the template tag to /resource-server/. Picking up that release in this repo is a gradle.properties bump in the deployer's local file (per the template pattern landed earlier on this branch).
Problem: uportal-pw.config.ts pinned retries to 0, which left timing-sensitive tests (notably the BS5 options dropdown — see uPortal#2981) flaking under CI without recourse. The existing config already enables `video: "on-first-retry"` and `trace: "retain-on-failure"`, both of which assume retries happen, so retries:0 also defeated those debug aids. Goal: allow Playwright to retry transient failures up to twice before marking a test failed. Stabilizes CI signal on PR uPortal-Project#694 without masking durable failures (a test failing 3/3 still fails). Changes: - tests/uportal-pw.config.ts: retries 0 -> 2 Notes: per reviewer (Naenyn) suggestion on the uPortal-Project#694 dropdown flake. The underlying Bootstrap-5 dropdown synthetic-click issue is tracked at uPortal#2981; this is mitigation, not a fix.
92e4dc2 to
c95ee63
Compare
ChristianMurphy
approved these changes
May 12, 2026
Problem: PR uPortal-Project#694's CI fails at :overlays:uPortal:compileLess0 because the pinned uPortal 5.17.5 still imports legacy LESS sub-files (grids.less, variables.less, mixins.less, regions.less, gallery.less, tags.less, etc.) that were deleted during the Bootstrap 5 / SCSS migration. Goal: pick up uPortal 5.17.7, which lands Bill's PR #2982 deprecating the LESS pipeline by commenting out every orphaned @import in the respondr skin's common.less. Changes: - bump uPortalVersion=5.17.5 to 5.17.7 in gradle.properties.example Refs: uPortal-Project#694
Problem: playwrightLint failed locally on three rules:
- unicorn/prevent-abbreviations: variable name 'e' is ambiguous
- unicorn/prefer-dom-node-text-content: use .textContent over .innerText
- unicorn/better-regex: \{ inside a character class can be unescaped
Goal: clear the lint pass so the playwright run reaches the test
execution phase (where the consolidation invariants are actually
checked).
Changes:
- rename the filter-callback parameter 'e' to 'error' in the
CKEditor LTS-nag filter
- replace page.locator('body').innerText() with .textContent()
- drop the unnecessary backslash escapes from /{{[#/]?[A-Za-z]/
Refs: uPortal-Project#694
Problem: PR uPortal-Project#694's visual-resource-server smoke spec gates on no /ResourceServingWebapp/ URLs being requested by uPortal core or any of the deployed portlets. The pins were on versions predating both the uPortal-side path swaps (uPortal-Project/uPortal#2983, in v5.17.8) and the portlet-side overlay drops (SimpleContent uPortal-Project#554, Feedback uPortal-Project#112, NewsReader uPortal-Project#438; in 3.4.3 / 1.3.2 / 5.1.5 respectively). CI's visual smoke tests therefore stayed red until all five releases shipped together. Goal: pick up the Wave 1 portlet releases and the Wave 2 uPortal release so PR uPortal-Project#694's CI exercises the full post-consolidation stack. Changes: - bump uPortalVersion 5.17.7 -> 5.17.8 (uPortal#2983: skin XML + JSP path swaps off /ResourceServingWebapp/; drop dead utility-lib webjar deps) - bump simpleContentPortletVersion 3.4.2 -> 3.4.3 (uPortal-Project#554: CKEditor 4.22.1 webjar; drop resource-server-content overlay) - bump feedbackPortletVersion 1.3.1 -> 1.3.2 (uPortal-Project#112: drop overlay) - bump newsReaderPortletVersion 5.1.4 -> 5.1.5 (uPortal-Project#438: native mini-template renderer replacing Handlebars 3.0.3; drop overlay) Notes: validated locally against a fresh portalInit + tomcatStart with the bumped pins. Five of six visual-resource-server tests pass (guest welcome, admin home, student home, CKEditor 4 webjar instantiation, uportal-links config). The news-portlet-renders-without-Handlebars test was already failing in CI before this commit; not a regression from the bumps. CalendarPortlet event-fetch is flaky in local quickstart data; tracked separately. Refs: uPortal-Project#694
Problem: PR uPortal-Project#694's CI on the latest commit had two Playwright failures: 1. "news portlet renders without Handlebars" — page.locator('body') .textContent() includes <script type="text/template"> bodies, which legitimately contain {{var}} placeholder syntax (that's the template source the mini-renderer evaluates against). The assertion that the rendered DOM should not contain raw {{...}} therefore matched the template source itself, not actual un-rendered output. Confirmed via HTML parser: every {{ match in the failing snapshot is text inside a <script> tag; zero are in live element content. Switching from textContent to innerText (the original API before a lint-driven change) excludes script bodies from the captured text. 2. "uportal-links config loads no /ResourceServingWebapp/ resources" — failed in CI with "Received +3 ... 'This CKEditor 4.22.1 (Standard) version is not secure. Consider upgrading to the latest one, 4.25.1-lts'". The dedicated CKEditor-instantiates test (line 105) already filters this LTS-nag from its console errors, but the shared smokePage helper used by uportal-links did not. The uportal-links config view also loads CKEditor (for the link-text edit field) and the nag fires there too. The test was passing locally because the nag fires after the page's domcontentloaded snapshot in some timings, but is deterministic in CI. Goal: keep the assertions catching real regressions (un-rendered templates, runtime errors) without flagging known third-party noise. Changes: - revert textContent() back to innerText() on the news-portlet body read; add an explanatory comment and a single-line eslint-disable for unicorn/prefer-dom-node-text-content - pull the CKEditor LTS-nag filter into the smokePage helper so every page using the helper benefits from it Refs: uPortal-Project#694
2 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Completes uPortal-start's side of the resource-server consolidation, plus adds test infrastructure that pins recent regressions.
Resource-server consolidation (commit
7e931e146):/ResourceServingWebapp/(73 files, mechanical pass — tango/famfamfam paths now resolve under/resource-server/).etc/skin/skinName/skin.xml(new-skin template) onto the modern overlay; bump jquery-ui smoothness to the BS5/jquery-ui 1.14.2 webjar pattern.org.webjars.npm:ckeditor4:4.22.1to the resource-server overlay so SimpleContentPortlet'sconfigureContent.jspconsumes a webjar, not the legacy 1.0.48 WAR's bundled 4.3.2 (multiple historical XSS CVEs).gradle.propertiestemplate pattern (commit8366d18c1):gradle.properties.example; ignoregradle.propertiesso contributors' local SNAPSHOTs don't pollute upstream history and deployer forks no longer hit per-merge conflicts on pinned versions.Test coverage:
tests/ux/skin/custom-skin.spec.ts(commitba2845ad0): regression test for Comment out / deprecate less uPortal#2982 — scaffoldsplaywrightSkinfrometc/skin/, deploys, asserts the compiled CSS is served. NewplaywrightSkinFixtureGradle task regenerates the scaffold on everyplaywrightRunso scaffold-template drift fails the test.tests/ux/smoke/visual-resource-server.spec.tswithuportal-links?pCm=config(commit0584ba739): catches the JasigWidgetPortletsconfigLinks.jsplodash regression that was missed locally.Test plan
cp gradle.properties.example gradle.properties(per new pattern)./gradlew portalInit && ./gradlew tomcatStart./gradlew playwrightRun— full suite (gates on the new skin fixture + smoke spec)/gradle.propertiesin fork's.gitignore, commit local pins, merge upstream — confirm no conflict ongradle.properties