puppeteerでどのwaitForが失敗しているか分からず詰まった話

~~早速注意なのですが、現状暫定対応で凌いでおり個人的にしっくりしておりません。
なのでcoolな解決法がございましたら教えてください。~~

2018/06/13　追記
<font color="red">今は解消されていると思います！</font>

[暫定対応](#%E6%9A%AB%E5%AE%9A%E5%AF%BE%E5%BF%9C)（飛ばしたい人はこちらから）

さて、困っていることはタイトルの通りだが、うだうだ文章に書くより実際にコードを載せたほうが早いと思うので下記が該当のものになる。

```javascript:sample.js
const puppeteer = require('puppeteer');

(async () => {
    const browser = await puppeteer.launch({
        args: [
            '--no-sandbox',
            '--disable-setuid-sandbox',
        ]
    });
    process.on('unhandledRejection', (reason, p) => {
        console.log(reason, p);
        browser.close();
    });
    const page = await browser.newPage();
    await page.goto('https://www.google.com/');
    await page.type("#lst-ib", "puppeteer");
    await page.click('input[name="btnK"]');
    await page.waitFor('#rso > div > div > div:nth-child(1) > div > div.rc > h3 > a');
    await page.waitFor('存在しない要素', {timeout: 1});
    browser.close();
})();
```
で、上記を実行したときのコンソールがこちら

```
$ node sample01
Error: waiting failed: timeout 1ms exceeded
    at Timeout.WaitTask._timeoutTimer.setTimeout (/home/operational_work/puppeteer/node_modules/puppeteer/lib/FrameManager.js:695:58)
    at ontimeout (timers.js:475:11)
    at tryOnTimeout (timers.js:310:5)
    at Timer.listOnTimeout (timers.js:270:5) Promise {
  <rejected> Error: waiting failed: timeout 1ms exceeded
    at Timeout.WaitTask._timeoutTimer.setTimeout (/home/operational_work/puppeteer/node_modules/puppeteer/lib/FrameManager.js:695:58)
    at ontimeout (timers.js:475:11)
    at tryOnTimeout (timers.js:310:5)
    at Timer.listOnTimeout (timers.js:270:5) }
```
エラーログとしてはtimeoutで落ちているのかはわかったのだが、どのwaitForで落ちているのかはわからないのでそれを解決したい。

# 試したこと
## assert入れればいいんじゃない？
早速トライ

```javascript:sample.js
const puppeteer = require('puppeteer');
const assert = require('assert');

(async () => {
    const browser = await puppeteer.launch({
        args: [
            '--no-sandbox',
            '--disable-setuid-sandbox',
        ]
    });
    process.on('unhandledRejection', (reason, p) => {
        console.log(reason, p);
        browser.close();
    });
    const page = await browser.newPage();
    await page.goto('https://www.google.com/');
    await page.type("#lst-ib", "puppeteer");
    await page.click('input[name="btnK"]');
    await page.waitFor('#rso > div > div > div:nth-child(1) > div > div.rc > h3 > a');
    assert(await page.waitFor('存在しない要素', {timeout: 1}));
    browser.close();
})();
```
コンソール

```
$ node sample01
Error: waiting failed: timeout 1ms exceeded
    at Timeout.WaitTask._timeoutTimer.setTimeout (/home/operational_work/puppeteer/node_modules/puppeteer/lib/FrameManager.js:695:58)
    at ontimeout (timers.js:475:11)
    at tryOnTimeout (timers.js:310:5)
    at Timer.listOnTimeout (timers.js:270:5) Promise {
  <rejected> Error: waiting failed: timeout 1ms exceeded
    at Timeout.WaitTask._timeoutTimer.setTimeout (/home/operational_work/puppeteer/node_modules/puppeteer/lib/FrameManager.js:695:58)
    at ontimeout (timers.js:475:11)
    at tryOnTimeout (timers.js:310:5)
    at Timer.listOnTimeout (timers.js:270:5) }
```
ダメだ変わらん…

## バックトレース仕込めばいいんじゃない？

```javascript:sample.js
const puppeteer = require('puppeteer');

(async () => {
    const browser = await puppeteer.launch({
        args: [
            '--no-sandbox',
            '--disable-setuid-sandbox',
        ]
    });
    process.on('unhandledRejection', (reason, p) => {
        console.trace();
        browser.close();
    });
    const page = await browser.newPage();
    await page.goto('https://www.google.com/');
    await page.type("#lst-ib", "puppeteer");
    await page.click('input[name="btnK"]');
    await page.waitFor('#rso > div > div > div:nth-child(1) > div > div.rc > h3 > a');
    await page.waitFor('存在しない要素', {timeout: 1});
    browser.close();
})();
```
コンソール

```
$ node sample01
Trace
    at process.on (/home/operational_work/puppeteer/sample01.js:12:17)
    at emitTwo (events.js:126:13)
    at process.emit (events.js:214:7)
    at emitPendingUnhandledRejections (internal/process/promises.js:94:22)
    at runMicrotasksCallback (internal/process/next_tick.js:124:9)
    at _combinedTickCallback (internal/process/next_tick.js:131:7)
    at process._tickCallback (internal/process/next_tick.js:180:9)
```
あ、そうなるのね……。

# 暫定対応
色々ググってみたがようわからんとなり、どうしたか言うと……。

```javascript:sample.js
const puppeteer = require('puppeteer');

(async () => {
    const browser = await puppeteer.launch({
        args: [
            '--no-sandbox',
            '--disable-setuid-sandbox',
        ]
    });
    process.on('unhandledRejection', (reason, p) => {
        console.log('失敗したwaitFor：' + selector);
        browser.close();
    });
    const page = await browser.newPage();
    let selector;
    const waitFor = x => {
        selector = x;
        return page.waitFor(selector, {timeout: 500});
    };
    await page.goto('https://www.google.com/');
    await page.type("#lst-ib", "puppeteer");
    await page.click('input[name="btnK"]');
    await waitFor('#rso > div > div > div:nth-child(1) > div > div.rc > h3 > a');
    await waitFor('存在しない要素');
    browser.close();
})();
```
waitForのラッピング関数を作って、selectorをどんどん上書いて失敗したのをログに出した。

で、コンソール

```
$ node sample01
失敗したwaitFor：存在しない要素
```
一応、目的は達成したけどなんか腑に落ちにない……。
なので、アドバイス等を募集中です。