Skip to content

Commit 11d7745

Browse files
committed
[java] implement visual results
1 parent b41654b commit 11d7745

File tree

5 files changed

+260
-14
lines changed

5 files changed

+260
-14
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package com.saucelabs.saucebindings;
2+
3+
public class SauceVisualException extends RuntimeException {
4+
public SauceVisualException(String message) {
5+
super(message);
6+
}
7+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package com.saucelabs.saucebindings;
2+
3+
import lombok.Getter;
4+
import lombok.Setter;
5+
import org.openqa.selenium.remote.RemoteWebDriver;
6+
7+
import java.util.ArrayList;
8+
import java.util.List;
9+
import java.util.Map;
10+
11+
@Setter @Getter
12+
public class VisualResults {
13+
Map<String, Object> results;
14+
private Map<String, Object> totals;
15+
16+
private final Boolean passed;
17+
private final String message;
18+
private final String status;
19+
private final List<VisualSnapshot> snapshots = new ArrayList<>();
20+
private final Long totalNew;
21+
private final Long totalChanged;
22+
private final Long totalRejected;
23+
private final Long totalAccepted;
24+
private final Long total;
25+
26+
public static VisualResults generate(RemoteWebDriver driver) {
27+
return new VisualResults(driver);
28+
}
29+
30+
private VisualResults(RemoteWebDriver driver) {
31+
results = (Map<String, Object>) driver.executeScript("/*@visual.end*/");
32+
33+
this.passed = (Boolean) results.get("passed");
34+
this.message = (String) results.get("message");
35+
this.status = (String) results.get("status"); // success, failure, error, timeout, cancelled
36+
37+
for (Map state : (List<Map>) results.get("states")) {
38+
snapshots.add(new VisualSnapshot(state));
39+
}
40+
41+
this.totals = (Map) results.get("totals");
42+
this.totalNew = (Long) totals.get("new");
43+
this.totalChanged = (Long) totals.get("changed");
44+
this.totalRejected = (Long) totals.get("rejected");
45+
this.totalAccepted = (Long) totals.get("accepted");
46+
this.total = (Long) totals.get("all");
47+
}
48+
49+
public String getSummary() {
50+
String disposition = getPassed() ? getStatus() : getMessage();
51+
return "Totals: " + getTotals() + "; Disposition: " + disposition + "\n";
52+
}
53+
}

java/main/src/main/java/com/saucelabs/saucebindings/VisualSession.java

Lines changed: 44 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,14 @@
33
import com.saucelabs.saucebindings.options.SauceOptions;
44
import com.saucelabs.saucebindings.options.VisualOptions;
55
import org.openqa.selenium.InvalidArgumentException;
6-
import org.openqa.selenium.MutableCapabilities;
76
import org.openqa.selenium.remote.RemoteWebDriver;
87

98
import java.net.MalformedURLException;
109
import java.net.URL;
11-
import java.util.Map;
1210

1311
public class VisualSession extends SauceSession {
14-
private VisualOptions visualOptions;
12+
private VisualResults visualResults;
13+
private final VisualOptions visualOptions;
1514

1615
public VisualSession(String testName) {
1716
this(new VisualOptions(SauceOptions.chrome().setName(testName).build()));
@@ -22,6 +21,13 @@ public VisualSession(VisualOptions options) {
2221
this.visualOptions = options;
2322
}
2423

24+
@Override
25+
public RemoteWebDriver start() {
26+
this.driver = createRemoteWebDriver(getSauceUrl(), visualOptions.toCapabilities());
27+
newVisualTest(getSauceOptions().sauce().getName());
28+
return driver;
29+
}
30+
2531
@Override
2632
public URL getSauceUrl() {
2733
try {
@@ -31,25 +37,49 @@ public URL getSauceUrl() {
3137
}
3238
}
3339

34-
public RemoteWebDriver start() {
35-
MutableCapabilities capabilities = visualOptions.toCapabilities();
36-
37-
this.driver = createRemoteWebDriver(getSauceUrl(), capabilities);
38-
driver.executeScript("/*@visual.init*/", getSauceOptions().sauce().getName());
39-
40-
return driver;
40+
public void newVisualTest(String testName) {
41+
validateVisualStatus();
42+
driver.executeScript("/*@visual.init*/", testName);
4143
}
4244

4345
public void takeSnapshot(String name) {
46+
validateVisualStatus();
4447
driver.executeScript("/*@visual.snapshot*/", name);
4548
}
4649

47-
public Map<String, Object> getResults() {
48-
return (Map<String, Object>) driver.executeScript("/*@visual.end*/");
50+
public VisualResults getVisualResults() {
51+
if (visualResults == null) {
52+
this.visualResults = VisualResults.generate(driver);
53+
}
54+
return visualResults;
55+
}
56+
57+
@Override
58+
public void stop(Boolean passed) {
59+
String result = passed ? "passed" : "failed";
60+
stop(result);
61+
}
62+
63+
@Override
64+
public void stop(String result) {
65+
if (driver != null) {
66+
System.out.println(getVisualResults().getSummary());
67+
super.stop(result);
68+
}
4969
}
5070

5171
public void stop() {
52-
System.out.println("\n Visual Results: " + getResults());
53-
super.quit();
72+
if (driver != null) {
73+
VisualResults results = getVisualResults();
74+
System.out.println(results.getSummary());
75+
String result = results.getPassed() ? "passed" : "failed";
76+
super.stop(result);
77+
}
78+
}
79+
80+
private void validateVisualStatus() {
81+
if (this.visualResults != null) {
82+
throw new SauceVisualException("Can not execute Visual Commands after calling getVisualResults()");
83+
}
5484
}
5585
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package com.saucelabs.saucebindings;
2+
3+
import lombok.Getter;
4+
import lombok.Setter;
5+
6+
import java.util.Map;
7+
8+
@Setter @Getter
9+
public class VisualSnapshot {
10+
private final String name;
11+
private final String groupName;
12+
private final String status;
13+
private final String url;
14+
15+
public VisualSnapshot(Map<String, String> results) {
16+
this.name = results.get("name");
17+
this.groupName = results.get("groupName");
18+
this.status = results.get("status");
19+
this.url = results.get("url");
20+
}
21+
22+
@Override
23+
public String toString() {
24+
return name + ": " + url;
25+
}
26+
}
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
package com.saucelabs.saucebindings.integration;
2+
3+
import com.saucelabs.saucebindings.GitManager;
4+
import com.saucelabs.saucebindings.SauceVisualException;
5+
import com.saucelabs.saucebindings.VisualResults;
6+
import com.saucelabs.saucebindings.VisualSession;
7+
import com.saucelabs.saucebindings.VisualSnapshot;
8+
import org.junit.After;
9+
import org.junit.Before;
10+
import org.junit.Test;
11+
import org.openqa.selenium.remote.RemoteWebDriver;
12+
13+
import java.util.List;
14+
15+
import static org.junit.Assert.assertEquals;
16+
import static org.junit.Assert.assertNotNull;
17+
import static org.junit.Assert.assertNull;
18+
import static org.junit.Assert.assertTrue;
19+
import static org.junit.Assert.fail;
20+
21+
public class VisualTest {
22+
private VisualSession session;
23+
private RemoteWebDriver driver;
24+
25+
@Before
26+
public void setup() {
27+
System.setProperty("BUILD_NAME", "Sauce Bindings");
28+
}
29+
30+
@After
31+
public void cleanUp() {
32+
if (session != null) {
33+
session.stop();
34+
}
35+
}
36+
37+
@Test
38+
public void startsSession() {
39+
session = new VisualSession("VisualTest startsSession");
40+
driver = session.start();
41+
42+
assertNotNull(driver);
43+
assertTrue(session.getSauceUrl().toString().contains("screener.io"));
44+
}
45+
46+
@Test
47+
public void getVisualResults() {
48+
session = new VisualSession("VisualTest getVisualResults");
49+
driver = session.start();
50+
51+
session.takeSnapshot("Blank");
52+
53+
VisualResults results = session.getVisualResults();
54+
55+
assertTrue(results.getPassed());
56+
assertEquals("success", results.getStatus());
57+
58+
assertNull(results.getMessage());
59+
60+
assertEquals(Long.valueOf(1), results.getTotal());
61+
assertEquals(Long.valueOf(1), results.getTotalAccepted());
62+
assertEquals(Long.valueOf(0), results.getTotalNew());
63+
assertEquals(Long.valueOf(0), results.getTotalChanged());
64+
assertEquals(Long.valueOf(0), results.getTotalRejected());
65+
66+
List<VisualSnapshot> states = results.getSnapshots();
67+
assertEquals(1, states.size());
68+
69+
VisualSnapshot snapshot = results.getSnapshots().get(0);
70+
assertEquals("Blank", snapshot.getName());
71+
assertEquals("VisualTest getVisualResults", snapshot.getGroupName());
72+
assertEquals("accepted", snapshot.getStatus());
73+
String url = snapshot.getUrl();
74+
assertTrue(url.contains(GitManager.getCurrentBranch()));
75+
assertTrue(url.contains("Blank"));
76+
assertTrue(url.contains("Windows"));
77+
}
78+
79+
@Test
80+
public void runMultipleTests() {
81+
session = new VisualSession("VisualTest runMultipleTests 1");
82+
driver = session.start();
83+
84+
session.takeSnapshot("Blank1");
85+
86+
session.newVisualTest("VisualTest runMultipleTests 2");
87+
88+
session.takeSnapshot("Blank2");
89+
90+
VisualSnapshot test1 = session.getVisualResults().getSnapshots().get(0);
91+
VisualSnapshot test2 = session.getVisualResults().getSnapshots().get(1);
92+
assertEquals("Blank1", test1.getName());
93+
assertEquals("VisualTest runMultipleTests 1", test1.getGroupName());
94+
assertEquals("Blank2", test2.getName());
95+
assertEquals("VisualTest runMultipleTests 2", test2.getGroupName());
96+
}
97+
98+
@Test
99+
public void stopSendsVisualResultToSauce() {
100+
session = new VisualSession("VisualTest stopSendsVisualResultToSauce");
101+
driver = session.start();
102+
103+
session.stop();
104+
assertEquals("passed", session.getResult());
105+
}
106+
107+
@Test
108+
public void stopParameterOverridesVisualResult() {
109+
session = new VisualSession("VisualTest stopParameterOverridesVisualResult");
110+
driver = session.start();
111+
112+
session.stop(false);
113+
assertEquals("failed", session.getResult());
114+
}
115+
116+
@Test
117+
public void canNotTakeScreenshotAfterGettingVisualResults() {
118+
session = new VisualSession("VisualTest stopParameterOverridesVisualResult");
119+
driver = session.start();
120+
121+
session.getVisualResults();
122+
123+
try {
124+
session.takeSnapshot("Blank Page");
125+
fail("This should throw a SauceVisualException");
126+
} catch (SauceVisualException ex) {
127+
// Expected Behavior
128+
}
129+
}
130+
}

0 commit comments

Comments
 (0)