admin管理员组

文章数量:1122846

In a webpage, I have a table with many collapsible rows that are always expanded by default. These rows are not loaded all at once and are actually loaded dynamically as you scroll up or down the page. The total number of rows is usually under 50 and about 5 are visible in the screen/viewport.

In my test, I know the html Id of two random rows. I want to scrollIntoView() each row and then collapse it. I see that when I or the test scrolls to the 1st row, the 2nd row gets hidden from view. It turns out that the 2nd row is actually removed from the DOM (i.e. not merely marked hidden/invisible). As a result, my test fails because it cannot find the 2nd row in the DOM. So, it cannot scroll to the 2nd row and collapse it.

How do I fix this issue ? Here is an overview of the HTML code & the code which I have tried.

HTML -
    1 - Div containing a row header and the row contents.
        2 - Div containing the header content/text.
        3 - Div containing the row contents.
When you click div 1, then div 3 is collapsed or expanded. Div 2 still remains visible as desired.

The code which I call from my test -

  // Inside a page object class
  static collapseRows(rowIds: number[]): void {
    rowIds.forEach((rowId) => {   
      cy.get(`[id = "${rowId}"]`)
      .scrollIntoView({ duration: 1000, easing: "linear" })
      .then(() => {
        cy.get(`[id = "${rowId}"]`).click();//collapses or expands the row.
      });
    });
  }

In a webpage, I have a table with many collapsible rows that are always expanded by default. These rows are not loaded all at once and are actually loaded dynamically as you scroll up or down the page. The total number of rows is usually under 50 and about 5 are visible in the screen/viewport.

In my test, I know the html Id of two random rows. I want to scrollIntoView() each row and then collapse it. I see that when I or the test scrolls to the 1st row, the 2nd row gets hidden from view. It turns out that the 2nd row is actually removed from the DOM (i.e. not merely marked hidden/invisible). As a result, my test fails because it cannot find the 2nd row in the DOM. So, it cannot scroll to the 2nd row and collapse it.

How do I fix this issue ? Here is an overview of the HTML code & the code which I have tried.

HTML -
    1 - Div containing a row header and the row contents.
        2 - Div containing the header content/text.
        3 - Div containing the row contents.
When you click div 1, then div 3 is collapsed or expanded. Div 2 still remains visible as desired.

The code which I call from my test -

  // Inside a page object class
  static collapseRows(rowIds: number[]): void {
    rowIds.forEach((rowId) => {   
      cy.get(`[id = "${rowId}"]`)
      .scrollIntoView({ duration: 1000, easing: "linear" })
      .then(() => {
        cy.get(`[id = "${rowId}"]`).click();//collapses or expands the row.
      });
    });
  }
Share Improve this question edited Nov 21, 2024 at 22:46 MasterJoe asked Nov 21, 2024 at 20:20 MasterJoeMasterJoe 2,3156 gold badges36 silver badges64 bronze badges 3
  • Can you provide a sample of the Cypress code you've tried, and various HTML samples for the states you're describing? – agoff Commented Nov 21, 2024 at 21:47
  • @agoff - I added the necessary edits. I hope this helps to clarify. – MasterJoe Commented Nov 21, 2024 at 22:47
  • 1 It would be better to see the actual HTML rather that the pseudo description, the key would be to look for the scrollable parent then you don't have to worry about rows disappearing. – S.Lawson-Reynolds Commented Nov 22, 2024 at 5:07
Add a comment  | 

1 Answer 1

Reset to default 3

According to the HTML description there is a parent <div> and two child <div> and the last child is removed on click.

Further, .scrollIntoView() is failing because of the removal, so your id is on that removed <div>.

You could move the id to the parent, or if that is assigned by the framework add a data-test-id attribute to the parent.

Failing that, the starting state is "expanded" so you can take an alias of the parent while the elements are still accessible.

rowIds.forEach((rowId) => {
  cy.get(`[id = "${rowId}"]`)
    .parent()                  // Div 1 containing div 2 & div 3
    .as(`row:${rowId}`)
})

Now you have a reference to a fixed element to scroll

cy.get('@row:3')
  .scrollIntoView({ duration: 1000, easing: "linear" })
  .click()

Or apply the alias to div 2 - I can't tell which is clickable once in collapsed state.

rowIds.forEach((rowId) => {
  cy.get(`[id = "${rowId}"]`)
    .prev()                    // Div 2 with header text
    .as(`row:${rowId}`)
})

本文标签: CypressHow to scroll into view an element which is removed from the DOM temporarilyStack Overflow