[Resolved] CM6 failing unit test 'cross large line widgets' on macOS/Chrome

With macOS 10.13.6 (High Sierra), and an up to date Google Chrome browser, there is a single CodeMirror6 view/test that fails … sometimes.

The test code is

it(“can cross large line widgets during line motion”, function () {
var cm = tempEditor(“one\ntwo”, [ViewField.decorations({
create: function () {
return Decoration.set([
Decoration.widget(3, { widget: new BigWidget(undefined), side: 1, block: true }),
Decoration.widget(4, { widget: new BigWidget(undefined), side: -1, block: true })
update: function (deco) { return deco; }
ist_1(cm.contentDOM.offsetHeight, 400, “>”);
ist_1(cm.movePos(0, “forward”, “line”), 4);
ist_1(cm.movePos(2, “forward”, “line”), 6);
ist_1(cm.movePos(3, “forward”, “line”), 7);
ist_1(cm.movePos(4, “backward”, “line”), 0);
ist_1(cm.movePos(5, “backward”, “line”), 1);
ist_1(cm.movePos(7, “backward”, “line”), 3);

The particular line that is failing is in bold. It is the first call to movePos that tests the backward motion. The expected value is 0, but when this fails, the value returned by movePos is 3.

Most odd though is that this sometimes passes in the same OS and browser today.

When I first observed the problem, the test was served with a simple python file server. When I switched to loading the index.html file using file:/// from the Chrome search bar, the problem was also there, same test failing, same message about 3 != 0. But now for the past hour or more, this test case is only failing for the python server case and it is passing for the direct loaded file case. I have ensured caching is disabled and I have manually changed the expected response from 0, to 3, and ascertained that the page and it’s test does return a different value depending on how the page is loaded.

So does this point to a bug in the Chrome browser or is there some uninitialized data possible in the javascript code that could sometimes yield one answer or the other?

Short of other ideas, I may whittle down the test_built.js file first to see how small it can be made and still show the inconsistency.

It seems Adrian had the same issue when he logged #71. I suspect this test depends on window size or some similar non-controlled factor in some way, but I haven’t been able to get it to fail yet, so I’m not sure.

Yes, it looks like the same problem.

In the same Chrome window on my mac, one tab was loading from localhost:8000 and the test in question was failing, but another tab in the same window (so same size), was loading the page from the local file system and working. Repeatedly. Even if I swapped the positions of the tabs and even if I resized the window to be very large and very small. This from a Chrome app that had been open for weeks.

I then closed all my Chrome windows and restarted the Chrome process and now I have two tabs open like before but now both show the test in question failing. Also, regardless of the window size.

I was hoping to have one version that worked and one that didn’t but with both Chrome tabs failing the unit test, I started up Firefox on macOS. With Firefox it works.

And now I have found a piece of code that if commented out, gets the Chrome run tests to pass. Trying not to be confusing about things, the same commented out code still allows the test to pass on Firefox too.

In function posAtCoords():

Firefox has the function root.caretPositionFromPoint and calls it with x,y values
of 4 and 21.199996948242188, and gets the expected offset response of 0.

Chrome doesn’t have this property but it does have root.caretRangeFromPoint and calls it with x,y values
of 4 and 21, but gets the undesired offset back of 3. Hardcoding the use of the other y value in the Chrome case didn’t make any difference; still the wrong offset is returned.

But if the small block of code is completely commented out so neither caret*FromPoint function is called, and the logic falls through to a manual (potentially expensive) search, but come up with the expected offset of 0.

So have to understand what this root.caretRangeFromPoint function is doing and why in the backward case of a large line widget, it is not returning the expected offset. Also why it worked in one of my Chrome tabs the other day is still a mystery too.

I managed to reproduce it (Chrome with devtools closed) this time, and have pushed a patch that should fix it. (But let me know if it doesn’t for you.)

Yes, this does fix it. All the view/test cases (113) pass on Chrome on my macOS now.

All still pass with Firefox. This patch fixes the same test case that had been failing on Safari too.