1 2 3 Previous Next 41 Replies Latest reply on Dec 5, 2012 4:15 PM by dan.j.allen Go to original post
      • 30. Re: Warp: fluent API for request execution - naming
        dan.j.allen

        I consulted the editor. We arrived at a revision with the same basic structure, but may make this all a bunch clearer.

         

        Warp
            .initiate(new Activity() {
                public void perform() {
                    browser.findElement(By.id("order")).click();
                }
            })
            .observeServer(FacesLifecycle.class, forURLs("*.jsf"));
            .inspect(new Inspection() {
                @BeforePhase(Phase.RENDER_RESPONSE)
                public void checkOrder() {
                    FacesContext context = FacesContext.getCurrentInstance();
                    assertEquals(getMessageList().size(), 1);
                }); 
            });
        

         

        wdyt?

         

        We could also have observeResponse().inspect(Inspection) at the end, which could potentially trap a subset (or superset) of URLs. An alternative would be onReturn(Inspection)

        • 31. Re: Warp: fluent API for request execution - naming
          aslak

          doh.. yea.. I was reading it without "warp" for some reason..

          • 32. Re: Warp: fluent API for request execution - naming
            lfryc

            Filters are conditions which must be met to proceed with given inspection - they can be based on any attribute of request, either on client, proxy or server.

             

            Warp.fromClient(Activity).toServer(Inspector).observing(Conditions);
            

             

            I like wording, but the flow is broken here again:

            "For given activity, initiate request and inspect server once you will observe request under given conditions."

             

             

            Have in mind that specifying Conditions is optional - they could be pre-configured or you just know there won't be more than one request initiated by activity.

             

            Warp.observing(FacesViewRequests.class);
            // alternatively @WarpObserves(FacesViewRequests.class)
            
            Warp
                .when(Activity)
                .then(Inspect);
            

             

            One more thing we must be aware of are request groups: you might want to verify several requests initiated by one client activity - e.g. there is subsequent request, or there are several requests at once and each needs to be verified in different way.

             

            Warp
                 .when(Activity)
                 .group("first-request")
                     .observing(FacesResourceRequests.class, request().withCount(1)) // matching first request for URL /javax.faces.resource/
                      .then(Inspect)
                 .group("second-request")
                      .observing(FacesResourceRequests.class, request().withCount(2))
                      .then(Inspect);
                 .proceed();
            
            • 33. Re: Warp: fluent API for request execution - naming
              dan.j.allen

              Thanks for the clarification. I figured it had to do with which requests would be trapped, but I forgot about the fact that there can even be JSF requests we want to skip (as Aslak mentioned).

               

              I did even more thinking about the naming and I think I'm getting closer to something that feels right.

               

              As I understand it, there are three steps

               

              • perform activity in client that initiates a request (or more than one?)
              • filter the requests (optional)
              • inspect the server (possibly different inspections for different filters)

               

              The name "initiate" for the first step seems very natural to me.

               

              The obvious choice for the second step is "filter", though I'd also suggest "capture", "trap", "observe", "tunnel" or "jump" (the latter two to play on the Warp theme)

               

              The obvious choice for the third step is "inspect", though I also like "analyze" or "probe" (feels very alien)

               

              I think the grouping can be moved into the filter method. Any inspect command that occurs after a filter command applies to those requests.

               

              Here's the combo that really grabs me:

               

              Warp.initiate(Activity).capture(Filter).probe(Inspection)

               

              That could be branched using:

               

              Warp.initiate(Activity).capture(Filter1).probe(Inspection1).capture(Filter2).probe(Inspection2);

               

              Here's my full example from earlier w/ the new names:

               

               

              Warp
                  .initiate(new Activity() {
                      public void perform() {
                          browser.findElement(By.id("order")).click();
                      }
                  })
                  .capture(FacesLifecycle.class, request().endsWith("*.jsf"))
                  .probe(new Inspection() {
                      @BeforePhase(Phase.RENDER_RESPONSE)
                      public void checkOrder() {
                          FacesContext context = FacesContext.getCurrentInstance();
                          assertEquals(getMessageList().size(), 1);
                      }); 
                  });

               

               

              I've suggested a number of permutations. None of them feel wrong...we may be getting close to it being a style issue. We could do a vote and see what people like best. When I see examples from Arquillian in talks, it always reminds me that what matters the most is what people think when the first see it. If they react badly or get confused, then the API has the wrong names

              • 34. Re: Warp: fluent API for request execution - naming
                dan.j.allen

                I want to play the API over Jakub's REST example to see how it reads in a more concrete scenario:

                 

                  

                    @Test
                    public void testAjaxGetStock() {
                        browser.navigate().to(contextUrl + "restclient.jsp");
                
                        Warp.initiate(new Activity() {
                            @Override
                            public void perform() {
                                browser.findElement(By.className("stockLink")).click();
                            }
                        })
                        .capture(ServletLifecycle.class, request().endsWith("/stocks"))
                        .probe(new Inspection() {
                            private static final long serialVersionUID = 1L;
                
                            @ArquillianResource
                            private RestContext restContext;
                
                            @AfterServlet
                            public void testGetStock() {
                                assertThat(restContext.getRequest().getMethod()).isEqualTo(HttpMethod.GET);
                                assertThat(restContext.getResponse().getStatusCode()).isEqualTo(Response.Status.OK.getStatusCode());
                                assertThat(restContext.getResponse().getContentType()).isEqualTo("application/json");
                
                                Stock stock = (Stock) restContext.getResponse().getEntity();
                                assertThat(stock.getId()).isEqualTo(1L);
                                assertThat(stock.getName()).isEqualTo("Acme");
                                assertThat(stock.getCode()).isEqualTo("ACM");
                            }
                        });
                    }
                

                 

                I haven't fleshed out the API for the filtering...I'll let the fluent masters (graphene, fluentlenium) resolve that one

                • 35. Re: Warp: fluent API for request execution - naming
                  jmnarloch

                  In regards of filters:

                   

                  I was thikning about something like:

                   

                  {code}

                  request()

                       .url(regex("\\.jsf"))

                       .method(equal(HttpMethod.GET))

                       .header("Accept", contains("application/json")); // if warp will allow for header filtering

                  {code}

                   

                  With matchers being passed to specific methods.

                   

                  Inspired a bit by spring-mvc-test I was thinking about alternative syntax:

                   

                  {code}

                  request()

                       .add(url().regex("\\.jsf"))

                       .add(method().equal(HttpMethod.GET))

                       .add(header().contains("Accept" ,"application/json"));

                  {code}

                   

                  Although the first one, based on completly seperate matchers in my opinion is the most flexible:

                  I can imagine creating more complex conditions, (apart from the usefulness of the example):

                   

                  {code}

                  request.url(or(startsWith("http://"), startsWith("https://")));

                  {code}

                   

                  And more over we could have one set of the matchers for all of cases.

                  • 36. Re: Warp: fluent API for request execution - naming
                    lfryc
                    Warp.initiate(Activity).capture(What).probe(Inspection);
                    

                     

                    +1 sounds so alien-ish, best fit for the story

                    • 37. Re: Warp: fluent API for request execution - naming
                      lfryc

                      Jakub Narloch wrote:

                       

                      
                      request.url(or(startsWith("http://"), startsWith("https://")));
                      

                       

                       

                      And more over we could have one set of the matchers for all of cases.

                       

                      Could we design Filter builder without use of  "onioning" (how Bartosz said)? The true is that it requires more documentation efforts and involves more static imports than necessary.

                       

                      If we could get with powerful chaining API without onioning, it will be big win.

                      • 38. Re: Warp: fluent API for request execution - naming
                        jmnarloch

                        Lukáš Fryč wrote:

                         

                        Could we design Filter builder without use of  "onioning" (how Bartosz said)? The true is that it requires more documentation efforts and involves more static imports than necessary.

                         

                        If we could get with powerful chaining API without onioning, it will be big win.

                        Right. We could create everything we whant. Well maybe without reasonable "or" form.

                        The previouse example could look like:

                         

                         

                        {code}

                        request()

                             .url().regex("\\.jsf")

                             .method().equal(HttpMethod.GET)

                             .header().contains("Accept", "application/json")

                        {code}

                         

                        With one regards, that the equal in such case might be somehow confusing with Object#equals method so maybe it would good to rename it.

                        • 39. Re: Warp: fluent API for request execution - naming
                          lfryc

                          Prepared a survey which collects most important proposals here:

                           

                          https://docs.google.com/spreadsheet/viewform?formkey=dFlZeGI3ZklOUVlDX2M2V2owUkFmYVE6MQ

                           

                          Let's vote to choose a best fit!

                          • 40. Re: Warp: fluent API for request execution - naming
                            lfryc

                            Okay, everyone, we got nice 8 responses in the survey,

                             

                            and so a winner is

                             

                            Warp

                              .initiate(Activity)

                              .observe(What)

                              .inspect(Inspection);

                             

                             

                            with 50% people saying it's completely natural,

                            and 38% people saying it's quite natural.

                             

                             

                            I would like to thank everyone who participated and I don't need to say how valuable the feedback is!

                             

                            You can see complete results (exported to PDF) and issue is now tracked for renaming API.

                            • 41. Re: Warp: fluent API for request execution - naming
                              dan.j.allen

                              Awesome!

                               

                              Great job managing this design Lukas. There's no doubt, this is going to be one of the APIs for which were the most proud. Win.

                              1 2 3 Previous Next