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+ GET ,
19+ POST ,
20+ PATCH
21+ }
1822
1923@ Slf4j
2024public class VisualRegressionTracker {
2125
2226 private static final String TRACKER_NOT_STARTED = "Visual Regression Tracker has not been started" ;
2327 protected static final String API_KEY_HEADER = "apiKey" ;
24- protected static final MediaType JSON = MediaType .get ("application/json; charset=utf-8" );
2528 protected Gson gson ;
2629 protected VisualRegressionTrackerConfig configuration ;
2730 protected PathProvider paths ;
2831 protected String buildId ;
2932 protected String projectId ;
30- protected OkHttpClient client ;
3133
3234 public VisualRegressionTracker (VisualRegressionTrackerConfig trackerConfig ) {
3335 configuration = trackerConfig ;
3436 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 ();
4037 gson = new Gson ();
4138 }
4239
43- public BuildResponse start () throws IOException {
40+ public BuildResponse start () throws IOException , InterruptedException {
4441 String projectName = configuration .getProject ();
4542 String branch = configuration .getBranchName ();
4643 String ciBuildId = configuration .getCiBuildId ();
4744
4845 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-
46+ .branchName (branch )
47+ .project (projectName )
48+ .ciBuildId (ciBuildId )
49+ .build ();
6250 log .info ("Starting Visual Regression Tracker for project <{}> and branch <{}>" , projectName , branch );
63-
64- Response response = client .newCall (request ).execute ();
65-
51+ HttpRequest .BodyPublisher body = HttpRequest .BodyPublishers .ofString (gson .toJson (newBuild ));
52+ HttpResponse <String > response = getResponse (METHOD .POST , paths .getBuildPath (), body );
6653 BuildResponse buildResponse = handleResponse (response , BuildResponse .class );
6754
6855 buildId = buildResponse .getId ();
@@ -73,27 +60,22 @@ public BuildResponse start() throws IOException {
7360 return buildResponse ;
7461 }
7562
76- public void stop () throws IOException {
63+ public void stop () throws IOException , InterruptedException {
7764 if (!isStarted ()) {
7865 throw new TestRunException (TRACKER_NOT_STARTED );
7966 }
8067
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-
8768 log .info ("Stopping Visual Regression Tracker for buildId <{}>" , buildId );
8869
89- Response response = client .newCall (request ).execute ();
70+ HttpRequest .BodyPublisher body = HttpRequest .BodyPublishers .ofString ("" );
71+ HttpResponse <String > response = getResponse (METHOD .PATCH , paths .getBuildPathForBuild (buildId ), body );
9072 handleResponse (response , Object .class );
9173
9274 log .info ("Visual Regression Tracker is stopped for buildId <{}>" , buildId );
9375 }
9476
9577 public TestRunResult track (String name , String imageBase64 , TestRunOptions testRunOptions )
96- throws IOException {
78+ throws IOException , InterruptedException {
9779 log .info ("Tracking test run <{}> with options <{}> for buildId <{}>" , name , testRunOptions , buildId );
9880 TestRunResponse testResultDTO = submitTestRun (name , imageBase64 , testRunOptions );
9981
@@ -121,7 +103,7 @@ public TestRunResult track(String name, String imageBase64, TestRunOptions testR
121103 return new TestRunResult (testResultDTO , this .paths );
122104 }
123105
124- public TestRunResult track (String name , String imageBase64 ) throws IOException {
106+ public TestRunResult track (String name , String imageBase64 ) throws IOException , InterruptedException {
125107 return track (name , imageBase64 , TestRunOptions .builder ().build ());
126108 }
127109
@@ -130,46 +112,61 @@ protected boolean isStarted() {
130112 }
131113
132114 protected TestRunResponse submitTestRun (String name , String imageBase64 ,
133- TestRunOptions testRunOptions ) throws IOException {
115+ TestRunOptions testRunOptions ) throws IOException , InterruptedException {
134116 if (!isStarted ()) {
135117 throw new TestRunException (TRACKER_NOT_STARTED );
136118 }
137119
138120 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 ();
121+ .projectId (projectId )
122+ .buildId (buildId )
123+ .branchName (configuration .getBranchName ())
124+ .name (name )
125+ .imageBase64 (imageBase64 )
126+ .os (testRunOptions .getOs ())
127+ .browser (testRunOptions .getBrowser ())
128+ .viewport (testRunOptions .getViewport ())
129+ .device (testRunOptions .getDevice ())
130+ .diffTollerancePercent (testRunOptions .getDiffTollerancePercent ())
131+ .ignoreAreas (testRunOptions .getIgnoreAreas ())
132+ .build ();
133+
134+ HttpRequest .BodyPublisher body = HttpRequest .BodyPublishers .ofString (gson .toJson (newTestRun ));
135+ HttpResponse <String > response = getResponse (METHOD .POST , paths .getTestRunPath (), body );
161136 return handleResponse (response , TestRunResponse .class );
162137 }
163138
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 ();
139+ private HttpResponse <String > getResponse (METHOD method , String url , HttpRequest .BodyPublisher body ) throws IOException , InterruptedException {
140+ HttpRequest .Builder requestBuilder = HttpRequest .newBuilder ()
141+ .timeout (Duration .ofSeconds (configuration .getHttpTimeoutInSeconds ()))
142+ .header (API_KEY_HEADER , configuration .getApiKey ())
143+ .header ("Content-Type" , "application/json;charset=UTF-8" )
144+ .uri (URI .create (url ));
145+ HttpRequest request = getRequest (method , body , requestBuilder );
146+ HttpResponse <String > response = HttpClient .newBuilder ()
147+ .version (HttpClient .Version .HTTP_1_1 )
148+ .connectTimeout (Duration .ofSeconds (configuration .getHttpTimeoutInSeconds ()))
149+ .build ()
150+ .send (request , HttpResponse .BodyHandlers .ofString ());
151+ return response ;
152+ }
153+
154+ protected HttpRequest getRequest (METHOD method , HttpRequest .BodyPublisher body , HttpRequest .Builder requestBuilder ) {
155+ switch (method ) {
156+ case PATCH :
157+ return requestBuilder .method ("PATCH" , body ).build ();
158+ case POST :
159+ return requestBuilder .POST (body ).build ();
160+ default :
161+ throw new UnsupportedOperationException ("This method is not yet supported." );
162+ }
163+ }
168164
169- if (!response .isSuccessful ()) {
165+ protected <T > T handleResponse (HttpResponse <String > response , Class <T > classOfT ) {
166+ String responseBody = response .body ();
167+ if (!String .valueOf (response .statusCode ()).startsWith ("2" )) {
170168 throw new TestRunException (responseBody );
171169 }
172-
173170 return gson .fromJson (responseBody , classOfT );
174171 }
175172}
0 commit comments