mirror of
https://github.com/go-gitea/gitea.git
synced 2026-05-10 22:41:34 +02:00
Revert e2e org/user deletion to API calls
The UI-based deleteOrg and deleteUser functions fail due to form-fetch-action issues. Revert these to API calls while keeping the working UI-based createRepo/deleteRepo functions. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
c63da125bb
commit
79b4b2e0d4
@ -1,5 +1,5 @@
|
|||||||
import {test, expect} from '@playwright/test';
|
import {test, expect} from '@playwright/test';
|
||||||
import {login, deleteOrg} from './utils.ts';
|
import {login, deleteOrgApi} from './utils.ts';
|
||||||
|
|
||||||
test('create an organization', async ({page}) => {
|
test('create an organization', async ({page}) => {
|
||||||
const orgName = `e2e-org-${Date.now()}`;
|
const orgName = `e2e-org-${Date.now()}`;
|
||||||
@ -8,5 +8,6 @@ test('create an organization', async ({page}) => {
|
|||||||
await page.getByLabel('Organization Name').fill(orgName);
|
await page.getByLabel('Organization Name').fill(orgName);
|
||||||
await page.getByRole('button', {name: 'Create Organization'}).click();
|
await page.getByRole('button', {name: 'Create Organization'}).click();
|
||||||
await expect(page).toHaveURL(new RegExp(`/org/${orgName}`));
|
await expect(page).toHaveURL(new RegExp(`/org/${orgName}`));
|
||||||
await deleteOrg(page, orgName);
|
// delete via API because of issues related to form-fetch-action
|
||||||
|
await deleteOrgApi(page.request, orgName);
|
||||||
});
|
});
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
|
import {env} from 'node:process';
|
||||||
import {test, expect} from '@playwright/test';
|
import {test, expect} from '@playwright/test';
|
||||||
import {login, logout, deleteUser} from './utils.ts';
|
import {login, logout} from './utils.ts';
|
||||||
|
|
||||||
test.beforeEach(async ({page}) => {
|
test.beforeEach(async ({page}) => {
|
||||||
await page.goto('/user/sign_up');
|
await page.goto('/user/sign_up');
|
||||||
@ -48,10 +49,11 @@ test('register then login', async ({page}) => {
|
|||||||
await logout(page);
|
await logout(page);
|
||||||
await login(page, username, password);
|
await login(page, username, password);
|
||||||
|
|
||||||
// Clean up: login as admin and delete the user via site administration
|
// delete via API because of issues related to form-fetch-action
|
||||||
await logout(page);
|
const response = await page.request.delete(`/api/v1/admin/users/${username}?purge=true`, {
|
||||||
await login(page);
|
headers: {Authorization: `Basic ${btoa(`${env.E2E_USER}:${env.E2E_PASSWORD}`)}`},
|
||||||
await deleteUser(page, username);
|
});
|
||||||
|
expect(response.ok()).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('register with existing username shows error', async ({page}) => {
|
test('register with existing username shows error', async ({page}) => {
|
||||||
|
|||||||
@ -1,6 +1,28 @@
|
|||||||
import {env} from 'node:process';
|
import {env} from 'node:process';
|
||||||
import {expect} from '@playwright/test';
|
import {expect} from '@playwright/test';
|
||||||
import type {Locator, Page} from '@playwright/test';
|
import type {APIRequestContext, Locator, Page} from '@playwright/test';
|
||||||
|
|
||||||
|
export function apiBaseUrl() {
|
||||||
|
return env.E2E_URL?.replace(/\/$/g, '');
|
||||||
|
}
|
||||||
|
|
||||||
|
export function apiHeaders() {
|
||||||
|
return {Authorization: `Basic ${globalThis.btoa(`${env.E2E_USER}:${env.E2E_PASSWORD}`)}`};
|
||||||
|
}
|
||||||
|
|
||||||
|
async function apiRetry(fn: () => Promise<{ok: () => boolean; status: () => number; text: () => Promise<string>}>, label: string) {
|
||||||
|
const maxAttempts = 5;
|
||||||
|
for (let attempt = 0; attempt < maxAttempts; attempt++) {
|
||||||
|
const response = await fn();
|
||||||
|
if (response.ok()) return;
|
||||||
|
if ([500, 502, 503].includes(response.status()) && attempt < maxAttempts - 1) {
|
||||||
|
const jitter = Math.random() * 500;
|
||||||
|
await new Promise((resolve) => globalThis.setTimeout(resolve, 1000 * (attempt + 1) + jitter));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
throw new Error(`${label} failed: ${response.status()} ${await response.text()}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export async function createRepo(page: Page, name: string) {
|
export async function createRepo(page: Page, name: string) {
|
||||||
await page.goto('/repo/create');
|
await page.goto('/repo/create');
|
||||||
@ -18,24 +40,10 @@ export async function deleteRepo(page: Page, owner: string, name: string) {
|
|||||||
await page.waitForURL('**/');
|
await page.waitForURL('**/');
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function deleteOrg(page: Page, name: string) {
|
export async function deleteOrgApi(requestContext: APIRequestContext, name: string) {
|
||||||
await page.goto(`/org/${name}/settings`);
|
await apiRetry(() => requestContext.delete(`${apiBaseUrl()}/api/v1/orgs/${name}`, {
|
||||||
await page.locator('button[data-modal="#delete-org-modal"]').click();
|
headers: apiHeaders(),
|
||||||
const modal = page.locator('#delete-org-modal');
|
}), 'deleteOrgApi');
|
||||||
await modal.locator('input[name="org_name"]').fill(name);
|
|
||||||
await modal.getByRole('button', {name: 'Delete This Organization'}).click();
|
|
||||||
await page.waitForURL('**/');
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function deleteUser(page: Page, username: string) {
|
|
||||||
await page.goto(`/-/admin/users?q=${username}`);
|
|
||||||
const userRow = page.locator('tr', {has: page.locator(`a[href="/${username}"]`)});
|
|
||||||
await userRow.locator('a[data-tooltip-content="Edit"]').click();
|
|
||||||
await page.locator('button[data-modal="#delete-user-modal"]').click();
|
|
||||||
const modal = page.locator('#delete-user-modal');
|
|
||||||
await modal.locator('input[name="purge"]').check();
|
|
||||||
await modal.locator('.ok.button').click();
|
|
||||||
await page.waitForURL('**/-/admin/users');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function clickDropdownItem(page: Page, trigger: Locator, itemText: string) {
|
export async function clickDropdownItem(page: Page, trigger: Locator, itemText: string) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user