// @ts-check // @watch start // templates/repo/issue/view_content/** // web_src/css/repo/issue-** // web_src/js/features/repo-issue** // @watch end import {expect} from '@playwright/test'; import {test, login_user, login} from './utils_e2e.js'; test.beforeAll(async ({browser}, workerInfo) => { await login_user(browser, workerInfo, 'user2'); }); // belongs to test: Pull: Toggle WIP const prTitle = 'pull5'; async function click_toggle_wip({page}) { await page.locator('.toggle-wip>a').click(); await page.waitForLoadState('networkidle'); } async function check_wip({page}, is) { const elemTitle = '#issue-title-display'; const stateLabel = '.issue-state-label'; await expect(page.locator(elemTitle)).toContainText(prTitle); await expect(page.locator(elemTitle)).toContainText('#5'); if (is) { await expect(page.locator(elemTitle)).toContainText('WIP'); await expect(page.locator(stateLabel)).toContainText('Draft'); } else { await expect(page.locator(elemTitle)).not.toContainText('WIP'); await expect(page.locator(stateLabel)).toContainText('Open'); } } test('Pull: Toggle WIP', async ({browser}, workerInfo) => { test.skip(workerInfo.project.name === 'Mobile Safari', 'Unable to get tests working on Safari Mobile, see https://codeberg.org/forgejo/forgejo/pulls/3445#issuecomment-1789636'); const page = await login({browser}, workerInfo); const response = await page.goto('/user2/repo1/pulls/5'); await expect(response?.status()).toBe(200); // Status OK // initial state await check_wip({page}, false); // toggle to WIP await click_toggle_wip({page}); await check_wip({page}, true); // remove WIP await click_toggle_wip({page}); await check_wip({page}, false); // manually edit title to another prefix await page.locator('#issue-title-edit-show').click(); await page.locator('#issue-title-editor input').fill(`[WIP] ${prTitle}`); await page.getByText('Save').click(); await page.waitForLoadState('networkidle'); await check_wip({page}, true); // remove again await click_toggle_wip({page}); await check_wip({page}, false); // check maximum title length is handled gracefully const maxLenStr = prTitle + 'a'.repeat(240); await page.locator('#issue-title-edit-show').click(); await page.locator('#issue-title-editor input').fill(maxLenStr); await page.getByText('Save').click(); await page.waitForLoadState('networkidle'); await click_toggle_wip({page}); await check_wip({page}, true); await click_toggle_wip({page}); await check_wip({page}, false); await expect(page.locator('h1')).toContainText(maxLenStr); // restore original title await page.locator('#issue-title-edit-show').click(); await page.locator('#issue-title-editor input').fill(prTitle); await page.getByText('Save').click(); await check_wip({page}, false); }); test('Issue: Labels', async ({browser}, workerInfo) => { test.skip(workerInfo.project.name === 'Mobile Safari', 'Unable to get tests working on Safari Mobile, see https://codeberg.org/forgejo/forgejo/pulls/3445#issuecomment-1789636'); const page = await login({browser}, workerInfo); // select label list in sidebar only const labelList = page.locator('.issue-content-right .labels-list a'); const response = await page.goto('/user2/repo1/issues/1'); await expect(response?.status()).toBe(200); // preconditions await expect(labelList.filter({hasText: 'label1'})).toBeVisible(); await expect(labelList.filter({hasText: 'label2'})).toBeHidden(); // add label2 await page.locator('.select-label').click(); // label search could be tested this way: // await page.locator('.select-label input').fill('label2'); await page.locator('.select-label .item').filter({hasText: 'label2'}).click(); await page.locator('.select-label').click(); await page.waitForLoadState('networkidle'); await expect(labelList.filter({hasText: 'label2'})).toBeVisible(); // test removing label again await page.locator('.select-label').click(); await page.locator('.select-label .item').filter({hasText: 'label2'}).click(); await page.locator('.select-label').click(); await page.waitForLoadState('networkidle'); await expect(labelList.filter({hasText: 'label2'})).toBeHidden(); await expect(labelList.filter({hasText: 'label1'})).toBeVisible(); }); test('Issue: Milestone', async ({browser}, workerInfo) => { test.skip(workerInfo.project.name === 'Mobile Safari', 'Unable to get tests working on Safari Mobile, see https://codeberg.org/forgejo/forgejo/pulls/3445#issuecomment-1789636'); const page = await login({browser}, workerInfo); const response = await page.goto('/user2/repo1/issues/1'); await expect(response?.status()).toBe(200); const selectedMilestone = page.locator('.issue-content-right .select-milestone.list'); const milestoneDropdown = page.locator('.issue-content-right .select-milestone.dropdown'); await expect(selectedMilestone).toContainText('No milestone'); // Add milestone. await milestoneDropdown.click(); await page.getByRole('option', {name: 'milestone1'}).click(); await expect(selectedMilestone).toContainText('milestone1'); await expect(page.locator('.timeline-item.event').last()).toContainText('user2 added this to the milestone1 milestone'); // Clear milestone. await milestoneDropdown.click(); await page.getByText('Clear milestone', {exact: true}).click(); await expect(selectedMilestone).toContainText('No milestone'); await expect(page.locator('.timeline-item.event').last()).toContainText('user2 removed this from the milestone1 milestone'); }); test('New Issue: Milestone', async ({browser}, workerInfo) => { test.skip(workerInfo.project.name === 'Mobile Safari', 'Unable to get tests working on Safari Mobile, see https://codeberg.org/forgejo/forgejo/pulls/3445#issuecomment-1789636'); const page = await login({browser}, workerInfo); const response = await page.goto('/user2/repo1/issues/new'); await expect(response?.status()).toBe(200); const selectedMilestone = page.locator('.issue-content-right .select-milestone.list'); const milestoneDropdown = page.locator('.issue-content-right .select-milestone.dropdown'); await expect(selectedMilestone).toContainText('No milestone'); // Add milestone. await milestoneDropdown.click(); await page.getByRole('option', {name: 'milestone1'}).click(); await expect(selectedMilestone).toContainText('milestone1'); // Clear milestone. await milestoneDropdown.click(); await page.getByText('Clear milestone', {exact: true}).click(); await expect(selectedMilestone).toContainText('No milestone'); });