Repository navigation
fix(monkey): recognise non-English sign-out controls, configurable per project (#469) - #481
Merged
Merged
Conversation
…r project (#469) SIGN_OUT matched English captions only, so a Dutch app's "Afmelden" was clicked, the monkey landed on login.html and scored a false CRASH. The default now covers nl/de/fr/es/pt/it captions, a project adds its own via project.config.js signOutPattern or SIGN_OUT_PATTERN, and rapidTab steps past a focused sign-out control instead of pressing Enter on it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VJgWP5vEoAsNsJYqCDMGNw
…ct flags (#469 review) The non-English words are ordinary verbs, so a word match left "Ziek afmelden", "Afmelden nieuwsbrief", "Vom Kurs abmelden" and "Disconnetti dispositivo" unfuzzed; they now match only as the whole caption, and the focus check tests text, aria-label and title one by one. A project RegExp keeps its flags (g/y dropped). The rapidTab static guard is scoped to that branch: the old one passed a blind-Enter mutation, the new one fails it. Fixture 22/22; 8 FAIL on master, 3 on the previous head. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VJgWP5vEoAsNsJYqCDMGNw
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VJgWP5vEoAsNsJYqCDMGNw
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VJgWP5vEoAsNsJYqCDMGNw
MendixMau
added a commit
that referenced
this pull request
Oct 20, 2026
Merges six independently reviewed bug fixes. Each was MERGE after one fix round. - #486 progress-report nav (#479 items 1-3) - #480 conformance-check (#470) - #482 page-fidelity popup (#471) - #481 monkey sign-out i18n (#469) - #484 bare $VAR before non-ASCII (#467) - #485 \t in sed/grep brackets (#468) Verified on the integrated tree: - check-scripts, check-portability, render-routing --check, pr-discipline and the leak guard are clean. - progress-report polish 53, field-fixes 105 and pages 54 pass. - conformance-absent-marker 24, monkey-left-app 22, page-fidelity-mocks 78, status-bare-var 3, sed-tab-bracket 9, context-pack 55 and bug03-gates 47 pass. Field runs on real projects are owed by the maintainer. Fixes #479 items 1-3, #470, #471, #469, #467, #468.
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.
Fixes #469
Direct lane (changes to
skills/,bug-logs/,bin/,project-bin/,project-tests/, pipelines)What changed and why (one paragraph):
project-tests/e2e/monkey.jsexcluded sign-out controls with/\b(sign|log)\s*(out|off)\b/i, which is English only. In a Dutch app the monkey clicked Afmelden, landed onlogin.html, scoredCRASH 'blank page — no .mx-page or nav tree'and fuzzed nothing more. This PR follows the issue's suggestion: a multilingual default plus a project-configurable pattern.SIGN_OUTnow also matches common sign-out captions in Dutch (afmelden,uitloggen), German (abmelden,ausloggen), French (se déconnecter,déconnexion), Spanish (cerrar sesión), Portuguese (terminar/encerrar sessão) and Italian (disconnetti). These match as the whole caption only (^\s*(?:…)\s*$), because they are also ordinary verbs: "Ziek afmelden", "Afmelden nieuwsbrief", "Vom Kurs abmelden" and "Disconnetti dispositivo" stay fuzzable, and so do sign-in captions (Aanmelden,Inloggen,Anmelden,Se connecter). The issue lists no variants such as "nu afmelden", so none were added. The English phrase keeps its old word match.project.config.jssignOutPattern(a RegExp or a regex string) or theSIGN_OUT_PATTERNenv var, read throughconfig.jsascfg.signOutPattern. The project pattern is added to the default, never a replacement. A project RegExp keeps its own flags, merged withi;gandyare dropped because they make.test()stateful. An invalid pattern prints a warning and falls back to the default. The template declaressignOutPattern: null, so an olderproject.config.jswithout the key keeps working.rapidTabno longer presses Enter blind. After its 15 Tabs it reads the focused element's text,aria-labelandtitle, and tests each one on its own (isSignOutLabel, exported and unit-tested). If that is a sign-out control, it presses Tab again (at most 5 times), and skips Enter, saying so in the observation, if focus is still on one. This is how a sign-out in the layout's top bar or in a nav item, both outside.mx-page, was reached. The button locator only offers.mx-pagebuttons, so the keyboard was the only path to them.Golden input: the captions are the issue's own, verbatim:
Afmelden(clicked in the field run),Uitloggen,Abmelden,Se déconnecter. The fixture keeps the captured English ones from the 2026-09-26 run.Field evidence (rule 4):
Reported by jopterhorst:
monkey.js --rounds 24 --seed 204262061on a Dutch-UI app gave 3 observations and 1 crash-class, all from the sign-out. The reporter's local workaround (the same two Dutch words plus a Tab-past inrapidTab) gave 24 observations and 0 crash-class on the same seed. This PR is that workaround, generalised. Owed by the maintainer: a re-run of that seed against a non-English app. The author session had no running Mendix app, so the browser path (focusIsSignOut) is verified by its static guard and bynode --check, not by a live run.Impact
project-tests/e2e/config.jsgains one optional key, read bymonkey.jsonly. Its producer isproject.config.js, fromproject.config.template.js(which now declares it asnull) atinstall-tests.shtime, or the env. A missing key means the default. No new tools. No ordering constraint against #470/#471/#477 beyond a trivialCHANGELOG.mdline merge.bin/render-routing.sh --checkclean).page.evaluateperrapidTabround, plus at most 5 more when focus sits on a sign-out control. Each is milliseconds, against the round's fixed 1.8 s settle./Users/and/home/user: 0 hits;LEAKGUARD_ALLOW_NO_DENYLIST=1 bin/check-no-client-data.shclean)tests/wave2/test-monkey-left-app.sh project-tests/e2e/monkey.jsgives 22/22. New cases: the issue's captions, sign-in near-misses, the four over-match captions, a padded whole caption, a project RegExp and a project string, the RegExp's own flags, a project pattern adding to the default, an invalid or absent pattern, per-label focus testing, config/template plumbing, and the rapidTab focus check. On master'smonkey.jsit gives 9 FAIL; on this PR's first head (8427edc), 3 FAIL. The rapidTab static guard is now scoped to the rapidTab branch, because the old one also matched the ABUSES list and the function definition. Mutation check: with the rapidTab branch replaced by a blindpress('Enter'), the new guard FAILs and the old one passed.test-journey-preflight.sh(loads the sameconfig.js) gives 75/0.bin/check-scripts.sh,bin/check-portability.sh,bin/render-routing.sh --checkandbin/check-pr-discipline.sh origin/masterare clean.tests/e2e/under a project root). Platforms: pure Node regex and Playwright calls; no shell-outs added.CHANGELOG.mdline appended, crediting jopterhorstLeft open: the issue also suggested detecting sign-out by the button's action instead of its caption. I did not do that here. Mendix renders a
Forms$LogoutButton, but I could not confirm the DOM class or attribute it carries without a running app, and guessing a selector is the imagined-input failure the field-proof rule warns about. An icon-only sign-out button inside.mx-pagethat has no caption is still offered to the button picker, because thehasNotTextfilter sees text only.rapidTabdoes catch such a control through itsaria-label/title.https://claude.ai/code/session_01VJgWP5vEoAsNsJYqCDMGNw
Generated by Claude Code