Connect & Get help from fellow developers on our Discord community.Ask the Community
Screenshot a single element
Capture a percy snapshot of a specific element using the percySnapshot method.
In some cases, capturing the entire page isn’t necessary especially when you are only interested in a specific region or want to avoid dynamic sections of the page. For these situations, you can use the scope snapshot option to capture a single element instead of the full page.
Pass the scope option as a per-snapshot configuration, and Percy will capture only the scoped element at the given widths. The scope selector accepts any valid selector you can pass to document querySelector.
If there are multiple matching selectors on the page, Percy will select the first matching element.
If you would like to scope a screenshot to a specific element that has the same matching selector as other elements on the page you’ll have to get more specific with your selector. This can be done by either adding another unique selector to that element or by using standard CSS selectors to get more specific. This is the same way you would write CSS – Percy doesn’t add anything to this process.
For example, given the below DOM:
```html
<html>
<head>
<title>Example</title>
</head>
<body>
<h1 class="underline">My example</h1>
<p class="underline">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas tristique convallis sem, vitae sodales risus accumsan in</p>
<p class="underline">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas tristique convallis sem, vitae sodales risus accumsan in</p>
</body>
</html>
```
Instead of using just .underline to select the element, you would want to either specify the element type (h1 / p) or by using CSS tree-structural pseudo-classes like :last-of-type or :nth-child.
p.underline scope selects the ‘first’ paragraph
p.underline:last-of-type scope selects last paragraph
Selector for elements serialized by Percy
It may happen that your single-element screenshots are not working correctly with canvas/video elements.
During DOM serialization <canvas>, <video> elements are converted to <img>. Check canvas elements in Percy’s SDK Workflow. This can cause the selector to not match, and an incorrect screenshot.
To work around this, we can use CSS tree structural pseudo-classes as suggested in the previous section.
```html HTML
<!-- Skipping most of the stuff for brevity -->
<!-- Original DOM -->
<div class="selector">
<canvas> </canvas>
<canvas> </canvas>
<video> </video>
</div>
<!-- Post DOM Serialization -->
<div class="selector">
<img> </img>
<img> </img>
<img> </img>
</div>
```
.selector img:nth-of-type(2) scope selects the ‘second’ canvas
.selector img:last-of-type scope selects the ‘last’ video
Usage when having Selenium's WebElement
When dealing with Web elements, you may use the below utility function that returns CSS selector i.e scope in our case, that could be easily passed to the percySnapshot function.
Make sure script eval is allowed in the test browser, Please check ref on how to verify.
```java
public String percyScope(WebDriver driver, WebElement webElement) {
// util for getting css selector using the DOM element
String script = String.join(System.getProperty("line.separator"),
"if(typeof UTILS === 'undefined') {",
"return fetch('https://raw.githubusercontent.com/percy/percy-misc-examples/main/scripts/dom_css_path/dom_css_path.js')",
".then(res => res.text())",
".then(eval)",
".then( _ => UTILS.cssPath(arguments[0]));",
"} else {",
"return UTILS.cssPath(arguments[0]);",
"}"
);
JavascriptExecutor jse = (JavascriptExecutor) driver;
return (String) jse.executeScript(script, webElement);
}
```