木偶选择<td>后单击它

时间:2019-07-12 14:27:47

标签: node.js puppeteer

我在chrome开发工具中测试了我的xpath选择器,它找到了我要选择的<td>

我尝试了几种方法,使用page.x $,然后确保使用以下方法正确选择了元素:

page.waitForXPath("//td[contains(., 'All Projects')]")
.then(selector => {
    page.click(selector);
})

执行确实达到了page.click(),并且出现以下错误。我很困惑,因为我不认为自己正在改变环境。 UnhandledPromiseRejectionWarning: Error: JSHandles can be evaluated only in the context they were created!

编辑:这是HTML代码。它是用HTML表制作的Angular网格。 <td>在底部。 enter image description here

这是其余的代码。其他一切工作正常。抱歉,这很笨拙。

const puppeteer = require('puppeteer');
const kindle = puppeteer.devices['Kindle Fire HDX landscape'];

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

    //go to page and log in
    await page.emulate(kindle);
    await page.goto('http://localhost:4201/#/login');
    await page.waitForSelector('input[id="usr"]');
    await page.type('#usr', 'myusername');
    await page.type('#pwd', '');
    await page.click('button');

    //wait for homepage to load
    await page.waitForSelector('#menuData');
    await page.click('#menuData');
    await page.waitForSelector('#drCreate');
    await page.click('#drCreate');
    await page.waitForSelector('.mat-input-element'); //a request piece is loaded
    //populate fields

    var date = new Date();

    await page.type('#mat-input-0', humanReadableDate(date));
    date.setDate(date.getDate() + 1);
    await page.type('#mat-input-1', humanReadableDate(date));
    date.setDate(date.getDate() + 5)
    await page.type('#mat-input-3', humanReadableDate(date));

    await page.click('.pi-angle-double-right');

    page.waitForXPath("//td[contains(., 'All Projects')]")
    .then(selector => {
        page.click(selector);
    })
}

function humanReadableDate(date) {
    if (!date) {
        date = new Date();
    }
    return (date.getMonth() + 1) + '/' + date.getDate() + '/' + date.getFullYear();
}

main();

2 个答案:

答案 0 :(得分:1)

它看起来像是无效的页面上下文。尝试这样的事情:

await page.waitForXPath("//td[contains(., 'All Projects')]")
const [ projects ] = await page.$x("//td[contains(., 'All Projects')]");
projects.click()

或简短版本:

page.waitForXPath("//td[contains(., 'All Projects')]").then(selector => selector.click())

答案 1 :(得分:1)

问题

page.click需要一个字符串(选择器)作为参数,但是您正在传递元素句柄。

引用page.waitForXPath中的文档:

  

返回:> Promise,它解决将xpath字符串指定的元素添加到DOM时的问题。如果等待null并且在DOM中找不到xpath,则解析为hidden: true

这意味着您不能将来自该函数(元素句柄)的结果提供给page.click

解决方案

相反,您可以使用elementHandle.click这样编写代码:

await page.waitForXPath("//td[contains(., 'All Projects')]")
.then(elementHandle => elementHandle.click())

但是我建议改用async / await语法,使其与其余代码更加一致:

const elementHandle = await page.waitForXPath("//td[contains(., 'All Projects')]");
await elementHandle.click();