SeleniumとNode.jsでWebアプリケーションのUIテストをChromeで実施する
>種別 > 技術メモ
#blog #途中
どちらかと言うと、スクリーンショットを自動で撮る、ことを目的としている。
入力値などをチェックしてもよいが、そこはまた今度で。
`
const { Builder, By, until } = require("selenium-webdriver");
const assert = require("assert");
let driver;
const fs = require('fs');
const { promisify } = require('util');
/*
* 適当に定数を、ターゲットのURL、HTMLコントロールのIDに合わせて定義
* (略)
*/
const takeScreenshotAndSave = async function (targetDir, fileName) {
// スクリーンショット画像をbase64でエンコードしたもの
let base64 = await driver.takeScreenshot();
// bufferに変換
let buffer = Buffer.from(base64, 'base64');
// bufferを保存
return promisify(fs.writeFile)(targetDir + '/' + fileName, buffer);
}
describe("UIテスト", () => {
before(() => {
driver = new Builder().forBrowser("chrome").build();
process.on("unhandledRejection", console.dir);
});
after(() => {
return driver.quit();
});
describe('正常系', ()=>{
it("ログインから入力完了してログアウトする", async () => {
const targetScreenshotDir = SCREENSHOT_DIR;
// テスト対象のページへアクセス
await driver.get(
URL_ENTRANCE
);
await driver.sleep(3000);
await takeScreenshotAndSave(targetScreenshotDir, '001ログイン画面.jpg');
// ログインIDとパスワードを入力してログインする
await driver
.findElement(By.id(ID_ENTRANCE_USERID))
.sendKeys(TARGET_ID);
await driver
.findElement(By.id(ID_ENTRANCE_USERPASSWORD))
.sendKeys(TARGET_PASS);
await driver.findElement(By.id(ID_ENTRANCE_LOGIN_BUTTON)).click();
await driver.sleep(2000);
await takeScreenshotAndSave(targetScreenshotDir, '002ログイン直後.jpg');
// 「ID_CHOOSER_BUTTON」までスクロールしてスクショする
await driver.findElement(By.id(ID_SELECT_IMG_BUTTON)).click();
await driver.sleep(2000);
await takeScreenshotAndSave(targetScreenshotDir, '003案内ダイアログ1上部.jpg');
const elementChooser = await driver.findElement(By.id(ID_CHOOSER_BUTTON));
await driver.executeScript("arguments0.scrollIntoView()", elementChooser);
await driver.sleep(1000);
await takeScreenshotAndSave(targetScreenshotDir, '004案内ダイアログ2下部.jpg');
// ファイルチューザーにファイルを設定
await driver.findElement(By.id(ID_INPUTTAG_FILE)).sendKeys(__dirname + '\\' + TARGET_FILE);
await driver.sleep(1000);
// 登録ボタンが表示されるようにスクロール後、その状態をスクショする
const elementRegist = await driver.findElement(By.id(ID_REGIST_BUTTON));
await driver.executeScript("arguments0.scrollIntoView()", elementRegist);
await driver.sleep(1000);
await takeScreenshotAndSave(targetScreenshotDir, '005ファイル選択済み.jpg');
// ボタン状態の有効無効を直にチェックしたいときは、
// elementRegist.getAttribute('disabled') 等でとれる。
// chaiのexpect()などで検証すればよい。
// https://www.selenium.dev/selenium/docs/api/javascript/module/selenium-webdriver/lib/webdriver_exports_WebElement.html#getAttribute
// ログアウト
await driver.findElement(By.id(ID_LOGOUT_BUTTON)).click();
await driver.sleep(1000);
await takeScreenshotAndSave(targetScreenshotDir, '006ログアウト.jpg');
});
});
});
`
参考サイト
https://ics.media/entry/5759/
Mochaで実行する場合の、とりあえずの全体像が分かりやすい
https://solutionware.jp/blog/2016/03/30/selenium-webdriver%E3%81%A7%E5%AE%9F%E8%B7%B5%E7%9A%84%E3%83%86%E3%82%B9%E3%83%88%E3%82%B1%E3%83%BC%E3%82%B9%E3%82%92%E4%BD%9C%E6%88%90%E3%81%99%E3%82%8B%EF%BC%88node-js%E7%B7%A8%EF%BC%89/
表示待ちとかの仕方
https://stackoverflow.com/questions/40258039/how-to-scroll-to-element-with-selenium-and-node-js-driving-firefox
スクロールのさせ方
https://www.it-swarm-ja.tech/ja/c%23/selenium-webdriver%E3%81%A8%E3%83%96%E3%83%A9%E3%82%A6%E3%82%B6%E3%83%BC%E3%81%8C%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%83%80%E3%82%A4%E3%82%A2%E3%83%AD%E3%82%B0%E3%82%92%E9%81%B8%E6%8A%9E/940934915/
ファイル選択ダイアログの扱い
https://qiita.com/tonio0720/items/70c13ad304154d95e4bc
Seleniumのメソッドをチートシート的に参照する
→「待ち処理」等も載っている。
Syntheticsのスクリプト化ブラウザリファレンス (モニターバージョン0.5.0+)
の「Selenium Webdriver API」が参照しやすいかも?
https://docs.newrelic.com/jp/docs/synthetics/synthetic-monitoring/scripting-monitors/synthetics-scripted-browser-reference-monitor-versions-050/
https://www.selenium.dev/selenium/docs/api/javascript/index.html
Seleniumの公式ドキュメント。左ペインから「Modules>selenium-webdriver」で辿る