11package io .visual_regression_tracker .sdk_java ;
22
3- import java .io .IOException ;
4- import java .util .Optional ;
5- import java .util .concurrent .TimeUnit ;
6-
73import com .google .gson .Gson ;
84import io .visual_regression_tracker .sdk_java .request .BuildRequest ;
95import io .visual_regression_tracker .sdk_java .request .TestRunRequest ;
106import io .visual_regression_tracker .sdk_java .response .BuildResponse ;
117import io .visual_regression_tracker .sdk_java .response .TestRunResponse ;
128import 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+ }
1821
1922@ Slf4j
2023public class VisualRegressionTracker {
2124
2225 private static final String TRACKER_NOT_STARTED = "Visual Regression Tracker has not been started" ;
2326 protected static final String API_KEY_HEADER = "apiKey" ;
24- protected static final MediaType JSON = MediaType .get ("application/json; charset=utf-8" );
2527 protected Gson gson ;
2628 protected VisualRegressionTrackerConfig configuration ;
2729 protected PathProvider paths ;
2830 protected String buildId ;
2931 protected String projectId ;
30- protected OkHttpClient client ;
3132
3233 public VisualRegressionTracker (VisualRegressionTrackerConfig trackerConfig ) {
3334 configuration = trackerConfig ;
3435 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 ();
4036 gson = new Gson ();
4137 }
4238
43- public BuildResponse start () throws IOException {
39+ public BuildResponse start () throws IOException , InterruptedException {
4440 String projectName = configuration .getProject ();
4541 String branch = configuration .getBranchName ();
4642 String ciBuildId = configuration .getCiBuildId ();
4743
4844 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 ();
6249 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 );
6652 BuildResponse buildResponse = handleResponse (response , BuildResponse .class );
6753
6854 buildId = buildResponse .getId ();
6955 projectId = buildResponse .getProjectId ();
7056
7157 log .info ("Visual Regression Tracker is started for project <{}>: buildId: <{}>, projectId: <{}>, ciBuildId: <{}>" ,
72- projectName , projectId , buildId , buildResponse .getCiBuildId ());
58+ projectName , projectId , buildId , buildResponse .getCiBuildId ());
7359 return buildResponse ;
7460 }
7561
76- public void stop () throws IOException {
62+ public void stop () throws IOException , InterruptedException {
7763 if (!isStarted ()) {
7864 throw new TestRunException (TRACKER_NOT_STARTED );
7965 }
8066
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-
8767 log .info ("Stopping Visual Regression Tracker for buildId <{}>" , buildId );
8868
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 );
9071 handleResponse (response , Object .class );
9172
9273 log .info ("Visual Regression Tracker is stopped for buildId <{}>" , buildId );
9374 }
9475
9576 public TestRunResult track (String name , String imageBase64 , TestRunOptions testRunOptions )
96- throws IOException {
77+ throws IOException , InterruptedException {
9778 log .info ("Tracking test run <{}> with options <{}> for buildId <{}>" , name , testRunOptions , buildId );
9879 TestRunResponse testResultDTO = submitTestRun (name , imageBase64 , testRunOptions );
9980
@@ -121,7 +102,7 @@ public TestRunResult track(String name, String imageBase64, TestRunOptions testR
121102 return new TestRunResult (testResultDTO , this .paths );
122103 }
123104
124- public TestRunResult track (String name , String imageBase64 ) throws IOException {
105+ public TestRunResult track (String name , String imageBase64 ) throws IOException , InterruptedException {
125106 return track (name , imageBase64 , TestRunOptions .builder ().build ());
126107 }
127108
@@ -130,46 +111,60 @@ protected boolean isStarted() {
130111 }
131112
132113 protected TestRunResponse submitTestRun (String name , String imageBase64 ,
133- TestRunOptions testRunOptions ) throws IOException {
114+ TestRunOptions testRunOptions ) throws IOException , InterruptedException {
134115 if (!isStarted ()) {
135116 throw new TestRunException (TRACKER_NOT_STARTED );
136117 }
137118
138119 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 );
161135 return handleResponse (response , TestRunResponse .class );
162136 }
163137
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+ }
168162
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" )) {
170166 throw new TestRunException (responseBody );
171167 }
172-
173168 return gson .fromJson (responseBody , classOfT );
174169 }
175170}
0 commit comments