mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2025-01-11 08:02:15 +01:00
68d690b6b9
Some checks are pending
/ release (push) Waiting to run
testing / test-remote-cacher (redis) (push) Blocked by required conditions
testing / backend-checks (push) Waiting to run
testing / frontend-checks (push) Waiting to run
testing / test-unit (push) Blocked by required conditions
testing / test-e2e (push) Blocked by required conditions
testing / test-remote-cacher (valkey) (push) Blocked by required conditions
testing / test-remote-cacher (garnet) (push) Blocked by required conditions
testing / test-remote-cacher (redict) (push) Blocked by required conditions
testing / test-mysql (push) Blocked by required conditions
testing / test-pgsql (push) Blocked by required conditions
testing / test-sqlite (push) Blocked by required conditions
testing / security-check (push) Blocked by required conditions
Replaced manual login and context loading across tests with Playwright's `test.use` configuration for user authentication. This simplifies test setup, improves readability, and reduces repetition. For #6362 Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6400 Reviewed-by: Gusted <gusted@noreply.codeberg.org> Co-authored-by: Julian Schlarb <julian.schlarb@denktmit.de> Co-committed-by: Julian Schlarb <julian.schlarb@denktmit.de>
193 lines
4.8 KiB
Go
193 lines
4.8 KiB
Go
// Copyright 2019 The Gitea Authors. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package e2e
|
|
|
|
import (
|
|
"context"
|
|
"crypto/rand"
|
|
"encoding/hex"
|
|
"fmt"
|
|
"net"
|
|
"net/http"
|
|
"net/url"
|
|
"os"
|
|
"path/filepath"
|
|
"regexp"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"code.gitea.io/gitea/models/unittest"
|
|
user_model "code.gitea.io/gitea/models/user"
|
|
"code.gitea.io/gitea/modules/json"
|
|
modules_session "code.gitea.io/gitea/modules/session"
|
|
"code.gitea.io/gitea/modules/setting"
|
|
"code.gitea.io/gitea/tests"
|
|
|
|
"code.forgejo.org/go-chi/session"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
var rootPathRe = regexp.MustCompile("\\[repository\\]\nROOT\\s=\\s.*")
|
|
|
|
func onForgejoRunTB(t testing.TB, callback func(testing.TB, *url.URL), prepare ...bool) {
|
|
if len(prepare) == 0 || prepare[0] {
|
|
defer tests.PrepareTestEnv(t, 1)()
|
|
}
|
|
createSessions(t)
|
|
|
|
s := http.Server{
|
|
Handler: testE2eWebRoutes,
|
|
}
|
|
|
|
u, err := url.Parse(setting.AppURL)
|
|
require.NoError(t, err)
|
|
listener, err := net.Listen("tcp", u.Host)
|
|
i := 0
|
|
for err != nil && i <= 10 {
|
|
time.Sleep(100 * time.Millisecond)
|
|
listener, err = net.Listen("tcp", u.Host)
|
|
i++
|
|
}
|
|
require.NoError(t, err)
|
|
u.Host = listener.Addr().String()
|
|
|
|
// Override repository root in config.
|
|
conf, err := os.ReadFile(setting.CustomConf)
|
|
require.NoError(t, err)
|
|
require.NoError(t, os.WriteFile(setting.CustomConf, rootPathRe.ReplaceAll(conf, []byte("[repository]\nROOT = "+setting.RepoRootPath)), 0o644))
|
|
|
|
defer func() {
|
|
require.NoError(t, os.WriteFile(setting.CustomConf, conf, 0o644))
|
|
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
|
|
s.Shutdown(ctx)
|
|
cancel()
|
|
}()
|
|
|
|
go s.Serve(listener)
|
|
// Started by config go ssh.Listen(setting.SSH.ListenHost, setting.SSH.ListenPort, setting.SSH.ServerCiphers, setting.SSH.ServerKeyExchanges, setting.SSH.ServerMACs)
|
|
|
|
callback(t, u)
|
|
}
|
|
|
|
func onForgejoRun(t *testing.T, callback func(*testing.T, *url.URL), prepare ...bool) {
|
|
onForgejoRunTB(t, func(t testing.TB, u *url.URL) {
|
|
callback(t.(*testing.T), u)
|
|
}, prepare...)
|
|
}
|
|
|
|
func createSessions(t testing.TB) {
|
|
t.Helper()
|
|
// copied from playwright.config.ts
|
|
browsers := []string{
|
|
"chromium",
|
|
"firefox",
|
|
"webkit",
|
|
"Mobile Chrome",
|
|
"Mobile Safari",
|
|
}
|
|
scopes := []string{
|
|
"shared",
|
|
}
|
|
users := []string{
|
|
"user1",
|
|
"user2",
|
|
"user12",
|
|
"user40",
|
|
}
|
|
|
|
authState := filepath.Join(filepath.Dir(setting.AppPath), "tests", "e2e", ".auth")
|
|
err := os.RemoveAll(authState)
|
|
require.NoError(t, err)
|
|
|
|
err = os.MkdirAll(authState, os.ModePerm)
|
|
require.NoError(t, err)
|
|
|
|
createSessionCookie := stateHelper(t)
|
|
|
|
for _, user := range users {
|
|
u := unittest.AssertExistsAndLoadBean(t, &user_model.User{LowerName: strings.ToLower(user)})
|
|
for _, browser := range browsers {
|
|
for _, scope := range scopes {
|
|
stateFile := strings.ReplaceAll(strings.ToLower(fmt.Sprintf("state-%s-%s-%s.json", browser, user, scope)), " ", "-")
|
|
createSessionCookie(filepath.Join(authState, stateFile), u)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func stateHelper(t testing.TB) func(stateFile string, user *user_model.User) {
|
|
type Cookie struct {
|
|
Name string `json:"name"`
|
|
Value string `json:"value"`
|
|
Domain string `json:"domain"`
|
|
Path string `json:"path"`
|
|
Expires int `json:"expires"`
|
|
HTTPOnly bool `json:"httpOnly"`
|
|
Secure bool `json:"secure"`
|
|
SameSite string `json:"sameSite"`
|
|
}
|
|
|
|
type BrowserState struct {
|
|
Cookies []Cookie `json:"cookies"`
|
|
Origins []string `json:"origins"`
|
|
}
|
|
|
|
options := session.Options{
|
|
Provider: setting.SessionConfig.Provider,
|
|
ProviderConfig: setting.SessionConfig.ProviderConfig,
|
|
CookieName: setting.SessionConfig.CookieName,
|
|
CookiePath: setting.SessionConfig.CookiePath,
|
|
Gclifetime: setting.SessionConfig.Gclifetime,
|
|
Maxlifetime: setting.SessionConfig.Maxlifetime,
|
|
Secure: setting.SessionConfig.Secure,
|
|
SameSite: setting.SessionConfig.SameSite,
|
|
Domain: setting.SessionConfig.Domain,
|
|
}
|
|
|
|
opt := session.PrepareOptions([]session.Options{options})
|
|
|
|
vsp := modules_session.VirtualSessionProvider{}
|
|
err := vsp.Init(opt.Maxlifetime, opt.ProviderConfig)
|
|
require.NoError(t, err)
|
|
|
|
return func(stateFile string, user *user_model.User) {
|
|
buf := make([]byte, opt.IDLength/2)
|
|
_, err = rand.Read(buf)
|
|
require.NoError(t, err)
|
|
|
|
sessionID := hex.EncodeToString(buf)
|
|
|
|
s, err := vsp.Read(sessionID)
|
|
require.NoError(t, err)
|
|
|
|
err = s.Set("uid", user.ID)
|
|
require.NoError(t, err)
|
|
|
|
err = s.Release()
|
|
require.NoError(t, err)
|
|
|
|
state := BrowserState{
|
|
Cookies: []Cookie{
|
|
{
|
|
Name: opt.CookieName,
|
|
Value: sessionID,
|
|
Domain: setting.Domain,
|
|
Path: "/",
|
|
Expires: -1,
|
|
HTTPOnly: true,
|
|
Secure: false,
|
|
SameSite: "Lax",
|
|
},
|
|
},
|
|
Origins: []string{},
|
|
}
|
|
|
|
jsonData, err := json.Marshal(state)
|
|
require.NoError(t, err)
|
|
|
|
err = os.WriteFile(stateFile, jsonData, 0o644)
|
|
require.NoError(t, err)
|
|
}
|
|
}
|