[v15.0/forgejo] fix: CodeMirror e2e test (#12199)

**Backport:** https://codeberg.org/forgejo/forgejo/pulls/12151

I tried a lot, but this seems to work. I know it is ugly, but checking and waiting after every action seems to make it stable. At least it succeeded five times in a row and the CI seemed to be under load due to the dependency updates. Maybe it is worth a try...

Co-authored-by: Beowulf <beowulf@beocode.eu>
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/12199
Reviewed-by: Beowulf <beowulf@beocode.eu>
Co-authored-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
Co-committed-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
This commit is contained in:
forgejo-backport-action 2026-04-20 14:23:22 +02:00 committed by Beowulf
parent 4a97de08f4
commit 7aa4b29d56

View file

@ -21,17 +21,21 @@ async function enterFilename(page: Page, filename: string) {
}
async function pressEnter(page: Page) {
// eslint-disable-next-line playwright/no-wait-for-timeout
await page.waitForTimeout(5);
await page.keyboard.press('Enter', {delay: 5});
// eslint-disable-next-line playwright/no-wait-for-timeout
await page.waitForTimeout(10);
}
async function type(page: Page, text: string) {
await page.keyboard.type(text, {delay: 10});
}
async function validate(page: Page, expected: string) {
await expect(async () => {
const internal = await page.evaluate(() => Array.from(window.codeEditors)[0].state.doc.toString());
expect(internal).toStrictEqual(expected);
}).toPass();
await expect(page.locator('#edit_area')).toHaveValue(expected);
}
test('New file editor', async ({page}) => {
const response = await page.goto('/user2/repo1/_new/master', {waitUntil: 'domcontentloaded'});
expect(response?.status()).toBe(200);
@ -39,21 +43,19 @@ test('New file editor', async ({page}) => {
await enterFilename(page, `f.txt`);
const editor = page.locator('.cm-content');
const backingTextArea = page.locator('#edit_area');
await editor.click();
await type(page, 'This');
await pressEnter(page);
await validate(page, 'This\n');
await type(page, 'is');
await pressEnter(page);
await type(page, 'Frogejo!');
await validate(page, 'This\nis\n');
const expected = 'This\nis\nFrogejo!';
await expect(async () => {
const internal = await page.evaluate(() => Array.from(window.codeEditors)[0].state.doc.toString());
expect(internal).toStrictEqual(expected);
}).toPass();
await expect(backingTextArea).toHaveValue(expected);
await type(page, 'Frogejo!');
await validate(page, 'This\nis\nFrogejo!');
});
test('New file with autocomplete and indent', async ({page}) => {
@ -63,26 +65,20 @@ test('New file with autocomplete and indent', async ({page}) => {
await enterFilename(page, 'f.html');
const editor = page.locator('.cm-content');
const backingTextArea = page.locator('#edit_area');
await expect(editor).toHaveAttribute('data-language', 'html', {timeout: 3000});
await editor.click();
await type(page, '<html>');
await pressEnter(page);
await type(page, '<hea');
await page.locator('.cm-tooltip-autocomplete').waitFor({state: 'visible'});
await pressEnter(page);
await type(page, '>');
await pressEnter(page);
await type(page, '<title>Frogejo is the future');
await validate(page, '<html>\n \n</html>');
const expected = '<html>\n <head>\n <title>Frogejo is the future</title>\n </head>\n</html>';
await expect(async () => {
const internal = await page.evaluate(() => Array.from(window.codeEditors)[0].state.doc.toString());
expect(internal).toStrictEqual(expected);
}).toPass();
await expect(backingTextArea).toHaveValue(expected);
await type(page, '<head>');
await pressEnter(page);
await validate(page, '<html>\n <head>\n \n </head>\n</html>');
await type(page, '<title>Frogejo is the future');
await validate(page, '<html>\n <head>\n <title>Frogejo is the future</title>\n </head>\n</html>');
});
test('Preview for markdown file', async ({page}) => {
@ -105,10 +101,7 @@ test('Set from query', async ({page}) => {
const response = await page.goto('/user2/repo1/_new/master?value=This\\nis\\\\nFrogejo!', {waitUntil: 'domcontentloaded'});
expect(response?.status()).toBe(200);
await expect(async () => {
const internal = await page.evaluate(() => Array.from(window.codeEditors)[0].state.doc.toString());
expect(internal).toStrictEqual('This\nis\\nFrogejo!');
}).toPass();
await validate(page, 'This\nis\\nFrogejo!');
});
test('Search in file', async ({page}) => {
@ -122,10 +115,7 @@ test('Search in file', async ({page}) => {
const toggleByWord = page.locator('label[for="search_by_word"]');
const nextButton = page.locator('button[aria-label="Next find"]');
await expect(async () => {
const internal = await page.evaluate(() => Array.from(window.codeEditors)[0].state.doc.toString());
expect(internal).toStrictEqual('This\nis\nFrogejo!\nthIs');
}).toPass();
await validate(page, 'This\nis\nFrogejo!\nthIs');
await editor.click();
@ -180,10 +170,7 @@ test('Replace in file', async ({page}) => {
const searchField = page.locator('.fj-search input[name="search"]');
const replaceField = page.locator('.fj-search input[name="replace"]');
await expect(async () => {
const internal = await page.evaluate(() => Array.from(window.codeEditors)[0].state.doc.toString());
expect(internal).toStrictEqual('This\nis\nFrogejo!\nthIs');
}).toPass();
await validate(page, 'This\nis\nFrogejo!\nthIs');
await editor.click();
@ -196,10 +183,7 @@ test('Replace in file', async ({page}) => {
await page.getByRole('button', {name: 'Replace all'}).click();
await expect(async () => {
const internal = await page.evaluate(() => Array.from(window.codeEditors)[0].state.doc.toString());
expect(internal).toStrictEqual('ThBlub\nBlub\nFrogejo!\nthBlub');
}).toPass();
await validate(page, 'ThBlub\nBlub\nFrogejo!\nthBlub');
});
test('Do not open search if search button not available', async ({page}) => {