59.8 KB1630 lines
Blame
1import { imgSnapshotTest, renderGraph } from '../../helpers/util.ts';
2
3const looks = ['classic'];
4const participantTypes = [
5 { type: 'participant', display: 'participant' },
6 { type: 'actor', display: 'actor' },
7 { type: 'boundary', display: 'boundary' },
8 { type: 'control', display: 'control' },
9 { type: 'entity', display: 'entity' },
10 { type: 'database', display: 'database' },
11 { type: 'collections', display: 'collections' },
12 { type: 'queue', display: 'queue' },
13];
14
15const restrictedTypes = ['boundary', 'control', 'entity', 'database', 'collections', 'queue'];
16
17const interactionTypes = ['->>', '-->>', '->', '-->', '-x', '--x', '->>+', '-->>+'];
18
19const notePositions = ['left of', 'right of', 'over'];
20
21function getParticipantLine(name, type, alias) {
22 if (restrictedTypes.includes(type)) {
23 return ` participant ${name}@{ "type" : "${type}" }\n`;
24 } else if (alias) {
25 return ` participant ${name}@{ "type" : "${type}" } \n`;
26 } else {
27 return ` participant ${name}@{ "type" : "${type}" }\n`;
28 }
29}
30
31looks.forEach((look) => {
32 describe(`Sequence Diagram Tests - ${look} look`, () => {
33 it('should render all participant types', () => {
34 let diagramCode = `sequenceDiagram\n`;
35 participantTypes.forEach((pt, index) => {
36 const name = `${pt.display}${index}`;
37 diagramCode += getParticipantLine(name, pt.type);
38 });
39 for (let i = 0; i < participantTypes.length - 1; i++) {
40 diagramCode += ` ${participantTypes[i].display}${i} ->> ${participantTypes[i + 1].display}${i + 1}: Message ${i}\n`;
41 }
42 imgSnapshotTest(diagramCode, { look, sequence: { diagramMarginX: 50, diagramMarginY: 10 } });
43 });
44
45 it('should render all interaction types', () => {
46 let diagramCode = `sequenceDiagram\n`;
47 diagramCode += getParticipantLine('A', 'actor');
48 diagramCode += getParticipantLine('B', 'boundary');
49 interactionTypes.forEach((interaction, index) => {
50 diagramCode += ` A ${interaction} B: ${interaction} message ${index}\n`;
51 });
52 imgSnapshotTest(diagramCode, { look });
53 });
54
55 it('should render participant creation and destruction', () => {
56 let diagramCode = `sequenceDiagram\n`;
57 participantTypes.forEach((pt, index) => {
58 const name = `${pt.display}${index}`;
59 diagramCode += getParticipantLine('A', pt.type);
60 diagramCode += getParticipantLine('B', pt.type);
61 diagramCode += ` create participant ${name}@{ "type" : "${pt.type}" }\n`;
62 diagramCode += ` A ->> ${name}: Hello ${pt.display}\n`;
63 if (index % 2 === 0) {
64 diagramCode += ` destroy ${name}\n`;
65 }
66 });
67 imgSnapshotTest(diagramCode, { look });
68 });
69
70 it('should render notes in all positions', () => {
71 let diagramCode = `sequenceDiagram\n`;
72 diagramCode += getParticipantLine('A', 'actor');
73 diagramCode += getParticipantLine('B', 'boundary');
74 notePositions.forEach((position, index) => {
75 diagramCode += ` Note ${position} A: Note ${position} ${index}\n`;
76 });
77 diagramCode += ` A ->> B: Message with notes\n`;
78 imgSnapshotTest(diagramCode, { look });
79 });
80
81 it('should render parallel interactions', () => {
82 let diagramCode = `sequenceDiagram\n`;
83 participantTypes.slice(0, 4).forEach((pt, index) => {
84 diagramCode += getParticipantLine(`${pt.display}${index}`, pt.type);
85 });
86 diagramCode += ` par Parallel actions\n`;
87 for (let i = 0; i < 3; i += 2) {
88 diagramCode += ` ${participantTypes[i].display}${i} ->> ${participantTypes[i + 1].display}${i + 1}: Message ${i}\n`;
89 if (i < participantTypes.length - 2) {
90 diagramCode += ` and\n`;
91 }
92 }
93 diagramCode += ` end\n`;
94 imgSnapshotTest(diagramCode, { look });
95 });
96
97 it('should render alternative flows', () => {
98 let diagramCode = `sequenceDiagram\n`;
99 diagramCode += getParticipantLine('A', 'actor');
100 diagramCode += getParticipantLine('B', 'boundary');
101 diagramCode += ` alt Successful case\n`;
102 diagramCode += ` A ->> B: Request\n`;
103 diagramCode += ` B -->> A: Success\n`;
104 diagramCode += ` else Failure case\n`;
105 diagramCode += ` A ->> B: Request\n`;
106 diagramCode += ` B --x A: Failure\n`;
107 diagramCode += ` end\n`;
108 imgSnapshotTest(diagramCode, { look });
109 });
110
111 it('should render loops', () => {
112 let diagramCode = `sequenceDiagram\n`;
113 participantTypes.slice(0, 3).forEach((pt, index) => {
114 diagramCode += getParticipantLine(`${pt.display}${index}`, pt.type);
115 });
116 diagramCode += ` loop For each participant\n`;
117 for (let i = 0; i < 3; i++) {
118 diagramCode += ` ${participantTypes[0].display}0 ->> ${participantTypes[1].display}1: Message ${i}\n`;
119 }
120 diagramCode += ` end\n`;
121 imgSnapshotTest(diagramCode, { look });
122 });
123
124 it('should render boxes around groups', () => {
125 let diagramCode = `sequenceDiagram\n`;
126 diagramCode += ` box Group 1\n`;
127 participantTypes.slice(0, 3).forEach((pt, index) => {
128 diagramCode += ` ${getParticipantLine(`${pt.display}${index}`, pt.type)}`;
129 });
130 diagramCode += ` end\n`;
131 diagramCode += ` box rgb(200,220,255) Group 2\n`;
132 participantTypes.slice(3, 6).forEach((pt, index) => {
133 diagramCode += ` ${getParticipantLine(`${pt.display}${index}`, pt.type)}`;
134 });
135 diagramCode += ` end\n`;
136 diagramCode += ` ${participantTypes[0].display}0 ->> ${participantTypes[3].display}0: Cross-group message\n`;
137 imgSnapshotTest(diagramCode, { look });
138 });
139
140 it('should render with different font settings', () => {
141 let diagramCode = `sequenceDiagram\n`;
142 participantTypes.slice(0, 3).forEach((pt, index) => {
143 diagramCode += getParticipantLine(`${pt.display}${index}`, pt.type);
144 });
145 diagramCode += ` ${participantTypes[0].display}0 ->> ${participantTypes[1].display}1: Regular message\n`;
146 diagramCode += ` Note right of ${participantTypes[1].display}1: Regular note\n`;
147 imgSnapshotTest(diagramCode, {
148 look,
149 sequence: {
150 actorFontFamily: 'courier',
151 actorFontSize: 14,
152 messageFontFamily: 'Arial',
153 messageFontSize: 12,
154 noteFontFamily: 'times',
155 noteFontSize: 16,
156 noteAlign: 'left',
157 },
158 });
159 });
160 });
161});
162
163// Additional tests for specific combinations
164describe('Sequence Diagram Special Cases', () => {
165 it('should render complex sequence with all features', () => {
166 const diagramCode = `
167 sequenceDiagram
168 box rgb(200,220,255) Authentication
169 actor User
170 participant LoginUI@{ "type": "boundary" }
171 participant AuthService@{ "type": "control" }
172 participant UserDB@{ "type": "database" }
173 end
174
175 box rgb(200,255,220) Order Processing
176 participant Order@{ "type": "entity" }
177 participant OrderQueue@{ "type": "queue" }
178 participant AuditLogs@{ "type": "collections" }
179 end
180
181 User ->> LoginUI: Enter credentials
182 LoginUI ->> AuthService: Validate
183 AuthService ->> UserDB: Query user
184 UserDB -->> AuthService: User data
185 alt Valid credentials
186 AuthService -->> LoginUI: Success
187 LoginUI -->> User: Welcome
188
189 par Place order
190 User ->> Order: New order
191 Order ->> OrderQueue: Process
192 and
193 Order ->> AuditLogs: Record
194 end
195
196 loop Until confirmed
197 OrderQueue ->> Order: Update status
198 Order -->> User: Notification
199 end
200 else Invalid credentials
201 AuthService --x LoginUI: Failure
202 LoginUI --x User: Retry
203 end
204 `;
205 imgSnapshotTest(diagramCode, {});
206 });
207
208 it('should render with wrapped messages and notes', () => {
209 const diagramCode = `
210 sequenceDiagram
211 participant A
212 participant B
213
214 A ->> B: This is a very long message that should wrap properly in the diagram rendering
215 Note over A,B: This is a very long note that should also wrap properly when rendered in the diagram
216
217 par Wrapped parallel
218 A ->> B: Parallel message 1<br>with explicit line break
219 and
220 B ->> A: Parallel message 2<br>with explicit line break
221 end
222
223 loop Wrapped loop
224 Note right of B: This is a long note<br>in a loop
225 A ->> B: Message in loop
226 end
227 `;
228 imgSnapshotTest(diagramCode, { sequence: { wrap: true } });
229 });
230 describe('Sequence Diagram Rendering with Different Participant Types', () => {
231 it('should render a sequence diagram with various participant types', () => {
232 imgSnapshotTest(
233 `
234 sequenceDiagram
235 participant User@{ "type": "actor" }
236 participant AuthService@{ "type": "control" }
237 participant UI@{ "type": "boundary" }
238 participant OrderController@{ "type": "control" }
239 participant Product@{ "type": "entity" }
240 participant MongoDB@{ "type": "database" }
241 participant Products@{ "type": "collections" }
242 participant OrderQueue@{ "type": "queue" }
243 User ->> UI: Login request
244 UI ->> AuthService: Validate credentials
245 AuthService -->> UI: Authentication token
246 UI ->> OrderController: Place order
247 OrderController ->> Product: Check availability
248 Product -->> OrderController: Available
249 OrderController ->> MongoDB: Save order
250 MongoDB -->> OrderController: Order saved
251 OrderController ->> OrderQueue: Process payment
252 OrderQueue -->> User: Order confirmation
253 `
254 );
255 });
256
257 it('should render participant creation and destruction with different types', () => {
258 imgSnapshotTest(`
259 sequenceDiagram
260 participant Alice@{ "type" : "boundary" }
261 Alice->>Bob: Hello Bob, how are you ?
262 Bob->>Alice: Fine, thank you. And you?
263 create participant Carl@{ "type" : "control" }
264 Alice->>Carl: Hi Carl!
265 create actor D as Donald
266 Carl->>D: Hi!
267 destroy Carl
268 Alice-xCarl: We are too many
269 destroy Bob
270 Bob->>Alice: I agree
271 `);
272 });
273
274 it('should handle complex interactions between different participant types', () => {
275 imgSnapshotTest(
276 `
277 sequenceDiagram
278 box rgb(200,220,255) Authentication
279 participant User@{ "type": "actor" }
280 participant LoginUI@{ "type": "boundary" }
281 participant AuthService@{ "type": "control" }
282 participant UserDB@{ "type": "database" }
283 end
284
285 box rgb(200,255,220) Order Processing
286 participant Order@{ "type": "entity" }
287 participant OrderQueue@{ "type": "queue" }
288 participant AuditLogs@{ "type": "collections" }
289 end
290
291 User ->> LoginUI: Enter credentials
292 LoginUI ->> AuthService: Validate
293 AuthService ->> UserDB: Query user
294 UserDB -->> AuthService: User data
295
296 alt Valid credentials
297 AuthService -->> LoginUI: Success
298 LoginUI -->> User: Welcome
299
300 par Place order
301 User ->> Order: New order
302 Order ->> OrderQueue: Process
303 and
304 Order ->> AuditLogs: Record
305 end
306
307 loop Until confirmed
308 OrderQueue ->> Order: Update status
309 Order -->> User: Notification
310 end
311 else Invalid credentials
312 AuthService --x LoginUI: Failure
313 LoginUI --x User: Retry
314 end
315 `,
316 { sequence: { useMaxWidth: false } }
317 );
318 });
319
320 it('should render parallel processes with different participant types', () => {
321 imgSnapshotTest(
322 `
323 sequenceDiagram
324 participant Customer@{ "type": "actor" }
325 participant Frontend@{ "type": "participant" }
326 participant PaymentService@{ "type": "boundary" }
327 participant InventoryManager@{ "type": "control" }
328 participant Order@{ "type": "entity" }
329 participant OrdersDB@{ "type": "database" }
330 participant NotificationQueue@{ "type": "queue" }
331
332 Customer ->> Frontend: Place order
333 Frontend ->> Order: Create order
334 par Parallel Processing
335 Order ->> PaymentService: Process payment
336 and
337 Order ->> InventoryManager: Reserve items
338 end
339 PaymentService -->> Order: Payment confirmed
340 InventoryManager -->> Order: Items reserved
341 Order ->> OrdersDB: Save finalized order
342 OrdersDB -->> Order: Order saved
343 Order ->> NotificationQueue: Send confirmation
344 NotificationQueue -->> Customer: Order confirmation
345 `
346 );
347 });
348 });
349 it('should render different participant types with notes and loops', () => {
350 imgSnapshotTest(
351 `
352 sequenceDiagram
353 actor Admin
354 participant Dashboard
355 participant AuthService@{ "type" : "boundary" }
356 participant UserManager@{ "type" : "control" }
357 participant UserProfile@{ "type" : "entity" }
358 participant UserDB@{ "type" : "database" }
359 participant Logs@{ "type" : "database" }
360
361 Admin ->> Dashboard: Open user management
362 loop Authentication check
363 Dashboard ->> AuthService: Verify admin rights
364 AuthService ->> Dashboard: Access granted
365 end
366 Dashboard ->> UserManager: List users
367 UserManager ->> UserDB: Query users
368 UserDB ->> UserManager: Return user data
369 Note right of UserDB: Encrypted data<br/>requires decryption
370 UserManager ->> UserProfile: Format profiles
371 UserProfile ->> UserManager: Formatted data
372 UserManager ->> Dashboard: Display users
373 Dashboard ->> Logs: Record access
374 Logs ->> Admin: Audit trail
375 `
376 );
377 });
378
379 it('should render different participant types with alternative flows', () => {
380 imgSnapshotTest(
381 `
382 sequenceDiagram
383 actor Client
384 participant MobileApp
385 participant CloudService@{ "type" : "boundary" }
386 participant DataProcessor@{ "type" : "control" }
387 participant Transaction@{ "type" : "entity" }
388 participant TransactionsDB@{ "type" : "database" }
389 participant EventBus@{ "type" : "queue" }
390
391 Client ->> MobileApp: Initiate transaction
392 MobileApp ->> CloudService: Authenticate
393 alt Authentication successful
394 CloudService -->> MobileApp: Auth token
395 MobileApp ->> DataProcessor: Process data
396 DataProcessor ->> Transaction: Create transaction
397 Transaction ->> TransactionsDB: Save record
398 TransactionsDB -->> Transaction: Confirmation
399 Transaction ->> EventBus: Publish event
400 EventBus -->> Client: Notification
401 else Authentication failed
402 CloudService -->> MobileApp: Error
403 MobileApp -->> Client: Show error
404 end
405 `
406 );
407 });
408
409 it('should render different participant types with wrapping text', () => {
410 imgSnapshotTest(
411 `
412 sequenceDiagram
413 participant B@{ "type" : "boundary" }
414 participant C@{ "type" : "control" }
415 participant E@{ "type" : "entity" }
416 participant DB@{ "type" : "database" }
417 participant COL@{ "type" : "collections" }
418 participant Q@{ "type" : "queue" }
419
420 FE ->> B: Another long message<br/>with explicit<br/>line breaks
421 B -->> FE: Response message that is also quite long and needs to wrap
422 FE ->> C: Process data
423 C ->> E: Validate
424 E -->> C: Validation result
425 C ->> DB: Save
426 DB -->> C: Save result
427 C ->> COL: Log
428 COL -->> Q: Forward
429 Q -->> LongNameUser: Final response with confirmation of all actions taken
430 `,
431 { sequence: { wrap: true } }
432 );
433 });
434
435 describe('Sequence Diagram - New Participant Types with Long Notes and Messages', () => {
436 it('should render long notes left of boundary', () => {
437 imgSnapshotTest(
438 `
439 sequenceDiagram
440 participant Alice@{ "type" : "boundary" }
441 actor Bob
442 Alice->>Bob: Hola
443 Note left of Alice: Extremely utterly long line of longness which had previously overflown the actor box as it is much longer than what it should be
444 Bob->>Alice: I'm short though
445 `,
446 {}
447 );
448 });
449
450 it('should render wrapped long notes left of control', () => {
451 imgSnapshotTest(
452 `
453 sequenceDiagram
454 participant Alice@{ "type" : "control" }
455 actor Bob
456 Alice->>Bob: Hola
457 Note left of Alice:wrap: Extremely utterly long line of longness which had previously overflown the actor box as it is much longer than what it should be
458 Bob->>Alice: I'm short though
459 `,
460 {}
461 );
462 });
463
464 it('should render long notes right of entity', () => {
465 imgSnapshotTest(
466 `
467 sequenceDiagram
468 participant Alice@{ "type" : "entity" }
469 actor Bob
470 Alice->>Bob: Hola
471 Note right of Alice: Extremely utterly long line of longness which had previously overflown the actor box as it is much longer than what it should be
472 Bob->>Alice: I'm short though
473 `,
474 {}
475 );
476 });
477
478 it('should render wrapped long notes right of database', () => {
479 imgSnapshotTest(
480 `
481 sequenceDiagram
482 participant Alice@{ "type" : "database" }
483 actor Bob
484 Alice->>Bob: Hola
485 Note right of Alice:wrap: Extremely utterly long line of longness which had previously overflown the actor box as it is much longer than what it should be
486 Bob->>Alice: I'm short though
487 `,
488 {}
489 );
490 });
491
492 it('should render long notes over collections', () => {
493 imgSnapshotTest(
494 `
495 sequenceDiagram
496 participant Alice@{ "type" : "collections" }
497 actor Bob
498 Alice->>Bob: Hola
499 Note over Alice: Extremely utterly long line of longness which had previously overflown the actor box as it is much longer than what it should be
500 Bob->>Alice: I'm short though
501 `,
502 {}
503 );
504 });
505
506 it('should render wrapped long notes over queue', () => {
507 imgSnapshotTest(
508 `
509 sequenceDiagram
510 participant Alice@{ "type" : "queue" }
511 actor Bob
512 Alice->>Bob: Hola
513 Note over Alice:wrap: Extremely utterly long line of longness which had previously overflown the actor box as it is much longer than what it should be
514 Bob->>Alice: I'm short though
515 `,
516 {}
517 );
518 });
519
520 it('should render notes over actor and boundary', () => {
521 imgSnapshotTest(
522 `
523 sequenceDiagram
524 actor Alice
525 participant Charlie@{ "type" : "boundary" }
526 note over Alice: Some note
527 note over Charlie: Other note
528 `,
529 {}
530 );
531 });
532
533 it('should render long messages from database to collections', () => {
534 imgSnapshotTest(
535 `
536 sequenceDiagram
537 participant Alice@{ "type" : "database" }
538 participant Bob@{ "type" : "collections" }
539 Alice->>Bob: Extremely utterly long line of longness which had previously overflown the actor box as it is much longer than what it should be
540 Bob->>Alice: I'm short though
541 `,
542 {}
543 );
544 });
545
546 it('should render wrapped long messages from control to entity', () => {
547 imgSnapshotTest(
548 `
549 sequenceDiagram
550 participant Alice@{ "type" : "control" }
551 participant Bob@{ "type" : "entity" }
552 Alice->>Bob:wrap: Extremely utterly long line of longness which had previously overflown the actor box as it is much longer than what it should be
553 Bob->>Alice: I'm short though
554 `,
555 {}
556 );
557 });
558
559 it('should render long messages from queue to boundary', () => {
560 imgSnapshotTest(
561 `
562 sequenceDiagram
563 participant Alice@{ "type" : "queue" }
564 participant Bob@{ "type" : "boundary" }
565 Alice->>Bob: I'm short
566 Bob->>Alice: Extremely utterly long line of longness which had previously overflown the actor box as it is much longer than what it should be
567 `,
568 {}
569 );
570 });
571
572 it('should render wrapped long messages from actor to database', () => {
573 imgSnapshotTest(
574 `
575 sequenceDiagram
576 actor Alice
577 participant Bob@{ "type" : "database" }
578 Alice->>Bob: I'm short
579 Bob->>Alice:wrap: Extremely utterly long line of longness which had previously overflown the actor box as it is much longer than what it should be
580 `,
581 {}
582 );
583 });
584 });
585
586 describe('svg size', () => {
587 it('should render a sequence diagram when useMaxWidth is true (default)', () => {
588 renderGraph(
589 `
590 sequenceDiagram
591 actor Alice
592 participant Bob@{ "type" : "boundary" }
593 participant John@{ "type" : "control" }
594 Alice ->> Bob: Hello Bob, how are you?
595 Bob-->>John: How about you John?
596 Bob--x Alice: I am good thanks!
597 Bob-x John: I am good thanks!
598 Note right of John: Bob thinks a long<br/>long time, so long<br/>that the text does<br/>not fit on a row.
599 Bob-->Alice: Checking with John...
600 alt either this
601 Alice->>John: Yes
602 else or this
603 Alice->>John: No
604 else or this will happen
605 Alice->John: Maybe
606 end
607 par this happens in parallel
608 Alice -->> Bob: Parallel message 1
609 and
610 Alice -->> John: Parallel message 2
611 end
612 `,
613 { sequence: { useMaxWidth: true } }
614 );
615 cy.get('svg').should((svg) => {
616 expect(svg).to.have.attr('width', '100%');
617 const style = svg.attr('style');
618 expect(style).to.match(/^max-width: [\d.]+px;$/);
619 const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join(''));
620 expect(maxWidthValue).to.be.within(820 * 0.95, 820 * 1.05);
621 });
622 });
623
624 it('should render a sequence diagram when useMaxWidth is false', () => {
625 renderGraph(
626 `
627 sequenceDiagram
628 actor Alice
629 participant Bob@{ "type" : "boundary" }
630 participant John@{ "type" : "control" }
631 Alice ->> Bob: Hello Bob, how are you?
632 Bob-->>John: How about you John?
633 Bob--x Alice: I am good thanks!
634 Bob-x John: I am good thanks!
635 Note right of John: Bob thinks a long<br/>long time, so long<br/>that the text does<br/>not fit on a row.
636 Bob-->Alice: Checking with John...
637 alt either this
638 Alice->>John: Yes
639 else or this
640 Alice->>John: No
641 else or this will happen
642 Alice->John: Maybe
643 end
644 par this happens in parallel
645 Alice -->> Bob: Parallel message 1
646 and
647 Alice -->> John: Parallel message 2
648 end
649 `,
650 { sequence: { useMaxWidth: false } }
651 );
652 cy.get('svg').should((svg) => {
653 const width = parseFloat(svg.attr('width'));
654 expect(width).to.be.within(820 * 0.95, 820 * 1.05);
655 expect(svg).to.not.have.attr('style');
656 });
657 });
658
659 describe('Central Connection Rendering Tests', () => {
660 it('should render central connection circles on actor vertical lines', () => {
661 imgSnapshotTest(
662 `sequenceDiagram
663 participant Alice
664 participant Bob
665 participant Charlie
666 Alice ()->>() Bob: Central connection
667 Bob ()-->> Charlie: Reverse central connection
668 Charlie ()<<-->>() Alice: Dual central connection`,
669 { look: 'classic', sequence: { diagramMarginX: 50, diagramMarginY: 10 } }
670 );
671 });
672
673 it('should render central connections with different arrow types', () => {
674 imgSnapshotTest(
675 `sequenceDiagram
676 participant Alice
677 participant Bob
678 Alice ()->>() Bob: Solid open arrow
679 Alice ()-->>() Bob: Dotted open arrow
680 Alice ()-x() Bob: Solid cross
681 Alice ()--x() Bob: Dotted cross
682 Alice ()->() Bob: Solid arrow`,
683 { look: 'classic', sequence: { diagramMarginX: 50, diagramMarginY: 10 } }
684 );
685 });
686
687 it('should render central connections with bidirectional arrows', () => {
688 imgSnapshotTest(
689 `sequenceDiagram
690 participant Alice
691 participant Bob
692 Alice ()<<->>() Bob: Bidirectional solid
693 Alice ()<<-->>() Bob: Bidirectional dotted`,
694 { look: 'classic', sequence: { diagramMarginX: 50, diagramMarginY: 10 } }
695 );
696 });
697
698 it('should render central connections with activations', () => {
699 imgSnapshotTest(
700 `sequenceDiagram
701 participant Alice
702 participant Bob
703 participant Charlie
704 Alice ()->>() Bob: Activate Bob
705 activate Bob
706 Bob ()-->> Charlie: Message to Charlie
707 Bob ()->>() Alice: Response to Alice
708 deactivate Bob`,
709 { look: 'classic', sequence: { diagramMarginX: 50, diagramMarginY: 10 } }
710 );
711 });
712
713 it('should render central connections mixed with normal messages', () => {
714 imgSnapshotTest(
715 `sequenceDiagram
716 participant Alice
717 participant Bob
718 participant Charlie
719 Alice ->> Bob: Normal message
720 Bob ()->>() Charlie: Central connection
721 Charlie -->> Alice: Normal dotted message
722 Alice ()<<-->>() Bob: Dual central connection
723 Bob -x Charlie: Normal cross message`,
724 { look: 'classic', sequence: { diagramMarginX: 50, diagramMarginY: 10 } }
725 );
726 });
727
728 it('should render central connections with notes', () => {
729 imgSnapshotTest(
730 `sequenceDiagram
731 participant Alice
732 participant Bob
733 participant Charlie
734 Alice ()->>() Bob: Central connection
735 Note over Alice,Bob: Central connection note
736 Bob ()-->> Charlie: Reverse central connection
737 Note right of Charlie: Response note
738 Charlie ()<<-->>() Alice: Dual central connection`,
739 { look: 'classic', sequence: { diagramMarginX: 50, diagramMarginY: 10 } }
740 );
741 });
742
743 it('should render central connections with loops and alternatives', () => {
744 imgSnapshotTest(
745 `sequenceDiagram
746 participant Alice
747 participant Bob
748 participant Charlie
749 loop Every minute
750 Alice ()->>() Bob: Central heartbeat
751 Bob ()-->> Charlie: Forward heartbeat
752 end
753 alt Success
754 Charlie ()<<-->>() Alice: Success response
755 else Failure
756 Charlie ()-x() Alice: Failure response
757 end`,
758 { look: 'classic', sequence: { diagramMarginX: 50, diagramMarginY: 10 } }
759 );
760 });
761
762 it('should render central connections with different participant types', () => {
763 imgSnapshotTest(
764 `sequenceDiagram
765 participant Alice
766 actor Bob
767 participant Charlie@{"type":"boundary"}
768 participant David@{"type":"control"}
769 participant Eve@{"type":"entity"}
770 Alice ()->>() Bob: To actor
771 Bob ()-->> Charlie: To boundary
772 Charlie ()->>() David: To control
773 David ()<<-->>() Eve: To entity
774 Eve ()-x() Alice: Back to participant`,
775 { look: 'classic', sequence: { diagramMarginX: 50, diagramMarginY: 10 } }
776 );
777 });
778 });
779
780 describe('Sequence Diagram Rendering with Autonumber and All Arrow Types', () => {
781 describe('Autonumber with All Arrow Types', () => {
782 it('should render all arrow types with autonumbering', () => {
783 imgSnapshotTest(
784 `%%{init: {'theme':'base'}}%%
785sequenceDiagram
786 autonumber
787 Alice->>Bob: Solid arrow (->>)
788 Bob-->>Alice: Dotted arrow (-->>)
789 Alice->Charlie: Solid open arrow (->)
790 Charlie-->Dave: Dotted open arrow (-->)
791 Alice-xBob: Solid cross (-x)
792 Bob--xAlice: Dotted cross (--x)
793 Alice-)Charlie: Solid point async (-)
794 Charlie--)Dave: Dotted point async (--)
795 Alice<<->>Bob: Bidirectional solid (<<->>)
796 Charlie<<-->>Dave: Bidirectional dotted (<<-->>)
797 Alice-|\\Bob: Solid top half (-|\\)
798 Bob-|/Alice: Solid bottom half (-|/)
799 Alice-\\\\Charlie: Stick top half (-\\\\)
800 Charlie-//Dave: Stick bottom half (-//)
801 Dave/|-Charlie: Solid top reverse (/|-)
802 Charlie\\|-Bob: Solid bottom reverse (\\|-)
803 Bob//-Alice: Stick top reverse (//-)
804 Alice\\\\-Bob: Stick bottom reverse (\\\\-)
805 Alice--|\\Bob: Dotted solid top (--|\\)
806 Bob--|/Alice: Dotted solid bottom (--|/)
807 Alice--\\\\Charlie: Dotted stick top (--\\\\)
808 Charlie--//Dave: Dotted stick bottom (--//)
809 Dave/|--Charlie: Dotted solid top reverse (/|--)
810 Charlie\\|--Bob: Dotted solid bottom reverse (\\|--)
811 Bob//--Alice: Dotted stick top reverse (//--)
812 Alice\\\\--Bob: Dotted stick bottom reverse (\\\\--)
813 Alice->>()Bob: Solid with central connection
814 Bob()-->>Alice: Dotted with reverse central
815 Alice()->>()Charlie: Dual central connections`,
816 { sequence: { diagramMarginX: 50, diagramMarginY: 10 } }
817 );
818 });
819
820 it('should render all arrow types with autonumbering - left to right only', () => {
821 imgSnapshotTest(
822 `%%{init: {'theme':'base'}}%%
823sequenceDiagram
824 autonumber
825 Alice->>Bob: Solid arrow (->>)
826 Alice-->>Bob: Dotted arrow (-->>)
827 Alice->Bob: Solid open arrow (->)
828 Alice-->Bob: Dotted open arrow (-->)
829 Alice-xBob: Solid cross (-x)
830 Alice--xBob: Dotted cross (--x)
831 Alice-)Bob: Solid point async (-)
832 Alice--)Bob: Dotted point async (--)
833 Alice<<->>Bob: Bidirectional solid (<<->>)
834 Alice<<-->>Bob: Bidirectional dotted (<<-->>)
835 Alice-|\\Bob: Solid top half (-|\\)
836 Alice-|/Bob: Solid bottom half (-|/)
837 Alice-\\\\Bob: Stick top half (-\\\\)
838 Alice-//Bob: Stick bottom half (-//)
839 Bob/|-Alice: Solid top reverse (/|-)
840 Bob\\|-Alice: Solid bottom reverse (\\|-)
841 Bob//-Alice: Stick top reverse (//-)
842 Bob\\\\-Alice: Stick bottom reverse (\\\\-)
843 Alice--|\\Bob: Dotted solid top (--|\\)
844 Alice--|/Bob: Dotted solid bottom (--|/)
845 Alice--\\\\Bob: Dotted stick top (--\\\\)
846 Alice--//Bob: Dotted stick bottom (--//)
847 Bob/|--Alice: Dotted solid top reverse (/|--)
848 Bob\\|--Alice: Dotted solid bottom reverse (\\|--)
849 Bob//--Alice: Dotted stick top reverse (//--)
850 Bob\\\\--Alice: Dotted stick bottom reverse (\\\\--)
851 Alice->>()Bob: Solid with central connection
852 Alice()-->>Bob: Dotted with reverse central
853 Alice()->>()Bob: Dual central connections`,
854 { sequence: { diagramMarginX: 50, diagramMarginY: 10 } }
855 );
856 });
857
858 it('should render central connections with autonumbering', () => {
859 imgSnapshotTest(
860 `%%{init: {'theme':'base'}}%%
861sequenceDiagram
862 autonumber
863 participant Alice
864 participant Bob
865 participant Charlie
866 Alice->>()Bob: Central connection at destination
867 Bob()->>Alice: Reverse central at source
868 Alice()->>()Bob: Dual central connections
869 Bob->>()Charlie: Another central connection
870 Charlie()-->>Alice: Reverse central dotted
871 Alice()<<-->>()Bob: Dual central bidirectional`,
872 { sequence: { diagramMarginX: 50, diagramMarginY: 10 } }
873 );
874 });
875
876 it('should render bidirectional arrows with autonumbering', () => {
877 imgSnapshotTest(
878 `%%{init: {'theme':'base'}}%%
879sequenceDiagram
880 autonumber
881 participant Alice
882 participant Bob
883 participant Charlie
884 Alice<<->>Bob: Bidirectional solid left to right
885 Bob<<->>Alice: Bidirectional solid right to left
886 Alice<<-->>Charlie: Bidirectional dotted left to right
887 Charlie<<-->>Alice: Bidirectional dotted right to left
888 Bob<<->>Charlie: Bidirectional solid
889 Charlie<<-->>Bob: Bidirectional dotted`,
890 { sequence: { diagramMarginX: 50, diagramMarginY: 10 } }
891 );
892 });
893
894 it('should render reverse arrows with autonumbering', () => {
895 imgSnapshotTest(
896 `%%{init: {'theme':'base'}}%%
897sequenceDiagram
898 autonumber
899 participant Alice
900 participant Bob
901 participant Charlie
902 Bob/|-Alice: Solid top reverse left to right
903 Alice/|-Bob: Solid top reverse right to left
904 Bob\\|-Alice: Solid bottom reverse left to right
905 Alice\\|-Bob: Solid bottom reverse right to left
906 Bob//-Alice: Stick top reverse left to right
907 Alice//-Bob: Stick top reverse right to left
908 Bob\\\\-Alice: Stick bottom reverse left to right
909 Alice\\\\-Bob: Stick bottom reverse right to left
910 Bob/|--Alice: Dotted solid top reverse
911 Alice\\|--Bob: Dotted solid bottom reverse
912 Bob//--Alice: Dotted stick top reverse
913 Alice\\\\--Bob: Dotted stick bottom reverse`,
914 { sequence: { diagramMarginX: 50, diagramMarginY: 10 } }
915 );
916 });
917 });
918
919 describe('Central Connections with Autonumber - Comprehensive Coverage', () => {
920 it('should render CENTRAL_CONNECTION with normal arrows - left to right', () => {
921 imgSnapshotTest(
922 `%%{init: {'theme':'base'}}%%
923sequenceDiagram
924 autonumber
925 participant Alice
926 participant Bob
927 participant Charlie
928 Alice->>()Bob: Solid arrow with circle at destination
929 Alice-->>()Bob: Dotted arrow with circle at destination
930 Alice->()Bob: Open arrow with circle at destination
931 Alice--x()Bob: Cross arrow with circle at destination
932 Alice--)()Bob: Close arrow with circle at destination`,
933 { sequence: { diagramMarginX: 50, diagramMarginY: 10 } }
934 );
935 });
936
937 it('should render CENTRAL_CONNECTION with normal arrows - right to left', () => {
938 imgSnapshotTest(
939 `%%{init: {'theme':'base'}}%%
940sequenceDiagram
941 autonumber
942 participant Alice
943 participant Bob
944 participant Charlie
945 Bob->>()Alice: Solid arrow with circle at destination (RTL)
946 Charlie-->>()Bob: Dotted arrow with circle at destination (RTL)
947 Bob->()Alice: Open arrow with circle at destination (RTL)
948 Charlie--x()Alice: Cross arrow with circle at destination (RTL)
949 Bob--)()Alice: Close arrow with circle at destination (RTL)`,
950 { sequence: { diagramMarginX: 50, diagramMarginY: 10 } }
951 );
952 });
953
954 it('should render CENTRAL_CONNECTION with reverse arrows - left to right', () => {
955 imgSnapshotTest(
956 `%%{init: {'theme':'base'}}%%
957sequenceDiagram
958 autonumber
959 participant Alice
960 participant Bob
961 participant Charlie
962 Bob/|-()Alice: Solid top reverse with circle (LTR)
963 Bob\\|-()Alice: Solid bottom reverse with circle (LTR)
964 Bob//-()Alice: Stick top reverse with circle (LTR)
965 Bob\\\\-()Alice: Stick bottom reverse with circle (LTR)
966 Bob/|--()Alice: Dotted solid top reverse with circle (LTR)
967 Bob\\|--()Alice: Dotted solid bottom reverse with circle (LTR)
968 Bob//--()Alice: Dotted stick top reverse with circle (LTR)
969 Bob\\\\--()Alice: Dotted stick bottom reverse with circle (LTR)`,
970 { sequence: { diagramMarginX: 50, diagramMarginY: 10 } }
971 );
972 });
973
974 it('should render CENTRAL_CONNECTION with reverse arrows - right to left', () => {
975 imgSnapshotTest(
976 `%%{init: {'theme':'base'}}%%
977sequenceDiagram
978 autonumber
979 participant Alice
980 participant Bob
981 participant Charlie
982 Alice/|-()Bob: Solid top reverse with circle (RTL)
983 Alice\\|-()Bob: Solid bottom reverse with circle (RTL)
984 Alice//-()Bob: Stick top reverse with circle (RTL)
985 Alice\\\\-()Bob: Stick bottom reverse with circle (RTL)
986 Alice/|--()Bob: Dotted solid top reverse with circle (RTL)
987 Alice\\|--()Bob: Dotted solid bottom reverse with circle (RTL)
988 Alice//--()Bob: Dotted stick top reverse with circle (RTL)
989 Alice\\\\--()Bob: Dotted stick bottom reverse with circle (RTL)`,
990 { sequence: { diagramMarginX: 50, diagramMarginY: 10 } }
991 );
992 });
993
994 it('should render Central_Connection_REVERSE ()->> normal LTR', () => {
995 imgSnapshotTest(
996 `%%{init: {'theme':'base'}}%%
997sequenceDiagram
998 autonumber
999 participant Alice
1000 participant Bob
1001 participant Charlie
1002 Alice()->>Bob: Circle at source with solid arrow
1003 Alice()-->>Bob: Circle at source with dotted arrow
1004 Alice()->Bob: Circle at source with open arrow
1005 Alice()--xBob: Circle at source with cross arrow
1006 Alice()--)Bob: Circle at source with close arrow`,
1007 { sequence: { diagramMarginX: 50, diagramMarginY: 10 } }
1008 );
1009 });
1010
1011 it('should render Central_Connection_REVERSE ()->> normal RTL', () => {
1012 imgSnapshotTest(
1013 `%%{init: {'theme':'base'}}%%
1014sequenceDiagram
1015 autonumber
1016 participant Alice
1017 participant Bob
1018 participant Charlie
1019 Bob()->>Alice: Circle at source with solid arrow (RTL)
1020 Charlie()-->>Bob: Circle at source with dotted arrow (RTL)
1021 Bob()->Alice: Circle at source with open arrow (RTL)
1022 Charlie()--xAlice: Circle at source with cross arrow (RTL)
1023 Bob()--)Alice: Circle at source with close arrow (RTL)`,
1024 { sequence: { diagramMarginX: 50, diagramMarginY: 10 } }
1025 );
1026 });
1027
1028 it('should render Central_Connection_REVERSE ()->> reverse LTR', () => {
1029 imgSnapshotTest(
1030 `%%{init: {'theme':'base'}}%%
1031sequenceDiagram
1032 autonumber
1033 participant Alice
1034 participant Bob
1035 participant Charlie
1036 Bob()/|-Alice: Circle at source with solid top reverse (LTR)
1037 Bob()\\|-Alice: Circle at source with solid bottom reverse (LTR)
1038 Bob()//-Alice: Circle at source with stick top reverse (LTR)
1039 Bob()\\\\-Alice: Circle at source with stick bottom reverse (LTR)
1040 Bob()/|--Alice: Circle at source with dotted solid top reverse (LTR)
1041 Bob()\\|--Alice: Circle at source with dotted solid bottom reverse (LTR)
1042 Bob()//--Alice: Circle at source with dotted stick top reverse (LTR)
1043 Bob()\\\\--Alice: Circle at source with dotted stick bottom reverse (LTR)`,
1044 { sequence: { diagramMarginX: 50, diagramMarginY: 10 } }
1045 );
1046 });
1047
1048 it('should render Central_Connection_REVERSE ()->> reverse RTL', () => {
1049 imgSnapshotTest(
1050 `%%{init: {'theme':'base'}}%%
1051sequenceDiagram
1052 autonumber
1053 participant Alice
1054 participant Bob
1055 participant Charlie
1056 Alice()/|-Bob: Circle at source with solid top reverse (RTL)
1057 Alice()\\|-Bob: Circle at source with solid bottom reverse (RTL)
1058 Alice()//-Bob: Circle at source with stick top reverse (RTL)
1059 Alice()\\\\-Bob: Circle at source with stick bottom reverse (RTL)
1060 Alice()/|--Bob: Circle at source with dotted solid top reverse (RTL)
1061 Alice()\\|--Bob: Circle at source with dotted solid bottom reverse (RTL)
1062 Alice()//--Bob: Circle at source with dotted stick top reverse (RTL)
1063 Alice()\\\\--Bob: Circle at source with dotted stick bottom reverse (RTL)`,
1064 { sequence: { diagramMarginX: 50, diagramMarginY: 10 } }
1065 );
1066 });
1067
1068 it('should render Central_Connection_DUAL ()->>() normal LTR', () => {
1069 imgSnapshotTest(
1070 `%%{init: {'theme':'base'}}%%
1071sequenceDiagram
1072 autonumber
1073 participant Alice
1074 participant Bob
1075 participant Charlie
1076 Alice()->>()Bob: Circles at both ends with solid arrow
1077 Alice()-->>()Bob: Circles at both ends with dotted arrow
1078 Alice()->()Bob: Circles at both ends with open arrow
1079 Alice()--x()Bob: Circles at both ends with cross arrow
1080 Alice()--)()Bob: Circles at both ends with close arrow`,
1081 { sequence: { diagramMarginX: 50, diagramMarginY: 10 } }
1082 );
1083 });
1084
1085 it('should render Central_Connection_DUAL ()->>() normal RTL', () => {
1086 imgSnapshotTest(
1087 `%%{init: {'theme':'base'}}%%
1088sequenceDiagram
1089 autonumber
1090 participant Alice
1091 participant Bob
1092 participant Charlie
1093 Bob()->>()Alice: Circles at both ends with solid arrow (RTL)
1094 Charlie()-->>()Bob: Circles at both ends with dotted arrow (RTL)
1095 Bob()->()Alice: Circles at both ends with open arrow (RTL)
1096 Charlie()--x()Alice: Circles at both ends with cross arrow (RTL)
1097 Bob()--)()Alice: Circles at both ends with close arrow (RTL)`,
1098 { sequence: { diagramMarginX: 50, diagramMarginY: 10 } }
1099 );
1100 });
1101
1102 it('should render Central_Connection_DUAL ()->>() reverse LTR', () => {
1103 imgSnapshotTest(
1104 `%%{init: {'theme':'base'}}%%
1105sequenceDiagram
1106 autonumber
1107 participant Alice
1108 participant Bob
1109 participant Charlie
1110 Bob()/|-()Alice: Circles at both ends with solid top reverse (LTR)
1111 Bob()\\|-()Alice: Circles at both ends with solid bottom reverse (LTR)
1112 Bob()//-()Alice: Circles at both ends with stick top reverse (LTR)
1113 Bob()\\\\-()Alice: Circles at both ends with stick bottom reverse (LTR)
1114 Bob()/|--()Alice: Circles at both ends with dotted solid top reverse (LTR)
1115 Bob()\\|--()Alice: Circles at both ends with dotted solid bottom reverse (LTR)
1116 Bob()//--()Alice: Circles at both ends with dotted stick top reverse (LTR)
1117 Bob()\\\\--()Alice: Circles at both ends with dotted stick bottom reverse (LTR)`,
1118 { sequence: { diagramMarginX: 50, diagramMarginY: 10 } }
1119 );
1120 });
1121
1122 it('should render Central_Connection_DUAL ()->>() reverse RTL', () => {
1123 imgSnapshotTest(
1124 `%%{init: {'theme':'base'}}%%
1125sequenceDiagram
1126 autonumber
1127 participant Alice
1128 participant Bob
1129 participant Charlie
1130 Alice()/|-()Bob: Circles at both ends with solid top reverse (RTL)
1131 Alice()\\|-()Bob: Circles at both ends with solid bottom reverse (RTL)
1132 Alice()//-()Bob: Circles at both ends with stick top reverse (RTL)
1133 Alice()\\\\-()Bob: Circles at both ends with stick bottom reverse (RTL)
1134 Alice()/|--()Bob: Circles at both ends with dotted solid top reverse (RTL)
1135 Alice()\\|--()Bob: Circles at both ends with dotted solid bottom reverse (RTL)
1136 Alice()//--()Bob: Circles at both ends with dotted stick top reverse (RTL)
1137 Alice()\\\\--()Bob: Circles at both ends with dotted stick bottom reverse (RTL)`,
1138 { sequence: { diagramMarginX: 50, diagramMarginY: 10 } }
1139 );
1140 });
1141
1142 it('should render mixed central connections with autonumber', () => {
1143 imgSnapshotTest(
1144 `%%{init: {'theme':'base'}}%%
1145sequenceDiagram
1146 autonumber
1147 participant Alice
1148 participant Bob
1149 participant Charlie
1150 participant David
1151
1152 Note over Alice,David: Normal arrows with central connections
1153 Alice->>()Bob: CENTRAL_CONNECTION LTR
1154 Bob->>()Alice: CENTRAL_CONNECTION RTL
1155 Alice()->>Bob: CENTRAL_CONNECTION_REVERSE LTR
1156 Bob()->>Alice: CENTRAL_CONNECTION_REVERSE RTL
1157 Alice()->>()Bob: CENTRAL_CONNECTION_DUAL LTR
1158 Bob()->>()Alice: CENTRAL_CONNECTION_DUAL RTL
1159
1160 Note over Alice,David: Reverse arrows with central connections
1161 Bob/|-()Alice: Reverse with CENTRAL_CONNECTION LTR
1162 Alice/|-()Bob: Reverse with CENTRAL_CONNECTION RTL
1163 Bob()/|-Alice: Reverse with CENTRAL_CONNECTION_REVERSE LTR
1164 Alice()/|-Bob: Reverse with CENTRAL_CONNECTION_REVERSE RTL
1165 Bob()/|-()Alice: Reverse with CENTRAL_CONNECTION_DUAL LTR
1166 Alice()/|-()Bob: Reverse with CENTRAL_CONNECTION_DUAL RTL
1167
1168 Note over Alice,David: Mixed with different participants
1169 Alice->>()Charlie: Skip participant
1170 Charlie()->>Alice: Back skip
1171 Bob()->>()David: Another skip
1172 David()->>()Bob: Return skip`,
1173 { sequence: { diagramMarginX: 50, diagramMarginY: 10 } }
1174 );
1175 });
1176
1177 it('should render central connections with bidirectional arrows and autonumber', () => {
1178 imgSnapshotTest(
1179 `%%{init: {'theme':'base'}}%%
1180sequenceDiagram
1181 autonumber
1182 participant Alice
1183 participant Bob
1184 participant Charlie
1185 Alice()<<->>()Bob: Dual central with bidirectional solid LTR
1186 Bob()<<->>()Alice: Dual central with bidirectional solid RTL
1187 Alice()<<-->>()Bob: Dual central with bidirectional dotted LTR
1188 Bob()<<-->>()Alice: Dual central with bidirectional dotted RTL
1189 Alice<<->>()Bob: Central at end with bidirectional LTR
1190 Bob()<<->>Alice: Central at start with bidirectional RTL`,
1191 { sequence: { diagramMarginX: 50, diagramMarginY: 10 } }
1192 );
1193 });
1194 });
1195
1196 describe('Self-Reference Arrows - Comprehensive Coverage', () => {
1197 it('should render self-reference with normal arrows - without autonumber', () => {
1198 imgSnapshotTest(
1199 `%%{init: {'theme':'base'}}%%
1200sequenceDiagram
1201 participant Alice
1202 participant Bob
1203 participant Charlie
1204 Alice->>Alice: Solid arrow self-reference
1205 Bob-->>Bob: Dotted arrow self-reference
1206 Charlie->Charlie: Open arrow self-reference
1207 Alice-->Alice: Dotted open arrow self-reference
1208 Bob-xBob: Cross arrow self-reference
1209 Charlie--xCharlie: Dotted cross self-reference`,
1210 { sequence: { diagramMarginX: 50, diagramMarginY: 10 } }
1211 );
1212 });
1213
1214 it('should render self-reference with normal arrows - with autonumber', () => {
1215 imgSnapshotTest(
1216 `%%{init: {'theme':'base'}}%%
1217sequenceDiagram
1218 autonumber
1219 participant Alice
1220 participant Bob
1221 participant Charlie
1222 Alice->>Alice: Solid arrow self-reference
1223 Bob-->>Bob: Dotted arrow self-reference
1224 Charlie->Charlie: Open arrow self-reference
1225 Alice-->Alice: Dotted open arrow self-reference
1226 Bob-xBob: Cross arrow self-reference
1227 Charlie--xCharlie: Dotted cross self-reference`,
1228 { sequence: { diagramMarginX: 50, diagramMarginY: 10 } }
1229 );
1230 });
1231
1232 it('should render self-reference with reverse arrows - without autonumber', () => {
1233 imgSnapshotTest(
1234 `%%{init: {'theme':'base'}}%%
1235 sequenceDiagram
1236 participant Alice
1237 participant Bob
1238 participant Charlie
1239 Alice/|-Alice: Solid top reverse self-reference
1240 Bob\\|-Bob: Solid bottom reverse self-reference
1241 Charlie//-Charlie: Stick top reverse self-reference
1242 Alice\\\\-Alice: Stick bottom reverse self-reference
1243 Bob/|--Bob: Dotted solid top reverse self-reference
1244 Charlie\\|--Charlie: Dotted solid bottom reverse self-reference
1245 Alice//--Alice: Dotted stick top reverse self-reference
1246 Bob\\\\--Bob: Dotted stick bottom reverse self-reference`,
1247 { sequence: { diagramMarginX: 50, diagramMarginY: 10 } }
1248 );
1249 });
1250
1251 it('should render self-reference with reverse arrows - with autonumber', () => {
1252 imgSnapshotTest(
1253 `%%{init: {'theme':'base'}}%%
1254sequenceDiagram
1255 autonumber
1256 participant Alice
1257 participant Bob
1258 participant Charlie
1259 Alice/|-Alice: Solid top reverse self-reference
1260 Bob\\|-Bob: Solid bottom reverse self-reference
1261 Charlie//-Charlie: Stick top reverse self-reference
1262 Alice\\\\-Alice: Stick bottom reverse self-reference
1263 Bob/|--Bob: Dotted solid top reverse self-reference
1264 Charlie\\|--Charlie: Dotted solid bottom reverse self-reference
1265 Alice//--Alice: Dotted stick top reverse self-reference
1266 Bob\\\\--Bob: Dotted stick bottom reverse self-reference`,
1267 { sequence: { diagramMarginX: 50, diagramMarginY: 10 } }
1268 );
1269 });
1270
1271 it('should render self-reference with bidirectional arrows - without autonumber', () => {
1272 imgSnapshotTest(
1273 `%%{init: {'theme':'base'}}%%
1274sequenceDiagram
1275 participant Alice
1276 participant Bob
1277 participant Charlie
1278 Alice<<->>Alice: Bidirectional solid self-reference
1279 Bob<<-->>Bob: Bidirectional dotted self-reference
1280 Charlie<<->>Charlie: Another bidirectional solid
1281 Alice<<-->>Alice: Another bidirectional dotted`,
1282 { sequence: { diagramMarginX: 50, diagramMarginY: 10 } }
1283 );
1284 });
1285
1286 it('should render self-reference with bidirectional arrows - with autonumber', () => {
1287 imgSnapshotTest(
1288 `%%{init: {'theme':'base'}}%%
1289sequenceDiagram
1290 autonumber
1291 participant Alice
1292 participant Bob
1293 participant Charlie
1294 Alice<<->>Alice: Bidirectional solid self-reference
1295 Bob<<-->>Bob: Bidirectional dotted self-reference
1296 Charlie<<->>Charlie: Another bidirectional solid
1297 Alice<<-->>Alice: Another bidirectional dotted`,
1298 { sequence: { diagramMarginX: 50, diagramMarginY: 10 } }
1299 );
1300 });
1301
1302 it('should render comprehensive self-reference scenario - all arrow types mixed', () => {
1303 imgSnapshotTest(
1304 `%%{init: {'theme':'base'}}%%
1305sequenceDiagram
1306 autonumber
1307 participant Alice
1308 participant Bob
1309 participant Charlie
1310
1311 Note over Alice,Charlie: Normal arrows
1312 Alice->>Alice: Normal solid
1313 Bob-->>Bob: Normal dotted
1314 Charlie->Charlie: Normal open
1315
1316 Note over Alice,Charlie: Reverse arrows
1317 Alice/|-Alice: Reverse solid top
1318 Bob\\|-Bob: Reverse solid bottom
1319
1320 Note over Alice,Charlie: Bidirectional arrows
1321 Charlie<<->>Charlie: Bidirectional solid
1322 Alice<<-->>Alice: Bidirectional dotted`,
1323 { sequence: { diagramMarginX: 50, diagramMarginY: 10 } }
1324 );
1325 });
1326
1327 it('should render self-reference mixed with regular messages and autonumber', () => {
1328 imgSnapshotTest(
1329 `%%{init: {'theme':'base'}}%%
1330sequenceDiagram
1331 autonumber
1332 participant Alice
1333 participant Bob
1334 participant Charlie
1335
1336 Alice->>Bob: Regular message
1337 Bob->>Bob: Self-reference solid
1338 Bob-->>Charlie: Regular dotted
1339 Charlie->>Alice: Regular back
1340 Alice<<->>Alice: Self-ref bidirectional
1341 Alice()->>Bob: Regular with central
1342 Bob-->>Alice: Regular dotted back`,
1343 { sequence: { diagramMarginX: 50, diagramMarginY: 10 } }
1344 );
1345 });
1346 });
1347 });
1348
1349 describe('Comprehensive Test - All Message Types and Arrow Types', () => {
1350 it('should render all message types and arrow types in a single comprehensive test', () => {
1351 imgSnapshotTest(
1352 `%%{init: {'theme':'base'}}%%
1353sequenceDiagram
1354 autonumber
1355 participant Alice
1356 participant Bob
1357 participant Charlie
1358 participant David
1359
1360 Note over Alice,David: SOLID ARROWS (Filled arrowhead)
1361 Alice->>Bob: Solid arrow (->>)
1362 Alice->Charlie: Solid open arrow (->)
1363 Alice-xDavid: Solid cross (-x)
1364 Alice-)Bob: Solid point async (-)
1365
1366 Note over Alice,David: DOTTED ARROWS (Dashed line)
1367 Bob-->>Alice: Dotted arrow (-->>)
1368 Bob-->Charlie: Dotted open arrow (-->)
1369 Bob--xDavid: Dotted cross (--x)
1370 Bob--)Alice: Dotted point async (--)
1371
1372 Note over Alice,David: BIDIRECTIONAL ARROWS
1373 Alice<<->>Bob: Bidirectional solid (<<->>)
1374 Charlie<<-->>David: Bidirectional dotted (<<-->>)
1375
1376 Note over Alice,David: REVERSE ARROWS (Half arrows)
1377 Bob/|-Alice: Solid top reverse (/|-)
1378 Charlie\\|-Bob: Solid bottom reverse (\\|-)
1379 David//-Alice: Stick top reverse (//)
1380 Alice\\\\-Bob: Stick bottom reverse (\\\\-)
1381
1382 Note over Alice,David: DOTTED REVERSE ARROWS
1383 Bob/|--Alice: Dotted solid top reverse (/|--)
1384 Charlie\\|--Bob: Dotted solid bottom reverse (\\|--)
1385 David//--Alice: Dotted stick top reverse (//--)
1386 Alice\\\\--Bob: Dotted stick bottom reverse (\\\\--)
1387
1388 Note over Alice,David: CENTRAL CONNECTIONS (Circle at destination)
1389 Alice->>()Bob: Solid with circle at destination
1390 Alice-->>()Charlie: Dotted with circle at destination
1391 Alice->()David: Open with circle at destination
1392 Alice--x()Bob: Cross with circle at destination
1393
1394 Note over Alice,David: CENTRAL CONNECTIONS REVERSE (Circle at source)
1395 Bob()->>Alice: Circle at source with solid
1396 Charlie()-->>Bob: Circle at source with dotted
1397 David()->Alice: Circle at source with open
1398 Bob()--xAlice: Circle at source with cross
1399
1400 Note over Alice,David: CENTRAL CONNECTIONS DUAL (Circles at both ends)
1401 Alice()->>()Bob: Dual circles with solid
1402 Alice()-->>()Charlie: Dual circles with dotted
1403 Alice()->()David: Dual circles with open
1404 Alice()--x()Bob: Dual circles with cross
1405
1406 Note over Alice,David: BIDIRECTIONAL WITH CENTRAL CONNECTIONS
1407 Alice()<<->>()Bob: Dual circles with bidirectional solid
1408 Charlie()<<-->>()David: Dual circles with bidirectional dotted
1409
1410 Note over Alice,David: SELF-REFERENCES (Same participant)
1411 Alice->>Alice: Self-reference solid
1412 Bob-->>Bob: Self-reference dotted
1413 Charlie->Charlie: Self-reference open
1414 David-xDavid: Self-reference cross
1415
1416 Note over Alice,David: SELF-REFERENCES WITH REVERSE ARROWS
1417 Alice/|-Alice: Self-ref reverse solid top
1418 Bob\\|-Bob: Self-ref reverse solid bottom
1419 Charlie//-Charlie: Self-ref reverse stick top
1420 David\\\\-David: Self-ref reverse stick bottom
1421
1422 Note over Alice,David: SELF-REFERENCES BIDIRECTIONAL
1423 Alice<<->>Alice: Self-ref bidirectional solid
1424 Bob<<-->>Bob: Self-ref bidirectional dotted
1425
1426 Note over Alice,David: MIXED COMPLEX SCENARIO
1427 Alice->>Bob: Regular message
1428 Bob()->>()Charlie: Central dual connection
1429 Charlie-->>David: Dotted response
1430 David/|-Alice: Reverse arrow
1431 Alice<<->>Bob: Bidirectional back
1432 Bob-xCharlie: Cross message
1433 Charlie()->>David: Central reverse
1434 David-->>()Alice: Dotted with circle`,
1435 { sequence: { diagramMarginX: 50, diagramMarginY: 10 } }
1436 );
1437 });
1438 });
1439
1440 describe('Participant Stereotypes with Aliases', () => {
1441 it('should render participants with stereotypes and aliases', () => {
1442 imgSnapshotTest(
1443 `sequenceDiagram
1444 participant API@{ "type" : "boundary" } as Public API
1445 participant Auth@{ "type" : "control" } as Auth Controller
1446 participant DB@{ "type" : "database" } as User Database
1447 participant Cache@{ "type" : "entity" } as Cache Layer
1448 API ->> Auth: Authenticate request
1449 Auth ->> DB: Query user
1450 DB -->> Auth: User data
1451 Auth ->> Cache: Store session
1452 Cache -->> Auth: Confirmed
1453 Auth -->> API: Token`,
1454 { look: 'classic', sequence: { diagramMarginX: 50, diagramMarginY: 10 } }
1455 );
1456 });
1457
1458 it('should render actors with stereotypes and aliases', () => {
1459 imgSnapshotTest(
1460 `sequenceDiagram
1461 actor U@{ "type" : "actor" } as End User
1462 actor A@{ "type" : "boundary" } as API Gateway
1463 actor S@{ "type" : "control" } as Service Layer
1464 actor D@{ "type" : "database" } as Data Store
1465 U ->> A: Send request
1466 A ->> S: Process
1467 S ->> D: Persist
1468 D -->> S: Success
1469 S -->> A: Response
1470 A -->> U: Result`,
1471 { look: 'classic', sequence: { diagramMarginX: 50, diagramMarginY: 10 } }
1472 );
1473 });
1474
1475 it('should render mixed participants and actors with stereotypes and aliases', () => {
1476 imgSnapshotTest(
1477 `sequenceDiagram
1478 actor Client@{ "type" : "actor" } AS Mobile Client
1479 participant Gateway@{ "type" : "boundary" } as API Gateway
1480 participant OrderSvc@{ "type" : "control" } as Order Service
1481 participant Queue@{ "type" : "queue" } as Message Queue
1482 participant DB@{ "type" : "database" } as Order Database
1483 participant Logs@{ "type" : "collections" } as Audit Logs
1484 Client ->> Gateway: Place order
1485 Gateway ->> OrderSvc: Validate order
1486 OrderSvc ->> Queue: Queue for processing as well
1487 OrderSvc ->> DB: Save order
1488 OrderSvc ->> Logs: Log transaction
1489 Queue -->> OrderSvc: Processing started AS Well
1490 DB -->> OrderSvc: Order saved
1491 Logs -->> OrderSvc: Logged
1492 OrderSvc -->> Gateway: Order confirmed
1493 Gateway -->> Client: Confirmation`,
1494 { look: 'classic', sequence: { diagramMarginX: 50, diagramMarginY: 10 } }
1495 );
1496 });
1497
1498 it('should render stereotypes with aliases in boxes', () => {
1499 imgSnapshotTest(
1500 `sequenceDiagram
1501 box rgb(200,220,255) Frontend Layer
1502 actor User@{ "type" : "actor" } as End User
1503 participant UI@{ "type" : "boundary" } as User Interface
1504 end
1505 box rgb(255,220,200) Backend Layer
1506 participant API@{ "type" : "boundary" } as REST API
1507 participant Svc@{ "type" : "control" } as Business Logic
1508 end
1509 box rgb(220,255,200) Data Layer
1510 participant DB@{ "type" : "database" } as Primary DB
1511 participant Cache@{ "type" : "entity" } as Cache Store
1512 end
1513 User ->> UI: Click button
1514 UI ->> API: HTTP request
1515 API ->> Svc: Process
1516 Svc ->> Cache: Check cache
1517 Cache -->> Svc: Cache miss
1518 Svc ->> DB: Query data
1519 DB -->> Svc: Data
1520 Svc ->> Cache: Update cache
1521 Svc -->> API: Response
1522 API -->> UI: Data
1523 UI -->> User: Display`,
1524 { look: 'classic', sequence: { diagramMarginX: 50, diagramMarginY: 10 } }
1525 );
1526 });
1527
1528 it('should render stereotypes with aliases and complex interactions', () => {
1529 imgSnapshotTest(
1530 `sequenceDiagram
1531 participant Web@{ "type" : "boundary" } as Web Portal
1532 participant Auth@{ "type" : "control" } as Auth Service
1533 participant UserDB@{ "type" : "database" } as User DB
1534 participant Queue@{ "type" : "queue" } as Event Queue
1535 participant Audit@{ "type" : "collections" } as Audit Trail
1536 Web ->> Auth: Login request
1537 activate Auth
1538 Auth ->> UserDB: Verify credentials
1539 activate UserDB
1540 UserDB -->> Auth: User found
1541 deactivate UserDB
1542 alt Valid credentials
1543 Auth ->> Queue: Publish login event
1544 Auth ->> Audit: Log success
1545 par Parallel processing
1546 Queue -->> Auth: Event queued
1547 and
1548 Audit -->> Auth: Logged
1549 end
1550 Auth -->> Web: Success token
1551 else Invalid credentials
1552 Auth ->> Audit: Log failure
1553 Audit -->> Auth: Logged
1554 Auth --x Web: Access denied
1555 end
1556 deactivate Auth
1557 Note over Web,Audit: All interactions logged`,
1558 { look: 'classic', sequence: { diagramMarginX: 50, diagramMarginY: 10 } }
1559 );
1560 });
1561 });
1562
1563 describe('Participant Inline Alias in Config', () => {
1564 it('should render participants with inline alias in config object', () => {
1565 imgSnapshotTest(
1566 `sequenceDiagram
1567 participant API@{ "type" : "boundary", "alias": "Public API" }
1568 participant Auth@{ "type" : "control", "alias": "Auth Service" }
1569 participant DB@{ "type" : "database", "alias": "User DB" }
1570 API ->> Auth: Login request
1571 Auth ->> DB: Query user
1572 DB -->> Auth: User data
1573 Auth -->> API: Token`,
1574 { look: 'classic', sequence: { diagramMarginX: 50, diagramMarginY: 10 } }
1575 );
1576 });
1577
1578 it('should render actors with inline alias in config object', () => {
1579 imgSnapshotTest(
1580 `sequenceDiagram
1581 actor U@{ "type" : "actor", "alias": "End User" }
1582 actor G@{ "type" : "boundary", "alias": "Gateway" }
1583 actor S@{ "type" : "control", "alias": "Service" }
1584 U ->> G: Request
1585 G ->> S: Process
1586 S -->> G: Response
1587 G -->> U: Result`,
1588 { look: 'classic', sequence: { diagramMarginX: 50, diagramMarginY: 10 } }
1589 );
1590 });
1591
1592 it('should handle mixed inline and external alias syntax', () => {
1593 imgSnapshotTest(
1594 `sequenceDiagram
1595 participant A@{ "type" : "boundary", "alias": "Service A" }
1596 participant B@{ "type" : "control" } as Service B
1597 participant C@{ "type" : "database" }
1598 A ->> B: Request
1599 B ->> C: Query
1600 C -->> B: Data
1601 B -->> A: Response`,
1602 { look: 'classic', sequence: { diagramMarginX: 50, diagramMarginY: 10 } }
1603 );
1604 });
1605
1606 it('should prioritize external alias over inline alias', () => {
1607 imgSnapshotTest(
1608 `sequenceDiagram
1609 participant API@{ "type" : "boundary", "alias": "Internal Name" } as External Name
1610 participant DB@{ "type" : "database", "alias": "Internal DB" } AS External DB
1611 API ->> DB: Query
1612 DB -->> API: Result`,
1613 { look: 'classic', sequence: { diagramMarginX: 50, diagramMarginY: 10 } }
1614 );
1615 });
1616
1617 it('should render inline alias with only alias field (no type)', () => {
1618 imgSnapshotTest(
1619 `sequenceDiagram
1620 participant API@{ "alias": "Public API" }
1621 participant Auth@{ "alias": "Auth Service" }
1622 API ->> Auth: Request
1623 Auth -->> API: Response`,
1624 { look: 'classic', sequence: { diagramMarginX: 50, diagramMarginY: 10 } }
1625 );
1626 });
1627 });
1628 });
1629});
1630