0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-01-20 22:42:53 -05:00
ghost/apps/comments-ui/test/e2e/lazy-loading.test.ts
Kevin Ansfield 5b6d8fb7a8
Added lazy-loading to comments (#19769)
closes ENG-678

The comments block is typically shown at the bottom of a post so it doesn't make sense to eagerly fetch comments from the API when we don't know if the comments block will even be viewed. By lazy-loading the data only when the comments block comes into view we can reduce both data usage for visitors and load on the site.

- uses IntersectionObserver API to delay comments app initialisation until the comments block has scrolled into view
- updated all iframe-related components to forward a `ref` so we can use the `<iframe>` element reference inside the `App` component
2024-02-28 12:52:24 +00:00

65 lines
2.4 KiB
TypeScript

import {E2E_PORT} from '../../playwright.config';
import {MOCKED_SITE_URL, MockedApi} from '../utils/e2e';
import {expect, test} from '@playwright/test';
test.describe('Lazy loading', async () => {
test('delays loading of content until scrolled into view', async ({page}) => {
const mockedApi = new MockedApi({});
mockedApi.setMember({});
mockedApi.addComment({
html: '<p>This is comment 1</p>'
});
const sitePath = MOCKED_SITE_URL;
await page.route(sitePath, async (route) => {
await route.fulfill({
status: 200,
// include a div at the top of the body that's 1.5x viewport height
// to force the need to scroll to see the comments
body: `<html><head><meta charset="UTF-8" /></head><body><div style="width: 100%; height: 1500px;"></div></body></html>`
});
});
const url = `http://localhost:${E2E_PORT}/comments-ui.min.js`;
await page.setViewportSize({width: 1000, height: 1000});
await page.goto(sitePath);
await mockedApi.listen({page, path: sitePath});
const options = {
publication: 'Publisher Weekly',
count: true,
title: 'Title',
ghostComments: MOCKED_SITE_URL,
postId: mockedApi.postId
};
await page.evaluate((data) => {
const scriptTag = document.createElement('script');
scriptTag.src = data.url;
for (const option of Object.keys(data.options)) {
scriptTag.dataset[option] = data.options[option];
}
document.body.appendChild(scriptTag);
}, {url, options});
await page.locator('iframe[title="comments-frame"]').waitFor({state: 'attached'});
const commentsFrameSelector = 'iframe[title="comments-frame"]';
const frame = page.frameLocator(commentsFrameSelector);
// wait for a little bit to ensure we're not loading comments until scrolled
await page.waitForTimeout(250);
// check that we haven't loaded comments yet
await expect(frame.getByTestId('loading')).toHaveCount(1);
const iframeHandle = await page.locator(commentsFrameSelector);
iframeHandle.scrollIntoViewIfNeeded();
await expect(frame.getByTestId('loading')).toHaveCount(0);
});
});