This is an internal documentation. There is a good chance you’re looking for something else. See Disclaimer.

Cypress (End-to-End-Test)

Local Cypress Setup

Postgres User

To ensure that Cypress scripts are able to log into the postgres server without using a password prompt one of the three settings has to be set up:

  1. set trust authentication method

  2. create ~/.pgpass for postgres database and postgres user

  3. set POSTGRES_PASSWORD in .env (see Environment variables)

Authentication Trust Method

  • set trust method in pg_hba.conf for local

  • restart postgresql

.pgpass file

  • create ~/.pgpass file (see: pgpass file)

  • add entry for postgres user on postgres database

    # hostname:port:database:username:password
    localhost:5432:postgres:postgres:postgres
    
  • set correct file permission

    chmod 0600 ~/.pgpass
    

Environment variables

A .env file in the root folder is needed so that test can authenticate to the nice2 backend.

Variable

Description

CYPRESS_USER

Tocco user name

CYPRESS_PASSWORD

Password for Tocco user

CYPRESS_USER_PASSWORD_HASH

The hash for the CYPRESS_PASSWORD

CYPRESS_API_KEY

Tocco API Key (needed for test-data setup via REST)

CYPRESS_USER_API_KEY_HASH

The hash for the CYPRESS_API_KEY

Note

The values for the Cypress environment variables can be found in the ansible vault.

Furthermore there are optional environment variables which can be set to overwrite some default values.

Variable

Description

Default value

POSTGRES_USER

postgres superuser (for test db restore and setup)

none (login user is taken)

POSTGRES_PASSWORD

pwd for postgres superuser [1]

none

HIBERNATE_MAIN_SERVERNAME

postgres hostname

localhost

HIBERNATE_MAIN_USER

postgres user for test database [2]

nice

HIBERNATE_MAIN_PASSWORD

postgres user password for test database

nice

HIBERNATE_MAIN_DATABASENAME

postgres test database name [3]

test_cypress

HIBERNATE_MAIN_SSLMODE

nice2 ssl mode

disable

BACKEND_URL

nice2 hostname

http://localhost:8080

CYPRESS_BASE_URL

nice2 hostname (officical Cypress env)

http://localhost:8080

Explanation

Run Cypress

Warning

Before you start ensure that you’ve properly set up Cypress locally (Local Cypress Setup).

# start nice2 via gradle and widget-server on localhost:3000
yarn cypress:nice2

# or run both separately
yarn nice2:run
yarn widgets:serve

# deploy local package to nice2 for testing purposes (OPTIONAL)
yarn  nice2:deploy-package --package=admin

# run cypress
yarn cypress:run
# or open cypress dashboard
yarn cypress:open

Note

Per default a database with name test_cypress is created right before running nice2. To overwrite the database name set HIBERNATE_MAIN_DATABASENAME environment variable (see Environment variables).

Writing Cypress Tests

With Cypress the admin and the widgets can be tested. But for the widgets there are some special helpers.

Do’s and Dont’s

See also Cypress Best Practices

data-cy attribute

Use data-cy attribute to select a elements. Using keys or unique identifiers helps to get the correct element out of many (e.g. data-cy="list-row-1229"). Do not use CSS classes for element selection except for external libraries.

data-cy naming

Prefix

Description

Examples

btn

Button

btn-confirmation

infobox

Infobox

infobox-newregistrations

export-item

For different export items in the export action

export-item-phonelist

communication

For different communication items in the communication action

communication-sms

action

For the different action groups like new, delete, output, etc.

action-delete

action-item

For the different actions

action-item-createTodo

list-row

Row in the table. Use the Entity-Id as the name

list-row-1

header-cell and list-cell

Are used in the tables. The name should be the relation or field name.

header-cell-firstname

form-field

Input fields in the admin. The name should be the relation or the field name.

form-field-firstname

box

For the boxes in the detail-form

box-masterdata

admin-menuitem

For the items in the admin menu

admin-menuitem-address

Create Cypress Tasks for seeding

Only seed data via Cypress Tasks and do not run REST APIs inside a test directly. Use the returned data for better testing:

cy.task('db:seed:entity-browser').then(response => {
  const {pk} = response
  visitEntityBrowser(pk)
})

cy.task('db:seed:user').then(user => {
  const {firstname} = user
  ...
  cy.getByAttr('input-detailForm-firstname').type(user.firstname)
  ...
})

See Test data for more information.

Use Custom Commands

Use custom commands instead implement common actions on each test (e.g. cy.getTableRow(0)).

See Custom Commands / Tasks for more information.

Widgets

Widgets are running on localhost:3000 and are threated as different origin.

Use following helpers for widgets in order to manage the origin handling in Cypress.

widgetOrigin and prepareWidgetOrigin

Wrap all Cypress calls which are made on a widget inside a widgetOrigin call (except loginWidget). Parameters have to be passed in via first parameter (see widgetConfigKey as an example below).

beforeEach(() => {
    cy.prepareWidgetOrigin()
})

cy.widgetOrigin({widgetConfigKey: widgetConfig.unique_id}, ({widgetConfigKey}) => {
    cy.visitWidget(widgetConfigKey)

    cy.get('#input-addressForm-firstname').should('have.text', 'Susanne')
    cy.get('#input-addressForm-lastname').should('have.text', 'Peters')
})

loginWidget and logoutWidget

Log in through the login widget.

cy.loginWidget({loginWidgetConfigKey: loginWidgetConfig.unique_id})
// or
cy.loginWidget({
    loginWidgetConfigKey: loginWidgetConfig.unique_id,
    username: login.username,
    password: login.password
})

Log out through the usermenu widget.

cy.logoutWidget({
  logoutWidgetConfigKey: userMenuWidgetConfig.unique_id
})

visitWidget

Do not use visit in widgets. Do use visitWidget (inside widgetOrigin) to open a widget by a widget config key.

cy.visitWidget(widgetConfigKey)

Test data

Test data should be added via REST API inside a Cypress Tasks.

  • Each test data task should be prefixed with db:seed:.

  • A test data task can be named and created for generic purposes or for single tests/specs only.

  • If possible the task should return the created IDs and as much data as possible.

Test data recoder

To be more efficient in creating the database seed task there is a test data recoder in the Tocco Chrome Extension. The recorder can be used to create REST API calls easily. It also transforms references to ids into unique_ids if available.

Custom Commands / Tasks

Custom Cypress Commands can be added for generic Tocco functionality (e.g. login or breadcrumbs validation). Each command should be listed in the index.d.ts file to enable code intellisense for those commands.

db:empty-Task

Every test should be independent and not rely on any data inside the database. Before each test the database should be emptied to start on a fresh db.

cy.task('db:empty')

login

A test should not log in via UI. Use login helper instead.

cy.login()

getByAttr

To select HTML element data-cy attributes should be used. CSS classes are not allowed except for external libraries. The getByAttr helper creates a query selector for the data-cy attribute.

cy.getByAttr('admin-nav')

Cypress on CI

On CI (gitlab) the nice2 and postgres instances are running in Docker: Nice2 Registry, Postgres Registry.

A test run saves the generated video artefacts for one week. Those artefacts can be found on the executed pipeline for further failure investigation.

Process

Run Nice2

  1. Restore DB from existing DB dump (create empty DB when no dump is available)

  2. Run DB refactoring

  3. Run Nice2

  4. Initialize DB

    1. Crate Tocco User and API Key for Cypress (See Environment variables)

    2. Create DB dump

Test Run

  1. Empty DB

    1. Forcefully restore DB from existing DB dump (created on nice2 start up)

  2. Seed DB via REST API

  3. Login

  4. Run Test