diff --git a/.github/workflows/files-changed.yml b/.github/workflows/files-changed.yml index 55d206bb0f6..b1d6fbe9d8e 100644 --- a/.github/workflows/files-changed.yml +++ b/.github/workflows/files-changed.yml @@ -21,6 +21,8 @@ on: value: ${{ jobs.detect.outputs.yaml }} json: value: ${{ jobs.detect.outputs.json }} + e2e: + value: ${{ jobs.detect.outputs.e2e }} jobs: detect: @@ -38,6 +40,7 @@ jobs: swagger: ${{ steps.changes.outputs.swagger }} yaml: ${{ steps.changes.outputs.yaml }} json: ${{ steps.changes.outputs.json }} + e2e: ${{ steps.changes.outputs.e2e }} steps: - uses: actions/checkout@v6 - uses: dorny/paths-filter@v4 @@ -107,3 +110,8 @@ jobs: json: - "**/*.json" + + e2e: + - "tests/e2e/**" + - "tools/test-e2e.sh" + - "playwright.config.ts" diff --git a/.github/workflows/pull-e2e-tests.yml b/.github/workflows/pull-e2e-tests.yml index 3472d517c15..fde36383b93 100644 --- a/.github/workflows/pull-e2e-tests.yml +++ b/.github/workflows/pull-e2e-tests.yml @@ -14,7 +14,7 @@ jobs: contents: read test-e2e: - if: needs.files-changed.outputs.backend == 'true' || needs.files-changed.outputs.frontend == 'true' + if: needs.files-changed.outputs.backend == 'true' || needs.files-changed.outputs.frontend == 'true' || needs.files-changed.outputs.e2e == 'true' needs: files-changed runs-on: ubuntu-latest permissions: diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index aea31640b32..3f0c548dcb4 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -151,7 +151,7 @@ Here's how to run the test suite: | :-------------------------------- | :---------------------------------------------------------- | | ``GITEA_TEST_E2E_DEBUG`` | When set, show Gitea server output | | ``GITEA_TEST_E2E_FLAGS`` | Additional flags passed to Playwright, for example ``--ui`` | -| ``GITEA_TEST_E2E_TIMEOUT_FACTOR`` | Timeout multiplier (default: 3 on CI, 1 locally) | +| ``GITEA_TEST_E2E_TIMEOUT_FACTOR`` | Timeout multiplier (default: 4 on CI, 1 locally) | ## Translation diff --git a/tests/e2e/issue-project.test.ts b/tests/e2e/issue-project.test.ts index 451006c3f02..c5249c0cdf7 100644 --- a/tests/e2e/issue-project.test.ts +++ b/tests/e2e/issue-project.test.ts @@ -1,67 +1,30 @@ import {env} from 'node:process'; import {test, expect} from '@playwright/test'; -import {login, apiCreateRepo, apiCreateIssue, apiDeleteRepo, createProjectColumn, randomString, timeoutFactor} from './utils.ts'; +import {login, apiCreateRepo, apiCreateIssue, apiDeleteRepo, createProjectColumn, randomString} from './utils.ts'; test('assign issue to project and change column', async ({page}) => { const repoName = `e2e-issue-project-${randomString(8)}`; const user = env.GITEA_TEST_E2E_USER; await Promise.all([login(page), apiCreateRepo(page.request, {name: repoName})]); - await page.goto(`/${user}/${repoName}/projects/new`); await page.locator('input[name="title"]').fill('Kanban Board'); await page.getByRole('button', {name: 'Create Project'}).click(); - const projectLink = page.locator('.milestone-list a', {hasText: 'Kanban Board'}).first(); await expect(projectLink).toBeVisible(); const href = await projectLink.getAttribute('href'); - const projectID = href!.split('/').pop(); - + const projectID = href!.split('/').pop()!; // columns created via POST because the web UI uses modals that are hard to drive - await Promise.all(['Backlog', 'In Progress', 'Done'].map((title) => - createProjectColumn(page.request, user, repoName, projectID!, title), - )); - - await apiCreateIssue(page.request, user, repoName, {title: 'Column picker test'}); - - // Same ceiling as tests/e2e/events.test.ts; Playwright defaults are 5000*factor (see playwright.config.ts). - const slowTimeout = 15_000 * timeoutFactor; - + await Promise.all([ + ...['Backlog', 'In Progress', 'Done'].map((title) => createProjectColumn(page.request, user, repoName, projectID, title)), + apiCreateIssue(page.request, user, repoName, {title: 'Column picker test'}), + ]); await page.goto(`/${user}/${repoName}/issues/1`); await page.locator('.sidebar-project-combo .ui.dropdown').click(); - await Promise.all([ - page.waitForResponse( - (resp) => resp.url().includes('/issues/projects') && resp.status() === 200, - {timeout: slowTimeout}, - ), - page.locator('.sidebar-project-combo .menu .item', {hasText: 'Kanban Board'}).click(), - ]); - + await page.locator('.sidebar-project-combo .menu a.item', {hasText: 'Kanban Board'}).click(); const columnCombo = page.locator('.sidebar-project-column-combo'); - await expect(columnCombo).toBeVisible({timeout: slowTimeout}); + await expect(columnCombo).toBeVisible(); await columnCombo.locator('.ui.dropdown').click(); - await columnCombo.locator('.menu').waitFor({state: 'visible', timeout: slowTimeout}); - - const inProgressItem = columnCombo.locator('a.item', {hasText: 'In Progress'}); - await expect(inProgressItem).toBeVisible({timeout: slowTimeout}); - await inProgressItem.scrollIntoViewIfNeeded(); - - await Promise.all([ - page.waitForResponse( - (resp) => - resp.request().method() === 'POST' && - resp.url().includes('/issues/projects/column') && - resp.ok(), - {timeout: slowTimeout}, - ), - inProgressItem.click(), - ]); - - await expect(columnCombo.getByTestId('sidebar-project-column-text')).toContainText('In Progress', { - timeout: slowTimeout, - }); - await expect(page.locator('.timeline-item', {hasText: 'moved this to In Progress'})).toBeVisible({ - timeout: slowTimeout, - }); - + await columnCombo.locator('.menu a.item', {hasText: 'In Progress'}).click(); + await expect(columnCombo.getByTestId('sidebar-project-column-text')).toHaveText('In Progress'); await apiDeleteRepo(page.request, user, repoName); }); diff --git a/tools/test-e2e.sh b/tools/test-e2e.sh index b8bf6718392..39405387b5b 100755 --- a/tools/test-e2e.sh +++ b/tools/test-e2e.sh @@ -95,10 +95,11 @@ GITEA_TEST_E2E_EMAIL="$GITEA_TEST_E2E_USER@$GITEA_TEST_E2E_DOMAIN" --must-change-password=false \ --admin -# timeout multiplier, CI runners are slower +# timeout multiplier to make the tests pass on slow CI runners while using +# factor 1 on a fast local machine like a MacBook Pro M1+ if [ -z "${GITEA_TEST_E2E_TIMEOUT_FACTOR:-}" ]; then if [ -n "${CI:-}" ]; then - GITEA_TEST_E2E_TIMEOUT_FACTOR=3 + GITEA_TEST_E2E_TIMEOUT_FACTOR=4 else GITEA_TEST_E2E_TIMEOUT_FACTOR=1 fi