mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2025-07-07 09:55:41 +02:00
This adds pasted images to the dropzone to provide the same experience as when using the dropzone. This gives the possibility to preview and delete the image. Additionally it provides a copy button to copy the markdown code for inserting the image. Removed the old implementation in `repo-legacy.js` and generalized everything in `common-global.js` as common implementation. Replaced old jquery code with plain JS. Fixes #4588
94 lines
3.2 KiB
TypeScript
94 lines
3.2 KiB
TypeScript
// 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, ';
|
|
|
|
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, ';
|
|
|
|
await save_visual(page);
|
|
});
|