Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Framasoft
PeerTube
PeerTube
Commits
5bdfa604
Commit
5bdfa604
authored
Jan 19, 2023
by
Chocobozzz
Committed by
Chocobozzz
Jan 19, 2023
Browse files
Add E2E client tests for signup approval
parent
9589907c
Changes
16
Expand all
Hide whitespace changes
Inline
Side-by-side
client/.gitignore
View file @
5bdfa604
...
...
@@ -11,5 +11,6 @@
/src/locale/target/server_*.xml
/e2e/local.log
/e2e/browserstack.err
/e2e/screenshots
/src/standalone/player/build
/src/standalone/player/dist
client/e2e/src/po/admin-config.po.ts
View file @
5bdfa604
import
{
getCheckbox
,
go
}
from
'
../utils
'
import
{
browserSleep
,
getCheckbox
,
go
,
isCheckboxSelected
}
from
'
../utils
'
export
class
AdminConfigPage
{
...
...
@@ -8,7 +8,6 @@ export class AdminConfigPage {
'
basic-configuration
'
:
'
APPEARANCE
'
,
'
instance-information
'
:
'
INSTANCE
'
}
await
go
(
'
/admin/config/edit-custom#
'
+
tab
)
await
$
(
'
.inner-form-title=
'
+
waitTitles
[
tab
]).
waitForDisplayed
()
...
...
@@ -28,17 +27,39 @@ export class AdminConfigPage {
return
$
(
'
#instanceCustomHomepageContent
'
).
setValue
(
newValue
)
}
async
toggleSignup
()
{
async
toggleSignup
(
enabled
:
boolean
)
{
if
(
await
isCheckboxSelected
(
'
signupEnabled
'
)
===
enabled
)
return
const
checkbox
=
await
getCheckbox
(
'
signupEnabled
'
)
await
checkbox
.
waitForClickable
()
await
checkbox
.
click
()
}
async
toggleSignupApproval
(
required
:
boolean
)
{
if
(
await
isCheckboxSelected
(
'
signupRequiresApproval
'
)
===
required
)
return
const
checkbox
=
await
getCheckbox
(
'
signupRequiresApproval
'
)
await
checkbox
.
waitForClickable
()
await
checkbox
.
click
()
}
async
toggleSignupEmailVerification
(
required
:
boolean
)
{
if
(
await
isCheckboxSelected
(
'
signupRequiresEmailVerification
'
)
===
required
)
return
const
checkbox
=
await
getCheckbox
(
'
signupRequiresEmailVerification
'
)
await
checkbox
.
waitForClickable
()
await
checkbox
.
click
()
}
async
save
()
{
const
button
=
$
(
'
input[type=submit]
'
)
await
button
.
waitForClickable
()
await
button
.
click
()
await
browserSleep
(
1000
)
}
}
client/e2e/src/po/admin-registration.po.ts
0 → 100644
View file @
5bdfa604
import
{
browserSleep
,
findParentElement
,
go
}
from
'
../utils
'
export
class
AdminRegistrationPage
{
async
navigateToRegistratonsList
()
{
await
go
(
'
/admin/moderation/registrations/list
'
)
await
$
(
'
my-registration-list
'
).
waitForDisplayed
()
}
async
accept
(
username
:
string
,
moderationResponse
:
string
)
{
const
usernameEl
=
await
$
(
'
*=
'
+
username
)
await
usernameEl
.
waitForDisplayed
()
const
tr
=
await
findParentElement
(
usernameEl
,
async
el
=>
await
el
.
getTagName
()
===
'
tr
'
)
await
tr
.
$
(
'
.action-cell .dropdown-root
'
).
click
()
const
accept
=
await
$
(
'
span*=Accept this registration
'
)
await
accept
.
waitForClickable
()
await
accept
.
click
()
const
moderationResponseTextarea
=
await
$
(
'
#moderationResponse
'
)
await
moderationResponseTextarea
.
waitForDisplayed
()
await
moderationResponseTextarea
.
setValue
(
moderationResponse
)
const
submitButton
=
$
(
'
.modal-footer input[type=submit]
'
)
await
submitButton
.
waitForClickable
()
await
submitButton
.
click
()
await
browserSleep
(
1000
)
}
}
client/e2e/src/po/login.po.ts
View file @
5bdfa604
...
...
@@ -6,7 +6,14 @@ export class LoginPage {
}
async
login
(
username
:
string
,
password
:
string
,
url
=
'
/login
'
)
{
async
login
(
options
:
{
username
:
string
password
:
string
displayName
?:
string
url
?:
string
})
{
const
{
username
,
password
,
url
=
'
/login
'
,
displayName
=
username
}
=
options
await
go
(
url
)
await
browser
.
execute
(
`window.localStorage.setItem('no_account_setup_warning_modal', 'true')`
)
...
...
@@ -27,27 +34,40 @@ export class LoginPage {
await
menuToggle
.
click
()
await
this
.
ensureIsLoggedInAs
(
usern
ame
)
await
this
.
ensureIsLoggedInAs
(
displayN
ame
)
await
menuToggle
.
click
()
}
else
{
await
this
.
ensureIsLoggedInAs
(
usern
ame
)
await
this
.
ensureIsLoggedInAs
(
displayN
ame
)
}
}
async
getLoginError
(
username
:
string
,
password
:
string
)
{
await
go
(
'
/login
'
)
await
$
(
'
input#username
'
).
setValue
(
username
)
await
$
(
'
input#password
'
).
setValue
(
password
)
await
browser
.
pause
(
1000
)
await
$
(
'
form input[type=submit]
'
).
click
()
return
$
(
'
.alert-danger
'
).
getText
()
}
async
loginAsRootUser
()
{
return
this
.
login
(
'
root
'
,
'
test
'
+
this
.
getSuffix
())
return
this
.
login
(
{
username
:
'
root
'
,
password
:
'
test
'
+
this
.
getSuffix
()
}
)
}
loginOnPeerTube2
()
{
return
this
.
login
(
'
e2e
'
,
process
.
env
.
PEERTUBE2_E2E_PASSWORD
,
'
https://peertube2.cpy.re/login
'
)
return
this
.
login
(
{
username
:
'
e2e
'
,
password
:
process
.
env
.
PEERTUBE2_E2E_PASSWORD
,
url
:
'
https://peertube2.cpy.re/login
'
}
)
}
async
logout
()
{
const
loggedIn
More
=
$
(
'
.logged-in-more
'
)
const
loggedIn
Dropdown
=
$
(
'
.logged-in-more
.logged-in-info
'
)
await
loggedIn
More
.
waitForClickable
()
await
loggedIn
More
.
click
()
await
loggedIn
Dropdown
.
waitForClickable
()
await
loggedIn
Dropdown
.
click
()
const
logout
=
$
(
'
.dropdown-item*=Log out
'
)
...
...
client/e2e/src/po/signup.po.ts
View file @
5bdfa604
...
...
@@ -27,42 +27,39 @@ export class SignupPage {
return
terms
.
click
()
}
async
getEndMessage
()
{
const
alert
=
$
(
'
.pt-alert-primary
'
)
await
alert
.
waitForDisplayed
()
return
alert
.
getText
()
}
async
fillRegistrationReason
(
reason
:
string
)
{
await
$
(
'
#registrationReason
'
).
setValue
(
reason
)
}
async
fillAccountStep
(
options
:
{
displayName
:
string
username
:
string
email
:
string
password
:
string
password
?:
string
displayName
?:
string
email
?:
string
})
{
if
(
options
.
displayName
)
{
await
$
(
'
#displayName
'
).
setValue
(
options
.
displayName
)
}
if
(
options
.
username
)
{
await
$
(
'
#username
'
).
setValue
(
options
.
username
)
}
await
$
(
'
#displayName
'
).
setValue
(
options
.
displayName
||
`
${
options
.
username
}
display name`
)
if
(
options
.
email
)
{
// Fix weird bug on firefox that "cannot scroll into view" when using just `setValue`
await
$
(
'
#email
'
).
scrollIntoView
(
false
)
await
$
(
'
#email
'
).
waitForClickable
()
await
$
(
'
#email
'
).
setValue
(
options
.
email
)
}
await
$
(
'
#username
'
).
setValue
(
options
.
username
)
await
$
(
'
#password
'
).
setValue
(
options
.
password
||
'
password
'
)
if
(
options
.
password
)
{
await
$
(
'
#password
'
).
setValue
(
options
.
password
)
}
// Fix weird bug on firefox that "cannot scroll into view" when using just `setValue`
await
$
(
'
#email
'
).
scrollIntoView
(
false
)
await
$
(
'
#email
'
).
waitForClickable
()
await
$
(
'
#email
'
).
setValue
(
options
.
email
||
`
${
options
.
username
}
@example.com`
)
}
async
fillChannelStep
(
options
:
{
displayName
:
string
name
:
string
displayName
?:
string
})
{
if
(
options
.
displayName
)
{
await
$
(
'
#displayName
'
).
setValue
(
options
.
displayName
)
}
if
(
options
.
name
)
{
await
$
(
'
#name
'
).
setValue
(
options
.
name
)
}
await
$
(
'
#displayName
'
).
setValue
(
options
.
displayName
||
`
${
options
.
name
}
channel display name`
)
await
$
(
'
#name
'
).
setValue
(
options
.
name
)
}
}
client/e2e/src/suites-local/signup.e2e-spec.ts
View file @
5bdfa604
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
()
})