1
1
package io .visual_regression_tracker .sdk_java ;
2
2
3
- import java .io .IOException ;
4
- import java .util .Optional ;
5
- import java .util .concurrent .TimeUnit ;
6
-
7
3
import com .google .gson .Gson ;
8
4
import io .visual_regression_tracker .sdk_java .request .BuildRequest ;
9
5
import io .visual_regression_tracker .sdk_java .request .TestRunRequest ;
10
6
import io .visual_regression_tracker .sdk_java .response .BuildResponse ;
11
7
import io .visual_regression_tracker .sdk_java .response .TestRunResponse ;
12
8
import lombok .extern .slf4j .Slf4j ;
13
- import okhttp3 .MediaType ;
14
- import okhttp3 .OkHttpClient ;
15
- import okhttp3 .Request ;
16
- import okhttp3 .RequestBody ;
17
- import okhttp3 .Response ;
9
+
10
+ import java .io .IOException ;
11
+ import java .net .URI ;
12
+ import java .net .http .HttpClient ;
13
+ import java .net .http .HttpRequest ;
14
+ import java .net .http .HttpResponse ;
15
+ import java .time .Duration ;
16
+
17
+ enum METHOD {
18
+ POST ,
19
+ PATCH
20
+ }
18
21
19
22
@ Slf4j
20
23
public class VisualRegressionTracker {
21
24
22
25
private static final String TRACKER_NOT_STARTED = "Visual Regression Tracker has not been started" ;
23
26
protected static final String API_KEY_HEADER = "apiKey" ;
24
- protected static final MediaType JSON = MediaType .get ("application/json; charset=utf-8" );
25
27
protected Gson gson ;
26
28
protected VisualRegressionTrackerConfig configuration ;
27
29
protected PathProvider paths ;
28
30
protected String buildId ;
29
31
protected String projectId ;
30
- protected OkHttpClient client ;
31
32
32
33
public VisualRegressionTracker (VisualRegressionTrackerConfig trackerConfig ) {
33
34
configuration = trackerConfig ;
34
35
paths = new PathProvider (trackerConfig .getApiUrl ());
35
- client = new OkHttpClient .Builder ()
36
- .connectTimeout (configuration .getHttpTimeoutInSeconds (), TimeUnit .SECONDS )
37
- .readTimeout (configuration .getHttpTimeoutInSeconds (), TimeUnit .SECONDS )
38
- .writeTimeout (configuration .getHttpTimeoutInSeconds (), TimeUnit .SECONDS )
39
- .build ();
40
36
gson = new Gson ();
41
37
}
42
38
43
- public BuildResponse start () throws IOException {
39
+ public BuildResponse start () throws IOException , InterruptedException {
44
40
String projectName = configuration .getProject ();
45
41
String branch = configuration .getBranchName ();
46
42
String ciBuildId = configuration .getCiBuildId ();
47
43
48
44
BuildRequest newBuild = BuildRequest .builder ()
49
- .branchName (branch )
50
- .project (projectName )
51
- .ciBuildId (ciBuildId )
52
- .build ();
53
-
54
- RequestBody body = RequestBody .create (JSON , gson .toJson (newBuild ));
55
-
56
- Request request = new Request .Builder ()
57
- .url (paths .getBuildPath ())
58
- .addHeader (API_KEY_HEADER , configuration .getApiKey ())
59
- .post (body )
60
- .build ();
61
-
45
+ .branchName (branch )
46
+ .project (projectName )
47
+ .ciBuildId (ciBuildId )
48
+ .build ();
62
49
log .info ("Starting Visual Regression Tracker for project <{}> and branch <{}>" , projectName , branch );
63
-
64
- Response response = client .newCall (request ).execute ();
65
-
50
+ HttpRequest .BodyPublisher body = HttpRequest .BodyPublishers .ofString (gson .toJson (newBuild ));
51
+ HttpResponse <String > response = getResponse (METHOD .POST , paths .getBuildPath (), body );
66
52
BuildResponse buildResponse = handleResponse (response , BuildResponse .class );
67
53
68
54
buildId = buildResponse .getId ();
69
55
projectId = buildResponse .getProjectId ();
70
56
71
57
log .info ("Visual Regression Tracker is started for project <{}>: buildId: <{}>, projectId: <{}>, ciBuildId: <{}>" ,
72
- projectName , projectId , buildId , buildResponse .getCiBuildId ());
58
+ projectName , projectId , buildId , buildResponse .getCiBuildId ());
73
59
return buildResponse ;
74
60
}
75
61
76
- public void stop () throws IOException {
62
+ public void stop () throws IOException , InterruptedException {
77
63
if (!isStarted ()) {
78
64
throw new TestRunException (TRACKER_NOT_STARTED );
79
65
}
80
66
81
- Request request = new Request .Builder ()
82
- .url (paths .getBuildPathForBuild (buildId ))
83
- .addHeader (API_KEY_HEADER , configuration .getApiKey ())
84
- .patch (RequestBody .create (JSON , "" ))
85
- .build ();
86
-
87
67
log .info ("Stopping Visual Regression Tracker for buildId <{}>" , buildId );
88
68
89
- Response response = client .newCall (request ).execute ();
69
+ HttpRequest .BodyPublisher body = HttpRequest .BodyPublishers .ofString ("" );
70
+ HttpResponse <String > response = getResponse (METHOD .PATCH , paths .getBuildPathForBuild (buildId ), body );
90
71
handleResponse (response , Object .class );
91
72
92
73
log .info ("Visual Regression Tracker is stopped for buildId <{}>" , buildId );
93
74
}
94
75
95
76
public TestRunResult track (String name , String imageBase64 , TestRunOptions testRunOptions )
96
- throws IOException {
77
+ throws IOException , InterruptedException {
97
78
log .info ("Tracking test run <{}> with options <{}> for buildId <{}>" , name , testRunOptions , buildId );
98
79
TestRunResponse testResultDTO = submitTestRun (name , imageBase64 , testRunOptions );
99
80
@@ -121,7 +102,7 @@ public TestRunResult track(String name, String imageBase64, TestRunOptions testR
121
102
return new TestRunResult (testResultDTO , this .paths );
122
103
}
123
104
124
- public TestRunResult track (String name , String imageBase64 ) throws IOException {
105
+ public TestRunResult track (String name , String imageBase64 ) throws IOException , InterruptedException {
125
106
return track (name , imageBase64 , TestRunOptions .builder ().build ());
126
107
}
127
108
@@ -130,46 +111,60 @@ protected boolean isStarted() {
130
111
}
131
112
132
113
protected TestRunResponse submitTestRun (String name , String imageBase64 ,
133
- TestRunOptions testRunOptions ) throws IOException {
114
+ TestRunOptions testRunOptions ) throws IOException , InterruptedException {
134
115
if (!isStarted ()) {
135
116
throw new TestRunException (TRACKER_NOT_STARTED );
136
117
}
137
118
138
119
TestRunRequest newTestRun = TestRunRequest .builder ()
139
- .projectId (projectId )
140
- .buildId (buildId )
141
- .branchName (configuration .getBranchName ())
142
- .name (name )
143
- .imageBase64 (imageBase64 )
144
- .os (testRunOptions .getOs ())
145
- .browser (testRunOptions .getBrowser ())
146
- .viewport (testRunOptions .getViewport ())
147
- .device (testRunOptions .getDevice ())
148
- .diffTollerancePercent (testRunOptions .getDiffTollerancePercent ())
149
- .ignoreAreas (testRunOptions .getIgnoreAreas ())
150
- .build ();
151
-
152
- RequestBody body = RequestBody .create (JSON , gson .toJson (newTestRun ));
153
-
154
- Request request = new Request .Builder ()
155
- .url (paths .getTestRunPath ())
156
- .addHeader (API_KEY_HEADER , configuration .getApiKey ())
157
- .post (body )
158
- .build ();
159
-
160
- Response response = client .newCall (request ).execute ();
120
+ .projectId (projectId )
121
+ .buildId (buildId )
122
+ .branchName (configuration .getBranchName ())
123
+ .name (name )
124
+ .imageBase64 (imageBase64 )
125
+ .os (testRunOptions .getOs ())
126
+ .browser (testRunOptions .getBrowser ())
127
+ .viewport (testRunOptions .getViewport ())
128
+ .device (testRunOptions .getDevice ())
129
+ .diffTollerancePercent (testRunOptions .getDiffTollerancePercent ())
130
+ .ignoreAreas (testRunOptions .getIgnoreAreas ())
131
+ .build ();
132
+
133
+ HttpRequest .BodyPublisher body = HttpRequest .BodyPublishers .ofString (gson .toJson (newTestRun ));
134
+ HttpResponse <String > response = getResponse (METHOD .POST , paths .getTestRunPath (), body );
161
135
return handleResponse (response , TestRunResponse .class );
162
136
}
163
137
164
- protected <T > T handleResponse (Response response , Class <T > classOfT ) throws IOException {
165
- String responseBody = Optional .ofNullable (response .body ())
166
- .orElseThrow (() -> new TestRunException ("Cannot get response body" ))
167
- .string ();
138
+ private HttpResponse <String > getResponse (METHOD method , String url , HttpRequest .BodyPublisher body ) throws IOException , InterruptedException {
139
+ HttpRequest .Builder requestBuilder = HttpRequest .newBuilder ()
140
+ .timeout (Duration .ofSeconds (configuration .getHttpTimeoutInSeconds ()))
141
+ .header (API_KEY_HEADER , configuration .getApiKey ())
142
+ .header ("Content-Type" , "application/json;charset=UTF-8" )
143
+ .uri (URI .create (url ));
144
+ HttpRequest request ;
145
+ switch (method ) {
146
+ case PATCH :
147
+ request = requestBuilder .method ("PATCH" , body ).build ();
148
+ break ;
149
+ case POST :
150
+ request = requestBuilder .POST (body ).build ();
151
+ break ;
152
+ default :
153
+ throw new IllegalStateException ("Not implemented: " + method );
154
+ }
155
+ HttpResponse <String > response = HttpClient .newBuilder ()
156
+ .version (HttpClient .Version .HTTP_1_1 )
157
+ .connectTimeout (Duration .ofSeconds (configuration .getHttpTimeoutInSeconds ()))
158
+ .build ()
159
+ .send (request , HttpResponse .BodyHandlers .ofString ());
160
+ return response ;
161
+ }
168
162
169
- if (!response .isSuccessful ()) {
163
+ protected <T > T handleResponse (HttpResponse <String > response , Class <T > classOfT ) {
164
+ String responseBody = response .body ();
165
+ if (!String .valueOf (response .statusCode ()).startsWith ("2" )) {
170
166
throw new TestRunException (responseBody );
171
167
}
172
-
173
168
return gson .fromJson (responseBody , classOfT );
174
169
}
175
170
}
0 commit comments