最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How do I navigate dom elements in puppeteer? - Stack Overflow

programmeradmin1浏览0评论

Background

We are writing some automated end to end tests with puppeteer for the first time. We've been digging through their APIs at great length, but we're stumped and struggling with what feels to us like basic uses for the system.

The Real Question

How does puppeteer want us to interact with the elements?

  • get their attributes
  • set stuff on them
  • find specific ancestors and descendants of them

Comments

What I really want is either a more trimmed API document targeted at our kinds of uses or, even better, a really slick tutorial. We've looked at quite a lot, but we just aren't getting these sorts of answers yet.

What all the guides we have found are doing, that we do not want to do, is manually putting into the code lots and lots of IDs and selectors. I understand why, but for our purposes we want to read from what is on the page and generate our behavior based on it's shape.

Thanks for your time!

Extra Credit

How should I actually approach these code snippets? What methods/structures?

Here's one that wants to type a string into all the text inputs, but gets the values for all inputs.

const nodeList = await page.$$('input');
const result = nodeList.map(async node => {
    if(node.type === 'text'){
        await node.type('2018');
    }
    return await node.getAttribute('value')
})
return result

Here's one that wants to type a span label into any child input within that span's parent div.

const nodeList = await page.$$('span');
const result = nodeList.map(async node => {
    const parentDiv = node.NearestAncestor('div')
    const inputs = parentDiv.$$('input')
    **Use Code From Above**
})
return result

Background

We are writing some automated end to end tests with puppeteer for the first time. We've been digging through their APIs at great length, but we're stumped and struggling with what feels to us like basic uses for the system.

The Real Question

How does puppeteer want us to interact with the elements?

  • get their attributes
  • set stuff on them
  • find specific ancestors and descendants of them

Comments

What I really want is either a more trimmed API document targeted at our kinds of uses or, even better, a really slick tutorial. We've looked at quite a lot, but we just aren't getting these sorts of answers yet.

What all the guides we have found are doing, that we do not want to do, is manually putting into the code lots and lots of IDs and selectors. I understand why, but for our purposes we want to read from what is on the page and generate our behavior based on it's shape.

Thanks for your time!

Extra Credit

How should I actually approach these code snippets? What methods/structures?

Here's one that wants to type a string into all the text inputs, but gets the values for all inputs.

const nodeList = await page.$$('input');
const result = nodeList.map(async node => {
    if(node.type === 'text'){
        await node.type('2018');
    }
    return await node.getAttribute('value')
})
return result

Here's one that wants to type a span label into any child input within that span's parent div.

const nodeList = await page.$$('span');
const result = nodeList.map(async node => {
    const parentDiv = node.NearestAncestor('div')
    const inputs = parentDiv.$$('input')
    **Use Code From Above**
})
return result
Share Improve this question asked Jun 22, 2018 at 17:54 SuniSuni 7231 gold badge8 silver badges16 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 10

You can try to wrap your promises inside a Promise.all.

So instead of returning result, you return Promise.all(result) which will resolve once it get's all of the data.

Also, there are many different ways to go thru the list or selectors.

$$eval

This runs Array.from(document.querySelectorAll(selector)) within the page and passes it as the first argument to pageFunction.

Example code:

await page.$$eval('a', a => a.href)

evaluate

This is golden and you can execute any code that you can execute on your browsers console.

const result = await page.evaluate(() =>
  [...document.querySelectorAll('input')] // or anything that you want to use normally
)

Useful APIs

There are several useful APIs that can be used wisely:

  • .type: types a text on selector
  • .click: Clicks an elementhandle/selector etc
  • .select: Selects something from a element

Know what doesn't work

elementHandle.attribute() has been removed on #638. Which means getting attribute should be handled by $eval from now.

发布评论

评论列表(0)

  1. 暂无评论
ok 不同模板 switch ($forum['model']) { /*case '0': include _include(APP_PATH . 'view/htm/read.htm'); break;*/ default: include _include(theme_load('read', $fid)); break; } } break; case '10': // 主题外链 / thread external link http_location(htmlspecialchars_decode(trim($thread['description']))); break; case '11': // 单页 / single page $attachlist = array(); $imagelist = array(); $thread['filelist'] = array(); $threadlist = NULL; $thread['files'] > 0 and list($attachlist, $imagelist, $thread['filelist']) = well_attach_find_by_tid($tid); $data = data_read_cache($tid); empty($data) and message(-1, lang('data_malformation')); $tidlist = $forum['threads'] ? page_find_by_fid($fid, $page, $pagesize) : NULL; if ($tidlist) { $tidarr = arrlist_values($tidlist, 'tid'); $threadlist = well_thread_find($tidarr, $pagesize); // 按之前tidlist排序 $threadlist = array2_sort_key($threadlist, $tidlist, 'tid'); } $allowpost = forum_access_user($fid, $gid, 'allowpost'); $allowupdate = forum_access_mod($fid, $gid, 'allowupdate'); $allowdelete = forum_access_mod($fid, $gid, 'allowdelete'); $access = array('allowpost' => $allowpost, 'allowupdate' => $allowupdate, 'allowdelete' => $allowdelete); $header['title'] = $thread['subject']; $header['mobile_link'] = $thread['url']; $header['keywords'] = $thread['keyword'] ? $thread['keyword'] : $thread['subject']; $header['description'] = $thread['description'] ? $thread['description'] : $thread['brief']; $_SESSION['fid'] = $fid; if ($ajax) { empty($conf['api_on']) and message(0, lang('closed')); $apilist['header'] = $header; $apilist['extra'] = $extra; $apilist['access'] = $access; $apilist['thread'] = well_thread_safe_info($thread); $apilist['thread_data'] = $data; $apilist['forum'] = $forum; $apilist['imagelist'] = $imagelist; $apilist['filelist'] = $thread['filelist']; $apilist['threadlist'] = $threadlist; message(0, $apilist); } else { include _include(theme_load('single_page', $fid)); } break; default: message(-1, lang('data_malformation')); break; } ?>