|
| 1 | +--- |
| 2 | +title: "Mastering Visual Testing: Strategies for Eliminating Flaky Screenshots" |
| 3 | +description: "Guide to eliminate flaky screenshots in visual testing. Transform your visual testing from flaky to flawless with actionable insights and Argos's innovative solutions." |
| 4 | +category: Visual testing |
| 5 | +author: Jeremy Sfez |
| 6 | +date: 2024-02-15 |
| 7 | +image: ./main.jpg |
| 8 | +imageAlt: image alt |
| 9 | +--- |
| 10 | + |
| 11 | +Visual testing stands at the forefront of ensuring your web application's UI integrity, yet flaky tests can significantly undermine its reliability. As an experienced developer and Argos co-founder, I've seen firsthand the frustration flaky screenshots cause. This guide distills years of experience to offer best practices for making your visual tests as robust as possible with Argos. |
| 12 | + |
| 13 | +<MainImage /> |
| 14 | + |
| 15 | +## Understanding Flaky Screenshots |
| 16 | + |
| 17 | +A flaky screenshot is one that differs between test runs without any changes to the application. Common culprits include network latency, lazy loading, animations, and dynamic content like dates and external scripts. Identifying these factors is the first step towards stabilizing your visual tests. |
| 18 | + |
| 19 | +### Disclaimer: Flaky Tests Mean Flaky UI |
| 20 | + |
| 21 | +Remember, flaky tests are usually a sign of underlying instability in your UI. Address these core issues before attempting to stabilize your visual tests. |
| 22 | + |
| 23 | +## Stabilization Strategies |
| 24 | + |
| 25 | +### Network Latency |
| 26 | + |
| 27 | +For network latency, ensure your application is fully loaded before capturing screenshots. Argos' `argosScreenshot()` command is designed to wait for all resources, including images and fonts. |
| 28 | + |
| 29 | +### Lazy Loading |
| 30 | + |
| 31 | +For lazy-loaded elements, utilize a loading indicator and wait for its removal before proceeding. We recommend using the `[aria-busy]` attribute on your loader component, aligning with ARIA specifications. The `argosScreenshot` command will delay the screenshot until all components marked with `[aria-busy]` are removed before taking a screenshot. |
| 32 | + |
| 33 | +### Handling Dynamic Content |
| 34 | + |
| 35 | +Dynamic elements like dates or time should be neutralized during tests. Using a `data-visual-test` attribute can effectively hide these elements without impacting layout: |
| 36 | + |
| 37 | +```JavaScript |
| 38 | +<div id="clock" data-visual-test="transparent">...</div> |
| 39 | +``` |
| 40 | + |
| 41 | +### Animations |
| 42 | + |
| 43 | +Animations need to be either completed or paused. With Argos, CSS animations are automatically paused. JavaScript animations require manual intervention or hiding via `data-visual-test`. |
| 44 | + |
| 45 | +**Note**: If an animation causes layout shifts, it's recommended to remove it from the DOM (`display: none`) instead of merely hiding it (`visibility: hidden`). |
| 46 | + |
| 47 | +### External Scripts and Iframes |
| 48 | + |
| 49 | +Manage external scripts and iframes by either bypassing them in your test environment or injecting CSS to hide their UI impacts: |
| 50 | + |
| 51 | +```JavaScript |
| 52 | +import { test } from "@playwright/test"; |
| 53 | +import { argosScreenshot } from "@argos-ci/playwright"; |
| 54 | + |
| 55 | +test("screenshot homepage", async ({ page }) => { |
| 56 | + await page.goto("http://localhost:3000"); |
| 57 | + await argosScreenshot(page, "homepage", { |
| 58 | + argosCSS: ` |
| 59 | + .__argos__ iframe { |
| 60 | + display: none; |
| 61 | + } |
| 62 | + `, |
| 63 | + }); |
| 64 | +}); |
| 65 | +``` |
| 66 | + |
| 67 | +### Data inconsistency |
| 68 | + |
| 69 | +The best practices is to rely on on a stable dataset for your test enviroment. If you have ramdom sorting like in a news website, blackout `data-visual-test="blackout"` the area where the data is displayed. |
| 70 | + |
| 71 | +### Mobile Status Bars |
| 72 | + |
| 73 | +Mask mobile status bars to avoid flakiness. Argos offers a mask option for this purpose: |
| 74 | + |
| 75 | +Example with Argos' WebDriverIO integration: |
| 76 | + |
| 77 | +```JavaScript |
| 78 | +import { argosScreenshot } from "@argos-ci/webdriverio"; |
| 79 | +import { browser } from "@wdio/globals"; |
| 80 | + |
| 81 | +describe("Integration test with visual testing", () => { |
| 82 | + it("covers homepage", async () => { |
| 83 | + await browser.url("http://localhost:3000"); |
| 84 | + await argosScreenshot(browser, "homepage", { |
| 85 | + mask: [{ x: 0, y: 0, width: 1170, height: 120 }], |
| 86 | + }); |
| 87 | + }); |
| 88 | +}); |
| 89 | +``` |
| 90 | + |
| 91 | +### Browser Quirks |
| 92 | + |
| 93 | +Here is a list a non exhaustive list of common browser glitches that our client encounter: **border-radius, caret, scroll, focus, hover, border-radius, aliasing, and rendering issues.** Argos provides built-in solutions for these, ensuring your screenshots are consistent across runs. |
| 94 | + |
| 95 | +### Layout Shift and Cropped Screenshots |
| 96 | + |
| 97 | +In some cases, flaky tests produce cropped screenshots due to Playwright (or other browser automation library) measuring the page size before the layout shift, and then taking the screenshot after the layout shift. The best way to fix this is find the root cause of the layout shift and fix it. |
| 98 | + |
| 99 | +### Taking Screenshots Locally |
| 100 | + |
| 101 | +Local environments can introduce variability in screenshots. Utilizing a CI/CD pipeline ensures a consistent testing environment, mitigating this source of flakiness. |
| 102 | + |
| 103 | +When taking screenshots locally, you may encounter flaky tests due to your local environment. We recommend using a CI/CD pipeline to ensure a consistent environment for your visual tests. |
| 104 | + |
| 105 | +## Argos helpers to stabilize screenshots |
| 106 | + |
| 107 | +In additions to the best practices, Argos provides a set of helpers to stabilize your screenshots. |
| 108 | + |
| 109 | +### Props to Hide Elements: |
| 110 | + |
| 111 | +- [data-visual-test="transparent"]: Renders the element transparent `visiblity: hidden`. |
| 112 | +- [data-visual-test="removed"]: Removes the element from view `display: none` (to avoid layout shift). |
| 113 | +- [data-visual-test="blackout"]: Masks the element with a blackout effect. |
| 114 | +- [data-visual-test-no-radius]: Renders the element without border-radius. |
| 115 | +- [aria-busy]: Waits for the element to be removed before taking the screenshot. |
| 116 | + |
| 117 | +### `argosScreenshot` options for Enhanced Stability: |
| 118 | + |
| 119 | +- `argosCSS`: Injects custom CSS before taking the screenshot and remove it after. |
| 120 | +- `mask`: Hides the mobile status bar before taking the screenshot. |
| 121 | + |
| 122 | +## Conclusion |
| 123 | + |
| 124 | +Flaky tests not only frustrate developers but also erode trust in your testing suite, potentially leading you to abandon visual testing altogether. By familiarizing yourself with the patterns of flakiness and employing Argos's powerful features, you can transform visual testing into a reliable part of your development process. For further questions or to share your experiences, feel free to reach out or join our [Discord community](https://argos-ci.com/discord). |
0 commit comments