如何确保在“Playwright”中截取屏幕截图之前将图像渲染到“Konva React”画布?

问题描述 投票:0回答:2

我编写了一个 React 组件,可以将图像绘制到“konva React”画布上。该组件使用 useImage hook。问题是首先绘制画布,然后将图像添加到画布。这会导致测试时出现问题。在我的剧作家测试中,我寻找“画布”DOM 元素并截取屏幕截图以进行视觉比较。

现在的问题是“画布”将渲染,并且在图像绘制在画布上之前将截取屏幕截图。这会导致“片状”测试,有时在绘制图像之前截取屏幕截图,有时在绘制图像之后截取屏幕截图。

这是该组件的简化版本。


const Figure: React.FC<FigureProps> = ({
  url,
  x,
  y,
}) => {

  const [image] = useImage(url);

  return (
    <Image
      x={x}
      y={y}
      image={image}
    />
  );
};

export default Figure;

到目前为止,我发现的最相似的问题是this。然而,建议的使用回调和“useImage”状态的解决方案并不真正适用,因为剧作家只能看到组件是否存在。

我知道我可以实现任意等待时间,但这不是一个可靠的解决方案。我想要一个解决方案,在“剧作家”拍摄屏幕截图之前,我可以确定图像已绘制到画布上。

playwright react-konva
2个回答
0
投票

如链接您共享的中所述,您可以使用特殊逻辑来跟踪应用程序的加载。从剧作家那里你可以观察加载变量。

其简化版本可以是:


window.loadingCount = 0;

const Figure: React.FC<FigureProps> = ({
  url,
  x,
  y,
}) => {

  const [image] = useImage(url);

  // use layout effect for faster execution
  React.useLayoutEffect(() => {
    if(image) {
      // image is loaded
      window.loadingCount -= 1;
    } else {
      // image is not loaded yet
      window.loadingCount += 1;
    }

  }, [image]);

  return (
    <Image
      x={x}
      y={y}
      image={image}
    />
  );
};

export default Figure;

然后在剧作家中你这样做:

await page.waitForFunction(() => window.loadingCount === 0);

只需确保该函数将在安装

Figure
组件后开始执行。


0
投票

感谢@lavrton,我从答案中获得了一些灵感,并提出了以下解决方案。

  1. 按照@lavrton的建议,我使用了一个全局变量,但将其初始化为布尔值。使用布尔值的原因是,我认为不可能等到
    Figure
    组件安装,因为 Playwright 只能“看到”
    canvas
    组件,而其中没有任何内容。

window.ImageLoaded = false;

const Figure: React.FC<FigureProps> = ({
  url,
  x,
  y,
}) => {

  const [image] = useImage(url);

  // use layout effect for faster execution
  React.useLayoutEffect(() => {
    if (image) {
      window.ImageLoaded = true;
    }
  });


  return (
    <Image
      x={x}
      y={y}
      image={image}
    />
  );
};

export default Figure;
  1. 这是我的具体用例,但我希望这可以对某人有所帮助。由于我们使用 Storybook 来测试组件,而 Storybook 使用
    frames
    ,因此在 Playwright 测试中访问框架然后访问窗口非常重要,因为框架有自己的窗口对象。这是通过以下方式完成的:
// ...navigation to page code

// access the frame and the window
  await page.frame("storybook-preview-iframe")?.waitForFunction(() => {
    return window.ImageLoaded === true;
  });

//...here we are sure the image is loaded and can do a visual comparison
© www.soinside.com 2019 - 2024. All rights reserved.