2121import static java .util .concurrent .TimeUnit .SECONDS ;
2222import static org .assertj .core .api .Assertions .assertThat ;
2323import static org .assertj .core .api .Assertions .assertThatExceptionOfType ;
24+ import static org .assertj .core .api .Assertions .assertThatThrownBy ;
2425import static org .assertj .core .api .InstanceOfAssertFactories .MAP ;
2526import static org .openqa .selenium .json .Json .MAP_TYPE ;
2627import static org .openqa .selenium .remote .http .Contents .string ;
3132import com .google .common .collect .ImmutableSet ;
3233
3334import java .nio .file .Path ;
35+ import java .util .List ;
36+ import java .util .Optional ;
3437import org .junit .jupiter .api .BeforeEach ;
38+ import org .junit .jupiter .api .DisplayName ;
3539import org .junit .jupiter .api .Test ;
40+ import org .junit .jupiter .api .TestInfo ;
3641import org .openqa .selenium .Capabilities ;
3742import org .openqa .selenium .ImmutableCapabilities ;
3843import org .openqa .selenium .NoSuchSessionException ;
4954import org .openqa .selenium .grid .data .Session ;
5055import org .openqa .selenium .grid .data .SessionClosedEvent ;
5156import org .openqa .selenium .grid .node .local .LocalNode ;
57+ import org .openqa .selenium .grid .node .local .LocalNode .Builder ;
5258import org .openqa .selenium .grid .node .remote .RemoteNode ;
5359import org .openqa .selenium .grid .security .Secret ;
5460import org .openqa .selenium .grid .testing .EitherAssert ;
@@ -106,7 +112,7 @@ private static <A, B> EitherAssert<A, B> assertThatEither(Either<A, B> either) {
106112 }
107113
108114 @ BeforeEach
109- public void setUp () throws URISyntaxException {
115+ public void setUp (TestInfo testInfo ) throws URISyntaxException {
110116 tracer = DefaultTestTracer .createTracer ();
111117 bus = new GuavaEventBus ();
112118
@@ -129,13 +135,15 @@ public HttpResponse execute(HttpRequest req) throws UncheckedIOException {
129135 }
130136 }
131137
132- local = LocalNode .builder (tracer , bus , uri , uri , registrationSecret )
133- .add (caps , new TestSessionFactory ((id , c ) -> new Handler (c )))
134- .add (caps , new TestSessionFactory ((id , c ) -> new Handler (c )))
135- .add (caps , new TestSessionFactory ((id , c ) -> new Handler (c )))
136- .downloadsPath (downloadsPath .getAbsolutePath ())
137- .maximumConcurrentSessions (2 )
138- .build ();
138+ Builder builder = LocalNode .builder (tracer , bus , uri , uri , registrationSecret )
139+ .add (caps , new TestSessionFactory ((id , c ) -> new Handler (c )))
140+ .add (caps , new TestSessionFactory ((id , c ) -> new Handler (c )))
141+ .add (caps , new TestSessionFactory ((id , c ) -> new Handler (c )))
142+ .maximumConcurrentSessions (2 );
143+ if (!testInfo .getDisplayName ().equalsIgnoreCase ("BootWithoutDownloadsDir" )) {
144+ builder = builder .downloadsPath (downloadsPath .getAbsolutePath ());
145+ }
146+ local = builder .build ();
139147
140148 node = new RemoteNode (
141149 tracer ,
@@ -495,20 +503,111 @@ void canDownloadAFile() throws IOException {
495503 Session session = response .right ().getSession ();
496504 String hello = "Hello, world!" ;
497505
498- HttpRequest req = new HttpRequest (GET , String .format ("/session/%s/se/file " , session .getId ()));
506+ HttpRequest req = new HttpRequest (POST , String .format ("/session/%s/se/files " , session .getId ()));
499507 File zip = createTmpFile (hello );
500- req .addQueryParameter ("filename" , zip .getName ());
508+ String payload = new Json ().toJson (Collections .singletonMap ("name" , zip .getName ()));
509+ req .setContent (() -> new ByteArrayInputStream (payload .getBytes ()));
501510 HttpResponse rsp = node .execute (req );
511+ Map <String , Object > raw = new Json ().toType (string (rsp ), Json .MAP_TYPE );
502512 node .stop (session .getId ());
503- Map < String , Object > map = new Json (). toType ( string ( rsp ), Json . MAP_TYPE );
513+ assertThat ( raw ). isNotNull ( );
504514 File baseDir = getTemporaryFilesystemBaseDir (TemporaryFilesystem .getDefaultTmpFS ());
515+ Map <String , Object > map = Optional .ofNullable (
516+ raw .get ("value" )
517+ ).map (data -> (Map <String , Object >) data )
518+ .orElseThrow (() -> new IllegalStateException ("Could not find value attribute" ));
505519 String encodedContents = map .get ("contents" ).toString ();
506520 Zip .unzip (encodedContents , baseDir );
507521 Path path = new File (baseDir .getAbsolutePath () + "/" + map .get ("filename" )).toPath ();
508522 String decodedContents = String .join ("" , Files .readAllLines (path ));
509523 assertThat (decodedContents ).isEqualTo (hello );
510524 }
511525
526+ @ Test
527+ void canListFilesToDownload () {
528+ Either <WebDriverException , CreateSessionResponse > response =
529+ node .newSession (createSessionRequest (caps ));
530+ assertThatEither (response ).isRight ();
531+ Session session = response .right ().getSession ();
532+ String hello = "Hello, world!" ;
533+ File zip = createTmpFile (hello );
534+ HttpRequest req = new HttpRequest (GET , String .format ("/session/%s/se/files" , session .getId ()));
535+ HttpResponse rsp = node .execute (req );
536+ Map <String , Object > raw = new Json ().toType (string (rsp ), Json .MAP_TYPE );
537+ node .stop (session .getId ());
538+ assertThat (raw ).isNotNull ();
539+ Map <String , Object > map = Optional .ofNullable (
540+ raw .get ("value" )
541+ ).map (data -> (Map <String , Object >) data )
542+ .orElseThrow (() -> new IllegalStateException ("Could not find value attribute" ));
543+ List <String > files = (List <String >) map .get ("names" );
544+ assertThat (files ).contains (zip .getName ());
545+ }
546+
547+ @ Test
548+ @ DisplayName ("BootWithoutDownloadsDir" )
549+ void canDownloadFileThrowsErrorMsgWhenDownloadsDirNotSpecified () {
550+ Either <WebDriverException , CreateSessionResponse > response =
551+ node .newSession (createSessionRequest (caps ));
552+ assertThatEither (response ).isRight ();
553+ Session session = response .right ().getSession ();
554+ createTmpFile ("Hello, world!" );
555+
556+ HttpRequest req = new HttpRequest (POST , String .format ("/session/%s/se/files" , session .getId ()));
557+ String msg = "Please specify the path wherein the files downloaded using the browser "
558+ + "would be available via the command line arg [--downloads-path] and restart the node" ;
559+ assertThatThrownBy (() -> node .execute (req ))
560+ .hasMessageContaining (msg );
561+ }
562+
563+ @ Test
564+ void canDownloadFileThrowsErrorMsgWhenPayloadIsMissing () {
565+ Either <WebDriverException , CreateSessionResponse > response =
566+ node .newSession (createSessionRequest (caps ));
567+ assertThatEither (response ).isRight ();
568+ Session session = response .right ().getSession ();
569+ createTmpFile ("Hello, world!" );
570+
571+ HttpRequest req = new HttpRequest (POST , String .format ("/session/%s/se/files" , session .getId ()));
572+ String msg = "Please specify file to download in payload as {\" name\" : \" fileToDownload\" }" ;
573+ assertThatThrownBy (() -> node .execute (req ))
574+ .hasMessageContaining (msg );
575+ }
576+
577+ @ Test
578+ void canDownloadFileThrowsErrorMsgWhenWrongPayloadIsGiven () {
579+ Either <WebDriverException , CreateSessionResponse > response =
580+ node .newSession (createSessionRequest (caps ));
581+ assertThatEither (response ).isRight ();
582+ Session session = response .right ().getSession ();
583+ createTmpFile ("Hello, world!" );
584+
585+ HttpRequest req = new HttpRequest (POST , String .format ("/session/%s/se/files" , session .getId ()));
586+ String payload = new Json ().toJson (Collections .singletonMap ("my-file" , "README.md" ));
587+ req .setContent (() -> new ByteArrayInputStream (payload .getBytes ()));
588+
589+ String msg = "Please specify file to download in payload as {\" name\" : \" fileToDownload\" }" ;
590+ assertThatThrownBy (() -> node .execute (req ))
591+ .hasMessageContaining (msg );
592+ }
593+
594+ @ Test
595+ void canDownloadFileThrowsErrorMsgWhenFileNotFound () {
596+ Either <WebDriverException , CreateSessionResponse > response =
597+ node .newSession (createSessionRequest (caps ));
598+ assertThatEither (response ).isRight ();
599+ Session session = response .right ().getSession ();
600+ createTmpFile ("Hello, world!" );
601+
602+ HttpRequest req = new HttpRequest (POST , String .format ("/session/%s/se/files" , session .getId ()));
603+ String payload = new Json ().toJson (Collections .singletonMap ("name" , "README.md" ));
604+ req .setContent (() -> new ByteArrayInputStream (payload .getBytes ()));
605+
606+ String msg = "Cannot find file [README.md] in directory" ;
607+ assertThatThrownBy (() -> node .execute (req ))
608+ .hasMessageContaining (msg );
609+ }
610+
512611 @ Test
513612 void shouldNotCreateSessionIfDraining () {
514613 node .drain ();
0 commit comments