Skip to content

Bring controls newer than UI5 1.71 into scope and port their 48 samples - #276

Merged
oblomov-dev merged 33 commits into
mainfrom
claude/festive-brown-66e47b
Oct 21, 2026
Merged

oblomov-dev merged 33 commits into
mainfrom
claude/festive-brown-66e47b

Conversation

@oblomov-dev

@oblomov-dev oblomov-dev commented Oct 20, 2026 •

Copy link
Copy Markdown
Member

Why

Coverage read 100 % only because 48 demo kit samples were excluded by the rule "the control must exist since UI5 1.71". src/02 already holds 221 ports that need a newer runtime for a member, so excluding a newer control was inconsistent. The maintainer decision is to drop that exclusion.

Coverage is now 669 / 669 (12 hold-outs reserved). The only samples left unported are 20 on deprecated controls, 37 that are not app views (OPA5, routing, view templating) and 3 demo apps without a control.

Rule change

  • generate-coverage.mjs: scopeOf no longer returns newer. A port of a post-1.71 control must carry a POST_171 deviation naming the control (the gate fails otherwise); that deviation files it under src/02.
  • scaffold.mjs: writes that deviation and scaffolds straight into src/02. It also no longer clips GROUP-nested names to an identical sap.m... description.
  • scope-of.mjs reports such a control IN_SCOPE. lib-packages.mjs reads the release level from POST_171 only, so the four newer entries of ui5/scope-exceptions.json are gone.
  • AGENTS.md, README, TRAINING.md, the generation prompt, the skills and the golden fixtures are updated.

Ports: apps 624–671, all in src/02

Batch Control Apps
b52 sap.m.Avatar 624–628
b53 sap.m.IllustratedMessage 629–638
b54 sap.m.DynamicDateRange, sap.m.ExpandableText 639–643
b55 sap.m.p13n Container/Engine/Popup, sap.m.VariantManagement 644–651
b56 sap.m.plugins.UploadSetwithTable 652–661
b49 sap.f.AvatarGroup, SidePanel, ProductSwitch 662–666
b50 sap.f.HeroBanner 667–671

What could not be ported 1:1 is declared in the sidecars:

  • Illustration sets: there is no way to call IllustrationPool.registerIllustrationSet, so 630 and 635–638 show no Custom/tnt illustration. This is a new ❌ row in CAPABILITIES.md.
  • Function-typed properties: p13n.Popup.reset, FilterPanel.itemFactory, itemValidationHandler, customPageContentHandler and app-written DynamicDateOption subclasses have no equivalent.
  • p13n Engine (645–649): the controller logic runs in ABAP. The Popup is a fragment that is built per press and destroyed on close.
  • Uploads (652–661): emulated by vetoing beforeUploadStarts; the backend adds the row.

Live verification

Every new port now has an e2e interaction module, and all 25 LIVE_TESTs are closed. STATUS.md shows 0 open. The interactions found and fixed real defects:

  • DynamicDateRange (639, 640, 642): toDates() returns UniversalDate objects, so every row was filtered away. The dates are now sent as .getJSDate().
  • p13n (645, 648, 649): a never-opened p13n.Popup leaks its panels in UI5, and the second re-render died on a duplicate id.
  • 650: JSON.stringify is not available in event-handler expressions, so no request was ever sent.
  • 651: the bound VariantItem template broke the favourites list on UI5 1.152, and translate() failed on the transpiled runtime.
  • 644: the new view's name now matches the original.
  • 638: the countdown tick no longer flashes the busy indicator.

e2e harness

  • e2e_smoke.theme (new sidecar opt-in): boots a port with the theme CSS. sap.f.AvatarGroup (662) loops when unthemed; with the theme it passes. The opt-in is re-verified each run and fails as stale if the port also passes unthemed (641 uses it too).
  • App 600: its interaction now waits for in-flight POSTs instead of the busy indicator, which UI5 shows only after a delay. That wait was flaky under full-corpus load.
  • Apps 351, 353 and demo_004: their modules compare origins instead of hard-coding port 3000.

Shared changes

Validation

  • npm run gates: green.
  • npm test: 64/64.
  • view-gates --strict with render: 670 ports, 0 failing.
  • abaplint, standard and cloud: 0 issues.
  • CI abap-702: green.
  • e2e:
    • all 48 new ports pass on a rebuilt backend;
    • the full-corpus run's remaining failures were the three port-hardcoded modules (now fixed) and a one-off framework flake on 545 that passes on re-run.

🤖 Generated with Claude Code

https://claude.ai/code/session_01PTMAfPJZ78qd9zmLoHGZwx

Maintainer decision: a sample whose control is newer than UI5 1.71 is no
longer out of scope. Its port keeps the control 1:1 and declares it as a
POST_171 deviation naming the control, which files it under src/02.

- generate-coverage: scopeOf drops the 'newer' verdict; a port of a
  post-1.71 control without a POST_171 deviation now fails the gate
- scaffold: writes that POST_171 deviation and files the port in src/02
- scope-of: reports such controls IN_SCOPE with the POST_171 note
- lib-packages: the release level reads POST_171 only; the
  scope-exceptions path for post-1.71 controls is gone, and the four
  'newer' entries (apps 136, 141, 165, 203 - all carry POST_171) with it
- AGENTS, README, TRAINING, generation prompt and skills updated

The backlog grows by 48 samples (coverage 621 / 669).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PTMAfPJZ78qd9zmLoHGZwx
Stubs only - the views are rebuilt in the following commits.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PTMAfPJZ78qd9zmLoHGZwx
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PTMAfPJZ78qd9zmLoHGZwx
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PTMAfPJZ78qd9zmLoHGZwx
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PTMAfPJZ78qd9zmLoHGZwx
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PTMAfPJZ78qd9zmLoHGZwx
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PTMAfPJZ78qd9zmLoHGZwx
Batches b52 Avatar, b53 IllustratedMessage, b54 DynamicDateRange and
ExpandableText, b55 p13n and VariantManagement, b56 UploadSetwithTable
(sap.m), b49 AvatarGroup, SidePanel and ProductSwitch, b50 HeroBanner
(sap.f). Every port declares its control as POST_171 and lives in src/02.

Also: app 649's label 'Peter Mueller' restored to the original 'Peter Müller'
(with 649/668/671 added to the 7bit_ascii
exclusions); the scaffolder no longer clips GROUP-nested sample names to
an identical 'sap.m...' description; generated @summary/@keywords/@origin
headers and artefacts regenerated. Coverage 669 / 669.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PTMAfPJZ78qd9zmLoHGZwx
- view-gates ADVISORY_BUDGET follows what the originals carry:
  missing-accessibility 93 -> 107, editable-control-without-binding
  343 -> 356, event-on-disabled-control 7 -> 8; unused-namespace-
  declaration ratchets down to 100
- CAPABILITIES.md: new row for registering an illustration set
- docs/history.md: the journal entry for the scope change and batch

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PTMAfPJZ78qd9zmLoHGZwx
The e2e harness serves UI5 from the @openui5 packages, which ship the
themes as .less only, so every port runs unthemed. sap.f.AvatarGroup sizes
itself from its own CSS: unthemed it measures unstyled avatars, re-renders
with fewer and loops until 'Rendering has been re-started too many times'
(e2e_pr red on app 662). With the theme CSS it renders once.

A sidecar 'e2e_smoke': { theme: true, reason } now boots a port with the
theme CSS from sdk.openui5.org. It is verified like the other declared
exceptions: the port is booted unthemed as well, and a declaration whose
port passes that way too fails as stale. validate-meta guards the schema;
the e2e-debugging guide records the case.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PTMAfPJZ78qd9zmLoHGZwx

Copy link
Copy Markdown
Member Author

check-app-rules is red because this PR adds 649, 668 and 671 to the 7bit_ascii excludes. The check compares against abap2UI5 main, and the shared rule set there only changes with abap2UI5/abap2UI5#2928. Nothing in this PR can fix it: once #2928 is merged, a re-run turns it green.

The copies in the other consumers are in abap2UI5/samples#884 and abap2UI5/protocol#10. samples-stack still needs the same one-line copy. I could not reach that repository from this session.

e2e_pr went red on app 662 (sap.f.AvatarGroup): Rendering has been re-started too many times. The cause is the harness, not the port:

  • The harness boots UI5 unthemed, and AvatarGroup measures its unstyled avatars and loops.
  • With the theme CSS loaded it renders once.
  • c37bd33 adds a sidecar e2e_smoke.theme opt-in that boots such a port with the theme CSS. The opt-in is re-verified each run and fails as stale if the port also passes unthemed.
  • Locally, 662 now passes with the theme.

Generated by Claude Code

claude added 17 commits October 20, 2026 20:32
…cator

The interaction waited for the global BusyIndicator to read hidden before
firing the drop. UI5 shows it only after its show delay, so under the load
of a full-corpus run it still read hidden while a drag-start probe was in
flight, the drop was swallowed and the run failed (1 of 676). It now counts
the backend POSTs and fires once none has been in flight for 500 ms.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PTMAfPJZ78qd9zmLoHGZwx
The WIP snapshots skipped the pre-commit hook, so the closed LIVE_TESTs of
apps 625/638/670 were not reflected in the generated artefacts and
meta_valid failed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PTMAfPJZ78qd9zmLoHGZwx
DynamicDateRange.toDates returns sap.ui.core.date.UniversalDate objects, so
apps 639/640/642 sent {oDate, sCalendarType} instead of a date and the
binding_call filter dropped every row (found by the new e2e interactions).
Each date is now sent as .getJSDate(), the second one guarded because
FROM/TO yield a single date.

App 638 arms its countdown tick with START_TIMER's no-busy flag, so a slow
backend does not flash the busy overlay over the countdown.

Also: e2e interaction modules for 639-642 (641 closed, themed boot), and
WIP modules of the agents still running.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PTMAfPJZ78qd9zmLoHGZwx
abap_true is a character value and t_arg is a string table, so the VALUE
#( ) of the previous commit failed check_syntax on all three targets
(abap-cloud red). The demo app's carousel timer passes the same flag as
`X`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PTMAfPJZ78qd9zmLoHGZwx
… 644/646/647 closed

App 651: update_items deletes the variants by replace( ) instead of
translate( ), whose FROM set the transpiled runtime turns into an
unescaped regex class - ']' broke it and no variant was ever deleted.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PTMAfPJZ78qd9zmLoHGZwx
- 645/648/649: a sap.m.p13n.Popup declared in the view leaks its panels
  when it is never opened (Popup.exit destroys only the Dialog open()
  creates), and the next-but-one re-render died on a duplicate panel id.
  The Popup is now a popup_display fragment, built per press and
  popup_destroy'ed on close, as Engine.show() does.
- 650: event args no longer use JSON.stringify (no JSON global in XML
  event-handler expressions, so no request was ever sent); the panels'
  getP13nData() travels as is and a small printer reproduces the
  original's JSON.stringify(..., null, '  ') output.
- 651: static VariantItems instead of a bound template (on 1.152 the
  favourites list filtered every item away); renames and favourite/execute
  changes travel with the manage event.
- 644: a new view is 'View ' + (views + 1), as the original counts the
  container's own default view.
- LIVE_TESTs of 639/640/642/645/648/649/650/651 closed - all 12 touched
  ports green on a rebuilt backend.
- Interaction modules of 351/353/demo_004 compare origins instead of
  naming port 3000, so they pass under --port.
- e2e-debugging guide records the lessons.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PTMAfPJZ78qd9zmLoHGZwx
@oblomov-dev
oblomov-dev merged commit 174d274 into main Oct 21, 2026
22 of 23 checks passed
@oblomov-dev
oblomov-dev deleted the claude/festive-brown-66e47b branch October 21, 2026 14:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants