mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2024-11-24 06:15:42 +03:00
Merge pull request 'refactor: Migrate playwright to typescript' (#5734) from anbraten/forgejo:ts-test into forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5734 Reviewed-by: Otto <otto@codeberg.org> Reviewed-by: Michael Kriese <michael.kriese@gmx.de>
This commit is contained in:
commit
1b3497c9c4
25 changed files with 42 additions and 79 deletions
|
@ -1,4 +1,4 @@
|
|||
import {devices} from '@playwright/test';
|
||||
import {devices, type PlaywrightTestConfig} from '@playwright/test';
|
||||
|
||||
const BASE_URL = process.env.GITEA_URL?.replace?.(/\/$/g, '') || 'http://localhost:3000';
|
||||
|
||||
|
@ -8,7 +8,7 @@ const BASE_URL = process.env.GITEA_URL?.replace?.(/\/$/g, '') || 'http://localho
|
|||
*/
|
||||
export default {
|
||||
testDir: './tests/e2e/',
|
||||
testMatch: /.*\.test\.e2e\.js/, // Match any .test.e2e.js files
|
||||
testMatch: /.*\.test\.e2e\.ts/, // Match any .test.e2e.js files
|
||||
|
||||
// you can adjust this value locally to match your machine's power,
|
||||
// or pass `--workers x` to playwright
|
||||
|
@ -99,4 +99,4 @@ export default {
|
|||
outputDir: 'tests/e2e/test-artifacts/',
|
||||
/* Folder for test artifacts such as screenshots, videos, traces, etc. */
|
||||
snapshotDir: 'tests/e2e/test-snapshots/',
|
||||
};
|
||||
} satisfies PlaywrightTestConfig;
|
||||
|
|
|
@ -90,7 +90,7 @@ npx playwright test --ui
|
|||
#### Running individual tests
|
||||
|
||||
```
|
||||
npx playwright test actions.test.e2e.js:9
|
||||
npx playwright test actions.test.e2e.ts:9
|
||||
```
|
||||
|
||||
First, specify the complete test filename,
|
||||
|
@ -144,7 +144,7 @@ TEST_PGSQL_HOST=localhost:5432 TEST_PGSQL_DBNAME=test TEST_PGSQL_USERNAME=postgr
|
|||
|
||||
### Running individual tests
|
||||
|
||||
Example command to run `example.test.e2e.js` test file:
|
||||
Example command to run `example.test.e2e.ts` test file:
|
||||
|
||||
> **Note**
|
||||
> Unlike integration tests, this filtering is at the file level, not function
|
||||
|
@ -211,7 +211,7 @@ Feel free to improve the logic used there if you need more advanced functionalit
|
|||
If you can, perform automated accessibility testing using
|
||||
[AxeCore](https://github.com/dequelabs/axe-core-npm/blob/develop/packages/playwright/README.md).
|
||||
|
||||
Take a look at `shared/forms.js` and some other places for inspiration.
|
||||
Take a look at `shared/forms.ts` and some other places for inspiration.
|
||||
|
||||
### List related files coverage
|
||||
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
// @ts-check
|
||||
|
||||
// @watch start
|
||||
// templates/repo/actions/**
|
||||
// web_src/css/actions.css
|
||||
|
@ -12,7 +10,7 @@
|
|||
// @watch end
|
||||
|
||||
import {expect} from '@playwright/test';
|
||||
import {test, login_user, load_logged_in_context} from './utils_e2e.js';
|
||||
import {test, login_user, load_logged_in_context} from './utils_e2e.ts';
|
||||
|
||||
test.beforeAll(async ({browser}, workerInfo) => {
|
||||
await login_user(browser, workerInfo, 'user2');
|
|
@ -29,7 +29,7 @@ func initChangedFiles() {
|
|||
globalPatterns := []string{
|
||||
// meta and config
|
||||
"Makefile",
|
||||
"playwright.config.js",
|
||||
"playwright.config.ts",
|
||||
".forgejo/workflows/testing.yml",
|
||||
"tests/e2e/*.go",
|
||||
"tests/e2e/shared/*",
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
// @ts-check
|
||||
|
||||
// @watch start
|
||||
// web_src/js/components/DashboardRepoList.vue
|
||||
// @watch end
|
||||
|
||||
import {expect} from '@playwright/test';
|
||||
import {test, login_user, load_logged_in_context} from './utils_e2e.js';
|
||||
import {test, login_user, load_logged_in_context} from './utils_e2e.ts';
|
||||
|
||||
test.beforeAll(async ({browser}, workerInfo) => {
|
||||
await login_user(browser, workerInfo, 'user2');
|
|
@ -79,7 +79,7 @@ func TestMain(m *testing.M) {
|
|||
// TestE2e should be the only test e2e necessary. It will collect all "*.test.e2e.js" files in this directory and build a test for each.
|
||||
func TestE2e(t *testing.T) {
|
||||
// Find the paths of all e2e test files in test directory.
|
||||
searchGlob := filepath.Join(filepath.Dir(setting.AppPath), "tests", "e2e", "*.test.e2e.js")
|
||||
searchGlob := filepath.Join(filepath.Dir(setting.AppPath), "tests", "e2e", "*.test.e2e.ts")
|
||||
paths, err := filepath.Glob(searchGlob)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
// @ts-check
|
||||
|
||||
// @watch start
|
||||
// templates/user/auth/**
|
||||
// web_src/js/features/user-**
|
||||
|
@ -7,7 +5,7 @@
|
|||
// @watch end
|
||||
|
||||
import {expect} from '@playwright/test';
|
||||
import {test, login_user, save_visual} from './utils_e2e.js';
|
||||
import {test, login_user, save_visual} from './utils_e2e.ts';
|
||||
|
||||
test.beforeAll(async ({browser}, workerInfo) => {
|
||||
await login_user(browser, workerInfo, 'user2');
|
|
@ -1,4 +1,3 @@
|
|||
// @ts-check
|
||||
// document is a global in evaluate, so it's safe to ignore here
|
||||
// eslint playwright/no-conditional-in-test: 0
|
||||
|
||||
|
@ -8,7 +7,7 @@
|
|||
// @watch end
|
||||
|
||||
import {expect} from '@playwright/test';
|
||||
import {test} from './utils_e2e.js';
|
||||
import {test} from './utils_e2e.ts';
|
||||
|
||||
test('Explore view taborder', async ({page}) => {
|
||||
await page.goto('/explore/repos');
|
|
@ -1,5 +1,3 @@
|
|||
// @ts-check
|
||||
|
||||
// @watch start
|
||||
// web_src/js/features/comp/**
|
||||
// web_src/js/features/repo-**
|
||||
|
@ -7,7 +5,7 @@
|
|||
// @watch end
|
||||
|
||||
import {expect} from '@playwright/test';
|
||||
import {test, login_user, login} from './utils_e2e.js';
|
||||
import {test, login_user, login} from './utils_e2e.ts';
|
||||
|
||||
test.beforeAll(async ({browser}, workerInfo) => {
|
||||
await login_user(browser, workerInfo, 'user2');
|
|
@ -1,5 +1,3 @@
|
|||
// @ts-check
|
||||
|
||||
// @watch start
|
||||
// templates/repo/issue/view_content/**
|
||||
// web_src/css/repo/issue-**
|
||||
|
@ -7,7 +5,7 @@
|
|||
// @watch end
|
||||
|
||||
import {expect} from '@playwright/test';
|
||||
import {test, login_user, login} from './utils_e2e.js';
|
||||
import {test, login_user, login} from './utils_e2e.ts';
|
||||
|
||||
test.beforeAll(async ({browser}, workerInfo) => {
|
||||
await login_user(browser, workerInfo, 'user2');
|
|
@ -1,5 +1,3 @@
|
|||
// @ts-check
|
||||
|
||||
// @watch start
|
||||
// web_src/js/features/comp/ComboMarkdownEditor.js
|
||||
// web_src/css/editor/combomarkdowneditor.css
|
||||
|
@ -7,7 +5,7 @@
|
|||
// @watch end
|
||||
|
||||
import {expect} from '@playwright/test';
|
||||
import {test, load_logged_in_context, login_user} from './utils_e2e.js';
|
||||
import {test, load_logged_in_context, login_user} from './utils_e2e.ts';
|
||||
|
||||
test.beforeAll(async ({browser}, workerInfo) => {
|
||||
await login_user(browser, workerInfo, 'user2');
|
|
@ -1,11 +1,9 @@
|
|||
// @ts-check
|
||||
|
||||
// @watch start
|
||||
// web_src/css/markup/**
|
||||
// @watch end
|
||||
|
||||
import {expect} from '@playwright/test';
|
||||
import {test} from './utils_e2e.js';
|
||||
import {test} from './utils_e2e.ts';
|
||||
|
||||
test('markup with #xyz-mode-only', async ({page}) => {
|
||||
const response = await page.goto('/user2/repo1/issues/1');
|
|
@ -1,5 +1,3 @@
|
|||
// @ts-check
|
||||
|
||||
// @watch start
|
||||
// templates/org/team/new.tmpl
|
||||
// web_src/css/form.css
|
||||
|
@ -7,8 +5,8 @@
|
|||
// @watch end
|
||||
|
||||
import {expect} from '@playwright/test';
|
||||
import {test, login_user, login} from './utils_e2e.js';
|
||||
import {validate_form} from './shared/forms.js';
|
||||
import {test, login_user, login} from './utils_e2e.ts';
|
||||
import {validate_form} from './shared/forms.ts';
|
||||
|
||||
test.beforeAll(async ({browser}, workerInfo) => {
|
||||
await login_user(browser, workerInfo, 'user2');
|
|
@ -1,5 +1,3 @@
|
|||
// @ts-check
|
||||
|
||||
// @watch start
|
||||
// routers/web/user/**
|
||||
// templates/shared/user/**
|
||||
|
@ -7,7 +5,7 @@
|
|||
// @watch end
|
||||
|
||||
import {expect} from '@playwright/test';
|
||||
import {test, login_user, load_logged_in_context} from './utils_e2e.js';
|
||||
import {test, login_user, load_logged_in_context} from './utils_e2e.ts';
|
||||
|
||||
test('Follow actions', async ({browser}, workerInfo) => {
|
||||
await login_user(browser, workerInfo, 'user2');
|
|
@ -1,12 +1,10 @@
|
|||
// @ts-check
|
||||
|
||||
// @watch start
|
||||
// web_src/js/features/comp/ReactionSelector.js
|
||||
// routers/web/repo/issue.go
|
||||
// @watch end
|
||||
|
||||
import {expect} from '@playwright/test';
|
||||
import {test, login_user, load_logged_in_context} from './utils_e2e.js';
|
||||
import {test, login_user, load_logged_in_context} from './utils_e2e.ts';
|
||||
|
||||
test.beforeAll(async ({browser}, workerInfo) => {
|
||||
await login_user(browser, workerInfo, 'user2');
|
|
@ -1,5 +1,3 @@
|
|||
// @ts-check
|
||||
|
||||
// @watch start
|
||||
// models/repo/attachment.go
|
||||
// modules/structs/attachment.go
|
||||
|
@ -11,8 +9,8 @@
|
|||
// @watch end
|
||||
|
||||
import {expect} from '@playwright/test';
|
||||
import {test, login_user, save_visual, load_logged_in_context} from './utils_e2e.js';
|
||||
import {validate_form} from './shared/forms.js';
|
||||
import {test, login_user, save_visual, load_logged_in_context} from './utils_e2e.ts';
|
||||
import {validate_form} from './shared/forms.ts';
|
||||
|
||||
test.beforeAll(async ({browser}, workerInfo) => {
|
||||
await login_user(browser, workerInfo, 'user2');
|
|
@ -1,5 +1,3 @@
|
|||
// @ts-check
|
||||
|
||||
// @watch start
|
||||
// web_src/js/features/repo-code.js
|
||||
// web_src/css/repo.css
|
||||
|
@ -7,7 +5,7 @@
|
|||
// @watch end
|
||||
|
||||
import {expect} from '@playwright/test';
|
||||
import {test, login_user, load_logged_in_context} from './utils_e2e.js';
|
||||
import {test, login_user, load_logged_in_context} from './utils_e2e.ts';
|
||||
|
||||
test.beforeAll(async ({browser}, workerInfo) => {
|
||||
await login_user(browser, workerInfo, 'user2');
|
|
@ -1,5 +1,3 @@
|
|||
// @ts-check
|
||||
|
||||
// @watch start
|
||||
// templates/repo/graph.tmpl
|
||||
// web_src/css/features/gitgraph.css
|
||||
|
@ -7,7 +5,7 @@
|
|||
// @watch end
|
||||
|
||||
import {expect} from '@playwright/test';
|
||||
import {test, login_user, load_logged_in_context} from './utils_e2e.js';
|
||||
import {test, login_user, load_logged_in_context} from './utils_e2e.ts';
|
||||
|
||||
test.beforeAll(async ({browser}, workerInfo) => {
|
||||
await login_user(browser, workerInfo, 'user2');
|
|
@ -1,11 +1,9 @@
|
|||
// @ts-check
|
||||
|
||||
// @watch start
|
||||
// web_src/js/features/repo-migrate.js
|
||||
// @watch end
|
||||
|
||||
import {expect} from '@playwright/test';
|
||||
import {test, login_user, load_logged_in_context} from './utils_e2e.js';
|
||||
import {test, login_user, load_logged_in_context} from './utils_e2e.ts';
|
||||
|
||||
test.beforeAll(({browser}, workerInfo) => login_user(browser, workerInfo, 'user2'));
|
||||
|
|
@ -1,5 +1,3 @@
|
|||
// @ts-check
|
||||
|
||||
// @watch start
|
||||
// templates/webhook/shared-settings.tmpl
|
||||
// templates/repo/settings/**
|
||||
|
@ -9,8 +7,8 @@
|
|||
// @watch end
|
||||
|
||||
import {expect} from '@playwright/test';
|
||||
import {test, login_user, login} from './utils_e2e.js';
|
||||
import {validate_form} from './shared/forms.js';
|
||||
import {test, login_user, login} from './utils_e2e.ts';
|
||||
import {validate_form} from './shared/forms.ts';
|
||||
|
||||
test.beforeAll(async ({browser}, workerInfo) => {
|
||||
await login_user(browser, workerInfo, 'user2');
|
|
@ -1,12 +1,10 @@
|
|||
// @ts-check
|
||||
|
||||
// @watch start
|
||||
// templates/repo/wiki/**
|
||||
// web_src/css/repo**
|
||||
// @watch end
|
||||
|
||||
import {expect} from '@playwright/test';
|
||||
import {test} from './utils_e2e.js';
|
||||
import {test} from './utils_e2e.ts';
|
||||
|
||||
test(`Search for long titles and test for no overflow`, async ({page}, workerInfo) => {
|
||||
test.skip(workerInfo.project.name === 'Mobile Safari', 'Fails as always, see https://codeberg.org/forgejo/forgejo/pulls/5326#issuecomment-2313275');
|
|
@ -1,5 +1,3 @@
|
|||
// @ts-check
|
||||
|
||||
// @watch start
|
||||
// templates/org/**
|
||||
// templates/repo/**
|
||||
|
@ -7,7 +5,7 @@
|
|||
// @watch end
|
||||
|
||||
import {expect} from '@playwright/test';
|
||||
import {test, login_user, load_logged_in_context} from './utils_e2e.js';
|
||||
import {test, login_user, load_logged_in_context} from './utils_e2e.ts';
|
||||
|
||||
test.beforeAll(async ({browser}, workerInfo) => {
|
||||
await login_user(browser, workerInfo, 'user2');
|
|
@ -1,8 +1,7 @@
|
|||
import {expect} from '@playwright/test';
|
||||
import {expect, type Page} from '@playwright/test';
|
||||
import {AxeBuilder} from '@axe-core/playwright';
|
||||
|
||||
export async function validate_form({page}, scope) {
|
||||
scope ??= 'form';
|
||||
export async function validate_form({page}: {page: Page}, scope: 'form' | 'fieldset' = 'form') {
|
||||
const accessibilityScanResults = await new AxeBuilder({page})
|
||||
// disable checking for link style - should be fixed, but not now
|
||||
.disableRules('link-in-text-block')
|
|
@ -1,4 +1,4 @@
|
|||
import {expect, test as baseTest} from '@playwright/test';
|
||||
import {expect, test as baseTest, type Browser, type BrowserContextOptions, type APIRequestContext, type TestInfo, type Page} from '@playwright/test';
|
||||
|
||||
export const test = baseTest.extend({
|
||||
context: async ({browser}, use) => {
|
||||
|
@ -6,7 +6,7 @@ export const test = baseTest.extend({
|
|||
},
|
||||
});
|
||||
|
||||
async function test_context(browser, options) {
|
||||
async function test_context(browser: Browser, options?: BrowserContextOptions) {
|
||||
const context = await browser.newContext(options);
|
||||
|
||||
context.on('page', (page) => {
|
||||
|
@ -21,7 +21,7 @@ const LOGIN_PASSWORD = 'password';
|
|||
|
||||
// log in user and store session info. This should generally be
|
||||
// run in test.beforeAll(), then the session can be loaded in tests.
|
||||
export async function login_user(browser, workerInfo, user) {
|
||||
export async function login_user(browser: Browser, workerInfo: TestInfo, user: string) {
|
||||
test.setTimeout(60000);
|
||||
// Set up a new context
|
||||
const context = await test_context(browser);
|
||||
|
@ -47,7 +47,7 @@ export async function login_user(browser, workerInfo, user) {
|
|||
return context;
|
||||
}
|
||||
|
||||
export async function load_logged_in_context(browser, workerInfo, user) {
|
||||
export async function load_logged_in_context(browser: Browser, workerInfo: TestInfo, user: string) {
|
||||
let context;
|
||||
try {
|
||||
context = await test_context(browser, {storageState: `${ARTIFACTS_PATH}/state-${user}-${workerInfo.workerIndex}.json`});
|
||||
|
@ -59,12 +59,12 @@ export async function load_logged_in_context(browser, workerInfo, user) {
|
|||
return context;
|
||||
}
|
||||
|
||||
export async function login({browser}, workerInfo) {
|
||||
export async function login({browser}: {browser: Browser}, workerInfo: TestInfo) {
|
||||
const context = await load_logged_in_context(browser, workerInfo, 'user2');
|
||||
return await context.newPage();
|
||||
return await context?.newPage();
|
||||
}
|
||||
|
||||
export async function save_visual(page) {
|
||||
export async function save_visual(page: Page) {
|
||||
// Optionally include visual testing
|
||||
if (process.env.VISUAL_TEST) {
|
||||
await page.waitForLoadState('networkidle');
|
||||
|
@ -83,7 +83,7 @@ export async function save_visual(page) {
|
|||
|
||||
// Create a temporary user and login to that user and store session info.
|
||||
// This should ideally run on a per test basis.
|
||||
export async function create_temp_user(browser, workerInfo, request) {
|
||||
export async function create_temp_user(browser: Browser, workerInfo: TestInfo, request: APIRequestContext) {
|
||||
const username = globalThis.crypto.randomUUID();
|
||||
const newUser = await request.post(`/api/v1/admin/users`, {
|
||||
headers: {
|
|
@ -1,6 +1,5 @@
|
|||
// Copyright 2024 The Forgejo Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
// @ts-check
|
||||
|
||||
// @watch start
|
||||
// templates/user/auth/**
|
||||
|
@ -9,7 +8,7 @@
|
|||
// @watch end
|
||||
|
||||
import {expect} from '@playwright/test';
|
||||
import {test, create_temp_user} from './utils_e2e.js';
|
||||
import {test, create_temp_user} from './utils_e2e.ts';
|
||||
|
||||
test('WebAuthn register & login flow', async ({browser, request}, workerInfo) => {
|
||||
test.skip(workerInfo.project.name !== 'chromium', 'Uses Chrome protocol');
|
||||
|
@ -31,7 +30,7 @@ test('WebAuthn register & login flow', async ({browser, request}, workerInfo) =>
|
|||
transport: 'usb',
|
||||
automaticPresenceSimulation: true,
|
||||
isUserVerified: true,
|
||||
backupEligibility: true,
|
||||
backupEligibility: true, // TODO: this doesn't seem to be available?!
|
||||
},
|
||||
});
|
||||
|
Loading…
Reference in a new issue