package suites import ( "context" "log" "testing" "time" "github.com/stretchr/testify/suite" ) type ResetPasswordScenario struct { *RodSuite } func NewResetPasswordScenario() *ResetPasswordScenario { return &ResetPasswordScenario{RodSuite: new(RodSuite)} } func (s *ResetPasswordScenario) SetupSuite() { browser, err := StartRod() if err != nil { log.Fatal(err) } s.RodSession = browser } func (s *ResetPasswordScenario) TearDownSuite() { err := s.RodSession.Stop() if err != nil { log.Fatal(err) } } func (s *ResetPasswordScenario) SetupTest() { s.Page = s.doCreateTab(s.T(), HomeBaseURL) s.verifyIsHome(s.T(), s.Page) } func (s *ResetPasswordScenario) TearDownTest() { s.collectCoverage(s.Page) s.MustClose() } func (s *ResetPasswordScenario) TestShouldResetPassword() { ctx, cancel := context.WithTimeout(context.Background(), 45*time.Second) defer func() { cancel() s.collectScreenshot(ctx.Err(), s.Page) }() s.doVisit(s.T(), s.Context(ctx), GetLoginBaseURL()) s.verifyIsFirstFactorPage(s.T(), s.Context(ctx)) // Reset the password to abc. s.doResetPassword(s.T(), s.Context(ctx), "john", "abc", "abc", false) // Try to login with the old password. s.doLoginOneFactor(s.T(), s.Context(ctx), "john", "password", false, "") s.verifyNotificationDisplayed(s.T(), s.Context(ctx), "Incorrect username or password.") // Try to login with the new password. s.doLoginOneFactor(s.T(), s.Context(ctx), "john", "abc", false, "") // Logout. s.doLogout(s.T(), s.Context(ctx)) // Reset the original password. s.doResetPassword(s.T(), s.Context(ctx), "john", "password", "password", false) } func (s *ResetPasswordScenario) TestShouldMakeAttackerThinkPasswordResetIsInitiated() { ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second) defer func() { cancel() s.collectScreenshot(ctx.Err(), s.Page) }() s.doVisit(s.T(), s.Context(ctx), GetLoginBaseURL()) s.verifyIsFirstFactorPage(s.T(), s.Context(ctx)) // Try to initiate a password reset of an nonexistent user. s.doInitiatePasswordReset(s.T(), s.Context(ctx), "i_dont_exist") // Check that the notification make the attacker thinks the process is initiated. s.verifyMailNotificationDisplayed(s.T(), s.Context(ctx)) } func (s *ResetPasswordScenario) TestShouldLetUserNoticeThereIsAPasswordMismatch() { ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) defer func() { cancel() s.collectScreenshot(ctx.Err(), s.Page) }() s.doVisit(s.T(), s.Context(ctx), GetLoginBaseURL()) s.verifyIsFirstFactorPage(s.T(), s.Context(ctx)) s.doInitiatePasswordReset(s.T(), s.Context(ctx), "john") s.verifyMailNotificationDisplayed(s.T(), s.Context(ctx)) s.doCompletePasswordReset(s.T(), s.Context(ctx), "password", "another_password") s.verifyNotificationDisplayed(s.T(), s.Context(ctx), "Passwords do not match.") } func TestRunResetPasswordScenario(t *testing.T) { if testing.Short() { t.Skip("skipping suite test in short mode") } suite.Run(t, NewResetPasswordScenario()) }