HeadlessなLinux環境でNightmare(v2)を動かすためにしたこと

  • 19
    いいね
  • 2
    コメント

はじめに

この記事を書こうと思った背景や動機を箇条書きにまとめると以下のようになります。

  • Nightmare(v1)で書いたEnd-To-Endのテストコードがあり、CIサーバーで運用している
  • Nightmare(v2)に移行したい
  • Nightmare(v1)から(v2)でPhantomJSベースからElectronベースに大きく変わった
  • HeadlessなLinux環境にて、そもそもElectronを動かそうとして、いろいろハマった

環境構築(CentOS7)

CentOS6.xでは、Electronは動かない

正直、ここに気付くのに相当な時間を使ってしまいましたが、glibcのバージョンが古いため、CentOS6.xでは、Electronは動きません。

本家、ElectronのSupported Platformsを見ても、CentOSについての記載がないので、はっきりしません。
が、ElectornベースのVisual Studio CodeのRequirements for Visual Studio Codeを見ると、はっきりと下記のように記載があります。

Platforms

VS Code has been tested on the following platforms:

  • OS X Yosemite
  • Windows 7 (with .NET Framework 4.5), 8.0, 8.1 and 10 (32-bit and 64-bit)
  • Linux (Debian): Ubuntu Desktop 14.04, Debian 7
  • Linux (Red Hat): Red Hat Enterprise Linux 7, CentOS 7, Fedora 23

Additional Linux requirements

  • GLIBCXX version 3.4.15 or later
  • GLIBC version 2.15 or later

glibcのバージョン

尚、OSとglibcの初期バージョンをまとめると以下のようになります。

OS glibc
RHEL / CentOS 7.x 2.17
RHEL / CentOS 6.x 2.12
RHEL / CentOS 5.x 2.5
AmazonLinux 2.17
Ubuntu 14.04 2.19
Ubuntu 12.04 2.15

参考URL:

CentOS7のインストール

ここでは、CentOS7のインストール手順については、割愛します。

Xvfbのインストール

CUIベースのサーバーなど、GUIを持たない(=ヘッドレス)サーバーにて、GUIを伴うテストを実行するために、仮想ディスプレイフレームバッファを使用します。

Xvfbとは

Xvfb そのものについては、下記を参照ください。
- Xvfb - Wikipedia

Xvfbに必要なライブラリのインストール

Xvfbに必要なライブラリをインストールします。

  • gtk2
  • atk
  • pango
  • gdk-pixbuf2
  • libXrandr
  • GConf2
  • libXcursor
  • libXcomposite
  • libnotify
  • libXtst
  • cups-libs
  • glib2-devel

参考URL:

Xvfbのインストール

Xvfb本体およびフォントセットをインストールします。

  • xorg-x11-server-Xvfb
  • xorg-x11-fonts*

日本語フォントのインストール

日本語が化けてしまうので、IPAフォントをyumでインストールします。

  • ipa-mincho-fonts
  • ipa-gothic-fonts
  • ipa-pmincho-fonts
  • ipa-pgothic-fonts

nodejsのインストール

nightmare v2.4からは、node v4.0以上が必要

PR #579がmergeされた結果、nightmare v2.4からは、node v4.0 と --harmonyオプション、または、node v5.0以上が必要になりました。

下記のコードにて、template literalsが使われていることが確認できます。
`CALL_DATA_${id}`の部分ですね。

lib/ipc.js
    var id = callId++;
    var progress = new Emitter();

    emitter.on(`CALL_DATA_${id}`, function() {
      progress.emit.apply(progress, ['data'].concat(sliced(arguments)));
    });

template literalsは、node v4.0+以上が必要なことは、ECMAScript 6 compatibility tableから分かります。

es6_compability_table.png

参考URL:

node v4.x をソースからインストールします。

$ curl -O https://nodejs.org/dist/v4.4.4/node-v4.4.4.tar.gz
$ sudo tar -zxvf node-v4.4.4.tar.gz
$ cd node-v4.4.4
$ ./configure
$ make
$ make install

テストの実行

exampleの作成

下記のように、exampleを作成します。

test/example.js
require('mocha-generators').install();

var Nightmare = require('nightmare');
var config = require('../config');
var assert = require('assert');

describe('home', function() {

    this.timeout(config.mocha.timeout);

    it('execute example', function*() {

        var nightmare = Nightmare();
        yield nightmare
            .viewport(1024, 768)
            .goto('http://google.com')
            .wait(500)
            .screenshot('/path/to/screenshots/example-google.png')
            .end();
        ;
    });

});

実行時オプション

npm run コマンドから実行したいので、package.jsonの"scripts"に下記のように記述します。

package.json
{
  "dependencies": {
    "mocha": "^2.3.3",
    "mocha-generators": "~1.2.0",
    "nightmare": "^2.3.4"
  },
  "scripts": {
    "e2e-test:example": "DEBUG=nightmare:*,electron:* xvfb-run --server-args='-screen 0 1024x768x24' mocha --harmony test/example.js",
  }
}

参考URL:

npm run

作成したexampleを実行します。

$ npm run e2e-test:example

> example@0.0.1 e2e-test:example /path/to/app
> DEBUG=nightmare:*,electron:* xvfb-run --server-args='-screen 0 1024x768x24' mocha --harmony test/example.js

...(中略)...

  nightmare:actions .screenshot() +96ms
  nightmare:log subscribing to browser window frames +2ms
  nightmare:log altering page to force rendering +0ms
  nightmare:log unsubscribing from browser window frames +28ms
  nightmare:actions .screenshot() captured with length 32311 +80ms
    ✓ execute example (3743ms)


  1 passing (4s)

成功すれば、下記のようにスクリーンショットが保存されます。

example-google.png

CircleCIで動かすためにしたこと(2016-05-23追記)

Xvfbはセットアップ済み

公式のドキュメントにもあるとおり、Xvfbはセットアップ済みですので、xvfb-runコマンドがすぐに使えます。

CircleCI runs graphical programs in a virtual framebuffer, using xvfb.

nodejsをv4に

machine:
  node:
    version: 4.2.2

しただけでは、切り替わらなかったので、

dependencies:
  override:
    - nvm use default

を追加しました

xvfb-runの実行時オプションに--auto-servernum追加

xvfb-run: error: Xvfb failed to start

とエラーになったので、下記の記事などを参考に--auto-servernumを追加してみたところ、無事動作しました。

参考URL:

DEBUG=nightmare:*,electron:*は削除

以前、「おわりに」の部分にて、「nightmare v2はそんなに早くない」、とか「まだまだ不安定」とか書いてましたが、DEBUG=nightmare:*,electron:*を削除したら、速度は改善(v1で15分かかっていたテストが5分程度に)し、途中で止まるようなこともなくなりました。
なので、CIでもデバッグモードなしで運用することをお勧めします。

おわりに(2016-05-23更新)

以下、nightmare v2についての所感。

  • nightmare v2は活発に開発が行われている
  • ES6のFeatureも積極的に使われている
  • 日本語の記事がおいついていない
  • 結果、githubのissuesを確認するのが近道
  • すでに、v3の仕様が検討されている模様
  • デバッグモード(DEBUG=nightmare:*,electron:*)は要注意
    • デバッグモードで動かすと、かなり動作が重くなり、仮想マシンごと止まったりする
    • 今のところ、普段づかいしないほうが良さそう

以上です。