test(suites): refactor flaky tests (#4502)

pull/4466/head^2
Amir Zarrinkafsh 2022-12-07 20:22:03 +11:00 committed by GitHub
parent c5387460c7
commit 99f965ae25
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 70 additions and 21 deletions

View File

@ -151,8 +151,8 @@ func createTemporaryDirectory() {
func createPNPMDirectory() { func createPNPMDirectory() {
home := os.Getenv("HOME") home := os.Getenv("HOME")
if home != "" { if home != "" {
bootstrapPrintln("Creating ", home+"/.pnpm-store") bootstrapPrintln("Creating ", home+"/.local/share/pnpm/store")
err := os.MkdirAll(home+"/.pnpm-store", 0755) err := os.MkdirAll(home+"/.local/share/pnpm/store", 0755)
if err != nil { if err != nil {
panic(err) panic(err)
@ -161,7 +161,7 @@ func createPNPMDirectory() {
} }
func pnpmInstall() { func pnpmInstall() {
bootstrapPrintln("Installing web dependences ") bootstrapPrintln("Installing web dependencies ")
cwd, err := os.Getwd() cwd, err := os.Getwd()
if err != nil { if err != nil {

View File

@ -10,22 +10,38 @@ import (
func (rs *RodSession) doFillLoginPageAndClick(t *testing.T, page *rod.Page, username, password string, keepMeLoggedIn bool) { func (rs *RodSession) doFillLoginPageAndClick(t *testing.T, page *rod.Page, username, password string, keepMeLoggedIn bool) {
usernameElement := rs.WaitElementLocatedByID(t, page, "username-textfield") usernameElement := rs.WaitElementLocatedByID(t, page, "username-textfield")
err := usernameElement.Input(username) passwordElement := rs.WaitElementLocatedByID(t, page, "password-textfield")
buttonElement := rs.WaitElementLocatedByID(t, page, "sign-in-button")
username:
err := usernameElement.MustSelectAllText().Input(username)
require.NoError(t, err) require.NoError(t, err)
passwordElement := rs.WaitElementLocatedByID(t, page, "password-textfield") if usernameElement.MustText() != username {
err = passwordElement.Input(password) goto username
}
password:
err = passwordElement.MustSelectAllText().Input(password)
require.NoError(t, err) require.NoError(t, err)
if passwordElement.MustText() != password {
goto password
}
if keepMeLoggedIn { if keepMeLoggedIn {
keepMeLoggedInElement := rs.WaitElementLocatedByID(t, page, "remember-checkbox") keepMeLoggedInElement := rs.WaitElementLocatedByID(t, page, "remember-checkbox")
err = keepMeLoggedInElement.Click("left", 1) err = keepMeLoggedInElement.Click("left", 1)
require.NoError(t, err) require.NoError(t, err)
} }
buttonElement := rs.WaitElementLocatedByID(t, page, "sign-in-button") click:
err = buttonElement.Click("left", 1) err = buttonElement.Click("left", 1)
require.NoError(t, err) require.NoError(t, err)
if buttonElement.MustInteractable() {
goto click
}
} }
// Login 1FA. // Login 1FA.

View File

@ -2,7 +2,6 @@ package suites
import ( import (
"testing" "testing"
"time"
"github.com/go-rod/rod" "github.com/go-rod/rod"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
@ -23,16 +22,25 @@ func (rs *RodSession) doCompletePasswordReset(t *testing.T, page *rod.Page, newP
link := doGetLinkFromLastMail(t) link := doGetLinkFromLastMail(t)
rs.doVisit(t, page, link) rs.doVisit(t, page, link)
time.Sleep(1 * time.Second) password1 := rs.WaitElementLocatedByID(t, page, "password1-textfield")
password2 := rs.WaitElementLocatedByID(t, page, "password2-textfield")
err := rs.WaitElementLocatedByID(t, page, "password1-textfield").Input(newPassword1) password1:
err := password1.MustSelectAllText().Input(newPassword1)
require.NoError(t, err) require.NoError(t, err)
time.Sleep(1 * time.Second) if password1.MustText() != newPassword1 {
goto password1
}
err = rs.WaitElementLocatedByID(t, page, "password2-textfield").Input(newPassword2) password2:
err = password2.MustSelectAllText().Input(newPassword2)
require.NoError(t, err) require.NoError(t, err)
if password2.MustText() != newPassword2 {
goto password2
}
err = rs.WaitElementLocatedByID(t, page, "reset-button").Click("left", 1) err = rs.WaitElementLocatedByID(t, page, "reset-button").Click("left", 1)
require.NoError(t, err) require.NoError(t, err)
} }

View File

@ -6,6 +6,7 @@ import (
"time" "time"
"github.com/go-rod/rod" "github.com/go-rod/rod"
"github.com/go-rod/rod/lib/input"
"github.com/pquerna/otp/totp" "github.com/pquerna/otp/totp"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
@ -31,7 +32,8 @@ func (rs *RodSession) doEnterOTP(t *testing.T, page *rod.Page, code string) {
inputs := rs.WaitElementsLocatedByID(t, page, "otp-input input") inputs := rs.WaitElementsLocatedByID(t, page, "otp-input input")
for i := 0; i < len(code); i++ { for i := 0; i < len(code); i++ {
inputs[i].MustInput(string(code[i])) err := inputs[i].Type(input.Key(code[i]))
require.NoError(t, err)
} }
} }

View File

@ -14,7 +14,7 @@ services:
volumes: volumes:
- './example/compose/authelia/resources/:/resources' - './example/compose/authelia/resources/:/resources'
- '../../web:/app' - '../../web:/app'
- '~/.pnpm-store:/tmp/.pnpm-store' - '~/.local/share/pnpm/store:/tmp/.pnpm-store'
labels: labels:
# Traefik 1.x # Traefik 1.x
- 'traefik.frontend.rule=Host:login.example.com' - 'traefik.frontend.rule=Host:login.example.com'

View File

@ -30,6 +30,18 @@ func (s *DefaultRedirectionURLScenario) SetupSuite() {
} }
s.RodSession = browser s.RodSession = browser
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer func() {
cancel()
s.collectScreenshot(ctx.Err(), s.Page)
s.collectCoverage(s.Page)
s.MustClose()
}()
s.Page = s.doCreateTab(s.T(), HomeBaseURL)
s.secret = s.doLoginAndRegisterTOTP(s.T(), s.Context(ctx), "john", "password", false)
} }
func (s *DefaultRedirectionURLScenario) TearDownSuite() { func (s *DefaultRedirectionURLScenario) TearDownSuite() {
@ -59,9 +71,7 @@ func (s *DefaultRedirectionURLScenario) TestUserIsRedirectedToDefaultURL() {
targetURL := fmt.Sprintf("%s/secret.html", AdminBaseURL) targetURL := fmt.Sprintf("%s/secret.html", AdminBaseURL)
s.doVisit(s.T(), s.Context(ctx), HomeBaseURL) s.doLoginTwoFactor(s.T(), s.Context(ctx), "john", "password", false, s.secret, targetURL)
s.verifyIsHome(s.T(), s.Page)
s.secret = s.doRegisterAndLogin2FA(s.T(), s.Context(ctx), "john", "password", false, targetURL)
s.verifySecretAuthorized(s.T(), s.Context(ctx)) s.verifySecretAuthorized(s.T(), s.Context(ctx))
s.doLogout(s.T(), s.Context(ctx)) s.doLogout(s.T(), s.Context(ctx))

View File

@ -12,6 +12,7 @@ import (
type InactivityScenario struct { type InactivityScenario struct {
*RodSuite *RodSuite
secret string secret string
} }

View File

@ -16,6 +16,7 @@ import (
type OIDCScenario struct { type OIDCScenario struct {
*RodSuite *RodSuite
secret string secret string
} }

View File

@ -12,6 +12,8 @@ import (
type TwoFactorSuite struct { type TwoFactorSuite struct {
*RodSuite *RodSuite
secret string
} }
func New2FAScenario() *TwoFactorSuite { func New2FAScenario() *TwoFactorSuite {
@ -28,6 +30,18 @@ func (s *TwoFactorSuite) SetupSuite() {
} }
s.RodSession = browser s.RodSession = browser
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer func() {
cancel()
s.collectScreenshot(ctx.Err(), s.Page)
s.collectCoverage(s.Page)
s.MustClose()
}()
s.Page = s.doCreateTab(s.T(), HomeBaseURL)
s.secret = s.doLoginAndRegisterTOTP(s.T(), s.Context(ctx), "john", "password", false)
} }
func (s *TwoFactorSuite) TearDownSuite() { func (s *TwoFactorSuite) TearDownSuite() {
@ -60,7 +74,7 @@ func (s *TwoFactorSuite) TestShouldAuthorizeSecretAfterTwoFactor() {
// Login and register TOTP, logout and login again with 1FA & 2FA. // Login and register TOTP, logout and login again with 1FA & 2FA.
targetURL := fmt.Sprintf("%s/secret.html", AdminBaseURL) targetURL := fmt.Sprintf("%s/secret.html", AdminBaseURL)
_ = s.doRegisterAndLogin2FA(s.T(), s.Context(ctx), username, password, false, targetURL) s.doLoginTwoFactor(s.T(), s.Context(ctx), username, password, false, s.secret, targetURL)
// And check if the user is redirected to the secret. // And check if the user is redirected to the secret.
s.verifySecretAuthorized(s.T(), s.Context(ctx)) s.verifySecretAuthorized(s.T(), s.Context(ctx))
@ -81,9 +95,6 @@ func (s *TwoFactorSuite) TestShouldFailTwoFactor() {
s.collectScreenshot(ctx.Err(), s.Page) s.collectScreenshot(ctx.Err(), s.Page)
}() }()
// Register TOTP secret and logout.
s.doRegisterThenLogout(s.T(), s.Context(ctx), testUsername, testPassword)
wrongPasscode := "123456" wrongPasscode := "123456"
s.doLoginOneFactor(s.T(), s.Context(ctx), testUsername, testPassword, false, "") s.doLoginOneFactor(s.T(), s.Context(ctx), testUsername, testPassword, false, "")