Merge branch 'master' into 2766-bug-migration-of-communities-with-errors

This commit is contained in:
clauspeterhuebner 2023-03-02 15:28:18 +01:00 committed by GitHub
commit 3cfc6e61f0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 75 additions and 36 deletions

View File

@ -550,7 +550,7 @@ jobs:
run: | run: |
cd e2e-tests/ cd e2e-tests/
yarn yarn
yarn run cypress run --spec cypress/e2e/User.Authentication.feature,cypress/e2e/User.Authentication.ResetPassword.feature yarn run cypress run --spec cypress/e2e/User.Authentication.feature,cypress/e2e/User.Authentication.ResetPassword.feature,cypress/e2e/User.Registration.feature
- name: End-to-end tests | if tests failed, upload screenshots - name: End-to-end tests | if tests failed, upload screenshots
if: ${{ failure() && steps.e2e-tests.conclusion == 'failure' }} if: ${{ failure() && steps.e2e-tests.conclusion == 'failure' }}
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v3

View File

@ -2,7 +2,7 @@ import { defineConfig } from 'cypress'
import { addCucumberPreprocessorPlugin } from '@badeball/cypress-cucumber-preprocessor' import { addCucumberPreprocessorPlugin } from '@badeball/cypress-cucumber-preprocessor'
import browserify from '@badeball/cypress-cucumber-preprocessor/browserify' import browserify from '@badeball/cypress-cucumber-preprocessor/browserify'
let resetPasswordLink: string let emailLink: string
async function setupNodeEvents( async function setupNodeEvents(
on: Cypress.PluginEvents, on: Cypress.PluginEvents,
@ -18,11 +18,11 @@ async function setupNodeEvents(
) )
on('task', { on('task', {
setResetPasswordLink: (val) => { setEmailLink: (link: string) => {
return (resetPasswordLink = val) return (emailLink = link)
}, },
getResetPasswordLink: () => { getEmailLink: () => {
return resetPasswordLink return emailLink
}, },
}) })

View File

@ -13,8 +13,8 @@ Feature: User Authentication - reset password
And the user navigates to the forgot password page And the user navigates to the forgot password page
When the user enters the e-mail address "bibi@bloxberg.de" When the user enters the e-mail address "bibi@bloxberg.de"
And the user submits the e-mail form And the user submits the e-mail form
Then the user receives an e-mail containing the password reset link Then the user receives an e-mail containing the "password reset" link
When the user opens the password reset link in the browser When the user opens the "password reset" link in the browser
And the user enters the password "12345Aa_" And the user enters the password "12345Aa_"
And the user repeats the password "12345Aa_" And the user repeats the password "12345Aa_"
And the user submits the password form And the user submits the password form

View File

@ -2,12 +2,16 @@ Feature: User registration
As a user As a user
I want to register to create an account I want to register to create an account
@skip
Scenario: Register successfully Scenario: Register successfully
Given the user navigates to page "/register" Given the user navigates to page "/register"
When the user fills name and email "Regina" "Register" "regina@register.com" When the user fills name and email "Regina" "Register" "regina@register.com"
And the user agrees to the privacy policy And the user agrees to the privacy policy
And the user submits the registration form And the user submits the registration form
Then the user can use a provided activation link Then the user receives an e-mail containing the "activation" link
And the user can set a password "Aa12345_" When the user opens the "activation" link in the browser
And the user can login with the credentials "regina@register.com" "Aa12345_" And the user enters the password "12345Aa_"
And the user repeats the password "12345Aa_"
And the user submits the password form
And the user clicks the sign in button
Then the user submits the credentials "regina@register.com" "12345Aa_"
And the user is logged in with username "Regina Register"

View File

@ -4,7 +4,7 @@ export class RegistrationPage {
// selectors // selectors
firstnameInput = '#registerFirstname' firstnameInput = '#registerFirstname'
lastnameInput = '#registerLastname' lastnameInput = '#registerLastname'
emailInput = '#Email-input-field' emailInput = 'input[type=email]'
checkbox = '#registerCheckbox' checkbox = '#registerCheckbox'
submitBtn = '[type=submit]' submitBtn = '[type=submit]'
@ -35,7 +35,7 @@ export class RegistrationPage {
cy.get(this.checkbox).click({ force: true }) cy.get(this.checkbox).click({ force: true })
} }
submitRegistrationPage() { submitRegistrationForm() {
cy.get(this.submitBtn).should('be.enabled') cy.get(this.submitBtn).should('be.enabled')
cy.get(this.submitBtn).click() cy.get(this.submitBtn).click()
} }

View File

@ -2,19 +2,19 @@
export class ResetPasswordPage { export class ResetPasswordPage {
// selectors // selectors
newPasswordBlock = '#new-password-input-field' newPasswordInput = '#new-password-input-field'
newPasswordRepeatBlock = '#repeat-new-password-input-field' newPasswordRepeatInput = '#repeat-new-password-input-field'
resetPasswordBtn = 'button[type=submit]' resetPasswordBtn = 'button[type=submit]'
resetPasswordMessageBlock = '[data-test="reset-password-message"]' resetPasswordMessageBlock = '[data-test="reset-password-message"]'
signinBtn = '.btn.test-message-button' signinBtn = '.btn.test-message-button'
enterNewPassword(password: string) { enterNewPassword(password: string) {
cy.get(this.newPasswordBlock).find('input[type=password]').type(password) cy.get(this.newPasswordInput).find('input[type=password]').type(password)
return this return this
} }
repeatNewPassword(password: string) { repeatNewPassword(password: string) {
cy.get(this.newPasswordRepeatBlock) cy.get(this.newPasswordRepeatInput)
.find('input[type=password]') .find('input[type=password]')
.type(password) .type(password)
return this return this

View File

@ -5,41 +5,55 @@ import { UserEMailSite } from '../../e2e/models/UserEMailSite'
const userEMailSite = new UserEMailSite() const userEMailSite = new UserEMailSite()
const resetPasswordPage = new ResetPasswordPage() const resetPasswordPage = new ResetPasswordPage()
Then('the user receives an e-mail containing the password reset link', () => { Then('the user receives an e-mail containing the {string} link', (linkName: string) => {
let emailSubject: string
let linkPattern: RegExp
switch (linkName) {
case 'activation':
emailSubject = 'Email Verification'
linkPattern = /\/checkEmail\/[0-9]+\d/
break
case 'password reset':
emailSubject = 'asswor'
linkPattern = /\/reset-password\/[0-9]+\d/
break
default:
throw new Error(`Error in "Then the user receives an e-mail containing the {string} link" step: incorrect linkname string "${linkName}"`)
}
cy.origin( cy.origin(
Cypress.env('mailserverURL'), Cypress.env('mailserverURL'),
{ args: userEMailSite }, { args: { emailSubject, linkPattern, userEMailSite } },
(userEMailSite) => { ({ emailSubject, linkPattern, userEMailSite }) => {
const linkPattern = /\/reset-password\/[0-9]+\d/ cy.visit('/') // navigate to user's e-mail site (on fake mail server)
cy.visit('/') // navigate to user's e-maile site (on fake mail server)
cy.get(userEMailSite.emailInbox).should('be.visible') cy.get(userEMailSite.emailInbox).should('be.visible')
cy.get(userEMailSite.emailList) cy.get(userEMailSite.emailList)
.find('.email-item') .find('.email-item')
.filter(':contains(asswor)') .filter(`:contains(${emailSubject})`)
.first() .first()
.click() .click()
cy.get(userEMailSite.emailMeta) cy.get(userEMailSite.emailMeta)
.find(userEMailSite.emailSubject) .find(userEMailSite.emailSubject)
.contains('asswor') .contains(emailSubject)
cy.get('.email-content') cy.get('.email-content', { timeout: 2000})
.find('.plain-text') .find('.plain-text')
.contains(linkPattern) .contains(linkPattern)
.invoke('text') .invoke('text')
.then((text) => { .then((text) => {
const resetPasswordLink = text.match(linkPattern)[0] const emailLink = text.match(linkPattern)[0]
cy.task('setResetPasswordLink', resetPasswordLink) cy.task('setEmailLink', emailLink)
}) })
} }
) )
}) })
When('the user opens the password reset link in the browser', () => { When('the user opens the {string} link in the browser', (linkName: string) => {
cy.task('getResetPasswordLink').then((passwordResetLink) => { cy.task('getEmailLink').then((emailLink) => {
cy.visit(passwordResetLink) cy.visit(emailLink)
}) })
cy.get(resetPasswordPage.newPasswordRepeatBlock).should('be.visible') cy.get(resetPasswordPage.newPasswordInput).should('be.visible')
}) })

View File

@ -18,7 +18,7 @@ And('the user agrees to the privacy policy', () => {
}) })
And('the user submits the registration form', () => { And('the user submits the registration form', () => {
registrationPage.submitRegistrationPage() registrationPage.submitRegistrationForm()
cy.get(registrationPage.RegistrationThanxHeadline).should('be.visible') cy.get(registrationPage.RegistrationThanxHeadline).should('be.visible')
cy.get(registrationPage.RegistrationThanxText).should('be.visible') cy.get(registrationPage.RegistrationThanxText).should('be.visible')
}) })

View File

@ -22,7 +22,7 @@
"@cypress/browserify-preprocessor": "^3.0.2", "@cypress/browserify-preprocessor": "^3.0.2",
"@typescript-eslint/eslint-plugin": "^5.38.0", "@typescript-eslint/eslint-plugin": "^5.38.0",
"@typescript-eslint/parser": "^5.38.0", "@typescript-eslint/parser": "^5.38.0",
"cypress": "^10.4.0", "cypress": "^12.7.0",
"eslint": "^8.23.1", "eslint": "^8.23.1",
"eslint-config-prettier": "^8.3.0", "eslint-config-prettier": "^8.3.0",
"eslint-config-standard": "^16.0.3", "eslint-config-standard": "^16.0.3",

View File

@ -1,6 +1,23 @@
<template> <template>
<div class="contribution-messages-list-item"> <div class="contribution-messages-list-item">
<div v-if="isNotModerator" class="text-right pr-4 pr-lg-0 is-not-moderator"> <div v-if="message.type === 'HISTORY'">
<b-row class="mb-3 border border-197 p-1">
<b-col cols="10">
<small>{{ $d(new Date(message.createdAt), 'short') }}</small>
<div class="font-weight-bold" data-test="username">
{{ storeName.username }} {{ $t('contribution.isEdited') }}
</div>
<div class="small">
{{ $t('contribution.oldContribution') }}
</div>
<parse-message v-bind="message" data-test="message" class="p-2"></parse-message>
</b-col>
<b-col cols="2">
<avatar :username="storeName.username" :initials="storeName.initials"></avatar>
</b-col>
</b-row>
</div>
<div v-else-if="isNotModerator" class="text-right pr-4 pr-lg-0 is-not-moderator">
<b-row class="mb-3"> <b-row class="mb-3">
<b-col cols="10"> <b-col cols="10">
<div class="font-weight-bold" data-test="username">{{ storeName.username }}</div> <div class="font-weight-bold" data-test="username">{{ storeName.username }}</div>

View File

@ -56,6 +56,7 @@
"openAmountForMonth": "Für <b>{monthAndYear}</b> kannst du noch <b>{creation}</b> GDD einreichen.", "openAmountForMonth": "Für <b>{monthAndYear}</b> kannst du noch <b>{creation}</b> GDD einreichen.",
"yourContribution": "Dein Beitrag zum Gemeinwohl" "yourContribution": "Dein Beitrag zum Gemeinwohl"
}, },
"isEdited": "hat den Beitrag bearbeitet",
"lastContribution": "Letzte Beiträge", "lastContribution": "Letzte Beiträge",
"noContributions": { "noContributions": {
"allContributions": "Es wurden noch keine Beiträge eingereicht.", "allContributions": "Es wurden noch keine Beiträge eingereicht.",
@ -67,6 +68,7 @@
"lastMonth": "Für den ausgewählten Monat ist das Schöpfungslimit erreicht.", "lastMonth": "Für den ausgewählten Monat ist das Schöpfungslimit erreicht.",
"thisMonth": "Für den aktuellen Monat ist das Schöpfungslimit erreicht." "thisMonth": "Für den aktuellen Monat ist das Schöpfungslimit erreicht."
}, },
"oldContribution": "Vorherige Version",
"selectDate": "Wann war dein Beitrag?", "selectDate": "Wann war dein Beitrag?",
"submit": "Einreichen", "submit": "Einreichen",
"submitted": "Der Beitrag wurde eingereicht.", "submitted": "Der Beitrag wurde eingereicht.",

View File

@ -56,6 +56,7 @@
"openAmountForMonth": "For <b>{monthAndYear}</b>, you can still submit <b>{creation}</b> GDD.", "openAmountForMonth": "For <b>{monthAndYear}</b>, you can still submit <b>{creation}</b> GDD.",
"yourContribution": "Your Contributions to the Common Good" "yourContribution": "Your Contributions to the Common Good"
}, },
"isEdited": "edited the contribution",
"lastContribution": "Last Contributions", "lastContribution": "Last Contributions",
"noContributions": { "noContributions": {
"allContributions": "No contributions have been submitted yet.", "allContributions": "No contributions have been submitted yet.",
@ -67,6 +68,7 @@
"lastMonth": "The creation limit is reached for the selected month.", "lastMonth": "The creation limit is reached for the selected month.",
"thisMonth": "The creation limit has been reached for the current month." "thisMonth": "The creation limit has been reached for the current month."
}, },
"oldContribution": "Previous version",
"selectDate": "When was your contribution?", "selectDate": "When was your contribution?",
"submit": "Submit", "submit": "Submit",
"submitted": "The contribution was submitted.", "submitted": "The contribution was submitted.",