Search code examples
reactjscypresscss-positioncypress-testing-library

Input field gets hidden behind banner when focusing on it to test it


I'm writing integration tests with Cypress for a form inside a modal, with the particularity that it has a fixed height, a fixed header and a fixed footer, which means the form scrolls and remains always partly covered those.

       <Container>
          <Modal width={width}>
            <Header/> // fixed on top pf modal
            <ModalBody/> // scrolling up and down underneath
            <Footer/> // fixed on bottom of modal
          </Modal>
          <Background onClick={onClose} />
       </Container>

This is proving problematic when testing with Cypress, as the input elements I query to input data go to the very top of the modal when I do, which means they get covered by the top banner and become impossible to interact with.

I think the current setup for the modal and the form should be changed to be better coded and easier to test, but I was wondering if for now I can have a way to scroll the inputs into view after I've selected them.

In the commented out code you can see the type of logic I was hoping for. I've tried several combinations on scrolling, querying and triggering events to no avail.

it("completes protocol", () => {
    cy.findByRole("button", { name: /Complete protocol/i }).click();

    cy.findByLabelText(/Hours/i).type(10);
    
    // cy.get('input[type="number"]')
    //   .then((elements) => {
    //     elements[0].scrollIntoView({ offset: { top: 100, left: 0 } });
    //     elements[0].type(10);
    //   })
  });

Solution

  • Found the solution! I had never seen these options passed after the test name, but turns out there's one called 'scrollBehaviour' that changes the standard "move-to-the-top-on-focus" behaviour, and seems to fix my issue perfectly.

    it("completes protocol", { scrollBehavior: "center" }, () => {
        cy.findByRole("button", { name: /Complete protocol/i }).click();
    
        cy.findByLabelText(/Hours/i).type(10);
      });