すでに社内で、electronで作成した座席表アプリを配布済みです。この環境下でpuppeteer + nexeでバイナリ配布をするのも良いのですが、すでにある座席表アプリでpuppeteerを動かせないかな?と思い挑戦しました。

ただし、keytarも使わなければ行けない環境であるため、これまでのelectron 3.0.0 + keytar 4.2.1の環境では古すぎてpuppeteerが動きません(Error : Protocol errorが出て、getBrowserContexts wasn’t foundと出ます)。そこで、今回electronを5.0にし、keytarを4.6.0でビルドし直した所うまく動いたので、これを元に進めたいと思います。

難易度:


今回使用するモジュール等

事前準備

Keytarのインストール

Node.jsはv10.15.1を利用しています。リビルド環境の構築はWindows向けで構築しています。electron-rebuildは最新版に入れ直しています。keytarのインストールは以下のような手順です。

Puppeteerをインストール

electron自体がChromiumなので、別途Chromiumは必要ありません。ということで、今回もpuppeteer-coreを利用します。また、electronのBrowserWindow内で使いたいので、puppeteer-in-electronもインストールします。

electron v5.0.0はpuppeteerから操作が可能なので、今回のようなアプリを作る場合には、electronのバージョンは5以上推奨です(ただし、keytarを使うとなると簡単に最新版という事にはいかないのが残念)。

ソースコード

Puppeteer単体での場合

puppeteer + node.jsとは異なりpuppeteer-in-electronの場合冒頭の部分が少々異なります。その部分以降はこれまでのawaitから始まる命令文をつなげていけば良いので、そこだけ要注意です。また今回は、keytarとの併用ができるかの確認の為に、main()につなげて無駄にパスワードの保存と取り出しを記述しています。

  • main関数がpuppeteerで自動操縦させる関数になります。
  • main関数冒頭のpuppeteerを起動する部分が異なります。pie.connect(app, puppeteer);にてbrowserを宣言
  • executablePathなどは不要です。BrowserWindowがそれを担います。
  • page.gotoは冒頭は不要です。BrowserWindowに対してloadUrlを指定でロードさせればOK
  • pie.getPage以降は通常のpuppeteerでの記法と同じになります。
  • Windowを閉じる場合には、electronなのでwindow.destroy()で閉じればOKです。
  • main関数につづけて、promiseにてkeytarによる資格情報マネージャへのパスワードの格納/取得を追加して動作確認しています。
  • electron 5.0.0 + keytar 4.6.0での動作確認が取れましたので、今後はこのバージョンを基準に開発していきたいと思います。

他のアプリ内に取り込んで使う場合

puppeteer-in-electronを使う上でちょっと厄介だったのが、既存のアプリに組み込んで使いたい場合。単体と違い、他のコードが存在し、それが原因でエラーが出たりします。特に厄介なのは、Must be called at startup before the electron app is ready.というエラー。app.onのreadyよりも前に、browserについて初期化しておいて、puppeteerに接続させておかなければなりません。よって、以下のような形で記述します。

  • app.onのready前にbrowserとpageを宣言しておいて、browserに対してconnectさせて置かなければならない。
  • フォームに入力させる場合は、自動化よりも前に予め入力予定のワードはどこかで取得させておくとスムーズです。
  • kintoneのフォームブリッジは、ちょっと変な仕様で、直接機械的にinputに対して値をねじ込むと、入っていても送信時に「入っていない」と言われるので、このようにpuppeteerにて入力させ、keydownイベントを発火させる必要があります。
  • viewportを常にウィンドウサイズに合わせるには、await page._client.send(‘Emulation.clearDeviceMetricsOverride’);にて実現可能です。
  • tempid, frmname, frmmailは予め自分の場合、MySQLから取得したものを格納してあります。
  • BrowserWindowが開かれるとPuppeteerが発動し、社員番号と名前、メールアドレスがフォームに自動入力されます。
  • webviewタグ表示の対象に対して、javascriptでキーコードを送っても反応しないので、Puppeteerでページ表示させて操作する方法がもっともベターです。

jQueryを使えるようにする

Puppeteerの非常に優れている点は、既存のフォームなどに対して後から、jQueryなどのモジュールを読み込ませて、機能を付け足すことが出来る点です。例えば、formブリッジのテキストボックスに対して、jQueryのAutocompleteを付け足すことで、フォームでの入力補助機能をアップさせたりなどなど。

今回、GoogleのCDNで配布されているライブラリを用いて、formブリッジのテキストボックスにautocompleteを設定してみました。

※Autocompleteは文字列でなければいけないので、xlsxモジュールなどでデータを生成する場合、String()で型変換しておくことが必要です。

  • addScriptTagにてURL指定でスクリプトライブラリを挿入可能です
  • addStyleTagにてURL指定でスタイルシートを挿入可能です。
  • page.evaluateにて、任意のスクリプトを対象のページに対して実行させることが可能です。
  • あとは、通常のHTML上で記述するようにJavaScriptを記述すればOK.
  • evaluate内に外側の変数を渡したい場合には、以下のように引数で渡すと利用すことが可能になります。
  • xlsxモジュールなどで、固定場所にあるexcelデータからautocomplete用のデータを生成しておき、引数でevaluateに渡せば最新のリストをもってautocompleteが反映可能です。

図:formブリッジに対してautocompleteが反映出来た

関連リンク

共有してみる: