// Copyright 2025 The Forgejo Authors. All rights reserved. // SPDX-License-Identifier: GPL-3.0-or-later // @watch start // web_src/js/features/common-global.js // web_src/js/features/comp/Paste.js // web_src/js/features/repo-issue.js // web_src/js/features/repo-legacy.js // @watch end import {expect, type Locator, type Page, type TestInfo} from '@playwright/test'; import {test, save_visual, dynamic_id} from './utils_e2e.ts'; test.use({user: 'user2'}); async function pasteImage(el: Locator) { await el.evaluate(async (el) => { const base64 = `data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAYAAAAfSC3RAAAAHklEQVQoU2MUk1P7z0AGYBzViDvURgMHT4oaQoEDAFuJEu2fuGfhAAAAAElFTkSuQmCC`; // eslint-disable-next-line no-restricted-syntax const response = await fetch(base64); const blob = await response.blob(); el.focus(); let pasteEvent = new Event('paste', {bubbles: true, cancelable: true}); pasteEvent = Object.assign(pasteEvent, { clipboardData: { items: [ { kind: 'file', type: 'image/png', getAsFile() { return new File([blob], 'foo.png', {type: blob.type}); }, }, ], }, }); el.dispatchEvent(pasteEvent); }); } async function assertCopy(page: Page, workerInfo: TestInfo, startWith: string) { const project = workerInfo.project.name; if (project === 'webkit' || project === 'Mobile Safari') return; const dropzone = page.locator('.dropzone'); const preview = dropzone.locator('.dz-preview'); const copyLink = preview.locator('.octicon-copy').locator('..'); await copyLink.click(); const clipboardContent = await page.evaluate(() => navigator.clipboard.readText()); expect(clipboardContent).toContain(startWith); } test('Paste image in new comment', async ({page}, workerInfo) => { await page.goto('/user2/repo1/issues/new'); await pasteImage(page.locator('.markdown-text-editor')); const dropzone = page.locator('.dropzone'); await expect(dropzone.locator('.files')).toHaveCount(1); const preview = dropzone.locator('.dz-preview'); await expect(preview).toHaveCount(1); await expect(preview.locator('.dz-filename')).toHaveText('foo.png'); await expect(preview.locator('.octicon-copy')).toBeVisible(); await assertCopy(page, workerInfo, '![foo]('); await save_visual(page); }); test('Re-add images to dropzone on edit', async ({page}, workerInfo) => { await page.goto('/user2/repo1/issues/new'); const issueTitle = dynamic_id(); await page.locator('#issue_title').fill(issueTitle); await pasteImage(page.locator('.markdown-text-editor')); await page.getByRole('button', {name: 'Create issue'}).click(); await expect(page).toHaveURL(/\/user2\/repo1\/issues\/\d+$/); await page.click('.comment-container .context-menu'); await page.click('.comment-container .menu > .edit-content'); const dropzone = page.locator('.dropzone'); await expect(dropzone.locator('.files').first()).toHaveCount(1); const preview = dropzone.locator('.dz-preview'); await expect(preview).toHaveCount(1); await expect(preview.locator('.dz-filename')).toHaveText('foo.png'); await expect(preview.locator('.octicon-copy')).toBeVisible(); await assertCopy(page, workerInfo, '![foo]('); await save_visual(page); });