はじめに
郵便番号, 都道府県, 住所, 建物名, 氏名, フリガナ, メールアドレス, 生年月日...など一通りのユーザー情報を入力するフォームの動作確認で、大量の input
を何度も入力するシーンが出てきます。
手入力で対処しようとすると 動作確認NGを繰り返すたびに心が折れます。
そこで、Puppeteerのみを含めたNode.jsの簡単なプロジェクトを立ち上げて、自動入力するツールを作り突破しようとしました。
同様なソリューションとしてCypressも考えられますが、Puppeteerは自身とローカルにインストールしたChromeで完結するためこちらを採用しました。
この記事ではフォームの自動入力でPuppeteerを用いた際に役立ったTipsを紹介します。
自動入力の対象はjQuery + JavaScriptのプロジェクトを想定しています。
インストール・実行
$ npm install puppeteer-core
https://github.com/YusukeIwaki/ggrks-puppeteer-js などを参考にプロジェクトに合ったPuppeteerのテストケースを作成し、次のコマンドで自動入力を実行します。これでローカルにインストールされたChromeを使うことができます。
(macOSの場合。WSL2では追加の設定が必要になります)
$ node puppeteer-test.js
input type=number に入力する
テキストと同様に page.type
を使いますが、 引数はStringしか受け付けません。
await page.type('input', '333');
~/work/puppeteer/node_modules/puppeteer-core/lib/cjs/puppeteer/common/Input.js:222
for (const char of text) {
^TypeError: text is not iterable
セレクタにdata属性を指定する
jQueryと違って クオーテーションで囲まないと認識しません。
Error: Evaluation failed: DOMException: Failed to execute 'querySelector' on 'Document': 'input[data-sample=some]' is not a valid selector.
await page.type('input[data-sample="some"]', 'hoge');
jQueryで生成したモーダル内のinputに値を入力する
waitForSelector
では反応しないので、モーダル表示のイベントを発火させてから waitFor
とかで2秒ほど待って入力する必要があります。
入力しても onChange イベントが発火しない
page.type
, page.$eval
の両方をそのまま使っても発火しないので、eval内で明示的にeventを呼びます。
await page.$eval('input#id-selector', (element, count) => {
element.value = 2;
const event = new Event('change');
element.dispatchEvent(event);
}, count);
input type=dateに入力する
キーボードの矢印キーで年月日を移動させ、数値を入力する発想で対処します。
const cssid = "input#testdate";
const y = "2019";
const m = "05";
const d = "06";
// まず年をtypeして…
await page.type(cssid, y);
// ここがキモ。右矢印押すことで、月の欄に移動します。
await page.keyboard.press('ArrowRight');
// 次は月
await page.type(cssid, m);
// 日の欄に移動します。
await page.keyboard.press('ArrowRight');
// 最後に日
await page.type(cssid, d);
evalに変数を突っ込みたい
$evalの中には外部からの変数は認識してくれません。
const count = 0;
await page.$eval('.selector', element => element.value=count);
~/work/puppeteer/node_modules/puppeteer-core/lib/cjs/puppeteer/common/ExecutionContext.js:221
throw new Error('Evaluation failed: ' + helper_js_1.helper.getExceptionMessage(exceptionDetails));
^Error: Evaluation failed: ReferenceError: count is not defined
アロー関数でvalueを入れてから、 $evalの末尾に変数を指定します。
await page.$eval('.selector', (element, value) => { element.value = value }, count);