puppeteer를 사용한 E2E 테스트에 수동 캡처 포함
요약
Puppeteer + Intro.js = E2E + Manual Capture
동기 부여
puppeteer을 사용하면 Google Chrome의 헤드리스 모드를 제어하여 쉽게 화면 캡처를 수행 할 수 있습니다. 이 기능을 사용하면 reg-suit 등과 연계하여 E2E 테스트를 비교적 쉽게 실현할 수 있습니다.
그런데 E2E의 본래의 목적은 무엇입니까?
그리고 나는 생각한다.
그 때문에 동시에 매뉴얼용 화면 캡쳐도 함께 하고 싶다는 것이 이번 이야기의 발단입니다.
말하지 않는 것
Puppeteer의 자세한 사용법이나 reg-suit에 관해서는 이 기사에서는 언급하지 않습니다.
E2E를 어떻게 CI에서 수행하는지에 대해서도 마찬가지입니다.
사용하는 도구
puppeteer 은 GoogleChrome을 DevTool 프로토콜을 통해 제어하는 고수준 API를 제공합니다.
물어보고 말하면 node.js에서 Google Chrome을 쉽게 조작 할 수 있습니다.
Intro.js 은 데모나 튜토리얼적인 것을 간단하게 만들 수 있는 라이브러리입니다.
스포트라이트와 같은 느낌으로, 서비스의 사용법을 가르쳐 주는 기능을 제공해 줍니다.
준비
시나리오 만들기
우선 puppeteer를 사용한 시나리오 테스트가 없다면 의미가 없습니다.
이번에는 다음과 같은 흐름 시나리오를 만듭니다.
capture.js
// node capture.js で実行するとactual_images/以下にそれぞれのスナプショットが保存される。
const puppeteer = require("puppeteer");
(async () => {
// ブラウザを起動
// わかりやすいように、ヘッドレスモードをOFFにして、各アクションに300msec遅延させる
const browser = await puppeteer.launch({
headless: false,
slowMo: 300,
});
// ブラウザの新規ウィンドウ作成
const page = await browser.newPage();
// ウィンドウサイズを調整
await page.setViewport({ width: 1600, height: 1200 });
// Googleへ遷移し、ネットワーク通信が終わるまで待つ
const URL = "http://google.co.jp";
await page.goto(URL, {waitUntil: "networkidle2"});
await page.screenshot({path: "./actual_images/1.png"});
// 入力フィールドに検索文字列を入力
await page.type("#lst-ib", "burikaigi2018 connpass");
await page.screenshot({path: "./actual_images/2.png"});
// 検索実行し検索結果が表示されるまで待つ
await page.click("input[type=submit]");
await page.waitFor("#resultStats");
await page.screenshot({path: "./actual_images/3.png"});
// 検索結果のタイトル一覧を取得し、connpass.comを含むコンテンツへ遷移
const aHandles = await page.$$("h3 > a");
for (var i = 0; i < aHandles.length; i++) {
const href = await page.evaluate((handle) => handle.href, aHandles[i]);
if (href.includes("connpass.com")) {
await page.screenshot({path: "./actual_images/4.png"});
await aHandles[i].click();
break;
}
}
// ナビゲーションが完了するまで待つ
await page.waitForNavigation({ waitUntil: "networkidle2" });
await page.screenshot({path: "./actual_images/5.png"});
// ブラウザを閉じる
await browser.close();
})();
도움말용 이미지 얻기
위의 시나리오에 도움말용 이미지 취득 처리를 통합해 나갑니다.
도움말 생성 Intro.js를 동적으로 로드하는 메서드를 정의합니다.
async function appendIntro(page, setup) {
// Intro.jsをCDNから読み込み
await page.evaluate(() => {
var script = document.createElement('script');
script.src = 'https://cdn.jsdelivr.net/npm/[email protected]/intro.min.js';
document.body.appendChild(script);
var link = document.createElement('link');
link.rel = "stylesheet";
link.href = "https://cdnjs.cloudflare.com/ajax/libs/intro.js/2.7.0/introjs.min.css"
document.body.appendChild(link);
});
// IntroJSがアクセス可能になるまで待つ
await page.waitForFunction("window.introJs");
// 対象のセレクタにIntro.jsのデータ属性を設定する
await setup(page);
}
상기 메소드를, 화면 천이시에 읽어들입니다 (일부 발췌).
const URL = "http://google.co.jp";
await page.goto(URL, {waitUntil: "networkidle2"});
await appendIntro(page, setupGoogleTop);
appendIntro에 정의 된
setupGoogleTop
는 각 선택기에 Intro.js 설정을 통합하기위한 것입니다.data-step
는 튜토리얼의 순서를, data-intro
는 실제로 표시되는 툴팁을 나타냅니다.자세한 내용은 Intro.js의 API을 참조하십시오.
function setupGoogleTop(page) {
return page.evaluate(() => {
const textInput = document.getElementById("lst-ib");
textInput.setAttribute('data-step', 1);
textInput.setAttribute('data-intro', '入力フィールドを選択し、burikaigi2018 connpassと入力してください');
const submitButton = document.querySelector("input[name=btnK]");
submitButton.setAttribute('data-step', 2);
submitButton.setAttribute('data-intro', '検索ボタンを押します');
});
}
이것으로 Intro.js를 실행하는 메커니즘의 준비가 완료됩니다.
다음과 같이 메소드를 실행하여 화면 전환 시 튜토리얼을 시작합니다.
// チュートリアル開始
await page.evaluate(() => window._intro = introJs().start());
// 次のヘルプを表示
await page.evaluate(() => window._intro.nextStep());
완성형은 Gist 에 Up 하고 있습니다.
실제로 실행한 경우의 캡처는 다음과 같습니다.
결론
E2E 테스트를 만들 때 열심히 취득한 셀렉터를, 그 이외에도 유효 활용하고 싶다고 생각해, 실천한 안의 하나입니다.
이 기사에서는 매뉴얼을위한 캡처 였지만 puppeteer는 DevTool에도 액세스 할 수 있습니다.
예를 들어, 성능 측정 등도 포함할 수 있다고 생각합니다.
덤
Q. 직접 Intro.js만 읽어서, 릴리스시만 제외하면 좋지 않겠습니까?
네, 맞습니다.
Q. Intro.js의 접두사 처음부터 붙이면 좋을까요?
네, 맞습니다.
Q. 캡처만 취해도 매뉴얼이 아니지요?
data-step/data-intro의 부분을 외부화해 생성할 수 있도록 생각하고 있습니다만 아직 하고 있지 않습니다.
Q. 완성계의 Gist 보면, E2E용의 캡쳐가 사라지고 있는데?
코드를 단순화하기 위해 일단 매뉴얼에 대한 캡처 이외의 요소는 사라졌습니다.
참고
Reference
이 문제에 관하여(puppeteer를 사용한 E2E 테스트에 수동 캡처 포함), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/hikaruworld@github/items/6ef5ee0752aaa2fff2b4텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)