GitLab-CIとCypressを連携してみた（自力編）

# 背景

WebアプリケーションのGUI自動テストを実施することになった。
自動テストのフレームワークは[Cypress](https://www.cypress.io/)を導入する。
せっかくテストを自動化するのに、手動トリガではカッコ悪いし非効率なので、トリガも自動で発動するようにしたい。

既にオンプレミスのGitLab環境で[GitLab-CI](https://docs.gitlab.com/ce/ci/)を活用していたので、GitLab-CIからCypressによる自動試験を実行する手法を調査。

[公式のdockerイメージ](https://github.com/cypress-io/cypress-docker-images)を使えば簡単に構築できそうだが、この記事では自前で環境構築を試みた記録を残す。

> **追記**
> 公式のdockerイメージを使用する方法を▼の記事で紹介。
> 
> * [GitLab-CIとCypressを連携してみた（公式dockerイメージ編）](https://qiita.com/itTkm/items/3a58d394e83be277f2a6)
> 
> 特にこだわりがなければ**dockerイメージを使用する方法をオススメ**する。
> また、同記事では、複数テストを実行したり、実行条件を変えながら実行したりするケースを考慮した`.gitlab-ci.yml`の書き方も解説。

# 環境

* CentOS 7.5.1804
* GitLab CE 11.11.3
* gitlab-runner v12.6.0
* Cypress v3.7.0

# `gitlab-runner`をインストール

```bash
curl -L https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.rpm.sh -o script.rpm.sh
sudo bash ./script.rpm.sh 
yum list gitlab-runner --showduplicates | sort -r
sudo yum install gitlab-runner-12.6.0-1
sudo systemctl status gitlab-runner.service
rm script.rpm.sh 
```

# GitLabにrunnerを登録

```bash
sudo gitlab-runner register \
    --url {your_gitlab_url} \
    --registration-token {your_gitlab_runner_token} \
    --name "gitlab-runner-cypress" \
    --tag-list "autotest-server,shell,cypress" \
    --executor "shell"
```

# (必要に応じて) 各種フレームワークをインストール

ここで、各プロジェクトのテスト環境に必要なフレームワーク類をインストールしておく。
私の場合、node.jsとyarnが必要だったので、下記のコマンドでインストール。

```bash
# nodejs
sudo yum install -y https://rpm.nodesource.com/pub_8.x/el/7/x86_64/nodesource-release-el7-1.noarch.rpm
sudo yum install -y nodejs
node --version

# yarn
sudo yum install -y yarn
yarn --version
```

# (必要に応じて) `gitlab-runner`ユーザでsudoした時のパスワード問い合わせをスキップ

CIのスクリプトの一部に`sudo`コマンドを使用する必要があったため、`gitlab-runner`ユーザでsudo時のパスワード問い合わせをスキップするように設定。

```bash
sudo visudo
# 最終行に下記を追加。
gitlab-runner ALL=NOPASSWD: ALL
```

# `.gitlab-ci.yml`を作成

```yaml:.gitlab-ci.yml
stages:
  - cypress

variables:
  AUTO_TEST_SERVER: "192.168.1.10"
  AUTO_TEST_SERVER_PORT: "3000"
  GIT_CLEAN_FLAGS: -fdx --exclude node_modules/ --exclude build/

cypress:
  stage: cypress
  cache:
    key: $CI_COMMIT_REF_SLUG
    paths:
      - node_modules
  variables:
    CY_SPEC: "cypress/integration/test/sample.spec.js"
    CY_BASE_URL: https://$AUTO_TEST_SERVER:$AUTO_TEST_SERVER_PORT
    CY_VIEWPORT_HEIGHT: 1080
    CY_VIEWPORT_WIDTH: 1920
  script:
    # 依存パッケージを取得
    - yarn
    # # 諸々の処理（省略）
    # - ビルド
    # - Dockerイメージのビルド
    # - デプロイ
    # GUIテストの実行
    - node_modules/.bin/cypress run -s $CY_SPEC --config baseUrl=$CY_BASE_URL,viewportHeight=$CY_VIEWPORT_HEIGHT,viewportWidth=$CY_VIEWPORT_WIDTH
  artifacts:
    # エビデンスをGitLabのGUIから参照するための設定
    expire_in: 1 week
    when: always
    paths:
    - cypress/screenshots
    - cypress/videos
  tags:
    - autotest-server
    - cypress
```

# GitLab-CIを一旦キック

gitlab-runnerにプロジェクトをcloneさせるために、GitLabのGUI上でCIを手動実行する。
この段階ではCypressがうまくインストールされず、`Failed`で終了するはず。

# Cypressをインストール

```bash

# ユーザを"gitlab-runner"に切り替える
su gitlab-runner

# Cypressのインストール
cd /home/gitlab-runner/
cd /home/gitlab-runner/builds/path/to/your/project/
./node_modules/cypress/bin/cypress install --force

# Cypressをヘッドレス実行するために必要なパッケージを追加でインストール
sudo yum -y install xorg-x11-server-Xvfb
```

## お試しでCypressのGUIを起動してみる

```bash
./node_modules/cypress/bin/cypress open
```

`libgtk-3.so.0`が見つからないと怒られたので追加でインストールする。

このとき、直接`sudo yum install -y libgtk-3.so.0`でインストールしようとしても成功しないので、このライブラリを含む親パッケージを探し、親パッケージをインストールする。

```bash
# "libgtk-3.so.0"を含むパッケージを探す
yum whatprovides */libgtk-3.so.0

# "gtk3"だと分かったので、gtk3をインストール
sudo yum install -y gtk3
```

## 気を取り直して、CypressのGUIを起動

```bash
./node_modules/cypress/bin/cypress open
```

`libXss.so.1`が見つからないと怒られたので追加でインストールする。

このとき、直接`sudo yum install -y libXss.so.1`でインストールしようとしても成功しないので、このライブラリを含む親パッケージを探し、親パッケージをインストールする。

```bash
# "libXss.so.1"を含むパッケージを探す
yum whatprovides */libXss.so.1

# "libXScrnSaver"だと分かったので、libXScrnSaverをインストール
sudo yum install -y libXScrnSaver
```

## 三度目の正直、CypressのGUI起動

```bash
./node_modules/cypress/bin/cypress open
```

CypressのGUIが起動することを確認！

## ヘッドレスでのCypress実行を確認

```bash
node_modules/.bin/cypress run -s cypress/integration/test/sample.spec.js
ls -al cypress/videos/test/
```

自動テストが実行され、テストの様子が動画で記録されていることを確認！！

# GitLab-CIを本番実行

GitLabのGUI上からCIを手動実行する。
正常に動くことが確認できれば、あとはトリガーなどを適切に設定し、いよいよ本番運用開始！！！

# エビデンスはGitLabのGUIから参照可能

GitLabのGUIでジョブの実行結果ページを参照すると、`.gitlab-ci.yml`で`artifacts`に登録したパスのファイルが参照できるようになっている。
当然ダウンロードも可能だが、ダウンロードせずにGitLabのGUI上からスナップショットや動画を直接確認できるので、とっても便利。