如何在 javascript nightwatch.js 测试自动化脚本中使用 forEach 循环将键值对分配给对象数组?

How do I assign a key value pair to an object array with a forEach loop in javascript nightwatch.js test automation script?

//我创建了一个循环,将索引号 [1-16] 附加到 xpath 选择器的末尾(这些是网站上 li 项目的选择器,除了索引号最后。)然后我想将该选择器分配给一个现有的对象数组,作为一个名为 'link' 的键的值。然后我想调用一个自定义命令来遍历数组并单击每个键值对。这是为了单击 links(xpath 选择器)并验证自动化登陆正确的页面,我用 url 验证了这一点。数组中的每个对象都有 2 个键值对,link 和 url。我尝试这样做,我只是将选择器添加到常规数组中,并且以这种方式工作正常。但是,当我尝试将选择器作为对象的一部分添加到数组时,出现错误。我的代码如下:

//这里是我要将新连接的 xpath 选择器分配给我的对象数组的地方。我试过 map、push、concat、assign 和我能找到的与数组相关的所有其他函数:


for (let i = 0; i < 17; i++) { 
    abtArr[i].concat({link: abtSel + `[${i}]`})
} 

abtArr.forEach(item => {
    aosPage
        .click(item.link) 
        .verify.urlContains(item.url)
})


//object array (abtArr)

module.exports = [
    {
        link: '//*[@id="aspnetForm"]/div[4]/section/div[1]/div/div[2]/div/div[2]/div[1]/div/ul/li[1]',
        url: 'https://www.aos.org/about-us/aos-membership.aspx'
    }, 
    {
        link: '//*[@id="aspnetForm"]/div[4]/section/div[1]/div/div[2]/div[1]/div[2]/div[1]/div/ul/li[2]',
        url: 'https://www.aos.org/about-us/lindleyana-magazine.aspx'
    },


]

代码片段(最小可重现示例):

function getElementByXpath(path) {
  return document.evaluate(path, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
}

/*
const abtArr = [
    {
        link: '//*[@id="aspnetForm"]/div[4]/section/div[1]/div/div[2]/div/div[2]/div[1]/div/ul/li[1]',
        url: 'https://www.aos.org/about-us/aos-membership.aspx'
    }, 
    {
        link: '//*[@id="aspnetForm"]/div[4]/section/div[1]/div/div[2]/div[1]/div[2]/div[1]/div/ul/li[2]',
        url: 'https://www.aos.org/about-us/lindleyana-magazine.aspx'
    },
];
*/

// const abtSel = '//*[@id="aspnetForm"]/div[4]/section/div[1]/div/div[2]/div/div[2]/div[1]/div/ul/li';
const abtSel = '//*[@id="target"]/ul/li';
const abtArr = [];

for (let i = 1; i < 11; i++) { 
    const xPath = `${abtSel}[${i}]/a`;
    const linkTag = getElementByXpath(xPath);
    const someUrl = linkTag ? linkTag.href : null;
    abtArr.push({link: xPath, url: someUrl})
} 

console.log(abtArr);
.as-console-wrapper { max-height: 100% !important; top: 0; }
<div id="target">
  <ul>
    <li><a href="example.com/1">Link</a></li>
    <li><a href="example.com/2">Link</a></li>
    <li><a href="example.com/3">Link</a></li>
    <li><a href="example.com/4">Link</a></li>
    <li><a href="example.com/5">Link</a></li>
    <li><a href="example.com/6">Link</a></li>
    <li><a href="example.com/7">Link</a></li>
    <li><a href="example.com/8">Link</a></li>
    <li><a href="example.com/9">Link</a></li>
    <li><a href="example.com/10">Link</a></li>
  </ul>
</div>

如果我没理解错的话,你的问题正好相反:

"You create 16 xPaths on the fly like 'div/ul/li[n]' where n = 1 through 16 and with each one, you select that element and check what the hyperlink href is, whatever the hyperlink is you save this to the URL property of your object and push that object to the array like [{link: 'div/ul/li[n]', URL: 'example.com/[n]'}]"(见底部反面)

这是带有 HTML 和 JS 的代码片段(最小可重现示例)(与我在您的问题中举的例子相同):

此外,看起来您正在使用 node 和 Nightwatch,您应该在问题中标记这些(我现在这样做 - 应该帮助合适的人找到问题等)并至少添加最少的导入语句和初始数据等

这是您想要做的事情吗? (当然,这个例子只是客户端的,所以它不是一对一,但至少它应该给你一个想法)

function getElementByXpath(path) {
  return document.evaluate(path, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
}

/*
const abtArr = [
    {
        link: '//*[@id="aspnetForm"]/div[4]/section/div[1]/div/div[2]/div/div[2]/div[1]/div/ul/li[1]',
        url: 'https://www.aos.org/about-us/aos-membership.aspx'
    }, 
    {
        link: '//*[@id="aspnetForm"]/div[4]/section/div[1]/div/div[2]/div[1]/div[2]/div[1]/div/ul/li[2]',
        url: 'https://www.aos.org/about-us/lindleyana-magazine.aspx'
    },
];
*/

// const abtSel = '//*[@id="aspnetForm"]/div[4]/section/div[1]/div/div[2]/div/div[2]/div[1]/div/ul/li';
const abtSel = '//*[@id="target"]/ul/li';
const abtArr = [];

for (let i = 1; i < 11; i++) { 
    const xPath = `${abtSel}[${i}]/a`;
    const linkTag = getElementByXpath(xPath);
    const someUrl = linkTag ? linkTag.href : null;
    abtArr.push({link: xPath, url: someUrl})
} 

console.log(abtArr);
/*.as-console-wrapper { max-height: 100% !important; top: 0; }*/
<div id="target">
  <ul>
    <li><a href="example.com/1">Link</a></li>
    <li><a href="example.com/2">Link</a></li>
    <li><a href="example.com/3">Link</a></li>
    <li><a href="example.com/4">Link</a></li>
    <li><a href="example.com/5">Link</a></li>
    <li><a href="example.com/6">Link</a></li>
    <li><a href="example.com/7">Link</a></li>
    <li><a href="example.com/8">Link</a></li>
    <li><a href="example.com/9">Link</a></li>
    <li><a href="example.com/10">Link</a></li>
  </ul>
</div>

输出:

[
  {
    "link": "//*[@id=\"target\"]/ul/li[1]/a",
    "url": "https://stacksnippets.net/example1.com"
  },
  {
    "link": "//*[@id=\"target\"]/ul/li[2]/a",
    "url": "https://stacksnippets.net/example2.com"
  },
  {
    "link": "//*[@id=\"target\"]/ul/li[3]/a",
    "url": "https://stacksnippets.net/example3.com"
  },
  {
    "link": "//*[@id=\"target\"]/ul/li[4]/a",
    "url": "https://stacksnippets.net/example4.com"
  },
  {
    "link": "//*[@id=\"target\"]/ul/li[5]/a",
    "url": "https://stacksnippets.net/example5.com"
  },
  {
    "link": "//*[@id=\"target\"]/ul/li[6]/a",
    "url": "https://stacksnippets.net/example6.com"
  },
  {
    "link": "//*[@id=\"target\"]/ul/li[7]/a",
    "url": "https://stacksnippets.net/example7.com"
  },
  {
    "link": "//*[@id=\"target\"]/ul/li[8]/a",
    "url": "https://stacksnippets.net/example8.com"
  },
  {
    "link": "//*[@id=\"target\"]/ul/li[9]/a",
    "url": "https://stacksnippets.net/example9.com"
  },
  {
    "link": "//*[@id=\"target\"]/ul/li[10]/a",
    "url": "https://stacksnippets.net/example10.com"
  }
]

因此,如果您的问题恰恰相反,即:

"You have 16 xPaths pre-defined like 'div/ul/li[n]' where n = 1 through 16 and with each one, you have a pre-defined URL you expect this list item / link tag to hold, you want to then click this link and you assert that the link you navigate to is the one that matches the xpath link in the array like [{link: 'div/ul/li[n]', URL: 'example.com/[n]'}]"

你想为此使用 Node 和 Nightwatch。

你可以这样做,我想:

function getElementByXpath(path) {
  return document.evaluate(path, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
}

const abtArr = [
  {
    "link": "//*[@id=\"target\"]/ul/li[1]/a",
    "url": "https://stacksnippets.net/example1.com"
  },
  {
    "link": "//*[@id=\"target\"]/ul/li[2]/a",
    "url": "https://stacksnippets.net/example2.com"
  },
  {
    "link": "//*[@id=\"target\"]/ul/li[3]/a",
    "url": "https://stacksnippets.net/example3.com"
  },
  {
    "link": "//*[@id=\"target\"]/ul/li[4]/a",
    "url": "https://stacksnippets.net/example4.com"
  },
  {
    "link": "//*[@id=\"target\"]/ul/li[5]/a",
    "url": "https://stacksnippets.net/example5.com"
  },
  {
    "link": "//*[@id=\"target\"]/ul/li[6]/a",
    "url": "https://stacksnippets.net/example6.com"
  },
  {
    "link": "//*[@id=\"target\"]/ul/li[7]/a",
    "url": "https://stacksnippets.net/example7.com"
  },
  {
    "link": "//*[@id=\"target\"]/ul/li[8]/a",
    "url": "https://stacksnippets.net/example8.com"
  },
  {
    "link": "//*[@id=\"target\"]/ul/li[9]/a",
    "url": "https://stacksnippets.net/example9.com"
  },
  {
    "link": "//*[@id=\"target\"]/ul/li[10]/a",
    "url": "https://stacksnippets.net/example10.com"
  }
];

abtArr.forEach(item => {
    
    const aTag = getElementByXpath(item.link);
    console.log(aTag);
    aTag.target = "_blank";
    aTag.click();

   //Somehow verify that the new tab opened contains the pre-defined url:
    //.verify.urlContains(item.url)
})
<div id="target">
  <ul>
    <li><a href="example.com/1">Link</a></li>
    <li><a href="example.com/2">Link</a></li>
    <li><a href="example.com/3">Link</a></li>
    <li><a href="example.com/4">Link</a></li>
    <li><a href="example.com/5">Link</a></li>
    <li><a href="example.com/6">Link</a></li>
    <li><a href="example.com/7">Link</a></li>
    <li><a href="example.com/8">Link</a></li>
    <li><a href="example.com/9">Link</a></li>
    <li><a href="example.com/10">Link</a></li>
  </ul>
</div>