日頃からコードをお書きになるみなさんなら、三度の飯よりテストですよね?

今回は Chrome 拡張「TweetDeck Accounts Switcher」を Travis CI/AppVeyor 上でテストしてみました。

用意するもの

  • GitHub アカウント
  • Travis CI アカウント
  • Google Chrome
  • Node.js

環境構築

はじめに macOS で試してみます。

Node.js でドライバーを読み込んで……。

imac chromedriver hang

ちくちょう! だいなしにしやがった! お前はいつもそうだ。

imac tweetdeck hang

このフリーズした TweetDeck はお前の人生そのものだ。

(node:43816) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection
WebDriverError: chrome not reachable
  (Session info: chrome=58.0.3013.3)
  (Driver info: chromedriver=2.27.440174 (e97a722caafc2d3a8b807ee115bfb307f7d2cfd9),pl
ac OS X 10.12.3 x86_64)
(node:43816) DeprecationWarning: Unhandled promise rejections are deprecated. In the f
romise rejections that are not handled will terminate the Node.js process with a non-z
 code.

誰もお前を愛さない。

閑話休題

macOS で動かないときがありましたが、神に許しを請えば多分大丈夫なので先へ行きます。

Travis CI では Linux と macOS に対するサポートを提供しているので、ここではどちらでも動かせるように .travis.yml を仕込みました。

Travis CI: Linux

apt を用いて google-chrome-stable をインストールします。

Travis CI での実行時はディスプレイを持たない環境となるので、xvfb(X virtual framebuffer)を用いてヘッドレスで動いてもらう必要があります。環境変数 DISPLAY をセットしておくといい感じにしてくれます。

os: linux
node_js: '12'
sudo: required
env: DISPLAY=':99.0'
dist: trusty
addons:
apt:
update: true
sources:
- google-chrome
packages:
- dpkg
- google-chrome-stable
before_script:
- sh -e /etc/init.d/xvfb start

Travis CI: macOS

brew cask を用いて google-chrome を /Applications にインストールします。これだけで動いたので手元の環境とは大違いで割と素直でした。

os: osx
node_js: '12'
sudo: required
env: HOMEBREW_CASK_OPTS='--appdir=/Applications'
before_install:
- brew update > /dev/null
- brew cask install google-chrome

AppVeyor: Windows

AppVeyor では Chrome も ChromeDriver も元から入っています。神。

ドライバー: ChromeDriver

package.json では Node.js の chromedriver と selenium-webdriver を使用しています。この chromedriver は Google から最新の ChromeDriver を取得して node_modules に置いてくれることに加えて、selenium-webdriver にもそのパスを渡してくれるスグレモノです。 npm に依存したくなければ簡単なシェルスクリプトでも良いと思います。

{
"devDependencies": {
"chromedriver": "^76.0.1",
"selenium-webdriver": "^4.0.0-alpha.5"
}
}
view raw package.json hosted with ❤ by GitHub

テストを実行する際は Chrome の起動オプションに --no-sandbox を追加しないとキー操作などが行えないので注意が必要です。

const webdriver = require("selenium-webdriver");
const chrome = require("selenium-webdriver/chrome");
const chromedriver = require("chromedriver");
const until = webdriver.until;
const By = webdriver.By;
const options = new chrome.Options();
options.addArguments("no-sandbox");
const builder = new webdriver.Builder();
builder.forBrowser("chrome");
builder.setChromeOptions(options);
const driver = builder.build();
(async () => {
await driver.manage().setTimeouts({ implicit: 30000 });
await driver.get("https://tweetdeck.twitter.com");
await driver.wait(until.titleIs("TweetDeck"));
const login = await driver.findElement(By.css("section.form-login a.Button"));
await login.click();
})();
view raw test.js hosted with ❤ by GitHub

あとはテストを書くだけです! お疲れさまでした!

API ドキュメント: Selenium WebDriver JavaScript API