# ========================================================================================= # 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. # ========================================================================================= # default workflow rules: Merge Request pipelines workflow: rules: # prevent branch pipeline when an MR is open (prefer MR pipeline) - if: '$CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS' when: never - when: always # acceptance job prototype: implement adaptive pipeline rules .acceptance-policy: rules: # exclude tags - if: $CI_COMMIT_TAG when: never # on production or integration branch(es): auto & failing - if: '$CI_COMMIT_REF_NAME =~ $PROD_REF || $CI_COMMIT_REF_NAME =~ $INTEG_REF' # disable if no review environment - if: '$REVIEW_ENABLED != "true"' when: never # on ADAPTIVE_PIPELINE_DISABLED: auto & failing - if: '$ADAPTIVE_PIPELINE_DISABLED == "true"' # early stage (dev branch, no MR): manual & non-failing - if: '$CI_MERGE_REQUEST_ID == null && $CI_OPEN_MERGE_REQUESTS == null' when: manual allow_failure: true # Draft MR: auto & non-failing - if: '$CI_MERGE_REQUEST_TITLE =~ /^Draft:.*/' allow_failure: true # else (Ready MR): auto & failing - when: on_success variables: # variabilized tracking image TBC_TRACKING_IMAGE: "$CI_REGISTRY/to-be-continuous/tools/tracking:master" # Default Docker image (can be overridden) PUPPETEER_IMAGE: "ghcr.io/puppeteer/puppeteer:latest" PUPPETEER_PROJECT_DIR: "." # default production ref name (pattern) PROD_REF: '/^(master|main)$/' # 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 .puppeteer-scripts: &puppeteer-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 Puppeteer 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_warn "No \\e[33;1mpackage.json\\e[0m file found: choose testing framework Jest or Mocha to use with Puppeteer" fi } function eval_base_url() { # shellcheck disable=SC2154 if [[ -n "$environment_url" ]] then PUPPETEER_BASE_URL="$environment_url" export PUPPETEER_BASE_URL log_info "Upstream \$environment_url variable set: use baseUrl \\e[33;1m$PUPPETEER_BASE_URL\\e[0m" elif [[ -f environment_url.txt ]] then PUPPETEER_BASE_URL=$(cat environment_url.txt) export PUPPETEER_BASE_URL log_info "Upstream environment_url.txt file found: use baseUrl \\e[33;1m$PUPPETEER_BASE_URL\\e[0m" else log_info "No upstream environment url found: leave default" fi } unscope_variables # ENDSCRIPT puppeteer: image: name: "$PUPPETEER_IMAGE" entrypoint: [""] cache: key: ${CI_COMMIT_REF_SLUG} paths: - $PUPPETEER_PROJECT_DIR/.npm/ services: - name: "$TBC_TRACKING_IMAGE" command: ["--service", "puppeteer", "3.1.0"] stage: acceptance before_script: - *puppeteer-scripts - install_ca_certs "${CUSTOM_CA_CERTS:-$DEFAULT_CA_CERTS}" # retrieve server url to test from 'environment_url.txt' file - eval_base_url - cd "$PUPPETEER_PROJECT_DIR" - maybe_install_deps # create directories - mkdir -p puppeteer/screenshots - mkdir -p -m 777 reports # set junit report dir and fileName - export JEST_JUNIT_OUTPUT_DIR="reports" - export JEST_JUNIT_OUTPUT_NAME="puppeteer.xunit.xml" script: # maybe activate DEBUG traces - 'if [[ "$TRACE" ]]; then export DEBUG=puppeteer:*; fi' # run puppeteer tests - npm run puppeteer -- --config '{"globals":{"URL":"$PUPPETEER_BASE_URL"}}' --reporters=default --reporters=jest-junit $PUPPETEER_TEST_EXTRA_ARGS artifacts: name: "$CI_JOB_NAME artifacts from $CI_PROJECT_NAME on $CI_COMMIT_REF_SLUG" when: always paths: - $PUPPETEER_PROJECT_DIR/reports/puppeteer.* - $PUPPETEER_PROJECT_DIR/puppeteer/screenshots/ reports: junit: - $PUPPETEER_PROJECT_DIR/reports/puppeteer.xunit.xml expire_in: 1 day rules: - !reference [.acceptance-policy, rules]