diff --git a/tests/e2e/markdown-copy-formatting.spec.ts b/tests/e2e/markdown-copy-formatting.spec.ts new file mode 100644 index 00000000000..5ef99daf431 --- /dev/null +++ b/tests/e2e/markdown-copy-formatting.spec.ts @@ -0,0 +1,59 @@ +import { test, expect } from './helpers/orca-app' +import { waitForActiveWorktree, waitForSessionReady } from './helpers/store' +import { + cleanupMarkdownFixture, + createMarkdownFixture, + getActiveWorktreeContext, + openMarkdownFixture, + waitForRichMarkdownEditor +} from './helpers/markdown-editor-fixture' + +test('copying a rich selection preserves Markdown formatting', async ({ orcaPage }, testInfo) => { + await waitForSessionReady(orcaPage) + await waitForActiveWorktree(orcaPage) + const context = await getActiveWorktreeContext(orcaPage) + const filePath = await createMarkdownFixture( + context, + 'markdown-clipboard', + 'formatted-copy', + testInfo.workerIndex, + '# Copy formatting\n\nA **bold** paragraph with a [link](https://example.com).\n' + ) + try { + await openMarkdownFixture(orcaPage, context, filePath) + const editor = await waitForRichMarkdownEditor(orcaPage) + await expect(editor.locator('strong')).toHaveText('bold') + await editor.locator('p').evaluate((paragraph) => { + const range = document.createRange() + range.selectNodeContents(paragraph) + const selection = window.getSelection() + selection?.removeAllRanges() + selection?.addRange(range) + paragraph.closest('[contenteditable]')?.focus() + document.dispatchEvent(new Event('selectionchange')) + }) + await expect + .poll(() => orcaPage.evaluate(() => window.getSelection()?.toString())) + .toBe('A bold paragraph with a link.') + await testInfo.attach('formatted-selection', { + body: await orcaPage.screenshot({ path: testInfo.outputPath('formatted-selection.png') }), + contentType: 'image/png' + }) + const copied = await editor.evaluate((element) => { + // Keep this check isolated from the user's system clipboard. + const clipboardData = new DataTransfer() + element.dispatchEvent( + new ClipboardEvent('copy', { clipboardData, bubbles: true, cancelable: true }) + ) + return { text: clipboardData.getData('text/plain'), html: clipboardData.getData('text/html') } + }) + expect(copied.text).toContain('**bold**') + expect(copied.text).toContain('[link](https://example.com)') + expect(copied.text).not.toContain('# Copy formatting') + expect(copied.html).toContain('bold') + await expect(editor.locator('p')).toHaveText('A bold paragraph with a link.') + await testInfo.attach('copied-markdown', { body: copied.text, contentType: 'text/markdown' }) + } finally { + await cleanupMarkdownFixture(filePath) + } +})