单击给定类页面上的所有锚标记,但在导航之前取消

Click all anchor tags on page with given class, but cancel prior to navigation

本文关键字:导航 取消 单击      更新时间:2023-09-26

尝试为一些分析跟踪代码自动化一些测试,当我尝试将links传递到each()方法时,我遇到了问题。

我从stackoverflow复制了很多-如何遵循casperjs中的所有链接,但我不需要返回链接的href;我需要返回链接本身(所以我可以点击它)。我一直得到这个error: each() only works with arrays.我不返回一个数组吗?

更新:

对于每个有。myclass的锚标记,单击它,然后从casper.options.onResourceReceived返回请求的参数,例如事件类别,事件动作等。我可能会也可能不会取消点击后发生的导航;我只需要查看请求,不需要加载后续页面。

测试步骤:

  1. 点击包含.myClass
  2. 的链接查看请求参数
  3. 取消点击以防止进入下一页。

我是javascript和casper.js的新手,所以如果我误解了,我很抱歉。

另一个更新:

我已经更新了代码,改为返回一个类数组。这里有一些粗略的代码(参见内联注释)。

然而,我现在有问题取消导航后单击。clear()取消了所有的js。无论如何,防止默认操作发生后点击?如e.preventDefault(); ?

var casper = require('casper').create({
    verbose: true,
    logLevel: 'debug'
});
casper.options.onResourceReceived = function(arg1, response) {
    if (response.url.indexOf('t=event') > -1) {
        var query = decodeURI(response.url);
        var data = query.split('&');
        var result = {};
        for (var i = 0; i < data.length; i++) {
            var item = data[i].split('=');
            result[item[0]] = item[1];
        }
        console.log('EVENT CATEGORY = ' + result.ec + ''n' +
            'EVENT ACTION = ' + result.ea + ''n' +
            'EVENT LABEL = ' + decodeURIComponent(result.el) + ''n' +
            'REQUEST STATUS = ' + response.status
        );
    }
};
var links;
//var myClass = '.myClass';
casper.start('http://www.leupold.com', function getLinks() {
    links = this.evaluate(function() {
        var links = document.querySelectorAll('.myClass');
        // having issues when I attempted to pass in myClass var.
        links = Array.prototype.map.call(links, function(link) {
            // seems like a sketchy way to get a class. what happens if there are multiple classes?
            return link.getAttribute('class');
        });
        return links;
    });
});
casper.waitForSelector('.myClass', function() {
    this.echo('selector is here');
    //this.echo(this.getCurrentUrl());
    //this.echo(JSON.stringify(links));
    this.each(links, function(self, link) {
        self.echo('this is a class : ' + link);
        // again this is horrible
        self.click('.' + link);
    });
});

casper.run(function() {
    this.exit();
});

您正在处理两个问题。

<标题> 1。根据类选择元素

通常一个类被多次使用。所以当你第一次基于这个类选择元素时,你会得到具有那个类的元素,但不能保证它是唯一的。例如,您可以通过.myClass:

选择元素。
  1. myClass
  2. myClass myClass2
  3. myClass myClass3
  4. myClass
  5. myClass myClass3

当您稍后遍历这些类名时,您遇到了一个问题,因为使用casper.click("." + links[i].replace(" ", "."))永远无法单击4和5(您需要另外用点替换空格)。casper.click只单击特定选择器的第一次出现。这就是为什么我使用来自stijn de ryck的createXPathFromElement来查找页面上下文中每个元素的唯一XPath表达式的原因。

然后可以通过惟一的XPath单击正确的元素,如

casper.click(x(xpathFromPageContext[i]));
<标题> 2。取消导航h1> 可能取决于您的页面实际是什么。

注意:我使用casper.test属性,这是测试仪模块。您可以像这样调用casper来访问它:casperjs test script.js .

注意:还有casper.waitForResource函数。看一看。

2.1 Web 1.0

当点击意味着将加载一个新页面时,您可以向page.resource.requested事件添加一个事件处理程序。然后,您可以将abort()设置为request,而无需将页面重置为startURL

var resourceAborted = false;
casper.on('page.resource.requested', function(requestData, request){
    if (requestData.url.match(/someURLMatching/)) {
        // you can also check requestData.headers which is an array of objects:
        // [{name: "header name", value: "some value"}]
        casper.test.pass("resource passed");
    } else {
        casper.test.fail("resource failed");
    }
    if (requestData.url != startURL) {
        request.abort();
    }
    resourceAborted = true;
});

,在测试流程中:

casper.each(links, function(self, link){
    self.thenClick(x(link));
    self.waitFor(function check(){
        return resourceAborted;
    });
    self.then(function(){
        resourceAborted = false; // reset state
    });
});
2.2单页应用

可能有很多附加的事件处理程序,很难阻止它们全部发生。一个更简单的方法(至少对我来说)是

  1. 获取所有唯一的元素路径,
  2. 遍历列表,每次执行以下操作:
    1. 重新打开原始页面(基本上重置每个链接)
    2. 点击当前XPath

这基本上就是我在这个回答中所做的。

因为单页应用程序不加载页面。navigation.requestedpage.resource.requested不会被触发。如果你想检查一些API调用,你需要resource.requested事件:

var clickPassed = -1;
casper.on('resource.requested', function(requestData, request){
    if (requestData.url.match(/someURLMatching/)) {
        // you can also check requestData.headers which is an array of objects:
        // [{name: "header name", value: "some value"}]
        clickPassed = true;
    } else {
        clickPassed = false;
    }
});

,在测试流程中:

casper.each(links, function(self, link){
    self.thenOpen(startURL);
    self.thenClick(x(link));
    self.waitFor(function check(){
        return clickPassed !== -1;
    }, function then(){
        casper.test.assert(clickPassed);
        clickPassed = -1;
    }, function onTimeout(){
        casper.test.fail("Resource timeout");
    });
});