test(suites): refactor flaky tests (#4502)
parent
c5387460c7
commit
99f965ae25
|
@ -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 {
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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'
|
||||||
|
|
|
@ -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))
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@ import (
|
||||||
|
|
||||||
type InactivityScenario struct {
|
type InactivityScenario struct {
|
||||||
*RodSuite
|
*RodSuite
|
||||||
|
|
||||||
secret string
|
secret string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@ import (
|
||||||
|
|
||||||
type OIDCScenario struct {
|
type OIDCScenario struct {
|
||||||
*RodSuite
|
*RodSuite
|
||||||
|
|
||||||
secret string
|
secret string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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, "")
|
||||||
|
|
Loading…
Reference in New Issue