diff --git a/src/frontend/apps/impress/src/features/docs/doc-export/__tests__/utilsPrint.test.ts b/src/frontend/apps/impress/src/features/docs/doc-export/__tests__/utilsPrint.test.ts
new file mode 100644
index 000000000..7421e58af
--- /dev/null
+++ b/src/frontend/apps/impress/src/features/docs/doc-export/__tests__/utilsPrint.test.ts
@@ -0,0 +1,70 @@
+import { afterEach, describe, expect, test } from 'vitest';
+
+import { wrapInterlinksWithAnchor, wrapMediaWithLink } from '../utils_print';
+
+describe('print DOM helpers', () => {
+ afterEach(() => {
+ document.body.innerHTML = '';
+ });
+
+ test('wraps media links only inside the provided root', () => {
+ document.body.innerHTML = `
+
+
+
+
+ `;
+
+ const root = document.getElementById('root');
+ if (!root) {
+ throw new Error('missing root');
+ }
+
+ const cleanup = wrapMediaWithLink(root);
+
+ const inside = document.getElementById('inside');
+ const outside = document.getElementById('outside');
+
+ expect(inside?.firstElementChild?.shadowRoot?.textContent).toContain(
+ 'inside.mp3',
+ );
+ expect(outside?.firstElementChild?.shadowRoot).toBeNull();
+
+ cleanup();
+
+ expect(inside?.firstElementChild?.shadowRoot).toBeNull();
+ });
+
+ test('wraps interlinks only inside the provided root', () => {
+ document.body.innerHTML = `
+
+ outside
+
+ inside
+
+
+ `;
+
+ const root = document.getElementById('root');
+ if (!root) {
+ throw new Error('missing root');
+ }
+
+ const cleanup = wrapInterlinksWithAnchor(root);
+
+ expect(root.querySelector('a[data-print-link]')?.textContent).toBe(
+ 'inside',
+ );
+ expect(document.querySelectorAll('a[data-print-link]')).toHaveLength(1);
+
+ cleanup();
+
+ expect(document.querySelectorAll('a[data-print-link]')).toHaveLength(0);
+ });
+});
diff --git a/src/frontend/apps/impress/src/features/docs/doc-export/utils_print.ts b/src/frontend/apps/impress/src/features/docs/doc-export/utils_print.ts
index cdbd30bf1..168869215 100644
--- a/src/frontend/apps/impress/src/features/docs/doc-export/utils_print.ts
+++ b/src/frontend/apps/impress/src/features/docs/doc-export/utils_print.ts
@@ -175,7 +175,7 @@ function appendPrintOnlyStyles() {
/**
* Wraps media elements with links to their source URLs for printing.
*/
-function wrapMediaWithLink() {
+export function wrapMediaWithLink(root: ParentNode = document) {
const createdShadowWrapper: HTMLElement[] = [];
const prependLink = (
@@ -222,7 +222,7 @@ function wrapMediaWithLink() {
createdShadowWrapper.push(shadowWrapper);
};
- document
+ root
.querySelectorAll(
'[data-content-type="pdf"], [data-content-type="file"], [data-content-type="audio"], [data-content-type="video"]',
)
@@ -248,14 +248,14 @@ function wrapMediaWithLink() {
* Wraps interlink inline content with anchor tags for printing,
* so they appear as clickable links in the printed PDF.
*/
-function wrapInterlinksWithAnchor() {
+export function wrapInterlinksWithAnchor(root: ParentNode = document) {
const wrappedElements: Array<{
el: Element;
anchor: HTMLAnchorElement;
parent: Node;
}> = [];
- document
+ root
.querySelectorAll('.--docs--interlinking-link-inline-content[data-href]')
.forEach((el) => {
const href = el.getAttribute('data-href');