jquery 如何选择表中元素的特定同级?

fhity93d  于 2023-04-20  发布在  jQuery
关注(0)|答案(5)|浏览(147)

我指向中间的表格单元格,我可以使用next()方法获取下一个单元格的文本,但当我试图使用parent()时,我得到了三个单元格的整行文本。下面是HTML代码。请帮助。

cy.get('[name="courses"] > tbody >tr >td:nth-child(2)').each((e1, index) => {
  const course = e1.text()
  
  if (course.includes('Python')) {
    cy.get('[name="courses"] > tbody >tr >td:nth-child(2)').eq(index).parent()
        .then((price) => {
      const courseprice = price.text()
      // expect(courseprice).to.be.equal('25')
      cy.log(courseprice)
    })
  }
})

zdwk9cvp

zdwk9cvp1#

对于包含“Python”的第一行.contains(selector, text)是最短的,.next()为您提供价格列。

cy.contains('[name="courses"] tbody tr td:nth-child(2)', 'Python') // first match
  .prev()                                             // move left one cell
  .invoke('text')
  .as('instructor')

cy.get('@instructor').then(instructorName => {   // "Rahul Shetty"
  ...
})

如果多行包含Python,则改为伪选择器:contains()

cy.get('[name="courses"] tbody tr td:nth-child(2):contains("Python")')   // all matches
  .prev()
  .then($instructors => {
    const names = [...$instructors].map(el => el.innerText)
    cy.wrap(names).as('instructors')
  })

cy.get('@instructor').then(instructorName => {   // ["Rahul Shetty", ...]
  ...
})
r3i60tvu

r3i60tvu2#

文本是整个文本的原因是它组合了所有子元素的文本。为了避免这种情况,我们可以采取几种不同的路线:
第一溶液:我们可以检查父对象是否包含值:

cy.get('[name="courses"] > tbody >tr >td:nth-child(2)')
  .eq(index)
  .parent()
  .should('contain.text', 25);

第二解决方案:直接抢第三排TD

cy.get('[name="courses"] > tbody >tr >td:nth-child(3)') // nth-child is index-1
  .should('have.text', 25);
quhf5bfb

quhf5bfb3#

更容易的做法是迭代行并检查第二行,而不是迭代第二行,然后遍历DOM以获取价格,然后使用cypress-if

cy.get('[name="courses"] > tbody >tr')
  .should("have.length.greaterThan", 0)
  .each($row =>{
    cy.wrap($row)
      .contains("td", "Python", { timeout: 0 })
      .if("visible")
      .then(() => {
        cy.log("Price of Python course");
        cy.wrap($row).contains("td", "25").should("be.visible");
      })
      .else()
      .log("Instructor does NOT sell Python");
   }
})

这是一个最小的可复制example

14ifxucb

14ifxucb4#

另一个选择,我的首选方法是使用find,我也建议不要使用then或其他嵌套函数,如each,如果你不需要它。即使你可以使用jquery选择器,如nth-child(),使用eq()使它更可读一点。nth-child的索引不是从0开始的,而是从1开始的,所以nth-child(2)返回第二列,而不是第三列。
例如,这将给予第8行和第3列

cy.get('[name="courses"] > tbody >tr')
  .eq(7)
  .find('td')
  .eq(2)

如果我在测试中重复任何东西超过两次,我倾向于在规范中编写帮助函数。

// define somewhere at the beginning of the file (or add to commands.js)
const getTableCell(r,c) => cy.get('[name="courses"] > tbody >tr')
  .eq(r)
  .find('td')
  .eq(c)

describe('🤷‍♂️', () => {
  it('😉', () => {
    getTableCell(0,0).should('have.text', 'Instructor')
    getTableCell(0,1).should('have.text', 'Course')
    getTableCell(0,2).should('have.text', 'Price')
    getTableCell(1,0).should('have.text', 'Rahul Shetty')
    getTableCell(1,1).should('contain.text', 'Appium')
    getTableCell(1,2).should('have.text', '25')
    // etc...
  })
})

在某些情况下,根据您的html标记,文本可能会用白色填充。在这种情况下,您可能希望使用contain.text而不是have.text,但这也可能导致问题,例如125将匹配contain.text("25")
另一种选择

cy.get('[name="courses"] > tbody >tr') // select all rows
  .contains("Python") // find 1st matched row
  .find("td") // find all columns in row
  .eq(2) // pick 3rd column
  .should("have.text", "25")  // make asserion

另外,如果你想从一个选择器中找到一个子元素,你可以使用find。在这个例子中,我添加了.find('td').eq(2)。但是请注意,这个例子展示了一个非常复杂的上下搜索DOM的方法。

cy.get('[name="courses"] > tbody >tr >td:nth-child(2)').each((e1, index)=>{
        const course = e1.text()
        if(course.includes('Python')){
            cy.get('[name="courses"] > tbody >tr >td:nth-child(2)').eq(index).parent().find('td').eq(2).then((price)=>{
                const courseprice = price.text()
                // expect(courseprice).to.be.equal('25')
                cy.log(courseprice)
            })
        }
    })
vh0rcniy

vh0rcniy5#

在使用parent之后,您可以使用within进入父tr并访问每个td元素,如下所示:

cy.get('[name="courses"] > tbody >tr >td:nth-child(2)')
  .eq(index)
  .parent()
  .within(() => {
    cy.get('td').eq(0).should('have.text', 'Rahul Shetty')
    cy.get('td')
      .eq(1)
      .should(
        'have.text',
        'Master Selenium Automation is simple Python Language'
      )
    cy.get('td').eq(2).should('have.text', '25')
  })

您可以基于第二个td来达到第一个td,如下所示:

cy.contains('td', 'Master Selenium Automation is simple Python Language')
  .parent()
  .within(() => {
    cy.get('td').eq(0).should('have.text', 'Rahul Shetty')
  })

相关问题