function loginAsAdmin(): void {
  cy.visit('/login')

  cy.get('[data-cy="login-email"]').type('admin@rabbigerzi.test')
  cy.get('[data-cy="login-password"]').type('password123!@#')
  cy.get('[data-cy="login-submit"]').click()

  cy.url().should('eq', Cypress.config().baseUrl + '/')
  cy.getCookie('auth_token').should('exist')
}

describe('element sibling navigation', () => {
  it('navigates public parent elements when one exists', () => {
    cy.visit('/element/1')
    cy.contains('h1', 'Baderech HaAvodah').should('be.visible')
    cy.get('[data-cy="element-parent-link"]').should('not.exist')

    cy.visit('/element/2')
    cy.contains('h1', '1. Introduction').should('be.visible')
    cy.get('[data-cy="element-parent-link"]').as('parentLink')
    cy.get('@parentLink')
      .should('be.visible')
      .and('contain.text', 'Parent: Baderech HaAvodah')
    cy.get('@parentLink').should('have.attr', 'href', '/element/1')
    cy.get('@parentLink').then((parentLinkElements) => {
      cy.get('h1').then((headingElements) => {
        expect(
          parentLinkElements[0].compareDocumentPosition(headingElements[0])
            & Node.DOCUMENT_POSITION_FOLLOWING,
        ).to.not.equal(0)
      })
    })
    cy.get('@parentLink').click()

    cy.location('pathname').should('eq', '/element/1')
    cy.contains('h1', 'Baderech HaAvodah').should('be.visible')
  })

  it('navigates admin parent elements when one exists', () => {
    loginAsAdmin()

    cy.visit('/admin/element/1')
    cy.get('[data-cy="admin-element-title"]')
      .should('have.value', 'Baderech HaAvodah')
    cy.get('[data-cy="admin-parent-link"]').should('not.exist')

    cy.visit('/admin/element/2')
    cy.get('[data-cy="admin-element-title"]')
      .should('have.value', '1. Introduction')
    cy.get('[data-cy="admin-parent-link"]').as('parentLink')
    cy.get('@parentLink')
      .should('be.visible')
      .and('contain.text', 'Parent: Baderech HaAvodah')
    cy.get('@parentLink').should('have.attr', 'href', '/admin/element/1')
    cy.get('@parentLink').then((parentLinkElements) => {
      cy.get('.admin-element-page__heading').then((headingElements) => {
        expect(
          parentLinkElements[0].compareDocumentPosition(headingElements[0])
            & Node.DOCUMENT_POSITION_FOLLOWING,
        ).to.not.equal(0)
      })
    })
    cy.get('@parentLink').click()

    cy.location('pathname').should('eq', '/admin/element/1')
    cy.get('[data-cy="admin-element-title"]')
      .should('have.value', 'Baderech HaAvodah')
  })

  it('navigates public same-parent elements with wraparound', () => {
    cy.visit('/element/1')
    cy.contains('h1', 'Baderech HaAvodah').should('be.visible')
    cy.get('[data-cy="element-sibling-navigation"]').should('not.exist')

    cy.visit('/element/2')
    cy.contains('h1', '1. Introduction').should('be.visible')
    cy.get('[data-cy="child-element-list"]').then((childList) => {
      cy.get('[data-cy="element-sibling-navigation"]').then(
        (siblingNavigation) => {
          expect(
            childList[0].compareDocumentPosition(siblingNavigation[0])
              & Node.DOCUMENT_POSITION_FOLLOWING,
          ).to.not.equal(0)
        },
      )
    })
    cy.get('[data-cy="element-sibling-navigation"]').should('be.visible')
    cy.get('[data-cy="element-sibling-previous"]')
      .should('have.attr', 'href', '/element/7')
      .click()

    cy.location('pathname').should('eq', '/element/7')
    cy.contains('h1', '6. Fluid Integration').should('be.visible')
    cy.get('[data-cy="element-sibling-next"]')
      .should('have.attr', 'href', '/element/2')
      .click()

    cy.location('pathname').should('eq', '/element/2')
    cy.contains('h1', '1. Introduction').should('be.visible')
    cy.get('[data-cy="element-sibling-next"]')
      .should('have.attr', 'href', '/element/3')
      .click()

    cy.location('pathname').should('eq', '/element/3')
    cy.contains('h1', '2. Foundations').should('be.visible')
  })

  it('navigates admin same-parent elements with wraparound', () => {
    loginAsAdmin()

    cy.visit('/admin/element/1')
    cy.get('[data-cy="admin-element-title"]')
      .should('have.value', 'Baderech HaAvodah')
    cy.get('[data-cy="admin-sibling-navigation"]').should('not.exist')

    cy.visit('/admin/element/2')
    cy.get('[data-cy="admin-element-title"]')
      .should('have.value', '1. Introduction')
    cy.get('[data-cy="admin-element-save"]').then((saveButton) => {
      cy.get('[data-cy="admin-sibling-navigation"]').then(
        (siblingNavigation) => {
          expect(
            saveButton[0].compareDocumentPosition(siblingNavigation[0])
              & Node.DOCUMENT_POSITION_FOLLOWING,
          ).to.not.equal(0)
        },
      )
    })
    cy.get('[data-cy="admin-sibling-navigation"]').should('be.visible')
    cy.get('[data-cy="admin-sibling-previous"]')
      .should('have.attr', 'href', '/admin/element/7')
      .click()

    cy.location('pathname').should('eq', '/admin/element/7')
    cy.get('[data-cy="admin-element-title"]')
      .should('have.value', '6. Fluid Integration')
    cy.get('[data-cy="admin-sibling-next"]')
      .should('have.attr', 'href', '/admin/element/2')
      .click()

    cy.location('pathname').should('eq', '/admin/element/2')
    cy.get('[data-cy="admin-element-title"]')
      .should('have.value', '1. Introduction')
    cy.get('[data-cy="admin-sibling-next"]')
      .should('have.attr', 'href', '/admin/element/3')
      .click()

    cy.location('pathname').should('eq', '/admin/element/3')
    cy.get('[data-cy="admin-element-title"]')
      .should('have.value', '2. Foundations')
  })
})
