0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-03-11 02:12:21 -05:00

Fixed flaky avatar saturation test in comments-ui

no issue

- running tests locally, especially in UI mode, would often result in an avatar saturation test failing
- the cause was calculating saturation for an element that still had it's opacity animating in
- added a test util function that waits for an element in a frame to reach full opacity
- used function in test to ensure we have a stable element before calculating the color saturation
This commit is contained in:
Kevin Ansfield 2024-11-12 16:42:56 +00:00
parent 0f2058cc2a
commit 097394bd88
3 changed files with 28 additions and 2 deletions

View file

@ -20,6 +20,7 @@ type AnimatedCommentProps = {
const AnimatedComment: React.FC<AnimatedCommentProps> = ({comment, parent, toggleParentReplyMode}) => { const AnimatedComment: React.FC<AnimatedCommentProps> = ({comment, parent, toggleParentReplyMode}) => {
return ( return (
<Transition <Transition
data-testid="animated-comment"
enter="transition-opacity duration-300 ease-out" enter="transition-opacity duration-300 ease-out"
enterFrom="opacity-0" enterFrom="opacity-0"
enterTo="opacity-100" enterTo="opacity-100"

View file

@ -1,4 +1,4 @@
import {MockedApi, initialize} from '../utils/e2e'; import {MockedApi, initialize, waitForFrameOpacity} from '../utils/e2e';
import {expect, test} from '@playwright/test'; import {expect, test} from '@playwright/test';
function rgbToHsl(r: number, g: number, b: number) { function rgbToHsl(r: number, g: number, b: number) {
@ -204,6 +204,10 @@ test.describe('Options', async () => {
const avatars = await frame.getByTestId('avatar-background').first(); const avatars = await frame.getByTestId('avatar-background').first();
// Comments animate in which can mess with the color saturation check,
// wait for full visibility before checking the color
await waitForFrameOpacity(frame, '[data-testid="animated-comment"]');
// Get computed background color // Get computed background color
const color = await avatars.evaluate((node) => { const color = await avatars.evaluate((node) => {
const style = window.getComputedStyle(node); const style = window.getComputedStyle(node);

View file

@ -112,7 +112,7 @@ export async function initialize({mockedApi, page, bodyStyle, labs = {}, key = '
} }
} }
}); });
await page.route(sitePath, async (route) => { await page.route(sitePath, async (route) => {
await route.fulfill({ await route.fulfill({
status: 200, status: 200,
@ -228,3 +228,24 @@ export function addMultipleComments(api, numComments) {
}); });
} }
} }
export async function waitForFrameOpacity(frameLocator, selector, timeout = 2000) {
const start = Date.now();
while (Date.now() - start < timeout) {
// Evaluate the opacity of the element within the frame
const opacity = await frameLocator.locator(selector).evaluate((element) => {
return window.getComputedStyle(element).opacity;
});
// Check if opacity is 1 (100%)
if (opacity === '1') {
return;
}
// Wait a little before retrying
await new Promise((resolve) => {
setTimeout(resolve, 100);
});
}
throw new Error(`Element ${selector} did not reach 100% opacity within ${timeout} ms`);
}