Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ jobs:
- name: Get yarn cache directory path
id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"
- uses: actions/cache@v2
- uses: actions/cache@v3
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
key: v1/${{ runner.os }}/java-${{ matrix.java }}/${{ hashFiles('**/yarn.lock') }}
Expand Down
54 changes: 54 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,60 @@ public class Example {
- `bottom` (int): Bottom coordinate of the consider region.
- `left` (int): Left coordinate of the consider region.
- `right` (int): Right coordinate of the consider region.
- `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.
- Parameters:
- `elementSelector` (optional)
Copy link
Copy Markdown

@this-is-shivamsingh this-is-shivamsingh Apr 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

elementSelector is optional for mandatory

  • if there is no element selector, did we run fullPage

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes we add this in cli for full page

- `boundingBox` (object): Defines the coordinates and size of the region.
- `x` (number): X-coordinate of the region.
- `y` (number): Y-coordinate of the region.
- `width` (number): Width of the region.
- `height` (number): Height of the region.
- `elementXpath` (string): The XPath selector for the element.
- `elementCSS` (string): The CSS selector for the element.

- `algorithm` (mandatory)
- Specifies the snapshot comparison algorithm.
- Allowed values: `standard`, `layout`, `ignore`, `intelliignore`.

- `configuration` (required for `standard` and `intelliignore` algorithms, ignored otherwise)
- `diffSensitivity` (number): Sensitivity level for detecting differences.
- `imageIgnoreThreshold` (number): Threshold for ignoring minor image differences.
- `carouselsEnabled` (boolean): Whether to enable carousel detection.
- `bannersEnabled` (boolean): Whether to enable banner detection.
- `adsEnabled` (boolean): Whether to enable ad detection.

- `assertion` (optional)
- Defines assertions to apply to the region.
- `diffIgnoreThreshold` (number): The threshold for ignoring minor differences.

### Example Usage for regions

```
Map<String, Object> elementSelector = new HashMap<>();
elementSelector.put("elementCSS", ".ad-banner");

Map<String, Object> configuration = new HashMap<>();
configuration.put("diffSensitivity", 2);
configuration.put("imageIgnoreThreshold", 0.2);
configuration.put("carouselsEnabled", true);
configuration.put("bannersEnabled", true);
configuration.put("adsEnabled", true);

Map<String, Object> assertion = new HashMap<>();
assertion.put("diffIgnoreThreshold", 0.4);

Map<String, Object> obj1 = new HashMap<>();
obj1.put("elementSelector", elementSelector);
obj1.put("padding", padding);
obj1.put("algorithm", "intelliignore");
obj1.put("configuration", configuration);
obj1.put("assertion", assertion);

List<Map<String, Object>> regions = Collections.singletonList(obj1);

percy.snapshot("Homepage", regions);

```

### Creating Percy on automate build
Note: Automate Percy Token starts with `auto` keyword. The command can be triggered using `exec` keyword.
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@
"test": "npx percy exec --testing -- mvn test"
},
"devDependencies": {
"@percy/cli": "1.28.7"
"@percy/cli": "1.30.9"
}
}
77 changes: 77 additions & 0 deletions src/main/java/io/percy/playwright/Percy.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@
import org.jetbrains.annotations.Nullable;
import org.json.JSONObject;
import java.util.*;

import javax.swing.text.html.CSS;
import javax.xml.xpath.XPath;

import com.microsoft.playwright.*;


Expand Down Expand Up @@ -51,6 +55,79 @@ public Percy(Page page) {
this.env = new Environment();
}

/**
* Creates a region configuration based on the provided parameters.
*
* @param boundingBox The bounding box of the region, or null.
* @param elementXpath The XPath of the element, or null.
* @param elementCSS The CSS selector of the element, or null.
* @param padding The padding around the region, or null.
* @param algorithm The algorithm to be used (default 'ignore').
* @param diffSensitivity The sensitivity for diffing, or null.
* @param imageIgnoreThreshold The image ignore threshold, or null.
* @param carouselsEnabled Flag for enabling carousels, or null.
* @param bannersEnabled Flag for enabling banners, or null.
* @param adsEnabled Flag for enabling ads, or null.
* @param diffIgnoreThreshold The diff ignore threshold, or null.
* @return A map representing the region configuration.
*/

public Map<String, Object> createRegion(Map<String, Object> params) {
Map<String, Object> elementSelector = new HashMap<>();
if (params.containsKey("boundingBox")) {
elementSelector.put("boundingBox", params.get("boundingBox"));
}
if (params.containsKey("elementXpath")) {
elementSelector.put("elementXpath", params.get("elementXpath"));
}
if (params.containsKey("elementCSS")) {
elementSelector.put("elementCSS", params.get("elementCSS"));
}

Map<String, Object> region = new HashMap<>();
region.put("algorithm", params.getOrDefault("algorithm", "ignore"));
region.put("elementSelector", elementSelector);

if (params.containsKey("padding")) {
region.put("padding", params.get("padding"));
}

Map<String, Object> configuration = new HashMap<>();
String algorithm = (String) params.getOrDefault("algorithm", "ignore");
if (algorithm.equals("standard") || algorithm.equals("intelliignore")) {
if (params.containsKey("diffSensitivity")) {
configuration.put("diffSensitivity", params.get("diffSensitivity"));
}
if (params.containsKey("imageIgnoreThreshold")) {
configuration.put("imageIgnoreThreshold", params.get("imageIgnoreThreshold"));
}
if (params.containsKey("carouselsEnabled")) {
configuration.put("carouselsEnabled", params.get("carouselsEnabled"));
}
if (params.containsKey("bannersEnabled")) {
configuration.put("bannersEnabled", params.get("bannersEnabled"));
}
if (params.containsKey("adsEnabled")) {
configuration.put("adsEnabled", params.get("adsEnabled"));
}
}

if (!configuration.isEmpty()) {
region.put("configuration", configuration);
}

Map<String, Object> assertion = new HashMap<>();
if (params.containsKey("diffIgnoreThreshold")) {
assertion.put("diffIgnoreThreshold", params.get("diffIgnoreThreshold"));
}

if (!assertion.isEmpty()) {
region.put("assertion", assertion);
}

return region;
}

/**
* Take a snapshot and upload it to Percy.
*
Expand Down
47 changes: 47 additions & 0 deletions src/test/java/io/percy/playwright/SDKTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -220,4 +220,51 @@ public void takeScreenshotWithOptions() throws Exception {
assertEquals(json.getString("framework"), capturedJson.getString("framework"));
assertTrue(json.getJSONObject("options").similar(capturedJson.getJSONObject("options")));
}
@Test
@Order(9)
public void createRegionTest() {
// Setup the parameters for the region
Map<String, Object> params = new HashMap<>();
params.put("boundingBox", "100,100,200,200");
params.put("elementXpath", "//div[@id='test']");
params.put("elementCSS", ".test-class");
params.put("padding", 10);
params.put("algorithm", "standard");
params.put("diffSensitivity", 0.5);
params.put("imageIgnoreThreshold", 0.2);
params.put("carouselsEnabled", true);
params.put("bannersEnabled", false);
params.put("adsEnabled", true);
params.put("diffIgnoreThreshold", 0.1);

// Call the method to create the region
Map<String, Object> region = percy.createRegion(params);

// Validate the returned region
assertNotNull(region);

// Check if elementSelector was added correctly
Map<String, Object> elementSelector = (Map<String, Object>) region.get("elementSelector");
assertNotNull(elementSelector);
assertEquals("100,100,200,200", elementSelector.get("boundingBox"));
assertEquals("//div[@id='test']", elementSelector.get("elementXpath"));
assertEquals(".test-class", elementSelector.get("elementCSS"));

// Validate algorithm and configuration
assertEquals("standard", region.get("algorithm"));

Map<String, Object> configuration = (Map<String, Object>) region.get("configuration");
assertNotNull(configuration);
assertEquals(0.5, configuration.get("diffSensitivity"));
assertEquals(0.2, configuration.get("imageIgnoreThreshold"));
assertTrue((Boolean) configuration.get("carouselsEnabled"));
assertFalse((Boolean) configuration.get("bannersEnabled"));
assertTrue((Boolean) configuration.get("adsEnabled"));

// Validate assertion
Map<String, Object> assertion = (Map<String, Object>) region.get("assertion");
assertNotNull(assertion);
assertEquals(0.1, assertion.get("diffIgnoreThreshold"));
}

}
Loading