简体   繁体   English

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

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

//I created a loop to append an index number [1-16] to the end of an xpath selector (these are selectors for li items on a website, they're all the same except the index number on the end.) Then I want to assign that selector to an existing object array as a value to a key named 'link'. //我创建了一个循环到 append 一个索引号 [1-16] 到 xpath 选择器的末尾(这些是网站上 li 项目的选择器,除了末尾的索引号外,它们都是相同的。)然后我想将该选择器分配给现有的 object 数组作为名为“链接”的键的值。 Then I want to call a custom command to loop through the array and click each key value pair.然后我想调用一个自定义命令来循环遍历数组并单击每个键值对。 This is for the purpose of clicking the links(xpath selectors) and verifying the automation lands on the correct page which I verify with the url.这是为了单击链接(xpath 选择器)并验证自动化降落在我使用 url 验证的正确页面上。 Each object in the array has 2 key value pairs, link and url.数组中的每个 object 都有 2 个键值对,链接和 url。 I tried doing it where I just add the selectors to a regular array and it works fine in that manner.我尝试这样做,我只是将选择器添加到常规数组中,并且以这种方式工作正常。 But when I try to add the selector to an array as part of an object I get errors.但是,当我尝试将选择器作为 object 的一部分添加到数组中时,出现错误。 My code is below:我的代码如下:

//Here is where I want to assign the newly concatenated xpath selector to my object array. //这里是我想将新连接的 xpath 选择器分配给我的 object 数组的地方。 Iv'e tried map, push, concat, assign and every other function I could find associated with arrays:我试过 map、push、concat、assign 以及我能找到与 arrays 相关的所有其他 function:


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'
    },


]

A Code Snippet (minimal reproducible example):代码片段(最小可重现示例):

 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>

If I understand correctly, your problem is sort of the opposite of this:如果我理解正确,您的问题与此相反:

"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]'}] " (see the opposite at the bottom) “您可以像 'div/ul/li[n]' 那样动态创建 16 个 xPath,其中 n = 1 到 16,并且对于每一个,您 select 该元素并检查超链接 href 是什么,无论超链接是什么,您都将其保存到the URL property of your object and push that object to the array like [{link: 'div/ul/li[n]', URL: 'example.com/[n]'}] " (see the opposite at the bottom )

Here is a Code Snippet (minimal reproducible example) with HTML & JS (same as I put in your question as an example):这是带有 HTML 和 JS 的代码片段(最小的可重现示例)(与我在您的问题中作为示例相同):

Also, it looks like you are using node and Nightwatch, you should tag these in the question (which I did now - should help the right people to find the question etc.) and add at least the minimal import statements and initial data etc.此外,看起来您正在使用节点和 Nightwatch,您应该在问题中标记它们(我现在这样做 - 应该帮助合适的人找到问题等)并至少添加最少的导入语句和初始数据等。

Is this the sort of thing you are trying to do?这是你想做的事情吗? (But of course, this example is client-side only, so it's not 1-for-1 but at least it should give you an idea) (当然,这个例子只是客户端,所以它不是一对一,但至少它应该给你一个想法)

 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>

Output: Output:

[
  {
    "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"
  }
]

So if your problem is the opposite, ie then:因此,如果您的问题相反,即:

"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]'}] " “您有 16 个预定义的 xPath,例如 'div/ul/li[n]',其中 n = 1 到 16,每一个都有一个预定义的 URL,您希望此列表项/链接标签保留,您想要然后单击此链接并断言您导航到的链接与数组中的 xpath 链接相匹配,例如[{link: 'div/ul/li[n]', URL: 'example.com/[n]'}] "

You want to use Node and Nightwatch for this.您想为此使用 Node 和 Nightwatch。

You could do it like this, I presume:你可以这样做,我想:

 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>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM