Getting all table rows and returning them using an XPath query in CasperJS

Deadly 提交于 2020-01-23 10:39:09

问题


I'm using Casper.js to automate a regular upload. I've managed to upload the file and check if it's valid, but I'd like to parse the table which is returned if there's errors, but I get the error [error] [remote] findAll(): invalid selector provided "[object Object]":Error: SYNTAX_ERR: DOM Exception 12. Here's the relevant part of my code:

casper.then(function() {
    if (this.fetchText('.statusMessageContainer').match(/Sorry, the file did not pass validation. Please review the validation errors in the report below/)) {
        this.echo("Upload failed!", "ERROR");
        errors = this.evaluate(function() {
            var errorRows = __utils__.findAll({
                type: 'xpath',
                path: '//table[@id="uploadTable"]/tr[position()>1]'
            });
            return Array.prototype.forEach.call(errorRows, function(e) {
                return e;
            });
        });
        this.echo(JSON.stringify(errors));
    } else {
        this.echo("Upload successful", "INFO");
    }
});

Any ideas?


回答1:


While you probably have an XPath syntax error, you must know that you cannot return DOM elements from a closure passed to the evaluate() method; you have to convert your NodeList and HTMLelement instances to some native Javascript types, eg. Arrays, Objects, strings, etc…

Also, there's a convenient getElementsByXPath() method in the ClientUtils module you can use from the __utils__ instance automatically injected in every page your load:

casper.then(function() {
    if (this.fetchText('.statusMessageContainer').match(/Sorry, the file did not pass validation. Please review the validation errors in the report below/)) {
        this.echo("Upload failed!", "ERROR");
        var errors = this.evaluate(function() {
            var errorRows = __utils__.getElementsByXPath('//table[@id="uploadTable"]/tr[position()>1]');
            return Array.prototype.map.call(errorRows, function(e) {
                return e.innerText; // let's get node text instead of HTMLelement!
            });
        });
        this.echo(JSON.stringify(errors));
    } else {
        this.echo("Upload successful", "INFO");
    }
});

You can also use the ClientUtils bookmarklet to test your selectors right within your browser console as well. For example here, click the bookmarklet and execute this in the js console:

__utils__.getElementsByXPath('//table[@id="uploadTable"]/tr[position()>1]')

Then you'll see if your selector is correct (it works by my side — I mean it is syntactically correct).




回答2:


Well from your error it appears there is something wrong with your selector. It's setup correctly from what I can see, except for one thing: Try changing '//table[@id="uploadTable"]/tr[position()>1]' to '//table[@id='uploadTable']/tr[position()>1]' (change "" to '')

Other than that, your XPath looks syntactically correct, so I'm not sure why it would qualify as an invalid selector.



来源:https://stackoverflow.com/questions/10740907/getting-all-table-rows-and-returning-them-using-an-xpath-query-in-casperjs

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!