Help us understand the problem. What is going on with this article?

MEMO: PuppeteerでSPA(Single Page Application)を操作する時の留意点

More than 1 year has passed since last update.

問題点

PuppeteerによるWebテストの自動化を行うと、HTML等のWebページ遷移が発生しないSingle Page Application(SPA)が正常に動作しない場合があります。特にGithubのPuppeteerのREADME.mdにある使用例をそのまま流用するとハマる可能性があります。

例えば、以下のようにCSSセレクターが見つからないエラーだったり

UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): AssertionError [ERR_ASSERTION]: No node found for selector: ...

画面が遷移したにも関わらず以下のようにタイムアウトが発生してしまうエラーだったりします。

UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): Error: Navigation Timeout Exceeded: 30000ms exceeded

対処方法

Single Page ApplicationのWebページの場合、以下の点を考慮する必要があるようです。

  • page.goto()の後は、動的生成されるHTMLタグのCSSセレクタが登場するまで待機する。
    • page.goto()のオプションで{waitUntil: 'networkidle'}を指定する。
    • またはpage.waitFor(), page.waitForSelector()などで待機する。
  • page.click()で画面が遷移した後に待機を行う場合は、page.waitForNavigation()を使用しない。
    • page.waitFor(), page.waitForSelector()などで待機する。
    • page.waitForNavigation()はあるWebページから別のWebページに移動するまで待機する関数のため、Single Page Applicationのように同じWebページに留まる場合は待機タイムアウトする。

VueによるSPAデモページにアクセスして操作を行い、画像キャプチャをとるサンプルコードを以下に示します。

const puppeteer = require('puppeteer');

async function spa_access() {
  const browser = await puppeteer.launch({headless: true});
  const page = await browser.newPage();

  await page.goto('https://skyronic.github.io/vue-spa/#/', {waitUntil: 'networkidle'});
  await page.screenshot({path: 'image-spa-top.png', fullPage: true});

  await page.click('body > div > div.page > div.product-container > div:nth-child(2) > a')
  //await page.waitFor(1000)  // waitFor()
  await page.waitForSelector('body > div > div.page > div.product-item > a')  // waitForSelector()
  await page.screenshot({path: 'image-spa-clicked.png', fullPage: true});

  await browser.close();
}

確認環境: Windows10, Node.js=v8.50, Puppeteer=v0.11.0

(おまけ) WindowsでPuppeteerのWebアクセス等がタイムアウトする場合

Chrome 60以降でWindowsもヘッドレスChromeに対応しているはずなのですが、Chromium 60以降を使用しているPuppeteerであっても何故か https://www.example.com 以外へのアクセスでタイムアウトしてしまう問題が発生する場合があるようです。その場合にはpuppeteer.launch()の関数のオプションとして {headless: false} を追加してヘッドレスモードを無効にして動作させるとタイムアウトを回避できる場合があるようです。

ヘッドレスモードではなくてもWindowsでPuppeteerを動かしたい場合は試してください。

yoichiwo7
秋葉原の某所でエンジニアとして働いてます。 開発ワークフロー改善、およびKubernetes等のインフラ関連の技術にハマってます。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした