Skip to content

Commit ede01f6

Browse files
test: cover .percy.yml config <-> per-snapshot merge precedence
Ref: PER-8053
1 parent fef3e61 commit ede01f6

1 file changed

Lines changed: 62 additions & 0 deletions

File tree

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

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1185,6 +1185,68 @@ public void snapshotSurvivesReadinessThrow() throws Exception {
11851185
assertEquals("<html></html>", result.get("html"));
11861186
}
11871187

1188+
@Test
1189+
public void snapshotMergesCliConfigWithPerCallOptionsPrecedence() throws Exception {
1190+
// .percy.yml config carries a config-only key (enableJavaScript) and a
1191+
// percyCSS value that the per-call option should override.
1192+
RemoteWebDriver mockedDriver = mock(RemoteWebDriver.class);
1193+
Percy mockedPercy = spy(new Percy(mockedDriver));
1194+
1195+
setField(mockedPercy, "isPercyEnabled", true);
1196+
setField(mockedPercy, "domJs",
1197+
"window.PercyDOM = window.PercyDOM || {}; window.PercyDOM.serialize = function(){ return {}; };");
1198+
setField(mockedPercy, "cliConfig", new JSONObject().put("snapshot",
1199+
new JSONObject()
1200+
.put("enableJavaScript", true)
1201+
.put("percyCSS", "FROM_CONFIG")));
1202+
mockedPercy.sessionType = "web";
1203+
1204+
when(mockedDriver.getCurrentUrl()).thenReturn("https://example.com");
1205+
WebDriver.Options mockedOptions = mock(WebDriver.Options.class);
1206+
when(mockedDriver.manage()).thenReturn(mockedOptions);
1207+
when(mockedOptions.getCookies()).thenReturn(Collections.emptySet());
1208+
when(mockedDriver.findElements(By.tagName("iframe"))).thenReturn(Collections.emptyList());
1209+
1210+
// Capture every script passed to the JavascriptExecutor so we can inspect
1211+
// the PercyDOM.serialize(...) payload that getSerializedDOM builds.
1212+
ArgumentCaptor<String> scriptCaptor = ArgumentCaptor.forClass(String.class);
1213+
when(((JavascriptExecutor) mockedDriver).executeScript(any(String.class)))
1214+
.thenReturn(new HashMap<String, Object>());
1215+
1216+
// Avoid an actual POST back to the CLI.
1217+
doReturn(new JSONObject()).when(mockedPercy)
1218+
.request(eq("/percy/snapshot"), any(JSONObject.class), eq("merge precedence"));
1219+
1220+
Map<String, Object> options = new HashMap<String, Object>();
1221+
options.put("percyCSS", "FROM_CALL");
1222+
1223+
mockedPercy.snapshot("merge precedence", options);
1224+
1225+
verify((JavascriptExecutor) mockedDriver, atLeastOnce()).executeScript(scriptCaptor.capture());
1226+
1227+
String serializeScript = null;
1228+
for (String script : scriptCaptor.getAllValues()) {
1229+
if (script != null && script.startsWith("return PercyDOM.serialize(")) {
1230+
serializeScript = script;
1231+
}
1232+
}
1233+
assertNotNull(serializeScript, "PercyDOM.serialize script should have been executed");
1234+
1235+
// Extract the JSON argument passed to PercyDOM.serialize(...) and assert
1236+
// the merged options reflect config<->per-call precedence.
1237+
String jsonArg = serializeScript
1238+
.substring(serializeScript.indexOf('(') + 1, serializeScript.lastIndexOf(')'))
1239+
.trim();
1240+
JSONObject serialized = new JSONObject(jsonArg);
1241+
1242+
// Config-only key survives the merge.
1243+
assertTrue(serialized.getBoolean("enableJavaScript"),
1244+
"enableJavaScript from .percy.yml config should be present in serialized options");
1245+
// Per-call option wins over the config value.
1246+
assertEquals("FROM_CALL", serialized.getString("percyCSS"),
1247+
"per-call percyCSS should override the .percy.yml config value");
1248+
}
1249+
11881250
private static Object invokePrivate(Object target, String methodName, Class<?>[] paramTypes, Object... args)
11891251
throws Exception {
11901252
Method method = Percy.class.getDeclaredMethod(methodName, paramTypes);

0 commit comments

Comments
 (0)