Skip to content

fix(tests): EdmView.regenerate waits for generated sources, not the transient toast#6127

Merged
delchev merged 1 commit into
masterfrom
fix/edm-regenerate-toast-flake
Jul 3, 2026
Merged

fix(tests): EdmView.regenerate waits for generated sources, not the transient toast#6127
delchev merged 1 commit into
masterfrom
fix/edm-regenerate-toast-flake

Conversation

@delchev

@delchev delchev commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

What

DependsOnIT has been failing flakily on CI — including on master (the fix(pdf) merge run) — while the generation it tests actually succeeds.

Evidence from the failure screenshots: the status bar shows "Generated from model 'edm.model'" and the gen folder is already in the project tree — the exact text the assertion looks for is on screen. The cross-frame text sweep times out anyway (a runner-side Selenium "Failed to establish BiDi connection" error accompanies the failures), and the sweep's timeout fallback reloads the page, destroying the transient toast so the retry can never succeed.

Fix

EdmView.regenerate now waits for the durable effect — the generated sources landing in the workspace project's gen folder, polled through IRepository with Awaitility (the same approach IntentEditorLoadsIT uses) — instead of the transient toast.

Verified locally: DependsOnIT passes in 69s with the change.

Merging this unblocks the failing integration-tests-* jobs on master, #6125 and #6126.

🤖 Generated with Claude Code

…he transient toast

DependsOnIT (and every PredefinedProjectIT generating from an EDM) asserted
the "Generated from model" success toast via a cross-frame text sweep. On
slow CI runners the sweep can outlast the toast, and its timeout fallback
RELOADS the page - destroying the toast for good, so the retry can never
succeed. Failure screenshots showed the toast on screen and the gen folder
already created while the assertion still failed; the flake hit master too
(fails alongside a runner-side Selenium "Failed to establish BiDi
connection" error that slows/breaks the frame iteration).

Wait for the durable effect instead: the generated sources landing in the
workspace project's gen folder, polled through IRepository (the same
approach IntentEditorLoadsIT uses).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@delchev delchev merged commit 1b1ba16 into master Jul 3, 2026
12 checks passed
@delchev delchev deleted the fix/edm-regenerate-toast-flake branch July 3, 2026 06:44
delchev added a commit that referenced this pull request Jul 3, 2026
integration-tests-postgresql failed DependsOnIT at
PredefinedProjectIT.test:28 - the 'Published all projects in' toast was
not found in any iframe. Same failure mode as the regenerate-toast flake
fixed in EdmView (#6127): on slow CI runners the Selenide cross-frame
text sweep outlasts the transient toast, and the sweep's timeout
fallback reloads the page, destroying the toast for good while the
publish itself succeeded.

Workbench.publishAll now waits for the DURABLE effect - every workspace
project appearing under /registry/public - via IRepository + Awaitility,
then proceeds to the existing synchronization wait.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
delchev added a commit that referenced this pull request Jul 3, 2026
…mplates (#6129)

* fix(harmonia): print language dialog must always show for multiple templates

The multilingual feature made openPrint auto-print the configured Region &
Language when a template for it exists. The locale store ALWAYS resolves to
a value (en by default, even untouched), so with 2+ templates the language
dialog became unreachable - uploading a bg template gave no way to pick it.

Several templates now ALWAYS open the dialog; the configured language is
only pre-sorted first as the suggested default. Single/zero template
behavior unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(harmonia): report.js integer fallback pattern broke Velocity parsing

The pattern-less numeric fallback used the DecimalFormat literal '##0'
inside the Velocity-rendered report.js.template. Velocity treats two
hashes as a line comment, so it swallowed the rest of the line including
the closing quote - the generated report.js carried an unterminated
string, failed to parse, reportPage never registered, and every report
page rendered blank with Alpine expression errors.

'0' formats identically in displayNumber (0 decimals, no grouping) and
carries no Velocity-significant characters.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* feat(application-shell): Region & Language picker in the shared shell Settings

The picker previously existed only in each generated app's own Settings
page (and only when that app's intent declares 2+ languages), so the
shared application shell at /services/web/application/ had no visible
place to switch the data language. The shell's Settings master pane now
offers the same Region & Language select, backed by the shared locale
store (localStorage codbex.harmonia.language, sent as Accept-Language
by every app's fetch client). The offered codes are the union of the
languages the embedded apps declare in their generated js/config.js
(read with a targeted match - the config is a JS file); hidden while
only one language is known.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* refactor(i18n): the supported language set is a platform concern, not per module

The Region & Language design was inverted: each module's intent declared
what languages the picker offers, so an app declaring only 'en' hid the
picker and a 5-language module next to an en-only one could not work.
Corrected contract:

- The PLATFORM defines the supported set: DIRIGIBLE_APPLICATION_LANGUAGES
  (DirigibleConfig + Configuration allow-list), default 'en,bg', served by
  the new platform-core/services/application-languages.js.
- The shared locale store fetches that set; every Region & Language picker
  (shared application shell + generated per-app Settings) always offers
  exactly the platform set.
- A module's intent 'languages:' only declares which languages it PROVIDES
  translations for (config.js semantics reworded accordingly). Untranslated
  content falls back to the default language naturally (the Translator
  overlays only existing _LANG rows).
- The shared application shell's Settings lists every module missing a
  platform language as a visible warning - the developers' to-do list for
  adding translation content.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* feat(application-shell): Region & Language as a Settings list item with a detail page

Instead of an inline picker above the settings list, Region & Language is
now a built-in entry in the Settings master list (globe icon, selectable
like the app-provided setting entities). Selecting it renders a local
detail page in the right pane: description of the platform-wide language
preference, the language select (the platform's supported set), and the
missing-translations warnings per module. Deep-linkable as
#/settings/region-language via the pseudo setting item.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* feat(harmonia): UI-label i18n reusing the platform i18next stack

The generated Harmonia views baked English labels as literals, so
switching Region & Language translated only the data, never the UI.
Labels now translate by REUSING the AngularJS stack's i18n backbone
end-to-end - nothing new server-side:

- i18next (the existing webjar), the locales.js extension service that
  aggregates every project's translations/<locale>/*.json from the
  registry, the platform-locales + application-locales locale registry,
  and the same catalogs/keys the 'translate' generation action already
  emits (namespace = project, path = <tprefix>.t.<DATA_NAME> /
  .defaults.* / .messages.*).
- New shared consumer application-core shell/js/services/i18n.js:
  self-loads i18next, fetches the catalogs (all registered locales, own
  project namespace), resolves the 2-letter platform code to a locale id
  (en -> en-US), exposes a reactive Alpine 'i18n' store + global
  T(key, fallback, options). In the default language the baked literal
  always wins (it is the prettier authored label); in other languages a
  missing key degrades per-key to the English literal. locale.set()
  reloads the page so labels and data switch together.
- All generated view templates (manage list/form, document, master,
  list, shell sidebar/dashboard/settings, detail registry metadata via
  tkey) bind labels as T('<project>:<tprefix>...', 'Fallback') - keys
  identical to the AngularJS stack, so one translations/<locale> folder
  serves both stacks. translations.json.template gains the few keys the
  Harmonia views need beyond the AngularJS set (new/retry/all/
  clearFilters/previous/next/details/selectTitle/back/backToList,
  noDataYet/getStarted/inputSelect, error.saving).

Verified by generating the multi-model sales-invoices model through the
updated templates: all 67 files render, every generated JS parses, keys
and fallbacks correct; the locales service returns the bg-BG catalogs
(project translations/bg-BG/*.json) with English (US) fallback.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(tests): publishAll waits for the registry, not the publish toast

integration-tests-postgresql failed DependsOnIT at
PredefinedProjectIT.test:28 - the 'Published all projects in' toast was
not found in any iframe. Same failure mode as the regenerate-toast flake
fixed in EdmView (#6127): on slow CI runners the Selenide cross-frame
text sweep outlasts the transient toast, and the sweep's timeout
fallback reloads the page, destroying the toast for good while the
publish itself succeeded.

Workbench.publishAll now waits for the DURABLE effect - every workspace
project appearing under /registry/public - via IRepository + Awaitility,
then proceeds to the existing synchronization wait.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* feat(harmonia): translate the shell chrome - sidebar, Inbox, Documents, Dashboard, Settings

The generated per-project shell and the shared application shell now
translate their own chrome, completing the label-i18n story: sidebar
entries and section headings (Application/Entities/Reports/Other),
built-in Inbox / Documents / Dashboard / Settings / Reports / not-found
pages, notifications popover, user menu, and breadcrumb Create/Edit.

The platform ships its own catalog pair: application-core/translations/
{en-US,bg-BG}/shell.json (namespace 'application-core', root 'shell') -
the locales.js service aggregates any registry module's translations
folder, so no service change was needed. i18n.js now always requests the
'application-core' namespace alongside the hosting app's project
namespace. Adding a platform language = adding one shell.json file.

Backward safety: apps generated before label i18n load the shared views
(which now bind through T()) without services/i18n.js - the always-loaded
shared app.js defines a fallback-returning T() stub that i18n.js
overwrites, so old apps keep rendering English instead of throwing.

Verified: locales service returns the bg shell catalog (nav.inbox =
'Входящи'); smoke generation over the updated shell templates renders
all chrome keys with English fallbacks and every generated JS parses.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
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.

1 participant