mirror of
https://github.com/go-gitea/gitea.git
synced 2026-05-18 03:38:01 +02:00
Revert e2e repo create/delete to API calls, double timeouts
Revert createRepo/deleteRepo to API-based functions for test reliability. The UI-based versions were flaky due to navigation timing. Also double all playwright timeouts (local and CI), rename API functions to apiX convention, and disable playwright/expect-expect lint rule. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
79b4b2e0d4
commit
766ba0184a
@ -913,6 +913,7 @@ export default defineConfig([
|
||||
files: ['tests/e2e/**/*.test.ts'],
|
||||
rules: {
|
||||
...playwright.configs['flat/recommended'].rules,
|
||||
'playwright/expect-expect': [0],
|
||||
},
|
||||
},
|
||||
{
|
||||
|
||||
@ -7,15 +7,15 @@ export default defineConfig({
|
||||
testMatch: /.*\.test\.ts/,
|
||||
forbidOnly: Boolean(env.CI),
|
||||
reporter: 'list',
|
||||
timeout: env.CI ? 6000 : 2000,
|
||||
timeout: env.CI ? 12000 : 6000,
|
||||
expect: {
|
||||
timeout: env.CI ? 3000 : 1000,
|
||||
timeout: env.CI ? 6000 : 3000,
|
||||
},
|
||||
use: {
|
||||
baseURL: env.E2E_URL?.replace?.(/\/$/g, ''),
|
||||
locale: 'en-US',
|
||||
actionTimeout: env.CI ? 3000 : 1000,
|
||||
navigationTimeout: env.CI ? 6000 : 2000,
|
||||
actionTimeout: env.CI ? 6000 : 3000,
|
||||
navigationTimeout: env.CI ? 12000 : 6000,
|
||||
},
|
||||
projects: [
|
||||
{
|
||||
|
||||
@ -6,7 +6,7 @@ test('homepage', async ({page}) => {
|
||||
await expect(page.getByRole('img', {name: 'Logo'})).toHaveAttribute('src', '/assets/img/logo.svg');
|
||||
});
|
||||
|
||||
test('login and logout', async ({page}) => { // eslint-disable-line playwright/expect-expect
|
||||
test('login and logout', async ({page}) => {
|
||||
await login(page);
|
||||
await logout(page);
|
||||
});
|
||||
|
||||
@ -1,14 +1,14 @@
|
||||
import {env} from 'node:process';
|
||||
import {test, expect} from '@playwright/test';
|
||||
import {login, createRepo, deleteRepo} from './utils.ts';
|
||||
import {login, apiCreateRepo, apiDeleteRepo} from './utils.ts';
|
||||
|
||||
test('create a milestone', async ({page}) => {
|
||||
const repoName = `e2e-milestone-${Date.now()}`;
|
||||
await login(page);
|
||||
await createRepo(page, repoName);
|
||||
await apiCreateRepo(page.request, {name: repoName});
|
||||
await page.goto(`/${env.E2E_USER}/${repoName}/milestones/new`);
|
||||
await page.getByPlaceholder('Title').fill('Test Milestone');
|
||||
await page.getByRole('button', {name: 'Create Milestone'}).click();
|
||||
await expect(page.locator('.milestone-list')).toContainText('Test Milestone');
|
||||
await deleteRepo(page, env.E2E_USER, repoName);
|
||||
await apiDeleteRepo(page.request, env.E2E_USER, repoName);
|
||||
});
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import {test, expect} from '@playwright/test';
|
||||
import {login, deleteOrgApi} from './utils.ts';
|
||||
import {login, apiDeleteOrg} from './utils.ts';
|
||||
|
||||
test('create an organization', async ({page}) => {
|
||||
const orgName = `e2e-org-${Date.now()}`;
|
||||
@ -9,5 +9,5 @@ test('create an organization', async ({page}) => {
|
||||
await page.getByRole('button', {name: 'Create Organization'}).click();
|
||||
await expect(page).toHaveURL(new RegExp(`/org/${orgName}`));
|
||||
// delete via API because of issues related to form-fetch-action
|
||||
await deleteOrgApi(page.request, orgName);
|
||||
await apiDeleteOrg(page.request, orgName);
|
||||
});
|
||||
|
||||
@ -1,12 +1,11 @@
|
||||
import {env} from 'node:process';
|
||||
import {test, expect} from '@playwright/test';
|
||||
import {login, createRepo, deleteRepo} from './utils.ts';
|
||||
import {apiCreateRepo, apiDeleteRepo} from './utils.ts';
|
||||
|
||||
test('README renders on repository page', async ({page}) => {
|
||||
const repoName = `e2e-readme-${Date.now()}`;
|
||||
await login(page);
|
||||
await createRepo(page, repoName);
|
||||
await apiCreateRepo(page.request, {name: repoName});
|
||||
await page.goto(`/${env.E2E_USER}/${repoName}`);
|
||||
await expect(page.locator('#readme')).toContainText(repoName);
|
||||
await deleteRepo(page, env.E2E_USER, repoName);
|
||||
await apiDeleteRepo(page.request, env.E2E_USER, repoName);
|
||||
});
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import {env} from 'node:process';
|
||||
import {test, expect} from '@playwright/test';
|
||||
import {login, deleteRepo} from './utils.ts';
|
||||
import {test} from '@playwright/test';
|
||||
import {login, apiDeleteRepo} from './utils.ts';
|
||||
|
||||
test('create a repository', async ({page}) => {
|
||||
const repoName = `e2e-repo-${Date.now()}`;
|
||||
@ -8,6 +8,6 @@ test('create a repository', async ({page}) => {
|
||||
await page.goto('/repo/create');
|
||||
await page.locator('input[name="repo_name"]').fill(repoName);
|
||||
await page.getByRole('button', {name: 'Create Repository'}).click();
|
||||
await expect(page).toHaveURL(new RegExp(`/${env.E2E_USER}/${repoName}$`));
|
||||
await deleteRepo(page, env.E2E_USER, repoName);
|
||||
await page.waitForURL(new RegExp(`/${env.E2E_USER}/${repoName}$`));
|
||||
await apiDeleteRepo(page.request, env.E2E_USER, repoName);
|
||||
});
|
||||
|
||||
@ -24,26 +24,23 @@ async function apiRetry(fn: () => Promise<{ok: () => boolean; status: () => numb
|
||||
}
|
||||
}
|
||||
|
||||
export async function createRepo(page: Page, name: string) {
|
||||
await page.goto('/repo/create');
|
||||
await page.locator('input[name="repo_name"]').fill(name);
|
||||
await page.locator('input[name="auto_init"]').check();
|
||||
await page.getByRole('button', {name: 'Create Repository'}).click();
|
||||
export async function apiCreateRepo(requestContext: APIRequestContext, {name, autoInit = true}: {name: string; autoInit?: boolean}) {
|
||||
await apiRetry(() => requestContext.post(`${apiBaseUrl()}/api/v1/user/repos`, {
|
||||
headers: apiHeaders(),
|
||||
data: {name, auto_init: autoInit},
|
||||
}), 'apiCreateRepo');
|
||||
}
|
||||
|
||||
export async function deleteRepo(page: Page, owner: string, name: string) {
|
||||
await page.goto(`/${owner}/${name}/settings`);
|
||||
await page.locator('button[data-modal="#delete-repo-modal"]').click();
|
||||
const modal = page.locator('#delete-repo-modal');
|
||||
await modal.locator('input[name="repo_name"]').fill(name);
|
||||
await modal.getByRole('button', {name: 'Delete Repository'}).click();
|
||||
await page.waitForURL('**/');
|
||||
export async function apiDeleteRepo(requestContext: APIRequestContext, owner: string, name: string) {
|
||||
await apiRetry(() => requestContext.delete(`${apiBaseUrl()}/api/v1/repos/${owner}/${name}`, {
|
||||
headers: apiHeaders(),
|
||||
}), 'apiDeleteRepo');
|
||||
}
|
||||
|
||||
export async function deleteOrgApi(requestContext: APIRequestContext, name: string) {
|
||||
export async function apiDeleteOrg(requestContext: APIRequestContext, name: string) {
|
||||
await apiRetry(() => requestContext.delete(`${apiBaseUrl()}/api/v1/orgs/${name}`, {
|
||||
headers: apiHeaders(),
|
||||
}), 'deleteOrgApi');
|
||||
}), 'apiDeleteOrg');
|
||||
}
|
||||
|
||||
export async function clickDropdownItem(page: Page, trigger: Locator, itemText: string) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user