From 072931d944b6e23781fad0d6f47f3e48113cbb62 Mon Sep 17 00:00:00 2001 From: Neha Sanserwal Date: Wed, 22 Apr 2026 19:55:05 +0530 Subject: [PATCH 1/4] Add Cucumber step definitions for Percy visual testing Add PercySteps class providing Gherkin step definitions for: - Percy Snapshot (DOM): widths, min height, percy CSS, scope, layout mode, JavaScript, labels, test case, responsive capture - Create Percy Region: ignore/consider/intelliignore by CSS, XPath, bounding box, with diff sensitivity and padding - Data table support for arbitrary options Cucumber dependency is provided scope - users bring their own version. Includes unit tests for all step definitions. Co-Authored-By: Claude Opus 4.6 (1M context) --- pom.xml | 13 + .../percy/playwright/cucumber/PercySteps.java | 314 ++++++++++++++++++ .../playwright/cucumber/PercyStepsTest.java | 124 +++++++ 3 files changed, 451 insertions(+) create mode 100644 src/main/java/io/percy/playwright/cucumber/PercySteps.java create mode 100644 src/test/java/io/percy/playwright/cucumber/PercyStepsTest.java diff --git a/pom.xml b/pom.xml index 666daed..63339c8 100644 --- a/pom.xml +++ b/pom.xml @@ -101,6 +101,19 @@ ${junit.jupiter.version} test + + + io.cucumber + cucumber-java + 7.15.0 + provided + + + io.cucumber + cucumber-junit-platform-engine + 7.15.0 + test + diff --git a/src/main/java/io/percy/playwright/cucumber/PercySteps.java b/src/main/java/io/percy/playwright/cucumber/PercySteps.java new file mode 100644 index 0000000..99b5c6f --- /dev/null +++ b/src/main/java/io/percy/playwright/cucumber/PercySteps.java @@ -0,0 +1,314 @@ +package io.percy.playwright.cucumber; + +import io.cucumber.java.en.Given; +import io.cucumber.java.en.When; +import io.cucumber.java.en.Then; +import io.percy.playwright.Percy; + +import com.microsoft.playwright.Page; + +import java.util.*; + +/** + * Cucumber step definitions for Percy visual testing with Playwright. + * + *

Provides Gherkin steps to capture Percy snapshots and define + * ignore/consider regions from Cucumber feature files.

+ * + *

Usage in feature files:

+ *
+ * Feature: Visual Testing
+ *   Scenario: Homepage visual test
+ *     Given I have a Percy instance
+ *     When I take a Percy snapshot named "Homepage"
+ *
+ *   Scenario: Snapshot with options
+ *     Given I have a Percy instance
+ *     When I take a Percy snapshot named "Responsive" with widths "375,768,1280"
+ *
+ *   Scenario: Ignore region
+ *     Given I have a Percy instance
+ *     And I create a Percy ignore region with CSS selector ".ad-banner"
+ *     When I take a Percy snapshot named "No Ads" with regions
+ * 
+ * + *

Setup in step definition glue:

+ *
+ * public class Hooks {
+ *     private static Playwright playwright;
+ *     private static Browser browser;
+ *     private static Page page;
+ *
+ *     {@literal @}Before
+ *     public void setUp() {
+ *         playwright = Playwright.create();
+ *         browser = playwright.chromium().launch();
+ *         page = browser.newPage();
+ *         PercySteps.setPage(page);
+ *     }
+ *
+ *     {@literal @}After
+ *     public void tearDown() {
+ *         if (browser != null) browser.close();
+ *         if (playwright != null) playwright.close();
+ *         PercySteps.reset();
+ *     }
+ * }
+ * 
+ */ +public class PercySteps { + + private static Page page; + private static Percy percy; + private static List> regions = new ArrayList<>(); + + /** + * Set the Playwright Page instance for Percy to use. + * Call this from your Cucumber hooks before using any Percy steps. + * + * @param playwrightPage the Playwright Page instance + */ + public static void setPage(Page playwrightPage) { + page = playwrightPage; + percy = new Percy(page); + } + + /** + * Get the current Percy instance. + * + * @return the Percy instance, or null if not initialized + */ + public static Percy getPercy() { + return percy; + } + + /** + * Reset the Percy instance and clear stored regions. + * Call this from your Cucumber hooks in teardown. + */ + public static void reset() { + percy = null; + page = null; + regions.clear(); + } + + // ------------------------------------------------------------------ + // Given steps + // ------------------------------------------------------------------ + + @Given("I have a Percy instance") + public void iHaveAPercyInstance() { + if (page == null) { + throw new IllegalStateException( + "Playwright Page not set. Call PercySteps.setPage(page) in your @Before hook."); + } + if (percy == null) { + percy = new Percy(page); + } + } + + @Given("I create a Percy ignore region with CSS selector {string}") + public void iCreateIgnoreRegionCSS(String cssSelector) { + Map params = new HashMap<>(); + params.put("algorithm", "ignore"); + params.put("elementCSS", cssSelector); + regions.add(percy.createRegion(params)); + } + + @Given("I create a Percy ignore region with XPath {string}") + public void iCreateIgnoreRegionXPath(String xpath) { + Map params = new HashMap<>(); + params.put("algorithm", "ignore"); + params.put("elementXpath", xpath); + regions.add(percy.createRegion(params)); + } + + @Given("I create a Percy ignore region with bounding box {int}, {int}, {int}, {int}") + public void iCreateIgnoreRegionBoundingBox(int x, int y, int width, int height) { + Map boundingBox = new HashMap<>(); + boundingBox.put("x", x); + boundingBox.put("y", y); + boundingBox.put("width", width); + boundingBox.put("height", height); + + Map params = new HashMap<>(); + params.put("algorithm", "ignore"); + params.put("boundingBox", boundingBox); + regions.add(percy.createRegion(params)); + } + + @Given("I create a Percy consider region with CSS selector {string}") + public void iCreateConsiderRegionCSS(String cssSelector) { + Map params = new HashMap<>(); + params.put("algorithm", "standard"); + params.put("elementCSS", cssSelector); + regions.add(percy.createRegion(params)); + } + + @Given("I create a Percy consider region with CSS selector {string} and diff sensitivity {int}") + public void iCreateConsiderRegionCSSWithSensitivity(String cssSelector, int sensitivity) { + Map params = new HashMap<>(); + params.put("algorithm", "standard"); + params.put("elementCSS", cssSelector); + params.put("diffSensitivity", sensitivity); + regions.add(percy.createRegion(params)); + } + + @Given("I create a Percy intelliignore region with CSS selector {string}") + public void iCreateIntelliIgnoreRegionCSS(String cssSelector) { + Map params = new HashMap<>(); + params.put("algorithm", "intelliignore"); + params.put("elementCSS", cssSelector); + regions.add(percy.createRegion(params)); + } + + @Given("I clear Percy regions") + public void iClearPercyRegions() { + regions.clear(); + } + + // ------------------------------------------------------------------ + // When steps - Snapshot (DOM) + // ------------------------------------------------------------------ + + @When("I take a Percy snapshot named {string}") + public void iTakeSnapshot(String name) { + percy.snapshot(name); + } + + @When("I take a Percy snapshot named {string} with widths {string}") + public void iTakeSnapshotWithWidths(String name, String widths) { + Map options = new HashMap<>(); + options.put("widths", parseWidths(widths)); + percy.snapshot(name, options); + } + + @When("I take a Percy snapshot named {string} with min height {int}") + public void iTakeSnapshotWithMinHeight(String name, int minHeight) { + Map options = new HashMap<>(); + options.put("minHeight", minHeight); + percy.snapshot(name, options); + } + + @When("I take a Percy snapshot named {string} with Percy CSS {string}") + public void iTakeSnapshotWithCSS(String name, String percyCSS) { + Map options = new HashMap<>(); + options.put("percyCSS", percyCSS); + percy.snapshot(name, options); + } + + @When("I take a Percy snapshot named {string} with scope {string}") + public void iTakeSnapshotWithScope(String name, String scope) { + Map options = new HashMap<>(); + options.put("scope", scope); + percy.snapshot(name, options); + } + + @When("I take a Percy snapshot named {string} with layout mode") + public void iTakeSnapshotWithLayout(String name) { + Map options = new HashMap<>(); + options.put("enableLayout", true); + percy.snapshot(name, options); + } + + @When("I take a Percy snapshot named {string} with JavaScript enabled") + public void iTakeSnapshotWithJS(String name) { + Map options = new HashMap<>(); + options.put("enableJavaScript", true); + percy.snapshot(name, options); + } + + @When("I take a Percy snapshot named {string} with labels {string}") + public void iTakeSnapshotWithLabels(String name, String labels) { + Map options = new HashMap<>(); + options.put("labels", labels); + percy.snapshot(name, options); + } + + @When("I take a Percy snapshot named {string} with test case {string}") + public void iTakeSnapshotWithTestCase(String name, String testCase) { + Map options = new HashMap<>(); + options.put("testCase", testCase); + percy.snapshot(name, options); + } + + @When("I take a Percy snapshot named {string} with regions") + public void iTakeSnapshotWithRegions(String name) { + Map options = new HashMap<>(); + if (!regions.isEmpty()) { + options.put("regions", new ArrayList<>(regions)); + regions.clear(); + } + percy.snapshot(name, options); + } + + @When("I take a Percy snapshot named {string} with widths {string} and regions") + public void iTakeSnapshotWithWidthsAndRegions(String name, String widths) { + Map options = new HashMap<>(); + options.put("widths", parseWidths(widths)); + if (!regions.isEmpty()) { + options.put("regions", new ArrayList<>(regions)); + regions.clear(); + } + percy.snapshot(name, options); + } + + @When("I take a Percy snapshot named {string} with options:") + public void iTakeSnapshotWithOptions(String name, Map optionsTable) { + Map options = buildOptions(optionsTable); + if (!regions.isEmpty()) { + options.put("regions", new ArrayList<>(regions)); + regions.clear(); + } + percy.snapshot(name, options); + } + + // ------------------------------------------------------------------ + // Then steps + // ------------------------------------------------------------------ + + @Then("Percy should be enabled") + public void percyShouldBeEnabled() { + if (percy == null) { + throw new IllegalStateException("Percy instance not initialized."); + } + } + + // ------------------------------------------------------------------ + // Helpers + // ------------------------------------------------------------------ + + private static List parseWidths(String widths) { + List result = new ArrayList<>(); + for (String w : widths.split(",")) { + result.add(Integer.parseInt(w.trim())); + } + return result; + } + + private static Map buildOptions(Map table) { + Map options = new HashMap<>(); + for (Map.Entry entry : table.entrySet()) { + String key = entry.getKey(); + String value = entry.getValue(); + switch (key) { + case "widths": + options.put("widths", parseWidths(value)); + break; + case "minHeight": + options.put("minHeight", Integer.parseInt(value)); + break; + case "enableJavaScript": + case "enableLayout": + case "disableShadowDom": + case "responsiveSnapshotCapture": + options.put(key, Boolean.parseBoolean(value)); + break; + default: + options.put(key, value); + break; + } + } + return options; + } +} diff --git a/src/test/java/io/percy/playwright/cucumber/PercyStepsTest.java b/src/test/java/io/percy/playwright/cucumber/PercyStepsTest.java new file mode 100644 index 0000000..89225a3 --- /dev/null +++ b/src/test/java/io/percy/playwright/cucumber/PercyStepsTest.java @@ -0,0 +1,124 @@ +package io.percy.playwright.cucumber; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.*; + +import io.percy.playwright.Percy; +import com.microsoft.playwright.Page; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +class PercyStepsTest { + + private Page mockPage; + + @BeforeEach + void setUp() { + mockPage = mock(Page.class); + } + + @AfterEach + void tearDown() { + PercySteps.reset(); + } + + @Test + void testSetPageAndGetPercy() { + PercySteps.setPage(mockPage); + assertNotNull(PercySteps.getPercy()); + } + + @Test + void testResetClearsState() { + PercySteps.setPage(mockPage); + assertNotNull(PercySteps.getPercy()); + + PercySteps.reset(); + assertNull(PercySteps.getPercy()); + } + + @Test + void testIHaveAPercyInstanceThrowsWithoutPage() { + PercySteps steps = new PercySteps(); + assertThrows(IllegalStateException.class, steps::iHaveAPercyInstance); + } + + @Test + void testIHaveAPercyInstanceSucceedsWithPage() { + PercySteps.setPage(mockPage); + PercySteps steps = new PercySteps(); + assertDoesNotThrow(steps::iHaveAPercyInstance); + } + + @Test + void testCreateIgnoreRegionCSS() { + PercySteps.setPage(mockPage); + PercySteps steps = new PercySteps(); + steps.iHaveAPercyInstance(); + assertDoesNotThrow(() -> steps.iCreateIgnoreRegionCSS(".ad-banner")); + } + + @Test + void testCreateIgnoreRegionXPath() { + PercySteps.setPage(mockPage); + PercySteps steps = new PercySteps(); + steps.iHaveAPercyInstance(); + assertDoesNotThrow(() -> steps.iCreateIgnoreRegionXPath("//div[@id='header']")); + } + + @Test + void testCreateIgnoreRegionBoundingBox() { + PercySteps.setPage(mockPage); + PercySteps steps = new PercySteps(); + steps.iHaveAPercyInstance(); + assertDoesNotThrow(() -> steps.iCreateIgnoreRegionBoundingBox(0, 0, 200, 100)); + } + + @Test + void testCreateConsiderRegionCSS() { + PercySteps.setPage(mockPage); + PercySteps steps = new PercySteps(); + steps.iHaveAPercyInstance(); + assertDoesNotThrow(() -> steps.iCreateConsiderRegionCSS(".content")); + } + + @Test + void testCreateConsiderRegionWithSensitivity() { + PercySteps.setPage(mockPage); + PercySteps steps = new PercySteps(); + steps.iHaveAPercyInstance(); + assertDoesNotThrow( + () -> steps.iCreateConsiderRegionCSSWithSensitivity(".content", 3)); + } + + @Test + void testCreateIntelliIgnoreRegion() { + PercySteps.setPage(mockPage); + PercySteps steps = new PercySteps(); + steps.iHaveAPercyInstance(); + assertDoesNotThrow(() -> steps.iCreateIntelliIgnoreRegionCSS(".dynamic")); + } + + @Test + void testClearRegions() { + PercySteps.setPage(mockPage); + PercySteps steps = new PercySteps(); + steps.iHaveAPercyInstance(); + steps.iCreateIgnoreRegionCSS(".ad"); + assertDoesNotThrow(steps::iClearPercyRegions); + } + + @Test + void testPercyShouldBeEnabledThrowsWithoutInit() { + PercySteps steps = new PercySteps(); + assertThrows(IllegalStateException.class, steps::percyShouldBeEnabled); + } + + @Test + void testPercyShouldBeEnabledSucceeds() { + PercySteps.setPage(mockPage); + PercySteps steps = new PercySteps(); + assertDoesNotThrow(steps::percyShouldBeEnabled); + } +} From 71853239d1e356d20b024d9fbb16db8ddb0e2eb1 Mon Sep 17 00:00:00 2001 From: Neha Sanserwal Date: Thu, 23 Apr 2026 10:19:19 +0530 Subject: [PATCH 2/4] Report Cucumber environment info in Percy build metadata - Add setClientInfo/setEnvironmentInfo to Percy and Environment classes - PercySteps sets client to "percy-cucumber-java-playwright/" and environment to "cucumber-java/; playwright-java" - Add Percy.getSdkVersion() public static method Co-Authored-By: Claude Opus 4.6 (1M context) --- .../java/io/percy/playwright/Environment.java | 21 +++++++++++++++++++ src/main/java/io/percy/playwright/Percy.java | 16 ++++++++++++++ .../percy/playwright/cucumber/PercySteps.java | 18 ++++++++++++++++ 3 files changed, 55 insertions(+) diff --git a/src/main/java/io/percy/playwright/Environment.java b/src/main/java/io/percy/playwright/Environment.java index 552373a..cfede57 100644 --- a/src/main/java/io/percy/playwright/Environment.java +++ b/src/main/java/io/percy/playwright/Environment.java @@ -9,12 +9,33 @@ class Environment { private final static String SDK_VERSION = "1.0.2"; private final static String SDK_NAME = "percy-playwright-java"; + private String clientInfoOverride; + private String environmentInfoOverride; + public String getClientInfo() { + if (clientInfoOverride != null) { + return clientInfoOverride; + } return SDK_NAME + "/" + SDK_VERSION; } public String getEnvironmentInfo() { + if (environmentInfoOverride != null) { + return environmentInfoOverride; + } String playwrightVersion = Playwright.class.getPackage().getImplementationVersion(); return String.format("playwright-java; %s", playwrightVersion); } + + void setClientInfo(String clientInfo) { + this.clientInfoOverride = clientInfo; + } + + void setEnvironmentInfo(String environmentInfo) { + this.environmentInfoOverride = environmentInfo; + } + + public static String getSdkVersion() { + return SDK_VERSION; + } } diff --git a/src/main/java/io/percy/playwright/Percy.java b/src/main/java/io/percy/playwright/Percy.java index 2f2224e..ff8b93e 100644 --- a/src/main/java/io/percy/playwright/Percy.java +++ b/src/main/java/io/percy/playwright/Percy.java @@ -73,6 +73,22 @@ public Percy(Page page) { this.env = new Environment(); } + /** + * Override the client info reported to Percy. + * Used by framework wrappers (e.g., Cucumber) to identify themselves. + */ + public void setClientInfo(String clientInfo, String environmentInfo) { + this.env.setClientInfo(clientInfo); + this.env.setEnvironmentInfo(environmentInfo); + } + + /** + * Get the SDK version string. + */ + public static String getSdkVersion() { + return Environment.getSdkVersion(); + } + /** * Creates a region configuration based on the provided parameters. * diff --git a/src/main/java/io/percy/playwright/cucumber/PercySteps.java b/src/main/java/io/percy/playwright/cucumber/PercySteps.java index 99b5c6f..e4238b7 100644 --- a/src/main/java/io/percy/playwright/cucumber/PercySteps.java +++ b/src/main/java/io/percy/playwright/cucumber/PercySteps.java @@ -71,6 +71,24 @@ public class PercySteps { public static void setPage(Page playwrightPage) { page = playwrightPage; percy = new Percy(page); + + // Identify as Cucumber wrapper in Percy build info + String sdkVersion = Percy.getSdkVersion(); + String cucumberVersion = getCucumberVersion(); + percy.setClientInfo( + "percy-cucumber-java-playwright/" + sdkVersion, + "cucumber-java/" + cucumberVersion + "; playwright-java" + ); + } + + private static String getCucumberVersion() { + try { + Package pkg = io.cucumber.java.en.Given.class.getPackage(); + String version = pkg != null ? pkg.getImplementationVersion() : null; + return version != null ? version : "unknown"; + } catch (Exception e) { + return "unknown"; + } } /** From 4b91f9e731dbe70ace37c4cc6d12298bbac5fa98 Mon Sep 17 00:00:00 2001 From: Neha Sanserwal Date: Thu, 23 Apr 2026 12:07:42 +0530 Subject: [PATCH 3/4] Add Percy Screenshot (Automate) steps to Cucumber support Add screenshot step definitions for BrowserStack Automate: - I take a Percy screenshot named {string} - I take a Percy screenshot named {string} with regions - I take a Percy screenshot named {string} with options: Co-Authored-By: Claude Opus 4.6 (1M context) --- .../percy/playwright/cucumber/PercySteps.java | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/src/main/java/io/percy/playwright/cucumber/PercySteps.java b/src/main/java/io/percy/playwright/cucumber/PercySteps.java index e4238b7..65649de 100644 --- a/src/main/java/io/percy/playwright/cucumber/PercySteps.java +++ b/src/main/java/io/percy/playwright/cucumber/PercySteps.java @@ -281,6 +281,47 @@ public void iTakeSnapshotWithOptions(String name, Map optionsTab percy.snapshot(name, options); } + // ------------------------------------------------------------------ + // When steps - Screenshot (Automate) + // ------------------------------------------------------------------ + + @When("I take a Percy screenshot named {string}") + public void iTakeScreenshot(String name) { + try { + percy.screenshot(name); + } catch (Exception e) { + throw new RuntimeException("Percy screenshot failed: " + e.getMessage(), e); + } + } + + @When("I take a Percy screenshot named {string} with regions") + public void iTakeScreenshotWithRegions(String name) { + Map options = new HashMap<>(); + if (!regions.isEmpty()) { + options.put("regions", new ArrayList<>(regions)); + regions.clear(); + } + try { + percy.screenshot(name, options); + } catch (Exception e) { + throw new RuntimeException("Percy screenshot failed: " + e.getMessage(), e); + } + } + + @When("I take a Percy screenshot named {string} with options:") + public void iTakeScreenshotWithOptions(String name, Map optionsTable) { + Map options = buildOptions(optionsTable); + if (!regions.isEmpty()) { + options.put("regions", new ArrayList<>(regions)); + regions.clear(); + } + try { + percy.screenshot(name, options); + } catch (Exception e) { + throw new RuntimeException("Percy screenshot failed: " + e.getMessage(), e); + } + } + // ------------------------------------------------------------------ // Then steps // ------------------------------------------------------------------ From 9efb2ead69ace6d10146bca361837cef5c8137bb Mon Sep 17 00:00:00 2001 From: Neha Sanserwal Date: Thu, 23 Apr 2026 12:20:44 +0530 Subject: [PATCH 4/4] Add parity with Robot Framework: missing region and snapshot steps - Add ignore/consider region with padding - Add consider region with XPath (+ diff sensitivity) - Add intelliignore region with XPath - Add snapshot steps: Shadow DOM disabled, responsive capture, sync - Add scopeOptions and sync parsing in buildOptions helper Co-Authored-By: Claude Opus 4.6 (1M context) --- .../percy/playwright/cucumber/PercySteps.java | 68 +++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/src/main/java/io/percy/playwright/cucumber/PercySteps.java b/src/main/java/io/percy/playwright/cucumber/PercySteps.java index 65649de..db59ee6 100644 --- a/src/main/java/io/percy/playwright/cucumber/PercySteps.java +++ b/src/main/java/io/percy/playwright/cucumber/PercySteps.java @@ -180,6 +180,49 @@ public void iCreateIntelliIgnoreRegionCSS(String cssSelector) { regions.add(percy.createRegion(params)); } + @Given("I create a Percy ignore region with CSS selector {string} and padding {int}") + public void iCreateIgnoreRegionCSSWithPadding(String cssSelector, int padding) { + Map params = new HashMap<>(); + params.put("algorithm", "ignore"); + params.put("elementCSS", cssSelector); + params.put("padding", padding); + regions.add(percy.createRegion(params)); + } + + @Given("I create a Percy ignore region with XPath {string} and padding {int}") + public void iCreateIgnoreRegionXPathWithPadding(String xpath, int padding) { + Map params = new HashMap<>(); + params.put("algorithm", "ignore"); + params.put("elementXpath", xpath); + params.put("padding", padding); + regions.add(percy.createRegion(params)); + } + + @Given("I create a Percy consider region with XPath {string}") + public void iCreateConsiderRegionXPath(String xpath) { + Map params = new HashMap<>(); + params.put("algorithm", "standard"); + params.put("elementXpath", xpath); + regions.add(percy.createRegion(params)); + } + + @Given("I create a Percy consider region with XPath {string} and diff sensitivity {int}") + public void iCreateConsiderRegionXPathWithSensitivity(String xpath, int sensitivity) { + Map params = new HashMap<>(); + params.put("algorithm", "standard"); + params.put("elementXpath", xpath); + params.put("diffSensitivity", sensitivity); + regions.add(percy.createRegion(params)); + } + + @Given("I create a Percy intelliignore region with XPath {string}") + public void iCreateIntelliIgnoreRegionXPath(String xpath) { + Map params = new HashMap<>(); + params.put("algorithm", "intelliignore"); + params.put("elementXpath", xpath); + regions.add(percy.createRegion(params)); + } + @Given("I clear Percy regions") public void iClearPercyRegions() { regions.clear(); @@ -250,6 +293,27 @@ public void iTakeSnapshotWithTestCase(String name, String testCase) { percy.snapshot(name, options); } + @When("I take a Percy snapshot named {string} with Shadow DOM disabled") + public void iTakeSnapshotWithShadowDomDisabled(String name) { + Map options = new HashMap<>(); + options.put("disableShadowDom", true); + percy.snapshot(name, options); + } + + @When("I take a Percy snapshot named {string} with responsive capture") + public void iTakeSnapshotWithResponsiveCapture(String name) { + Map options = new HashMap<>(); + options.put("responsiveSnapshotCapture", true); + percy.snapshot(name, options); + } + + @When("I take a Percy snapshot named {string} with sync") + public void iTakeSnapshotWithSync(String name) { + Map options = new HashMap<>(); + options.put("sync", true); + percy.snapshot(name, options); + } + @When("I take a Percy snapshot named {string} with regions") public void iTakeSnapshotWithRegions(String name) { Map options = new HashMap<>(); @@ -361,8 +425,12 @@ private static Map buildOptions(Map table) { case "enableLayout": case "disableShadowDom": case "responsiveSnapshotCapture": + case "sync": options.put(key, Boolean.parseBoolean(value)); break; + case "scopeOptions": + options.put(key, new org.json.JSONObject(value).toMap()); + break; default: options.put(key, value); break;