feat(feedback): render links in the operator reply (open in a new tab)
CI / changes (pull_request) Successful in 2s
CI / unit (pull_request) Successful in 9s
CI / integration (pull_request) Successful in 13s
CI / ui (pull_request) Successful in 47s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m6s

Linkify the operator reply on the feedback screen: http/https/ftp/mailto/tel URLs
become anchors (target=_blank rel=noopener), everything else stays escaped text.
A small whitelisted regex (no dependency) — the reply is operator-authored, so
explicit schemes suffice; dangerous schemes (javascript:/data:) are never linked,
and \b avoids matching a scheme inside a word (hotel:, email:).
This commit is contained in:
Ilia Denisov
2026-06-15 13:25:36 +02:00
parent 55ed87fb11
commit 277954c47f
7 changed files with 110 additions and 9 deletions
+5 -1
View File
@@ -43,7 +43,11 @@ test('feedback: an operator reply raises the badge and shows on the screen', asy
await openFeedback(page);
await expect(page.getByText('Reply to your last message')).toBeVisible();
await expect(page.getByText(/looking into it/)).toBeVisible();
// A URL in the reply renders as a link that opens in a new tab.
const link = page.getByRole('link', { name: 'https://example.com/help' });
await expect(link).toBeVisible();
await expect(link).toHaveAttribute('target', '_blank');
await expect(link).toHaveAttribute('rel', /noopener/);
});
test('feedback: sending a new message clears the previous reply', async ({ page }) => {