From 5bdfa604f102a5e51b5152457cd1a16d79177e26 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Thu, 19 Jan 2023 09:30:05 +0100 Subject: Add E2E client tests for signup approval --- client/e2e/src/suites-local/signup.e2e-spec.ts | 403 ++++++++++++++++++++++--- 1 file changed, 359 insertions(+), 44 deletions(-) (limited to 'client/e2e/src/suites-local') diff --git a/client/e2e/src/suites-local/signup.e2e-spec.ts b/client/e2e/src/suites-local/signup.e2e-spec.ts index 4eed3eefe..b6f7ad1a7 100644 --- a/client/e2e/src/suites-local/signup.e2e-spec.ts +++ b/client/e2e/src/suites-local/signup.e2e-spec.ts @@ -1,12 +1,89 @@ import { AdminConfigPage } from '../po/admin-config.po' +import { AdminRegistrationPage } from '../po/admin-registration.po' import { LoginPage } from '../po/login.po' import { SignupPage } from '../po/signup.po' -import { isMobileDevice, waitServerUp } from '../utils' +import { browserSleep, getVerificationLink, go, findEmailTo, isMobileDevice, MockSMTPServer, waitServerUp } from '../utils' + +function checkEndMessage (options: { + message: string + requiresEmailVerification: boolean + requiresApproval: boolean + afterEmailVerification: boolean +}) { + const { message, requiresApproval, requiresEmailVerification, afterEmailVerification } = options + + { + const created = 'account has been created' + const request = 'account request has been sent' + + if (requiresApproval) { + expect(message).toContain(request) + expect(message).not.toContain(created) + } else { + expect(message).not.toContain(request) + expect(message).toContain(created) + } + } + + { + const checkEmail = 'Check your emails' + + if (requiresEmailVerification) { + expect(message).toContain(checkEmail) + } else { + expect(message).not.toContain(checkEmail) + + const moderatorsApproval = 'moderator will check your registration request' + if (requiresApproval) { + expect(message).toContain(moderatorsApproval) + } else { + expect(message).not.toContain(moderatorsApproval) + } + } + } + + { + const emailVerified = 'email has been verified' + + if (afterEmailVerification) { + expect(message).toContain(emailVerified) + } else { + expect(message).not.toContain(emailVerified) + } + } +} describe('Signup', () => { let loginPage: LoginPage let adminConfigPage: AdminConfigPage let signupPage: SignupPage + let adminRegistrationPage: AdminRegistrationPage + + async function prepareSignup (options: { + enabled: boolean + requiresApproval?: boolean + requiresEmailVerification?: boolean + }) { + await loginPage.loginAsRootUser() + + await adminConfigPage.navigateTo('basic-configuration') + await adminConfigPage.toggleSignup(options.enabled) + + if (options.enabled) { + if (options.requiresApproval !== undefined) { + await adminConfigPage.toggleSignupApproval(options.requiresApproval) + } + + if (options.requiresEmailVerification !== undefined) { + await adminConfigPage.toggleSignupEmailVerification(options.requiresEmailVerification) + } + } + + await adminConfigPage.save() + + await loginPage.logout() + await browser.refresh() + } before(async () => { await waitServerUp() @@ -16,72 +93,310 @@ describe('Signup', () => { loginPage = new LoginPage(isMobileDevice()) adminConfigPage = new AdminConfigPage() signupPage = new SignupPage() + adminRegistrationPage = new AdminRegistrationPage() await browser.maximizeWindow() }) - it('Should disable signup', async () => { - await loginPage.loginAsRootUser() + describe('Signup disabled', function () { + it('Should disable signup', async () => { + await prepareSignup({ enabled: false }) - await adminConfigPage.navigateTo('basic-configuration') - await adminConfigPage.toggleSignup() + await expect(signupPage.getRegisterMenuButton()).not.toBeDisplayed() + }) + }) - await adminConfigPage.save() + describe('Email verification disabled', function () { - await loginPage.logout() - await browser.refresh() + describe('Direct registration', function () { - expect(signupPage.getRegisterMenuButton()).not.toBeDisplayed() - }) + it('Should enable signup without approval', async () => { + await prepareSignup({ enabled: true, requiresApproval: false, requiresEmailVerification: false }) - it('Should enable signup', async () => { - await loginPage.loginAsRootUser() + await signupPage.getRegisterMenuButton().waitForDisplayed() + }) - await adminConfigPage.navigateTo('basic-configuration') - await adminConfigPage.toggleSignup() + it('Should go on signup page', async function () { + await signupPage.clickOnRegisterInMenu() + }) - await adminConfigPage.save() + it('Should validate the first step (about page)', async function () { + await signupPage.validateStep() + }) - await loginPage.logout() - await browser.refresh() + it('Should validate the second step (terms)', async function () { + await signupPage.checkTerms() + await signupPage.validateStep() + }) - expect(signupPage.getRegisterMenuButton()).toBeDisplayed() - }) + it('Should validate the third step (account)', async function () { + await signupPage.fillAccountStep({ username: 'user_1', displayName: 'user_1_dn' }) - it('Should go on signup page', async function () { - await signupPage.clickOnRegisterInMenu() - }) + await signupPage.validateStep() + }) - it('Should validate the first step (about page)', async function () { - await signupPage.validateStep() - }) + it('Should validate the third step (channel)', async function () { + await signupPage.fillChannelStep({ name: 'user_1_channel' }) - it('Should validate the second step (terms)', async function () { - await signupPage.checkTerms() - await signupPage.validateStep() - }) + await signupPage.validateStep() + }) + + it('Should be logged in', async function () { + await loginPage.ensureIsLoggedInAs('user_1_dn') + }) + + it('Should have a valid end message', async function () { + const message = await signupPage.getEndMessage() + + checkEndMessage({ + message, + requiresEmailVerification: false, + requiresApproval: false, + afterEmailVerification: false + }) - it('Should validate the third step (account)', async function () { - await signupPage.fillAccountStep({ - displayName: 'user 1', - username: 'user_1', - email: 'user_1@example.com', - password: 'my_super_password' + await browser.saveScreenshot('./screenshots/direct-without-email.png') + + await loginPage.logout() + }) }) - await signupPage.validateStep() + describe('Registration with approval', function () { + + it('Should enable signup with approval', async () => { + await prepareSignup({ enabled: true, requiresApproval: true, requiresEmailVerification: false }) + + await signupPage.getRegisterMenuButton().waitForDisplayed() + }) + + it('Should go on signup page', async function () { + await signupPage.clickOnRegisterInMenu() + }) + + it('Should validate the first step (about page)', async function () { + await signupPage.validateStep() + }) + + it('Should validate the second step (terms)', async function () { + await signupPage.checkTerms() + await signupPage.fillRegistrationReason('my super reason') + await signupPage.validateStep() + }) + + it('Should validate the third step (account)', async function () { + await signupPage.fillAccountStep({ username: 'user_2', displayName: 'user_2 display name', password: 'password' }) + await signupPage.validateStep() + }) + + it('Should validate the third step (channel)', async function () { + await signupPage.fillChannelStep({ name: 'user_2_channel' }) + await signupPage.validateStep() + }) + + it('Should have a valid end message', async function () { + const message = await signupPage.getEndMessage() + + checkEndMessage({ + message, + requiresEmailVerification: false, + requiresApproval: true, + afterEmailVerification: false + }) + + await browser.saveScreenshot('./screenshots/request-without-email.png') + }) + + it('Should display a message when trying to login with this account', async function () { + const error = await loginPage.getLoginError('user_2', 'password') + + expect(error).toContain('awaiting approval') + }) + + it('Should accept the registration', async function () { + await loginPage.loginAsRootUser() + + await adminRegistrationPage.navigateToRegistratonsList() + await adminRegistrationPage.accept('user_2', 'moderation response') + + await loginPage.logout() + }) + + it('Should be able to login with this new account', async function () { + await loginPage.login({ username: 'user_2', password: 'password', displayName: 'user_2 display name' }) + + await loginPage.logout() + }) + }) }) - it('Should validate the third step (channel)', async function () { - await signupPage.fillChannelStep({ - displayName: 'user 1 channel', - name: 'user_1_channel' + describe('Email verification enabled', function () { + const emails: any[] = [] + let emailPort: number + + before(async () => { + // FIXME: typings are wrong, get returns a promise + emailPort = await browser.sharedStore.get('emailPort') as unknown as number + + MockSMTPServer.Instance.collectEmails(emailPort, emails) }) - await signupPage.validateStep() - }) + describe('Direct registration', function () { + + it('Should enable signup without approval', async () => { + await prepareSignup({ enabled: true, requiresApproval: false, requiresEmailVerification: true }) + + await signupPage.getRegisterMenuButton().waitForDisplayed() + }) + + it('Should go on signup page', async function () { + await signupPage.clickOnRegisterInMenu() + }) + + it('Should validate the first step (about page)', async function () { + await signupPage.validateStep() + }) + + it('Should validate the second step (terms)', async function () { + await signupPage.checkTerms() + await signupPage.validateStep() + }) + + it('Should validate the third step (account)', async function () { + await signupPage.fillAccountStep({ username: 'user_3', displayName: 'user_3 display name', email: 'user_3@example.com' }) + + await signupPage.validateStep() + }) + + it('Should validate the third step (channel)', async function () { + await signupPage.fillChannelStep({ name: 'user_3_channel' }) + + await signupPage.validateStep() + }) + + it('Should have a valid end message', async function () { + const message = await signupPage.getEndMessage() + + checkEndMessage({ + message, + requiresEmailVerification: true, + requiresApproval: false, + afterEmailVerification: false + }) + + await browser.saveScreenshot('./screenshots/direct-with-email.png') + }) + + it('Should validate the email', async function () { + let email: { text: string } + + while (!(email = findEmailTo(emails, 'user_3@example.com'))) { + await browserSleep(100) + } + + await go(getVerificationLink(email)) + + const message = await signupPage.getEndMessage() + + checkEndMessage({ + message, + requiresEmailVerification: false, + requiresApproval: false, + afterEmailVerification: true + }) - it('Should be logged in', async function () { - await loginPage.ensureIsLoggedInAs('user 1') + await browser.saveScreenshot('./screenshots/direct-after-email.png') + }) + }) + + describe('Registration with approval', function () { + + it('Should enable signup without approval', async () => { + await prepareSignup({ enabled: true, requiresApproval: true, requiresEmailVerification: true }) + + await signupPage.getRegisterMenuButton().waitForDisplayed() + }) + + it('Should go on signup page', async function () { + await signupPage.clickOnRegisterInMenu() + }) + + it('Should validate the first step (about page)', async function () { + await signupPage.validateStep() + }) + + it('Should validate the second step (terms)', async function () { + await signupPage.checkTerms() + await signupPage.fillRegistrationReason('my super reason 2') + await signupPage.validateStep() + }) + + it('Should validate the third step (account)', async function () { + await signupPage.fillAccountStep({ + username: 'user_4', + displayName: 'user_4 display name', + email: 'user_4@example.com', + password: 'password' + }) + await signupPage.validateStep() + }) + + it('Should validate the third step (channel)', async function () { + await signupPage.fillChannelStep({ name: 'user_4_channel' }) + await signupPage.validateStep() + }) + + it('Should have a valid end message', async function () { + const message = await signupPage.getEndMessage() + + checkEndMessage({ + message, + requiresEmailVerification: true, + requiresApproval: true, + afterEmailVerification: false + }) + + await browser.saveScreenshot('./screenshots/request-with-email.png') + }) + + it('Should display a message when trying to login with this account', async function () { + const error = await loginPage.getLoginError('user_4', 'password') + + expect(error).toContain('awaiting approval') + }) + + it('Should accept the registration', async function () { + await loginPage.loginAsRootUser() + + await adminRegistrationPage.navigateToRegistratonsList() + await adminRegistrationPage.accept('user_4', 'moderation response 2') + + await loginPage.logout() + }) + + it('Should validate the email', async function () { + let email: { text: string } + + while (!(email = findEmailTo(emails, 'user_4@example.com'))) { + await browserSleep(100) + } + + await go(getVerificationLink(email)) + + const message = await signupPage.getEndMessage() + + checkEndMessage({ + message, + requiresEmailVerification: false, + requiresApproval: true, + afterEmailVerification: true + }) + + await browser.saveScreenshot('./screenshots/request-after-email.png') + }) + }) + + before(() => { + MockSMTPServer.Instance.kill() + }) }) }) -- cgit v1.2.3