Skip to content

Commit e85253c

Browse files
added regions
1 parent 79d3ef3 commit e85253c

File tree

3 files changed

+185
-0
lines changed

3 files changed

+185
-0
lines changed

README.md

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,68 @@ public class Example {
220220
- `bottom` (int): Bottom coordinate of the consider region.
221221
- `left` (int): Left coordinate of the consider region.
222222
- `right` (int): Right coordinate of the consider region.
223+
- `regions` parameter that allows users to apply snapshot options to specific areas of the page. This parameter is an array where each object defines a custom region with configurations.
224+
- Parameters:
225+
- `elementSelector` (mandatory, only one of the following must be provided)
226+
- `boundingBox` (object): Defines the coordinates and size of the region.
227+
- `x` (number): X-coordinate of the region.
228+
- `y` (number): Y-coordinate of the region.
229+
- `width` (number): Width of the region.
230+
- `height` (number): Height of the region.
231+
- `elementXpath` (string): The XPath selector for the element.
232+
- `elementCSS` (string): The CSS selector for the element.
233+
- `padding` (optional)
234+
- Specifies additional padding around the selected region.
235+
- Properties:
236+
- `top` (number): Padding from the top.
237+
- `left` (number): Padding from the left.
238+
- `right` (number): Padding from the right.
239+
- `bottom` (number): Padding from the bottom.
240+
- `algorithm` (mandatory)
241+
- Specifies the snapshot comparison algorithm.
242+
- Allowed values: `standard`, `layout`, `ignore`, `intelliignore`.
243+
- `configuration` (required for `standard` and `intelliignore` algorithms, ignored otherwise)
244+
- `diffSensitivity` (number): Sensitivity level for detecting differences.
245+
- `imageIgnoreThreshold` (number): Threshold for ignoring minor image differences.
246+
- `carouselsEnabled` (boolean): Whether to enable carousel detection.
247+
- `bannersEnabled` (boolean): Whether to enable banner detection.
248+
- `adsEnabled` (boolean): Whether to enable ad detection.
249+
- `assertion` (optional)
250+
- Defines assertions to apply to the region.
251+
- `diffIgnoreThreshold` (number): The threshold for ignoring minor differences.
252+
### Example Usage for regions
253+
```
254+
Map<String, Object> elementSelector = new HashMap<>();
255+
elementSelector.put("elementCSS", ".ad-banner");
256+
257+
Map<String, Object> padding = new HashMap<>();
258+
padding.put("top", 10);
259+
padding.put("left", 20);
260+
padding.put("right", 15);
261+
padding.put("bottom", 10);
262+
263+
Map<String, Object> configuration = new HashMap<>();
264+
configuration.put("diffSensitivity", 2);
265+
configuration.put("imageIgnoreThreshold", 0.2);
266+
configuration.put("carouselsEnabled", true);
267+
configuration.put("bannersEnabled", true);
268+
configuration.put("adsEnabled", true);
269+
270+
Map<String, Object> assertion = new HashMap<>();
271+
assertion.put("diffIgnoreThreshold", 0.4);
272+
273+
Map<String, Object> obj1 = new HashMap<>();
274+
obj1.put("elementSelector", elementSelector);
275+
obj1.put("padding", padding);
276+
obj1.put("algorithm", "intelliignore");
277+
obj1.put("configuration", configuration);
278+
obj1.put("assertion", assertion);
279+
280+
List<Map<String, Object>> regions = Collections.singletonList(obj1);
281+
282+
percy.snapshot("Homepage", regions);
283+
284+
```
223285
224286
### Creating Percy on automate build
225287
Note: Automate Percy Token starts with `auto` keyword. The command can be triggered using `exec` keyword.

src/main/java/io/percy/selenium/Percy.java

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@
2828

2929
import java.util.stream.Collectors;
3030

31+
import javax.swing.text.html.CSS;
32+
import javax.xml.xpath.XPath;
33+
3134
/**
3235
* Percy client for visual testing.
3336
*/
@@ -75,6 +78,79 @@ public Percy(WebDriver driver) {
7578
this.env = new Environment(driver);
7679
}
7780

81+
/**
82+
* Creates a region configuration based on the provided parameters.
83+
*
84+
* @param boundingBox The bounding box of the region, or null.
85+
* @param elementXpath The XPath of the element, or null.
86+
* @param elementCSS The CSS selector of the element, or null.
87+
* @param padding The padding around the region, or null.
88+
* @param algorithm The algorithm to be used (default 'ignore').
89+
* @param diffSensitivity The sensitivity for diffing, or null.
90+
* @param imageIgnoreThreshold The image ignore threshold, or null.
91+
* @param carouselsEnabled Flag for enabling carousels, or null.
92+
* @param bannersEnabled Flag for enabling banners, or null.
93+
* @param adsEnabled Flag for enabling ads, or null.
94+
* @param diffIgnoreThreshold The diff ignore threshold, or null.
95+
* @return A map representing the region configuration.
96+
*/
97+
98+
public Map<String, Object> createRegion(Map<String, Object> params) {
99+
Map<String, Object> elementSelector = new HashMap<>();
100+
if (params.containsKey("boundingBox")) {
101+
elementSelector.put("boundingBox", params.get("boundingBox"));
102+
}
103+
if (params.containsKey("elementXpath")) {
104+
elementSelector.put("elementXpath", params.get("elementXpath"));
105+
}
106+
if (params.containsKey("elementCSS")) {
107+
elementSelector.put("elementCSS", params.get("elementCSS"));
108+
}
109+
110+
Map<String, Object> region = new HashMap<>();
111+
region.put("algorithm", params.getOrDefault("algorithm", "ignore"));
112+
region.put("elementSelector", elementSelector);
113+
114+
if (params.containsKey("padding")) {
115+
region.put("padding", params.get("padding"));
116+
}
117+
118+
Map<String, Object> configuration = new HashMap<>();
119+
String algorithm = (String) params.getOrDefault("algorithm", "ignore");
120+
if (algorithm.equals("standard") || algorithm.equals("intelliignore")) {
121+
if (params.containsKey("diffSensitivity")) {
122+
configuration.put("diffSensitivity", params.get("diffSensitivity"));
123+
}
124+
if (params.containsKey("imageIgnoreThreshold")) {
125+
configuration.put("imageIgnoreThreshold", params.get("imageIgnoreThreshold"));
126+
}
127+
if (params.containsKey("carouselsEnabled")) {
128+
configuration.put("carouselsEnabled", params.get("carouselsEnabled"));
129+
}
130+
if (params.containsKey("bannersEnabled")) {
131+
configuration.put("bannersEnabled", params.get("bannersEnabled"));
132+
}
133+
if (params.containsKey("adsEnabled")) {
134+
configuration.put("adsEnabled", params.get("adsEnabled"));
135+
}
136+
}
137+
138+
if (!configuration.isEmpty()) {
139+
region.put("configuration", configuration);
140+
}
141+
142+
Map<String, Object> assertion = new HashMap<>();
143+
if (params.containsKey("diffIgnoreThreshold")) {
144+
assertion.put("diffIgnoreThreshold", params.get("diffIgnoreThreshold"));
145+
}
146+
147+
if (!assertion.isEmpty()) {
148+
region.put("assertion", assertion);
149+
}
150+
151+
return region;
152+
}
153+
78154
/**
79155
* Take a snapshot and upload it to Percy.
80156
*

src/test/java/io/percy/selenium/SdkTest.java

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
import org.junit.jupiter.api.AfterAll;
99
import org.junit.jupiter.api.BeforeEach;
10+
import org.junit.jupiter.api.Order;
1011
import org.junit.jupiter.api.BeforeAll;
1112
import org.junit.jupiter.api.Test;
1213
import static org.junit.jupiter.api.Assertions.*;
@@ -207,4 +208,50 @@ public void takeScreenshotThrowErrorForWeb() {
207208
Throwable exception = assertThrows(RuntimeException.class, () -> mockedPercy.screenshot("Test"));
208209
assertEquals("Invalid function call - screenshot(). Please use snapshot() function for taking screenshot. screenshot() should be used only while using Percy with Automate. For more information on usage of snapshot(), refer doc for your language https://www.browserstack.com/docs/percy/integrate/overview", exception.getMessage());
209210
}
211+
212+
@Test
213+
public void createRegionTest() {
214+
// Setup the parameters for the region
215+
Map<String, Object> params = new HashMap<>();
216+
params.put("boundingBox", "100,100,200,200");
217+
params.put("elementXpath", "//div[@id='test']");
218+
params.put("elementCSS", ".test-class");
219+
params.put("padding", 10);
220+
params.put("algorithm", "standard");
221+
params.put("diffSensitivity", 0.5);
222+
params.put("imageIgnoreThreshold", 0.2);
223+
params.put("carouselsEnabled", true);
224+
params.put("bannersEnabled", false);
225+
params.put("adsEnabled", true);
226+
params.put("diffIgnoreThreshold", 0.1);
227+
228+
// Call the method to create the region
229+
Map<String, Object> region = percy.createRegion(params);
230+
231+
// Validate the returned region
232+
assertNotNull(region);
233+
234+
// Check if elementSelector was added correctly
235+
Map<String, Object> elementSelector = (Map<String, Object>) region.get("elementSelector");
236+
assertNotNull(elementSelector);
237+
assertEquals("100,100,200,200", elementSelector.get("boundingBox"));
238+
assertEquals("//div[@id='test']", elementSelector.get("elementXpath"));
239+
assertEquals(".test-class", elementSelector.get("elementCSS"));
240+
241+
// Validate algorithm and configuration
242+
assertEquals("standard", region.get("algorithm"));
243+
244+
Map<String, Object> configuration = (Map<String, Object>) region.get("configuration");
245+
assertNotNull(configuration);
246+
assertEquals(0.5, configuration.get("diffSensitivity"));
247+
assertEquals(0.2, configuration.get("imageIgnoreThreshold"));
248+
assertTrue((Boolean) configuration.get("carouselsEnabled"));
249+
assertFalse((Boolean) configuration.get("bannersEnabled"));
250+
assertTrue((Boolean) configuration.get("adsEnabled"));
251+
252+
// Validate assertion
253+
Map<String, Object> assertion = (Map<String, Object>) region.get("assertion");
254+
assertNotNull(assertion);
255+
assertEquals(0.1, assertion.get("diffIgnoreThreshold"));
256+
}
210257
}

0 commit comments

Comments
 (0)