ngrokでURLを発行しBrowserstackを使いTestCafeを実行する処理の自動化


# 記事の目的

BrowserstackとTestCafeの連携させて
複数の端末やOS、ブラウザ環境でE２Eテストを実行する

#記事を書くまでの経緯
１）[2020 Vue/Vuetify WEB開発 TestCafeを使ったE2Eテスト 基礎編](https://qiita.com/shiho_hoshino/items/62ad3f18be5105983f35)

TestCafeを使ったE2Eテストを作成した。
TestCafeはBrowserstackと連携して
複数の端末やOS、ブラウザでE２Eテストを実行することができる。

２）[ngrokでローカルサーバー起動と同時にBASIC認証付き外部URLを発行する方法【Nuxt / vue】](https://qiita.com/shiho_hoshino/items/354fd69b75436acc4c2b)

BrowserstackはローカルホストのURLは指定できないため
ngrokサービスを利用してhttpで外部公開する処理を検証

上記２つの記事で作成した環境を利用し
BrowserstackとTestCafeの連携を行う。

# 開発環境

- MacBook Pro (Retina, 13-inch, Early 2015)
- OS：macOS Mojava 10.14.6
- サーバサイドJavaScript：node v12.14.1
- パッケージマネージャー： yarn v1.22.4
- フレームワーク： nuxt v2.0.0
- JavaScriptライブラリ： Vue v2.6.11
- UIライブラリー： @nuxtjs/vuetify v1.11.2

# 参考

Browserstack公式ドキュメント
https://www.browserstack.com/docs/automate/selenium/getting-started/nodejs/testcafe

Node.js 初めてのファイル書き込み
https://qiita.com/PianoScoreJP/items/8598e028a2cb8f23014b

シェルコマンドを実行する方法(child_process)
https://www.wakuwakubank.com/posts/728-nodejs-child-process/

# 手順

## 前提

「記事を書くまでの経緯」で紹介した記事で
testcafe実行環境と、ngrokの認証設定が済んでいる。

## 準備 

ngrokで取得したURLを使って、テストコードを実行するスクリプトを作成します。

１）必要なmoduleのインストール  


ngrok
https://www.npmjs.com/package/ngrok


前記事ではNuxtで起動したかったため「@nuxtjs/ngrok」をインストールしたが、
本記事ではオリジナルの起動スクリプトを作成したいため、
通常の「ngrok」をインストールする。

```
$ yarn add -D ngrok
```
dotenv
https://www.npmjs.com/package/dotenv

アクセストークンなどはそれぞれの環境下に「.env」ファイルで
環境変数として設定してある前提
これを読み込むためdotenvを使用する

```
$ yarn add -D dotenv
```

2）スクリプトを作成  
「ngrok.js」を、プロジェクトのルートに作成する。

/ngrok.js

```javascript
require('dotenv').config();
const ngrok = require('ngrok');

(async () => {
  // Ngrokを起動
  const url = await ngrok.connect({
    // .envファイルに設定した ngrokのauthtoken
    authtoken: process.env.NGROK_AUTHTOKEN,
    // .envファイルに設定した basic認証の設定
    auth: process.env.NGROK_AUTH,
    // ローカルで起動する際のポート番号
    addr: '3000',
    region: 'jp',
  });

  // URLにBasic認証Passを設定
  const domain = url.match(/^https?:\/{2,}(.*?)(?:\/|\?|#|$)/)[1];
  urltmp = 'https://' + process.env.NGROK_AUTH + '@' + domain;

  // 環境変数に書き込み
  process.env.TEST_URL = urltmp;
  console.log('ngrok url:', process.env.TEST_URL);

  // Testcafeの実行
  const {exec} = require('child_process');
  exec('yarn testcafe chrome test/e2e/**.js', (err, stdout, stderr) => {
    if (err) {
      console.log(`stderr: ${stderr}`);
      return;
    }
    console.log(`stdout: ${stdout}`);
  });
})();

```

3)テストコードで環境変数を利用する

TestCafeのテストコードで、開始ページのURLを指定している箇所を
(2)で設定した「TEST_URL」を使う形に変更する

例

```javascript

fixture`Getting Started`.page`${process.env.TEST_URL}/login/`;
```

4）実行・確認

package.jsonでローカル環境を起動する

```
$ yarn run dev
```

Nuxtが起動したらnodecommandでスクリプトを実行する

```
$ node ngrok.js
```

![スクリーンショット 2021-01-21 10.09.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/645692/50110d17-7778-b220-11ca-daa2139510d1.png)

**ngrokで取得した外部URLを使って、テストコードを実行することに成功！**


## browserstackの処理の作成

公式サイトでTestCafeとの連携について記載がある
これを参考に進める
https://www.browserstack.com/docs/automate/selenium/getting-started/nodejs/testcafe

１） 環境変数に「BROWSERSTACK_USERNAME」と「BROWSERSTACK_ACCESS_KEY」を設定する

envに変数を追記

.env

```
BROWSERSTACK_USERNAME=[あなたのBROWSERSTACK_USERNAME]
BROWSERSTACK_ACCESS_KEY=[あなたのBROWSERSTACK_ACCESS_KEY]
```

2)process.envで読み込んでスクリプト内で環境変数に書き込む処理を追加する

dotenvプラグインを使って.envファイルの変数を読み込む
ngrok.jsに以下を追記

```javascript
process.env.BROWSERSTACK_USERNAME = process.env.BROWSERSTACK_USERNAME;
process.env.BROWSERSTACK_ACCESS_KEY = process.env.BROWSERSTACK_ACCESS_KEY;
```

3） testcafe-browser-provider-browserstackをインストール

```
yarn add -D testcafe-browser-provider-browserstack
```

3)testcafeの実行ブラウザをbrowserstackに変更

ngrok.js全文

```javascript
require('dotenv').config();
const ngrok = require('ngrok');

(async () => {
  // Ngrokを起動
  const url = await ngrok.connect({
    // .envファイルに設定した ngrokのauthtoken
    authtoken: process.env.NGROK_AUTHTOKEN,
    // .envファイルに設定した basic認証の設定
    auth: process.env.NGROK_AUTH,
    // ローカルで起動する際のポート番号
    addr: '3000',
    region: 'jp',
  });

  // URLにBasic認証Passを設定
  const domain = url.match(/^https?:\/{2,}(.*?)(?:\/|\?|#|$)/)[1];
  const urltmp = 'https://' + process.env.NGROK_AUTH + '@' + domain;

  // console.log(urltmp);

  // 環境変数に必要な情報を書き込み
  process.env.TEST_URL = urltmp;
  process.env.BROWSERSTACK_USERNAME = process.env.BROWSERSTACK_USERNAME;
  process.env.BROWSERSTACK_ACCESS_KEY = process.env.BROWSERSTACK_ACCESS_KEY;
  console.log('ngrok url:', process.env.TEST_URL);

  // const browser = 'chrome';
  const browser = '"browserstack:chrome@79.0:Windows 10"';

  // Testcafeの実行
  const {exec} = require('child_process');
  exec('yarn testcafe '+ browser +' test/e2e/**.js',
      (err, stdout, stderr) => {
        if (err) {
          console.log(`stderr: ${stderr}`);
          return;
        }
        console.log(`stdout: ${stdout}`);
      });
})();
```

## 実行・確認

ローカル環境を起動してからngrok.jsを実行


```
$ yarn run dev
```

```
$ node ngrok.js
```

Products > Automata を開くと
現在実行中のタスクが表示されている
成功すると「PASSED」、失敗すると「FAILED」が返ってくる

![スクリーンショット 2021-01-27 15.24.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/645692/56162ac8-0389-9c5a-9c27-67c85e550b54.png)

コンソール画面はこのようになる

![スクリーンショット 2021-01-27 15.38.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/645692/0052b3e1-7cf7-7996-ffc8-ca9837a9f2cf.png)

以上が、ngrokでURLを発行しBrowserstackを使い
TestCafeを実行する処理の自動化方法となる