✨
Puppeteerを利用する上で便利にする関数集
Puppeteerって凄いんだけど、ちょっと不便よね。
特に、SPAの時に。
具体的には、何かをクリックして、描写が変わった事を待ち受ける時。
システム的には、以下のように言うよね。
- 要素をクリックして、対象の要素が表示するまで待つ。
- 要素をクリックして、対象の要素がdisplay:noneじゃなくなるまで待つ。
- 要素をクリックして、対象の要素が非表示になるまで待つ。
- 要素をクリックして、対象の要素がdisplay:noneになるまで待つ。
- 要素をクリックして、対象の要素が表示して、消えるまで待つ。
こんな事って、毎回必要になるんだけど、
毎回書いてちゃきりが無いから、公開する。
ちょっと古い書き方だけど許してください。
.env
puppet_wait_ms = 500
puppet_wait_count = 60
puppet_crm_wallet_backspace_time = 10
util.js
const util = {
//elmの親要素を取得する
getOuter: async(elm) => {
return await util.getText(elm, 'outerHTML');
},
//elmの中のhtmlを取得する
getInner: async(elm) => {
return await util.getText(elm, 'innerHTML');
},
//elmの中のテキストコンテンツを取得する
getContent: async(elm) => {
return await util.getText(elm, 'textContent');
},
/**
* elmの中のpropertyを取得する
* @param ElementHandle elem puppeteerのElementHandle
* @param string property 属性名
*/
getText: async(elm, property) => {
const h = await elm.getProperty(property);
return await h.jsonValue();
},
/**
* elmに特定のClass名が指定されているか確認する
* @param ElementHandle elem puppeteerのElementHandle
* @param string className
*/
hasClass: async(elm, className) => {
const classNames = await (await elm.getProperty('className')).jsonValue();
if (classNames.indexOf(className) > -1) {
return true;
}
return false;
},
//elmのValueを取得する
getVal: async(elm) => {
const value = await elm.evaluate((node) => {
return node.value;
});
return value;
},
/**
* 対象の要素のelementをブラウザのConsleに表示する
*/
debug: async(elm) => {
await elm.evaluate((node) => {
console.log(node);
});
},
consolelog: async(elm) => {
const debug = async(targ) => {
await util.debug(targ);
const html = await util.getOuter(targ);
console.log(html);
}
if (Array.isArray(elm)) {
for (let i = 0; i < elm.length; i++) {
await debug(elm[i]);
}
} else {
await debug(elm);
}
},
};
module.exports = util;
wait.js
const Util = require('./util');
const wait = {
/**
* 指定時間処理を止める
*/
sleep: async(time) => {
if (time === undefined) {
time = process.env.puppet_wait_ms;
}
return new Promise(resolve => {
setTimeout(() => {
resolve();
}, time);
});
},
forGetIndexChildSelecterEvalHund: async(elm, selecter, index) => {
if (index === undefined) {
index = 0;
}
let isShow = false;
let targElms = {};
for (let i = 1; i <= process.env.puppet_wait_count; i++) {
try {
targElms = await elm.$$(selecter);
let isEvalHand = await targElms[index].evaluateHandle((node) => {
return true;
});
if (isEvalHand) {
isShow = true;
break;
}
} catch (error) {
}
await wait.sleep(1000);
}
if (isShow === false) {
throw new Error(process.env.puppet_wait_count + '回待ったけどダメ!');
} else {
return targElms[index];
}
},
/**
* 指定のエレメントの中に、selecterに指定する要素が表示されるまで待つ
* @param ElementHandle elem puppeteerのElementHandle
* @param string selecter
* @return Promise listで返す
*/
forChildSelecter: async(elm, selecter) => {
let isShow = false;
let targElms = {};
for (let i = 1; i <= process.env.puppet_wait_count; i++) {
try {
targElms = await elm.$$(selecter);
if (targElms.length > 0) {
isShow = true;
break;
}
} catch (error) {
}
await wait.sleep();
}
if (isShow === false) {
throw new Error(process.env.puppet_wait_count + '回待ったけどダメ!');
} else {
return targElms;
}
},
/**
* 指定のエレメントの中のselecter要素が消えるまで待つ
* @param ElementHandle elem puppeteerのElementHandle
* @param string selecter
*/
forChildSelecterHide: async(elm, selecter) => {
let isShow = true;
let targElms = {};
for (let i = 1; i <= process.env.puppet_wait_count; i++) {
targElms = await elm.$$(selecter);
if (targElms.length == 0) {
isShow = false;
break;
}
await wait.sleep();
}
if (isShow === true) {
throw new Error(process.env.puppet_wait_count + '回待ったけどダメ!');
} else {
return true;
}
},
/**
* 指定のエレメントの中のselecter要素が作られて、消えるまで待つ
* @param ElementHandle elem puppeteerのElementHandle
* @param string selecter
*/
forChildSelecterShowAndHide: async(elm, selecter) => {
await wait.forChildSelecter(elm, selecter);
await wait.forChildSelecterHide(elm, selecter);
return true;
},
/**
* ElementHandleから指定のClassNameが無くなるのを待つ。
* 再帰確認時間はenv.puppet_waitでms
*/
removeClass: async(elem, targClassName) => {
let isRemove = false;
for (let i = 1; i <= process.env.puppet_wait_count; i++) {
let handle = await elem.getProperty('className');
let classNames = await handle.jsonValue();
if (classNames.indexOf(targClassName) == -1) {
isRemove = true;
break;
}
await wait.sleep();
}
if (isRemove === false) {
throw new Error(process.env.puppet_wait_count + '回待ったけどダメ!');
} else {
return true;
}
},
/**
* 横スクロールができるまで、
*/
scrollLeft: async(elm, targScroll) => {
let isScroll = false;
for (let i = 1; i <= process.env.puppet_wait_count; i++) {
let scrollLeft = await elm.evaluate((node, targScroll) => {
node.scrollLeft = targScroll;
return node.scrollLeft;
}, targScroll)
if (scrollLeft == targScroll) {
isScroll = true;
break;
}
await wait.sleep();
}
if (isScroll === false) {
throw new Error('横スクロール:' + process.env.puppet_wait_count + '回待ったけどダメ!');
} else {
return true;
}
}
};
module.exports = wait;
Discussion