Analysis based on two Claude Code sessions with Opus 5 first and then a later session with Opus 5.5:
Summary
org.xwiki.realtime.wysiwyg.test.ui.AllIT$NestedRealtimeWYSIWYGEditorIT#dragAndDropFilesAtTheSameTime fails regularly on CI, on every branch. Over the 28 days from 2026-08-25 to 2026-09-22 it ran 559 times and failed 94 times (16.8%), but those failures are seven distinct problems, only one of which is a genuine flicker of this test:
Not this test. master only, 2026-09-04 to 2026-09-14, the wholeRealtimeWYSIWYGEditorIT class failed in those builds (median 27 other test failures per build). Gone since 2026-09-14.
F2/F3 - the test waits for a state that has already expired
dropFile(path, false) calls waitUntilWidgetSelected(), which polls the edited content for the cke_widget_selected CSS class. That state is transient: as soon as the upload completes, xwiki-upload's overrideUploadWidget replaces the upload widget with the final <a>/<img>, and cke_widget_selected is gone for good.
The content is polled every 500 ms, and RealtimeRichTextAreaElement.repeatedWait retries that 5 times for 2 s each. If a single poll gap straddles the widget's whole lifetime, the wait can never succeed and burns the full 10 s (switching browser tabs 4 times for nothing).
Evidence, from the REALTIME_DEBUG dump of build master#1381 (2026-09-22 01:12, chrome / mysql latest / tomcat 11-jdk25), second tab:
01:52:15.300 Push local content: ... ["P",["second ", SPAN.xwiki-widget-placeholder-uploadfile]] <- drop processed
01:52:15.570 Push local content: ... ["P",["second ", <attach link source-button.mp4>]] <- upload finished
01:52:16.067 (last remote content received)
01:52:17.6 .. 01:52:27.7 only Saver heartbeats - the test polled for 10 s, then gave up
The upload widget existed for 270 ms (377 ms for the first tab in the same run). No Received remote content happened in between, so nothing remote disturbed the widget: the local upload simply finished faster than the poller looked. The archived screenshot confirms it - source-button.mp4 is already a finished, selected attachment link with the link balloon open.
This also explains why 28 of the 29 occurrences are on Chrome: Chrome finishes these uploads faster than the poll interval more often. The mysql latest / tomcat 11-jdk25 / jdk25 correlations are just where Chrome runs.
Fix
Stop polling the DOM for an expiring state, and latch the event in the browser instead. The script that dispatches the drop in RichTextAreaElement.dropFile(WebElement) now also registers a one-shot editor.widgets.on('instanceCreated') listener for the uploadfile/uploadimage widgets and, from it, widget.once('select', ...), which sets a flag on the editor instance:
dropFile then waits on that flag, which stays set after the upload finishes. The public waitUntilWidgetSelected() is unchanged - its other callers (ImageIT, MacroIT) wait on widget selections that are not transient.
Validation
F2 does not reproduce locally, because local WebDriver round trips are about 10 ms, so the first poll always lands inside the widget's ~300 ms lifetime. Injecting a temporary 1 s sleep right after the drop is dispatched stands in for CI's slower first look:
Variant
Result
current code + 1 s delay
3/3 fail inside dropFile, with exactly the CI stack trace
fixed code + 1 s delay
3/3 pass
current code, 15 repetitions, no delay
6 pass / 9 fail - 7 x F4, 2 x F5, 0 inside dropFile
fixed code, 15 repetitions, no delay
5 pass / 10 fail - 6 x F4, 2 x F5, 2 x F6, 0 inside dropFile
Other failures of this test
F4, F5 and F6 are caused by realtime synchronization bugs that also affect users, not by the test. They are tracked separately in XWIKI-25071. With the fixes from both issues the test passed 15 times out of 15 locally on Chrome and on Firefox (versus 10 failures out of 15 with only the test fix).
How to reproduce locally
Temporarily turn the test into a @RepeatedTest(15) (the environment startup dominates: about 3.5 min per Maven run versus about 20 s per repetition), then:
Group the failures by the line number of the deepest RealtimeWYSIWYGEditorIT stack frame - several distinct races hide behind this one test. On CI, the RealtimeTestDebugger output (browser console logs plus window.REALTIME_DEBUG) is in the Jenkins console log, not in the archived artifacts.
This message was sent by Atlassian Jira (v9.3.0#930000-sha1:287aeb6)
If image attachments aren't displayed, see this article.