# ========================================================================================= # Copyright (C) 2021 Orange & contributors # # This program is free software; you can redistribute it and/or modify it under the terms # of the GNU Lesser General Public License as published by the Free Software Foundation; # either version 3 of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; # without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # See the GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License along with this # program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth # Floor, Boston, MA 02110-1301, USA. # ========================================================================================= variables: # Default Docker image (can be overridden) CYPRESS_IMAGE: "cypress/included:4.6.0" CYPRESS_PROJECT_DIR: "." # default production ref name (pattern) PROD_REF: '/^master$/' # default integration ref name (pattern) INTEG_REF: '/^develop$/' # allowed stages depend on your template type (see: to-be-continuous.gitlab.io/doc/dev-guidelines/#stages) stages: - acceptance .cypress-scripts: &cypress-scripts | # BEGSCRIPT set -e function log_info() { echo -e "[\\e[1;94mINFO\\e[0m] $*" } function log_warn() { echo -e "[\\e[1;93mWARN\\e[0m] $*" } function log_error() { echo -e "[\\e[1;91mERROR\\e[0m] $*" } function assert_defined() { if [[ -z "$1" ]] then log_error "$2" exit 1 fi } function install_ca_certs() { certs=$1 if [[ -z "$certs" ]] then return fi # import in system if echo "$certs" >> /etc/ssl/certs/ca-certificates.crt then log_info "CA certificates imported in \\e[33;1m/etc/ssl/certs/ca-certificates.crt\\e[0m" fi if echo "$certs" >> /etc/ssl/cert.pem then log_info "CA certificates imported in \\e[33;1m/etc/ssl/cert.pem\\e[0m" fi } function unscope_variables() { _scoped_vars=$(env | awk -F '=' "/^scoped__[a-zA-Z0-9_]+=/ {print \$1}" | sort) if [[ -z "$_scoped_vars" ]]; then return; fi log_info "Processing scoped variables..." for _scoped_var in $_scoped_vars do _fields=${_scoped_var//__/:} _condition=$(echo "$_fields" | cut -d: -f3) case "$_condition" in if) _not="";; ifnot) _not=1;; *) log_warn "... unrecognized condition \\e[1;91m$_condition\\e[0m in \\e[33;1m${_scoped_var}\\e[0m" continue ;; esac _target_var=$(echo "$_fields" | cut -d: -f2) _cond_var=$(echo "$_fields" | cut -d: -f4) _cond_val=$(eval echo "\$${_cond_var}") _test_op=$(echo "$_fields" | cut -d: -f5) case "$_test_op" in defined) if [[ -z "$_not" ]] && [[ -z "$_cond_val" ]]; then continue; elif [[ "$_not" ]] && [[ "$_cond_val" ]]; then continue; fi ;; equals|startswith|endswith|contains|in|equals_ic|startswith_ic|endswith_ic|contains_ic|in_ic) # comparison operator # sluggify actual value _cond_val=$(echo "$_cond_val" | tr '[:punct:]' '_') # retrieve comparison value _cmp_val_prefix="scoped__${_target_var}__${_condition}__${_cond_var}__${_test_op}__" _cmp_val=${_scoped_var#$_cmp_val_prefix} # manage 'ignore case' if [[ "$_test_op" == *_ic ]] then # lowercase everything _cond_val=$(echo "$_cond_val" | tr '[:upper:]' '[:lower:]') _cmp_val=$(echo "$_cmp_val" | tr '[:upper:]' '[:lower:]') fi case "$_test_op" in equals*) if [[ -z "$_not" ]] && [[ "$_cond_val" != "$_cmp_val" ]]; then continue; elif [[ "$_not" ]] && [[ "$_cond_val" == "$_cmp_val" ]]; then continue; fi ;; startswith*) if [[ -z "$_not" ]] && [[ "$_cond_val" != "$_cmp_val"* ]]; then continue; elif [[ "$_not" ]] && [[ "$_cond_val" == "$_cmp_val"* ]]; then continue; fi ;; endswith*) if [[ -z "$_not" ]] && [[ "$_cond_val" != *"$_cmp_val" ]]; then continue; elif [[ "$_not" ]] && [[ "$_cond_val" == *"$_cmp_val" ]]; then continue; fi ;; contains*) if [[ -z "$_not" ]] && [[ "$_cond_val" != *"$_cmp_val"* ]]; then continue; elif [[ "$_not" ]] && [[ "$_cond_val" == *"$_cmp_val"* ]]; then continue; fi ;; in*) if [[ -z "$_not" ]] && [[ "__${_cmp_val}__" != *"__${_cond_val}__"* ]]; then continue; elif [[ "$_not" ]] && [[ "__${_cmp_val}__" == *"__${_cond_val}__"* ]]; then continue; fi ;; esac ;; *) log_warn "... unrecognized test operator \\e[1;91m${_test_op}\\e[0m in \\e[33;1m${_scoped_var}\\e[0m" continue ;; esac # matches _val=$(eval echo "\$${_target_var}") log_info "... apply \\e[32m${_target_var}\\e[0m from \\e[32m\$${_scoped_var}\\e[0m${_val:+ (\\e[33;1moverwrite\\e[0m)}" _val=$(eval echo "\$${_scoped_var}") export "${_target_var}"="${_val}" done log_info "... done" } # maybe install NPM dependencies if package.json file found function maybe_install_deps() { if [[ -f "package-lock.json" ]] then log_info "\\e[33;1mpackage-lock.json\\e[0m file found: install dependencies..." npm ci --cache .npm --prefer-offline elif [[ -f "package.json" ]] then log_warn "\\e[33;1mpackage.json\\e[0m file found but no \\e[33;1mpackage-lock.json\\e[0m: use Cypress with default dependencies" log_warn "If your tests require additional dependencies, please create \\e[33;1mpackage-lock.json\\e[0m with 'npm install' and commit it" else log_info "No \\e[33;1mpackage.json\\e[0m file found: use Cypress with default dependencies" fi } function eval_base_url() { # shellcheck disable=SC2154 if [[ -n "$environment_url" ]] then CYPRESS_BASE_URL="$environment_url" export CYPRESS_BASE_URL log_info "Upstream \$environment_url variable set: use baseUrl \\e[33;1m$CYPRESS_BASE_URL\\e[0m" elif [[ -f environment_url.txt ]] then CYPRESS_BASE_URL=$(cat environment_url.txt) export CYPRESS_BASE_URL log_info "Upstream environment_url.txt file found: use baseUrl \\e[33;1m$CYPRESS_BASE_URL\\e[0m" else log_info "No upstream environment url found: leave default" fi } function get_latest_template_version() { tag_json=$(wget -T 5 -q -O - "$CI_API_V4_URL/projects/to-be-continuous%2F$1/repository/tags?per_page=1" || echo "") echo "$tag_json" | sed -rn 's/^.*"name":"([^"]*)".*$/\1/p' } function check_for_update() { template="$1" actual="$2" latest=$(get_latest_template_version "$template") if [[ -n "$latest" ]] && [[ "$latest" != "$actual" ]] then log_warn "\\e[1;93m=======================================================================================================\\e[0m" log_warn "\\e[93mThe template \\e[32m$template\\e[93m:\\e[33m$actual\\e[93m you're using is not up-to-date: consider upgrading to version \\e[32m$latest\\e[0m" log_warn "\\e[93m(set \$TEMPLATE_CHECK_UPDATE_DISABLED to disable this message)\\e[0m" log_warn "\\e[1;93m=======================================================================================================\\e[0m" fi } if [[ -z "$TEMPLATE_CHECK_UPDATE_DISABLED" ]]; then check_for_update cypress "1.1.0"; fi unscope_variables # ENDSCRIPT cypress: image: name: "$CYPRESS_IMAGE" entrypoint: [""] cache: key: "$CI_COMMIT_REF_SLUG-cypress" paths: - $CYPRESS_PROJECT_DIR/.npm/ services: - name: "$CI_REGISTRY/to-be-continuous/tools/tracking:master" command: ["--service", "cypress", "1.1.0"] stage: acceptance before_script: - *cypress-scripts - install_ca_certs "${CUSTOM_CA_CERTS:-$DEFAULT_CA_CERTS}" # retrieve server url to test from 'environment_url.txt' file - eval_base_url - cd "$CYPRESS_PROJECT_DIR" - maybe_install_deps script: # maybe activate DEBUG traces - 'if [[ "$TRACE" ]]; then export DEBUG=cypress:*; fi' # run Cypress tests - cypress run --reporter junit --reporter-options "mochaFile=cypress/reports/TEST-[hash].xml" $CYPRESS_EXTRA_ARGS artifacts: name: "$CI_JOB_NAME artifacts from $CI_PROJECT_NAME on $CI_COMMIT_REF_SLUG" when: always paths: - $CYPRESS_PROJECT_DIR/cypress/reports/ - $CYPRESS_PROJECT_DIR/cypress/videos/ - $CYPRESS_PROJECT_DIR/cypress/screenshots/ reports: junit: - $CYPRESS_PROJECT_DIR/cypress/reports/TEST-*.xml expire_in: 1 day rules: # exclude merge requests - if: $CI_MERGE_REQUEST_ID when: never # exclude tags - if: $CI_COMMIT_TAG when: never # on production and integration branch(es): auto (on_success) - if: '$CI_COMMIT_REF_NAME =~ $PROD_REF || $CI_COMMIT_REF_NAME =~ $INTEG_REF' # on other branch(es): manual & non-blocking if $REVIEW_ENABLED set - if: $REVIEW_ENABLED when: manual allow_failure: true