// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-nocheck
import React from 'react'
import { render, screen, fireEvent } from '@testing-library/react'
jest.mock('../../client/utils', () => ({
throttle: (fn) => fn,
}))
import BackToTopClient from '../../client'
describe('Back To Top', () => {
describe('when client-side', () => {
it('renders hidden by default', () => {
const tree = render()
expect(screen.findByText('Back to top')).toBeTruthy() // Assuming the button is directly rendered
expect(tree.container.children[0].style.display).toBe('none')
})
it('renders a button with attributes', () => {
render()
const button = screen.getByRole('button', { hidden: true })
expect(button.getAttribute('data-tracking')).toBe('backtotop')
})
it('becomes visible on scroll up', async () => {
const tree = render()
// Simulate scrolldown event and scrollup to test the display block
await fireEvent.scroll(window, { target: { scrollY: 300 } })
await fireEvent.scroll(window, { target: { scrollY: 100 } })
expect(tree.container.children[0].style.display).toBe('block')
})
it('renders the button and hides it again when user scrolls down', async () => {
const tree = render()
// Simulate scrolldown event and scrollup to test the display block
await fireEvent.scroll(window, { target: { scrollY: 300 } })
await fireEvent.scroll(window, { target: { scrollY: 100 } })
expect(tree.container.children[0].style.display).toBe('block')
// Simulate scrolldown after the last scrollup which should hide the button
await fireEvent.scroll(window, { target: { scrollY: 200 } })
expect(tree.container.children[0].style.display).toBe('none')
})
it('scrolls to the top when clicked on the button', async () => {
render()
// Simulate scrolldown event and scrollup to test the display block
await fireEvent.scroll(window, { target: { scrollY: 300 } })
await fireEvent.scroll(window, { target: { scrollY: 100 } })
const button = screen.getByRole('button')
window.scrollTo = jest.fn()
// Simulate scrolldown after the last scrollup which should hide the button
await fireEvent.click(button)
// Check is scrollTo is called with the correct arguments
expect(window.scrollTo).toHaveBeenCalledWith({
top: 0,
left: 0,
behavior: 'smooth',
})
})
it('the button hides if we scroll up to the top', async () => {
render()
// Simulate scrolldown and scrollup event to test the display block
await fireEvent.scroll(window, { target: { scrollY: 300 } })
await fireEvent.scroll(window, { target: { scrollY: 100 } })
const button = screen.getByRole('button')
// Check the button is visible
expect(button).toBeTruthy()
await fireEvent.scroll(window, { target: { scrollY: 0 } })
// Check the button is hidden , so getByRole should throw an error
expect(() => {
screen.getByRole('button')
}).toThrow()
})
it('renders the button after pass the element selected with startSelector', async () => {
const tree = render(
)
const head = tree.container.querySelector('#head')
// Mock that the head element is visible and we haven't passed it
jest.spyOn(head, 'getBoundingClientRect').mockReturnValue({
width: 500,
height: 500,
top: 0,
left: 0,
right: 500,
bottom: 500,
})
// Shouldn't be visible as we haven't passed the head element
await fireEvent.scroll(window, { target: { scrollY: 300 } })
await fireEvent.scroll(window, { target: { scrollY: 100 } })
expect(() => {
screen.getByRole('button')
}).toThrow()
//Mock that the head element is up on the scroll and not visible on the page which means we have passed it
jest.spyOn(head, 'getBoundingClientRect').mockReturnValue({
width: 500,
height: 500,
top: 0,
left: 0,
right: 500,
bottom: -200,
})
await fireEvent.scroll(window, { target: { scrollY: 700 } })
expect(() => {
screen.getByRole('button')
}).toThrow()
//Scrolled up and had passed the element that startSelector selects so it should be visible
await fireEvent.scroll(window, { target: { scrollY: 650 } })
expect(screen.getByRole('button')).toBeTruthy()
// The button should be visible if we scroll up and the head is visible after having shown it before
jest.spyOn(head, 'getBoundingClientRect').mockReturnValue({
width: 500,
height: 500,
top: 0,
left: 0,
right: 500,
bottom: 400,
})
await fireEvent.scroll(window, { target: { scrollY: 100 } })
expect(screen.getByRole('button')).toBeTruthy()
})
describe('If a `scrollableElement` is passed', () => {
it('renders the button after pass the element selected with startSelector', async () => {
const container = document.createElement('div')
container.id = 'scrollable-element'
container.style.display = 'block'
container.style.overflowY = 'scroll'
container.style.height = '500px'
document.body.appendChild(container)
const tree = render(
,
{ container }
)
const head = tree.container.querySelector('#head')
// Mock that the head element is visible and we haven't passed it
jest.spyOn(head, 'getBoundingClientRect').mockReturnValue({
width: 500,
height: 500,
top: 0,
left: 0,
right: 500,
bottom: 500,
})
// Shouldn't be visible as we haven't passed the head element
await fireEvent.scroll(container, { target: { scrollTop: 300 } })
await fireEvent.scroll(container, { target: { scrollTop: 100 } })
expect(() => {
screen.getByRole('button')
}).toThrow()
//Mock that the head element is up on the scroll and not visible on the page which means we have passed it
jest.spyOn(head, 'getBoundingClientRect').mockReturnValue({
width: 500,
height: 500,
top: 0,
left: 0,
right: 500,
bottom: -200,
})
await fireEvent.scroll(container, { target: { scrollTop: 700 } })
expect(() => {
screen.getByRole('button')
}).toThrow()
//Scrolled up and had passed the element that startSelector selects so it should be visible
await fireEvent.scroll(container, { target: { scrollTop: 650 } })
expect(screen.getByRole('button')).toBeTruthy()
// The button should be visible if we scroll up and the head is visible after having shown it before
jest.spyOn(head, 'getBoundingClientRect').mockReturnValue({
width: 500,
height: 500,
top: 0,
left: 0,
right: 500,
bottom: 400,
})
await fireEvent.scroll(container, { target: { scrollTop: 100 } })
expect(screen.getByRole('button')).toBeTruthy()
})
})
})
})