Skip to content

Commit

Permalink
Synchronous CLI implementation (#261)
Browse files Browse the repository at this point in the history
* initial commit

* covering poa

* covering poa

* changing default value of sync to null

* Add backward compatability

* test: added test for sync CLI

* test: added test for sync CLI

* empty commit

* test: added more assert checks

* test: test fix

---------

Co-authored-by: Chinmay Maheshwari <[email protected]>
Co-authored-by: this-is-shivamsingh <[email protected]>
Co-authored-by: Shivam singh <[email protected]>
  • Loading branch information
4 people authored Feb 1, 2024
1 parent 5419045 commit fe23f26
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 28 deletions.
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.27.7"
"@percy/cli": "1.28.0-beta.0"
}
}
84 changes: 57 additions & 27 deletions src/main/java/io/percy/selenium/Percy.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@
import org.apache.http.util.EntityUtils;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;

import org.apache.http.impl.client.HttpClients;
import org.json.JSONObject;

import java.io.InputStream;
Expand Down Expand Up @@ -76,8 +77,8 @@ public Percy(WebDriver driver) {
* @param name The human-readable name of the snapshot. Should be unique.
*
*/
public void snapshot(String name) {
snapshot(name, null, null, false, null, null);
public JSONObject snapshot(String name) {
return snapshot(name, null, null, false, null, null, null);
}

/**
Expand All @@ -87,8 +88,8 @@ public void snapshot(String name) {
* @param widths The browser widths at which you want to take the snapshot. In
* pixels.
*/
public void snapshot(String name, List<Integer> widths) {
snapshot(name, widths, null, false, null, null);
public JSONObject snapshot(String name, List<Integer> widths) {
return snapshot(name, widths, null, false, null, null, null);
}

/**
Expand All @@ -99,8 +100,8 @@ public void snapshot(String name, List<Integer> widths) {
* pixels.
* @param minHeight The minimum height of the resulting snapshot. In pixels.
*/
public void snapshot(String name, List<Integer> widths, Integer minHeight) {
snapshot(name, widths, minHeight, false, null, null);
public JSONObject snapshot(String name, List<Integer> widths, Integer minHeight) {
return snapshot(name, widths, minHeight, false, null, null, null);
}

/**
Expand All @@ -112,8 +113,8 @@ public void snapshot(String name, List<Integer> widths, Integer minHeight) {
* @param minHeight The minimum height of the resulting snapshot. In pixels.
* @param enableJavaScript Enable JavaScript in the Percy rendering environment
*/
public void snapshot(String name, List<Integer> widths, Integer minHeight, boolean enableJavaScript) {
snapshot(name, widths, minHeight, enableJavaScript, null, null);
public JSONObject snapshot(String name, List<Integer> widths, Integer minHeight, boolean enableJavaScript) {
return snapshot(name, widths, minHeight, enableJavaScript, null, null, null);
}

/**
Expand All @@ -126,8 +127,8 @@ public void snapshot(String name, List<Integer> widths, Integer minHeight, boole
* @param enableJavaScript Enable JavaScript in the Percy rendering environment
* @param percyCSS Percy specific CSS that is only applied in Percy's browsers
*/
public void snapshot(String name, @Nullable List<Integer> widths, Integer minHeight, boolean enableJavaScript, String percyCSS) {
snapshot(name, widths, minHeight, enableJavaScript, percyCSS, null);
public JSONObject snapshot(String name, @Nullable List<Integer> widths, Integer minHeight, boolean enableJavaScript, String percyCSS) {
return snapshot(name, widths, minHeight, enableJavaScript, percyCSS, null, null);
}

/**
Expand All @@ -141,8 +142,8 @@ public void snapshot(String name, @Nullable List<Integer> widths, Integer minHei
* @param percyCSS Percy specific CSS that is only applied in Percy's browsers
* @param scope A CSS selector to scope the screenshot to
*/
public void snapshot(String name, @Nullable List<Integer> widths, Integer minHeight, boolean enableJavaScript, String percyCSS, String scope) {
if (!isPercyEnabled) { return; }
public JSONObject snapshot(String name, @Nullable List<Integer> widths, Integer minHeight, boolean enableJavaScript, String percyCSS, String scope) {
if (!isPercyEnabled) { return null; }

Map<String, Object> domSnapshot = null;
Map<String, Object> options = new HashMap<String, Object>();
Expand All @@ -152,11 +153,26 @@ public void snapshot(String name, @Nullable List<Integer> widths, Integer minHei
options.put("percyCSS", percyCSS);
options.put("scope", scope);

snapshot(name, options);
return snapshot(name, options);
}

public void snapshot(String name, Map<String, Object> options) {
if (!isPercyEnabled) { return; }
public JSONObject snapshot(String name, @Nullable List<Integer> widths, Integer minHeight, boolean enableJavaScript, String percyCSS, String scope, @Nullable Boolean sync) {
if (!isPercyEnabled) { return null; }

Map<String, Object> domSnapshot = null;
Map<String, Object> options = new HashMap<String, Object>();
options.put("widths", widths);
options.put("minHeight", minHeight);
options.put("enableJavaScript", enableJavaScript);
options.put("percyCSS", percyCSS);
options.put("scope", scope);
options.put("sync", sync);

return snapshot(name, options);
}

public JSONObject snapshot(String name, Map<String, Object> options) {
if (!isPercyEnabled) { return null; }
if ("automate".equals(sessionType)) { throw new RuntimeException("Invalid function call - snapshot(). Please use screenshot() function while using Percy with Automate. For more information on usage of PercyScreenshot, refer https://docs.percy.io/docs/integrate-functional-testing-with-visual-testing"); }

Map<String, Object> domSnapshot = null;
Expand All @@ -170,17 +186,17 @@ public void snapshot(String name, Map<String, Object> options) {
if (PERCY_DEBUG) { log(e.getMessage()); }
}

postSnapshot(domSnapshot, name, driver.getCurrentUrl(), options);
return postSnapshot(domSnapshot, name, driver.getCurrentUrl(), options);
}

/**
* Take a snapshot and upload it to Percy.
*
* @param name The human-readable name of the screenshot. Should be unique.
*/
public void screenshot(String name) throws UnsupportedOperationException {
public JSONObject screenshot(String name) throws UnsupportedOperationException {
Map<String, Object> options = new HashMap<String, Object>();
screenshot(name, options);
return screenshot(name, options);
}

/**
Expand All @@ -189,8 +205,8 @@ public void screenshot(String name) throws UnsupportedOperationException {
* @param name The human-readable name of the screenshot. Should be unique.
* @param options Extra options
*/
public void screenshot(String name, Map<String, Object> options) throws UnsupportedOperationException {
if (!isPercyEnabled) { return; }
public JSONObject screenshot(String name, Map<String, Object> options) throws UnsupportedOperationException {
if (!isPercyEnabled) { return null; }
if ("web".equals(sessionType)) { throw new RuntimeException("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://docs.percy.io/docs/end-to-end-testing"); }

List<String> driverArray = Arrays.asList(driver.getClass().toString().split("\\$")); // Added to handle testcase (mocked driver)
Expand Down Expand Up @@ -234,7 +250,7 @@ public void screenshot(String name, Map<String, Object> options) throws Unsuppor
json.put("environmentInfo", env.getEnvironmentInfo());
json.put("options", options);

request("/percy/automateScreenshot", json, name);
return request("/percy/automateScreenshot", json, name);
}

/**
Expand Down Expand Up @@ -327,13 +343,13 @@ private String fetchPercyDOM() {
* @param enableJavaScript Enable JavaScript in the Percy rendering environment
* @param percyCSS Percy specific CSS that is only applied in Percy's browsers
*/
private void postSnapshot(
private JSONObject postSnapshot(
Map<String, Object> domSnapshot,
String name,
String url,
Map<String, Object> options
) {
if (!isPercyEnabled) { return; }
if (!isPercyEnabled) { return null; }

// Build a JSON object to POST back to the agent node process
JSONObject json = new JSONObject(options);
Expand All @@ -343,7 +359,7 @@ private void postSnapshot(
json.put("clientInfo", env.getClientInfo());
json.put("environmentInfo", env.getEnvironmentInfo());

request("/percy/snapshot", json, name);
return request("/percy/snapshot", json, name);
}

/**
Expand All @@ -353,17 +369,31 @@ private void postSnapshot(
* @param name The human-readable name of the snapshot. Should be unique.
* @param json Json object of all properties.
*/
protected void request(String url, JSONObject json, String name) {
protected JSONObject request(String url, JSONObject json, String name) {
StringEntity entity = new StringEntity(json.toString(), ContentType.APPLICATION_JSON);

try (CloseableHttpClient httpClient = HttpClientBuilder.create().build()) {
int timeout = 600000; // 600 seconds = 600,000 milliseconds

// Create RequestConfig with timeout
RequestConfig requestConfig = RequestConfig.custom()
.setSocketTimeout(timeout)
.setConnectTimeout(timeout)
.build();

try (CloseableHttpClient httpClient = HttpClients.custom().setDefaultRequestConfig(requestConfig).build()) {
HttpPost request = new HttpPost(PERCY_SERVER_ADDRESS + url);
request.setEntity(entity);
HttpResponse response = httpClient.execute(request);
JSONObject jsonResponse = new JSONObject(EntityUtils.toString(response.getEntity()));

if (jsonResponse.has("data")) {
return jsonResponse.getJSONObject("data");
}
} catch (Exception ex) {
if (PERCY_DEBUG) { log(ex.toString()); }
log("Could not post snapshot " + name);
}
return null;
}

/**
Expand Down
17 changes: 17 additions & 0 deletions src/test/java/io/percy/selenium/SdkTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

import org.json.JSONArray;
import org.json.JSONObject;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebDriver;
Expand All @@ -20,6 +22,9 @@
import io.github.bonigarcia.wdm.WebDriverManager;

import org.openqa.selenium.remote.*;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.*;
import java.net.URL;
public class SdkTest {
Expand Down Expand Up @@ -117,6 +122,18 @@ public void snapshotWithOptions() {
percy.snapshot("Site with options", options);
}

@Test
public void takeSnapshotWithSyncCLI(){
driver.get("https://example.com");
Map<String, Object> options = new HashMap<String, Object>();
options.put("sync", true);

JSONObject data = percy.snapshot("test_sync_cli_snapshot", options);
assertEquals(data.getString("snapshot-name"), "test_sync_cli_snapshot");
assertEquals(data.getString("status"), "success");
assertEquals(data.get("screenshots").getClass().isAssignableFrom(JSONArray.class), true);
}

@Test
public void takeScreenshot() {
RemoteWebDriver mockedDriver = mock(RemoteWebDriver.class);
Expand Down

0 comments on commit fe23f26

Please sign in to comment.