11import { test , expect } from '../../fixtures/superdoc.js' ;
2- import { addCommentByText , assertDocumentApiReady , listComments } from '../../helpers/document-api.js' ;
2+ import { addCommentByText , assertDocumentApiReady } from '../../helpers/document-api.js' ;
33
44/**
55 * SD-1963: Decoration range incorrectly expands to run boundaries;
@@ -22,29 +22,25 @@ test.describe('comment highlight survives mark changes', () => {
2222 await superdoc . waitForStable ( ) ;
2323
2424 // Add a comment on "brown fox"
25- const commentId = await addCommentByText ( superdoc . page , {
25+ await addCommentByText ( superdoc . page , {
2626 pattern : 'brown fox' ,
2727 text : 'Comment on brown fox' ,
2828 } ) ;
2929 await superdoc . waitForStable ( ) ;
3030
31- // Verify comment highlight exists
32- await superdoc . assertCommentHighlightExists ( {
33- text : 'brown fox' ,
34- commentId,
35- timeoutMs : 20_000 ,
36- } ) ;
31+ // Verify comment mark exists in PM state (avoids slow DOM highlight polling on WebKit)
32+ let pos = await superdoc . findTextPos ( 'brown fox' ) ;
33+ await superdoc . assertMarksAtPos ( pos , [ 'commentMark' ] ) ;
3734
3835 // Select "brown fox" and apply bold
39- const pos = await superdoc . findTextPos ( 'brown fox' ) ;
36+ pos = await superdoc . findTextPos ( 'brown fox' ) ;
4037 await superdoc . setTextSelection ( pos , pos + 'brown fox' . length ) ;
4138 await superdoc . bold ( ) ;
4239 await superdoc . waitForStable ( ) ;
4340
44- // Comment highlight must still be present
45- await superdoc . assertCommentHighlightExists ( {
46- commentId,
47- } ) ;
41+ // Comment mark must still be present after applying bold
42+ pos = await superdoc . findTextPos ( 'brown fox' ) ;
43+ await superdoc . assertMarksAtPos ( pos , [ 'commentMark' ] ) ;
4844
4945 // Bold must have been applied
5046 await superdoc . assertTextHasMarks ( 'brown fox' , [ 'bold' ] ) ;
@@ -59,48 +55,28 @@ test.describe('comment highlight survives mark changes', () => {
5955 await superdoc . waitForStable ( ) ;
6056
6157 // Comment spans "quick brown fox"
62- const commentId = await addCommentByText ( superdoc . page , {
58+ await addCommentByText ( superdoc . page , {
6359 pattern : 'quick brown fox' ,
6460 text : 'Partial italic test' ,
6561 } ) ;
6662 await superdoc . waitForStable ( ) ;
67- await superdoc . assertCommentHighlightExists ( { text : 'quick brown fox' , commentId, timeoutMs : 20_000 } ) ;
63+
64+ // Verify comment mark exists in PM state (avoids slow DOM highlight polling on WebKit)
65+ let pos = await superdoc . findTextPos ( 'quick brown fox' ) ;
66+ await superdoc . assertMarksAtPos ( pos , [ 'commentMark' ] ) ;
6867
6968 // Apply italic to only "brown" (middle of the commented range)
70- const pos = await superdoc . findTextPos ( 'brown' ) ;
69+ pos = await superdoc . findTextPos ( 'brown' ) ;
7170 await superdoc . setTextSelection ( pos , pos + 'brown' . length ) ;
7271 await superdoc . italic ( ) ;
7372 await superdoc . waitForStable ( ) ;
7473
75- // Comment highlight must still exist — after the run split the highlight may
76- // span multiple elements, so check by commentId AND all text segments in a
77- // single poll to avoid multiplicative timeouts in slower engines (webkit).
78- await expect
79- . poll (
80- ( ) =>
81- superdoc . page . evaluate (
82- ( { cId } ) => {
83- const normalize = ( v : string ) => v . replace ( / \s + / g, ' ' ) . trim ( ) ;
84- const highlights = Array . from ( document . querySelectorAll ( '.superdoc-comment-highlight' ) ) ;
85- if ( highlights . length === 0 ) return 'no highlights' ;
86- const hasId = highlights . some ( ( el ) =>
87- ( el . getAttribute ( 'data-comment-ids' ) ?? '' )
88- . split ( / [ \s , ] + / )
89- . filter ( Boolean )
90- . includes ( cId ) ,
91- ) ;
92- if ( ! hasId ) return 'missing commentId' ;
93- const texts = highlights . map ( ( el ) => normalize ( el . textContent ?? '' ) ) ;
94- for ( const word of [ 'quick' , 'brown' , 'fox' ] ) {
95- if ( ! texts . some ( ( t ) => t . includes ( word ) ) ) return `missing "${ word } "` ;
96- }
97- return 'ok' ;
98- } ,
99- { cId : commentId } ,
100- ) ,
101- { timeout : 25_000 } ,
102- )
103- . toBe ( 'ok' ) ;
74+ // Comment mark must still exist on all segments after the run split.
75+ // After italic splits the range, check each word's PM node still has commentMark.
76+ for ( const word of [ 'quick' , 'brown' , 'fox' ] ) {
77+ const wordPos = await superdoc . findTextPos ( word ) ;
78+ await superdoc . assertMarksAtPos ( wordPos , [ 'commentMark' ] ) ;
79+ }
10480
10581 // Italic applied to "brown"
10682 await superdoc . assertTextHasMarks ( 'brown' , [ 'italic' ] ) ;
@@ -114,33 +90,39 @@ test.describe('comment highlight survives mark changes', () => {
11490 await superdoc . type ( 'Decoration resilience test sentence' ) ;
11591 await superdoc . waitForStable ( ) ;
11692
117- const commentId = await addCommentByText ( superdoc . page , {
93+ await addCommentByText ( superdoc . page , {
11894 pattern : 'resilience test' ,
11995 text : 'Multi-mark test' ,
12096 } ) ;
12197 await superdoc . waitForStable ( ) ;
122- await superdoc . assertCommentHighlightExists ( { text : 'resilience test' , commentId, timeoutMs : 20_000 } ) ;
98+
99+ // Verify comment mark exists in PM state (avoids slow DOM highlight polling on WebKit)
100+ let pos = await superdoc . findTextPos ( 'resilience test' ) ;
101+ await superdoc . assertMarksAtPos ( pos , [ 'commentMark' ] ) ;
123102
124103 // Apply bold, then italic, then underline to the same range.
125104 // Re-select between each mark because WebKit can disrupt DOM selection
126105 // after Cmd+B/I/U shortcuts, and PM may re-index positions after marks.
127- let pos = await superdoc . findTextPos ( 'resilience test' ) ;
106+ pos = await superdoc . findTextPos ( 'resilience test' ) ;
128107 await superdoc . setTextSelection ( pos , pos + 'resilience test' . length ) ;
129108 await superdoc . bold ( ) ;
130109 await superdoc . waitForStable ( ) ;
131- await superdoc . assertCommentHighlightExists ( { commentId } ) ;
110+ pos = await superdoc . findTextPos ( 'resilience test' ) ;
111+ await superdoc . assertMarksAtPos ( pos , [ 'commentMark' ] ) ;
132112
133113 pos = await superdoc . findTextPos ( 'resilience test' ) ;
134114 await superdoc . setTextSelection ( pos , pos + 'resilience test' . length ) ;
135115 await superdoc . italic ( ) ;
136116 await superdoc . waitForStable ( ) ;
137- await superdoc . assertCommentHighlightExists ( { commentId } ) ;
117+ pos = await superdoc . findTextPos ( 'resilience test' ) ;
118+ await superdoc . assertMarksAtPos ( pos , [ 'commentMark' ] ) ;
138119
139120 pos = await superdoc . findTextPos ( 'resilience test' ) ;
140121 await superdoc . setTextSelection ( pos , pos + 'resilience test' . length ) ;
141122 await superdoc . underline ( ) ;
142123 await superdoc . waitForStable ( ) ;
143- await superdoc . assertCommentHighlightExists ( { commentId } ) ;
124+ pos = await superdoc . findTextPos ( 'resilience test' ) ;
125+ await superdoc . assertMarksAtPos ( pos , [ 'commentMark' ] ) ;
144126
145127 // All three marks should be present
146128 await superdoc . assertTextHasMarks ( 'resilience test' , [ 'bold' , 'italic' , 'underline' ] ) ;
0 commit comments