The group sheet's add handler (XWikiGroupSheet) and the live data delete action (DisplayerActions.vue) both display the success notification right after starting the members live data reload (updateEntries()), not after it completes. GroupEditPage#addMembersToGroup and GroupEditPage#removeMembers only waited for that notification, and TableLayoutElement#assertRow doesn't wait at all. So the test could read the members table before the reload finished. This shows up in two ways:
The add side, as in the description: after addUsers(alice).addGroups(backEndDevs), the table still held the rows from before the second add (Alice, Bob, frontEndDevs, no backEndDevs).
The remove side: in removeMembers, the next getRows() read rows that the reload from the previous removal replaced moments later, giving StaleElementReferenceException in GroupEditPage.getRowUserName. This was seen on CI in https://community.develocity.cloud/s/h6wgbd6zzcefc (master build 8781, editGroup line 192, removeMembers(alice, backEndDevs)) and once locally.
The product doesn't lose any add (each add is its own POST, and the following member count check of 4 passes whenever the table assertion does), so only the test wait was wrong.
Fix
GroupEditPage now waits for the success notification and then for the members live data to be ready (TableLayoutElement#waitUntilReady()), after each add and each remove. This wait cannot pass early: updateEntries() fires beforeEntryFetch synchronously, which puts the live data loader in its waiting state. That happens in the same JS task as, and before, the notification is created. So whenever WebDriver can see the notification, the loader is already waiting, and waitUntilReady() blocks until the fetch is over and the cells are rendered.
Verification
AllIT$NestedUsersGroupsRightsManagementIT (HSQLDB, Tomcat, Firefox): passed 3 times in a row, 19/19 each time.
Checkstyle on the page objects module: no violations.
CI history since 2026-01-01: editGroup failed 4 times out of 1969 runs. 3 of those were class-wide failures in GroupsPage.gotoPage (unrelated), and 1 was this race.
This message was sent by Atlassian Jira (v9.3.0#930000-sha1:287aeb6)
If image attachments aren't displayed, see this article.